Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions apps/remix-ide/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ import Filepanel from './app/panels/file-panel'
import Editor from './app/editor/editor'
import Terminal from './app/panels/terminal'
import TabProxy from './app/panels/tab-proxy.js'
import { Plugin } from '@remixproject/engine'
import BottomBarPanel from './app/components/bottom-bar-panel'
import { Circles } from './app/plugins/circles'

const _paq = (window._paq = window._paq || [])

Expand Down Expand Up @@ -403,6 +403,8 @@ class AppComponent {

const walletConnect = new WalletConnect()

const circles = new Circles()

this.engine.register([
permissionHandler,
this.layout,
Expand Down Expand Up @@ -459,7 +461,8 @@ class AppComponent {
scriptRunnerUI,
remixAI,
remixAiAssistant,
walletConnect
walletConnect,
circles
])

//---- fs plugin
Expand Down Expand Up @@ -736,7 +739,7 @@ class AppComponent {
})

// activate solidity plugin
this.appManager.activatePlugin(['solidity', 'udapp', 'deploy-libraries', 'link-libraries', 'openzeppelin-proxy', 'scriptRunnerBridge'])
this.appManager.activatePlugin(['solidity', 'udapp', 'deploy-libraries', 'link-libraries', 'openzeppelin-proxy', 'scriptRunnerBridge', 'circles'])

if (isElectron()){
this.appManager.activatePlugin(['desktopHost'])
Expand Down
57 changes: 57 additions & 0 deletions apps/remix-ide/src/app/plugins/circles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
'use strict'
import { Plugin } from '@remixproject/engine'
import { Sdk } from '@circles-sdk/sdk'
import { BrowserProviderContractRunner } from "@circles-sdk/adapter-ethers"
import { BrowserProvider } from 'ethers'
import { GitHubUser } from '@remix-api'

const _paq = window._paq = window._paq || []

const profile = {
name: 'circles',
description: 'circles UBI',
methods: ['initSdk', 'deleteProfile'],
events: [],
version: '1.0.0'
}

const CIRLCES_KEY = 'CIRLCES_KEY'

export class Circles extends Plugin {
constructor() {
super(profile)
}

onActivation(): void {}

public async initSdk (user: GitHubUser) {
try {
if (!user) {
this.call('terminal', 'log', { type: 'error', value: 'please log in with github before initiating a circles profile'})
return
}
const adapter = new BrowserProviderContractRunner()
const web3 = await this.call('blockchain', 'web3')
console.log('web3', web3);
// (adapter as any).provider = new BrowserProvider(web3.currentProvider)
await adapter.init();
const sdk = new Sdk(adapter)

if (!localStorage.getItem(CIRLCES_KEY)) {
this.call('terminal', 'log', { type: 'log', value: `creating Circles profile...${user.login}`})
const profileData = { name: user.login, description: '' }
const receipt = await sdk.createOrUpdateProfile(profileData)
localStorage.setItem(CIRLCES_KEY, JSON.stringify(receipt))
}
this.call('terminal', 'log', { type: 'log', value: 'Circles profile:'})
this.call('terminal', 'log', { type: 'log', value: localStorage.getItem(CIRLCES_KEY)})
} catch (e) {
console.error(e)
this.call('terminal', 'log', { type: 'error', value: e.message})
}
}

public deleteProfile () {
localStorage.removeItem(CIRLCES_KEY)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,12 @@ export const templates = (intl: any, plugin: any): TemplateGroup[] => {
},
],
},
{
name: "About Circles",
items: [
{ value: "circles", tagList: [], displayName: 'About Circles', description: 'Templates for interacting with the Cicles Sdk' }
]
},
{
name: 'GitHub Actions',
items: [
Expand Down
1 change: 1 addition & 0 deletions apps/remix-ide/src/remixEngine.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export class RemixEngine extends Engine {
if (name === 'contentImport') return { queueTimeout: 60000 * 3 }
if (name === 'circom') return { queueTimeout: 60000 * 4 }
if (name === 'noir-compiler') return { queueTimeout: 60000 * 4 }
if (name === 'circles') return { queueTimeout: 60000 * 4 }
return { queueTimeout: 10000 }
}

Expand Down
1 change: 1 addition & 0 deletions libs/remix-ui/workspace/src/lib/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const TEMPLATE_NAMES = {
'uniswapV4HookBookMultiSigSwapHook': 'Uniswap V4 HookBook MultiSigSwapHook',
'accountAbstraction': 'Account Abstraction Template',
'introToEIP7702': 'Intro to EIP-7702',
'circles': 'About Circles'
}

export const TEMPLATE_METADATA: Record<string, TemplateType> = {
Expand Down
1 change: 1 addition & 0 deletions libs/remix-ws-templates/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export { default as hashchecker } from './templates/hashchecker'
export { default as rln } from './templates/rln'
export { default as multNr } from './templates/multiplierNoir'
export { default as stealthDropNr } from './templates/stealthdropNoir'
export { default as circles } from './templates/circles'

export { contractDeployerScripts } from './script-templates/contract-deployer'
export { etherscanScripts } from './script-templates/etherscan'
Expand Down
44 changes: 44 additions & 0 deletions libs/remix-ws-templates/src/templates/circles/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"overrides": [
{
"files": "*.sol",
"options": {
"printWidth": 80,
"tabWidth": 4,
"useTabs": false,
"singleQuote": false,
"bracketSpacing": false
}
},
{
"files": "*.yml",
"options": {
}
},
{
"files": "*.yaml",
"options": {
}
},
{
"files": "*.toml",
"options": {
}
},
{
"files": "*.json",
"options": {
}
},
{
"files": "*.js",
"options": {
}
},
{
"files": "*.ts",
"options": {
}
}
]
}
40 changes: 40 additions & 0 deletions libs/remix-ws-templates/src/templates/circles/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

### Circles

This template introduces the usage of the Circles sdk.

## create-group.ts

This script creates a new group on the Circles platform using the Circles SDK. It initializes the SDK with a BrowserProviderContractRunner,
defines the group profile, sets up the base group options, creates the group profile CID, creates the base group,
waits for transaction confirmation, extracts the group address from the transaction receipt, and retrieves the group's avatar.

## group-creation-tx.ts

This script retrieves and logs information about a group created on the Circles platform using the Circles SDK.
It initializes the SDK with a BrowserProviderContractRunner, fetches a transaction receipt,
extracts the group address from the transaction logs, and then retrieves and logs the group's avatar
and its trust relations.

## invite-to-group.ts

This script invites a user to a group on the Circles platform using the Circles SDK. It initializes the SDK with a BrowserProviderContractRunner,
fetches a transaction receipt, extracts the group address from the transaction logs, retrieves the group's avatar,
and then checks if the user is already trusted by the group and trusts the user.

## pathfinder.ts

This script finds a path between two addresses on the Circles platform using the CirclesRpc. It initializes the CirclesRpc with the provided URL,
and then calls the 'circlesV2_findPath' method with the source address, target address, and value.

## set-owner.ts

This script sets the owner of a group on the Circles platform using the Circles SDK. It initializes the SDK with a BrowserProviderContractRunner,
fetches a transaction receipt, extracts the group address from the transaction logs, retrieves the group's avatar,
and then sets the owner of the group.

## user.ts

This script retrieves and logs information about a user's avatar on the Circles platform using the Circles SDK.
It initializes the SDK with a BrowserProviderContractRunner, retrieves the avatar information,
and then logs the mintable amount and the avatar information.
20 changes: 20 additions & 0 deletions libs/remix-ws-templates/src/templates/circles/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export default async () => {
return {
// @ts-ignore
'scripts/group-creation-tx.ts': (await import('!!raw-loader!./scripts/group-creation-tx.ts')).default,
// @ts-ignore
'scripts/create-group.ts': (await import('!!raw-loader!./scripts/create-group.ts')).default,
// @ts-ignore
'scripts/invite-to-group.ts': (await import('!!raw-loader!./scripts/invite-to-group.ts')).default,
// @ts-ignore
'scripts/pathfinder.ts': (await import('!!raw-loader!./scripts/pathfinder.ts')).default,
// @ts-ignore
'scripts/set-owner.ts': (await import('!!raw-loader!./scripts/set-owner.ts')).default,
// @ts-ignore
'scripts/user.ts': (await import('!!raw-loader!./scripts/user.ts')).default,
// @ts-ignore
'.prettierrc.json': (await import('raw-loader!./.prettierrc')).default,
// @ts-ignore
'README.md': (await import('raw-loader!./README.md')).default
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Sdk } from '@circles-sdk/sdk'
import { BrowserProviderContractRunner } from "@circles-sdk/adapter-ethers"
import { cidV0ToUint8Array } from '@circles-sdk/utils'
import { ethers } from 'ethers'

(window as any).ethereum = web3Provider

const run = async () => {
// Initialize the SDK
const adapter = new BrowserProviderContractRunner();
await adapter.init();
const sdk = new Sdk(adapter)
const sender = await (new ethers.BrowserProvider(web3Provider)).getSigner()

// Define the group profile (symbol is required)
const groupProfile = {
name: '',
symbol: '',
description: '',
imageUrl: '', // optional, can be uploaded via SDK
previewImageUrl: '', // optional, used for previews
}

// Define base group setup options
const circlesGroupOwner = ''
const groupOwner = circlesGroupOwner
const serviceAddress = sender.address // Replace with actual service address
const feeCollection = circlesGroupOwner // Replace with actual treasury address
const initialConditions = []

// Step 1: Create the group profile (CID will be returned)
const profileCID = await sdk.profiles.create(groupProfile)
if (!profileCID) throw new Error('Failed to create profile CID')

// Step 2: Create the base group using the factory
console.log('group owner will be', sender)
const tx = await sdk.baseGroupFactory.createBaseGroup(
groupOwner, // Usually wallet address of the sender
serviceAddress,
feeCollection,
initialConditions,
groupProfile.name,
groupProfile.symbol,
cidV0ToUint8Array(profileCID), // Convert CID to bytes
)

// Wait for transaction confirmation
const receipt = await tx.wait()

console.log('receipt', receipt)

// Step 3: Extract the group address from emitted events
const groupAddress = ethers.stripZerosLeft(receipt.logs[15].topics[1])

// Step 4: Get the avatar for the created group
const baseGroupAvatar = await sdk.getAvatar(groupAddress.toLowerCase())

console.log('Base group created at:', groupAddress)
console.log('Group avatar:', baseGroupAvatar)
}

run().catch(console.error).then(console.log)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ethers } from 'ethers'
import { Sdk } from '@circles-sdk/sdk'
import { BrowserProviderContractRunner } from "@circles-sdk/adapter-ethers"

const run = async () => {
// Initialize the SDK
const adapter = new BrowserProviderContractRunner();
await adapter.init();
const sdk = new Sdk(adapter)

const txHash = '' // transaction which registered the group.

const provider = new ethers.BrowserProvider(web3Provider)
const receipt = await provider.getTransactionReceipt(txHash)
const groupAddress = ethers.stripZerosLeft(receipt.logs[15].topics[1])

console.log('group address', groupAddress)
const baseGroupAvatar = await sdk.getAvatar(groupAddress.toLowerCase())

console.log('group avatar', baseGroupAvatar)
console.log('owner is', await baseGroupAvatar.owner())
console.log('trust relations are', await baseGroupAvatar.getTrustRelations())
}

run().then(console.log).catch(console.error)
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { ethers } from 'ethers'
import { Sdk } from '@circles-sdk/sdk'
import { BrowserProviderContractRunner } from "@circles-sdk/adapter-ethers"

(window as any).ethereum = web3Provider

const run = async () => {
// Initialize the SDK
const adapter = new BrowserProviderContractRunner();
await adapter.init();
const sdk = new Sdk(adapter)

const user = ''
const txHash = '' // transaction which registered the group.

const provider = new ethers.BrowserProvider(web3Provider)
const receipt = await provider.getTransactionReceipt(txHash)
const groupAddress = ethers.stripZerosLeft(receipt.logs[15].topics[1])

console.log('group address', groupAddress)
const baseGroupAvatar = await sdk.getAvatar(groupAddress.toLowerCase())

console.log('group avatar', baseGroupAvatar)

console.log('owner', await baseGroupAvatar.owner())
console.log('service', await baseGroupAvatar.service())

console.log(await baseGroupAvatar.isTrustedBy(user))

console.log(await baseGroupAvatar.trust(user))
}

run().then(console.log).catch(console.error)
Loading