Skip to content

Commit

Permalink
feat: node example for generic handler (#100)
Browse files Browse the repository at this point in the history
* added support of erc721

* cleanup

* fixes for sdk for erc721 example

* erc721 example local build

* updated yarn lock

* added scripts for minting

* update config to new local setup

* update readme

* fix readme

* use localy compile sdk version

* update erc20 react example

* delete old react example

* generic app example initial implementation

* adding sygma contracts dependency on package.json for react example

* update bridge setup to work with updated local setup

* update bridge setup for nft example

* adding method for creating deposit data for generic handler support

* toHex function as public method on Sygma

* wip: generic deposit

* wip: generic deposit providing fee from query the contract

* wip: generic deposit providing fee from query the contract

* improvements over code of generic app example, using custom hooks for connection, added couple of new methods to sdk

* remove artifacts folder

* remove artifacts folder inside src

* using generic deposit to transfer colors

* getting all the colors after tx

* Deposit generic method on EvmBridge class and more cleanup of the example app

* listening to event on chain change from meta

* update on reducer

* modifiying script for setting up colors

* readme with instructions on how to run generic app example

* update redme with troubleshootin instructions, remove no-check for typescript, some minor updates for the app example

* remove unnecesary scripts

* remove logs and format script

* adding types on function signatures for some of the methods and functions added to the SDK. Removing more logs

* minor change on app.tsx

* generic deposit example

* example and scripts

* README with instructions

* PR comments

Co-authored-by: Nikolay Topkaridi <[email protected]>
  • Loading branch information
wainola and enemycnt authored Nov 4, 2022
1 parent 8688bf3 commit 247dd7b
Show file tree
Hide file tree
Showing 14 changed files with 5,927 additions and 16 deletions.
1 change: 0 additions & 1 deletion examples/generic-colors/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ function App() {
"🚀 ~ file: App.tsx ~ line 148 ~ handleClick ~ first",
formatedHex,
);

const depositDataFee = `0x${
// @ts-ignore-next-line
ethers.utils.hexZeroPad(100, 32).substr(2) +
Expand Down
27 changes: 27 additions & 0 deletions examples/generic-node-example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build
/dist

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

.env
.vscode
16 changes: 16 additions & 0 deletions examples/generic-node-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Generic Colors Node.js example

## Setup

For you to run this example you need our local setup. Go to this [repo](https://github.com/sygmaprotocol/sygma-relayer) and make sure you have `golang` installed. Once you clone this repo, run the command `make example` and you will have two ganache nodes and three relayers with all the contracts deployed on each node

## How to run this example

After you clone this repo run. The transfer is from Ganache node on port `8545` to port `8547`

```bash
yarn # to install dependencies
cd ./examples/generic-node-example
yarn setupColors # to setup some colors on the Colors
yarn depositGeneric # run the script that takes care of the generic transfer
```
21 changes: 21 additions & 0 deletions examples/generic-node-example/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "@buildwithsygma/sygma-sdk-node-generic-colors",
"private": true,
"version": "0.1.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"ethers": "5.7.2",
"@buildwithsygma/sygma-sdk-core": "link:../../packages/sdk",
"@ethersproject/experimental": "^5.7.0",
"chalk": "4.1.2"
},
"devDependencies": {
"ts-node": "10.9.1",
"typescript": "4.8.4"
},
"scripts": {
"setupColors": "ts-node ./src/setupColors.ts",
"depositGeneric": "ts-node ./src/depositGeneric.ts"
}
}
5,538 changes: 5,538 additions & 0 deletions examples/generic-node-example/src/abis/colors-abi.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions examples/generic-node-example/src/abis/decodeColor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ethers } from "ethers";

const decodeColor = (color: string) => `#${ethers.utils.hexStripZeros(color).substr(2).toUpperCase()}`

export { decodeColor }
72 changes: 72 additions & 0 deletions examples/generic-node-example/src/bridgeSetup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { BridgeData } from "@buildwithsygma/sygma-sdk-core";

const bridgeAddress = "0x6CdE2Cd82a4F8B74693Ff5e194c19CA08c2d1c68";
const genericAddress = "0x783BB8123b8532CC85C8D2deF2f47C55D1e46b46";
const feeRouterAddress = "0x9275AC64D6556BE290dd878e5aAA3a5bae08ae0C";
const basicFeeAddress = "0x78E5b9cEC9aEA29071f070C8cC561F692B3511A6";
const colorsAddress = "0xE54Dc792c226AEF99D6086527b98b36a4ADDe56a";
const erc20HandlerAddress = "0x1ED1d77911944622FCcDDEad8A731fd77E94173e";
const erc721HandlerAddress = "0x481f97f9C82a971B3844a422936a4d3c4082bF84";

const bridgeSetup: BridgeData = {
chain1:
{
domainId: "1",
networkId: 1337,
name: "Local EVM 1",
decimals: 18,
bridgeAddress: bridgeAddress,
erc20HandlerAddress: erc20HandlerAddress,
erc721HandlerAddress: erc721HandlerAddress,
rpcUrl: "http://localhost:8545",
tokens: [
{
type: "erc20",
address: "0x1CcB4231f2ff299E1E049De76F0a1D2B415C563A",
name: "ERC20LRTST",
symbol: "ETHIcon",
imageUri: "ETHIcon",
decimals: 18,
resourceId:
"0x0000000000000000000000000000000000000000000000000000000000000300",
feeSettings: {
type: "basic",
address: "0x78E5b9cEC9aEA29071f070C8cC561F692B3511A6",
},
},
],
},
chain2: {
domainId: "2",
networkId: 1338,
name: "Local EVM 2",
decimals: 18,
bridgeAddress: "0x6CdE2Cd82a4F8B74693Ff5e194c19CA08c2d1c68",
erc20HandlerAddress: "0x1ED1d77911944622FCcDDEad8A731fd77E94173e",
erc721HandlerAddress: "0x481f97f9C82a971B3844a422936a4d3c4082bF84",
rpcUrl: "http://localhost:8547",
tokens: [
{
type: "erc20",
address: "0x1CcB4231f2ff299E1E049De76F0a1D2B415C563A",
name: "ERC20LRTST",
symbol: "ETHIcon",
imageUri: "ETHIcon",
decimals: 18,
resourceId:
"0x0000000000000000000000000000000000000000000000000000000000000300",
feeSettings: {
type: "basic",
address: "0x78E5b9cEC9aEA29071f070C8cC561F692B3511A6",
},
},
],
}
}

const node1RpcUrl = "http://localhost:8545";
const node2RpcUrl = "http://localhost:8547";

const bridgeAdmin = "0x5C1F5961696BaD2e73f73417f07EF55C62a2dC5b";

export { bridgeAddress, feeRouterAddress, genericAddress, colorsAddress, basicFeeAddress, bridgeSetup, node1RpcUrl, node2RpcUrl, bridgeAdmin }
102 changes: 102 additions & 0 deletions examples/generic-node-example/src/depositGeneric.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { ethers } from 'ethers'
import Chalk from 'chalk'
import ColorsABI from './abis/colors-abi.json'
import {
colorsAddress,
node1RpcUrl,
node2RpcUrl,
bridgeAdmin
} from './bridgeSetup'
import { decodeColor } from './abis/decodeColor';
import { setupSygma } from './sygmaInstance'
import { FeeDataResult } from '@buildwithsygma/sygma-sdk-core'

const providerNode1 = new ethers.providers.JsonRpcProvider(node1RpcUrl);
const providerNode2 = new ethers.providers.JsonRpcProvider(node2RpcUrl)

const depositGeneric = async () => {
const account = (await providerNode1.listAccounts())[0]
const signer = providerNode1.getSigner(account)
const balanceAccount = (await signer.getBalance()).toString()

console.log(`${Chalk.keyword('orange')(`Balance of account ${account}: `)} ${Chalk.keyword('yellow')(balanceAccount)}`)

const colorContractNode1 = new ethers.Contract(colorsAddress, ColorsABI.abi)

const colorArrayLength = await colorContractNode1.connect(signer).getColorsArrayLenght()

let depositDataArray: Array<{ color: string, depositData: string }>

if (colorArrayLength.toNumber() !== 0) {
const iterable = Array.from(Array(colorArrayLength.toNumber()).keys()).map(i => i)

let colors = []

for await (let k of iterable) {
const color = await colorContractNode1.connect(signer).colorsArray(k)
const colorDecoded = decodeColor(color)
console.log(`${Chalk.keyword('orange')('Color decoded')}: ${Chalk.hex(colorDecoded).bold(colorDecoded)}`)
colors.push(colorDecoded)
}

const colorsFormated = colors.map(color => color.substr(1))
const depositFunctionSignature = '0x103b854b'
const colorsResourceId = '0x0000000000000000000000000000000000000000000000000000000000000500'

const sygmaConnected = await setupSygma(account)

const basicFeeData = await sygmaConnected.fetchBasicFeeData({
amount: '1000000',
recipientAddress: bridgeAdmin
})

const colorsFormatedToHex = colorsFormated.map(color => ({ color: color, colorToHex: sygmaConnected.toHex(`0x${color}`, 32) }))

depositDataArray = colorsFormatedToHex.map(color => ({
color: color.color,
depositData: sygmaConnected.createGenericDepositDataV1(
depositFunctionSignature,
colorsAddress,
'2000000',
account,
color.colorToHex,
false
)
}))

for await (let { color, depositData } of depositDataArray) {
try {
const depositTx = await sygmaConnected.depositGeneric(
colorsResourceId,
depositData,
basicFeeData as FeeDataResult
)
console.log(`${Chalk.keyword('orange')('Status of deposit')} ${Chalk.keyword('yellow')(depositTx?.status)}`)
console.log(`${Chalk.keyword('red')('Color being sent:')} ${Chalk.hex(color).bold(color)}`)
} catch (e) {
console.log("Error on generic deposit", e)
}
}
}

const signerDestinationChain = providerNode2.getSigner(account)

const filters = colorContractNode1.connect(signerDestinationChain).filters.setColorEvent()

const listener = async (color: string, ...rest: any) => {
const colorDecoded = decodeColor(color)
console.log(`${Chalk.keyword('green')('Color decoded on destination chain')}: ${Chalk.hex(colorDecoded).bold(colorDecoded)}`)
const lastColor = depositDataArray.findIndex(colorData => colorData.color === colorDecoded.substr(1))

if (lastColor === depositDataArray.length - 1) {
setTimeout(() => {
process.exit(0)
}, 5000)
}
}

colorContractNode1.connect(signerDestinationChain).on(filters, listener)

}

depositGeneric()
98 changes: 98 additions & 0 deletions examples/generic-node-example/src/setupColors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { ethers, BigNumber } from 'ethers'
import { NonceManager } from '@ethersproject/experimental'
import ColorsAbi from './abis/colors-abi.json'
const colorsAddress = "0xE54Dc792c226AEF99D6086527b98b36a4ADDe56a";

const toHex = (covertThis: string, padding: number) => {
return ethers.utils.hexZeroPad(ethers.utils.hexlify(BigNumber.from(covertThis)), padding);
};

const setColor = async () => {
const bridgeAdmin = "0x5C1F5961696BaD2e73f73417f07EF55C62a2dC5b";
const provider1 = new ethers.providers.JsonRpcProvider('http://localhost:8545')
const provider2 = new ethers.providers.JsonRpcProvider('http://localhost:8547')

const firstAccount = (await provider1.listAccounts())[0]

const wallet = ethers.Wallet.fromMnemonic(
"black toward wish jar twin produce remember fluid always confirm bacon slush",
"m/44'/60'/0'/0/0",
);

const walletSignerNode1 = wallet.connect(provider1);
console.log(
"🚀 ~ file: colors.local.tx.ts ~ line 33 ~ walletSignerNode1",
walletSignerNode1.address,
);
console.log("wallet address", walletSignerNode1.address)

const tx = {
to: firstAccount,
value: ethers.utils.parseEther('10')
}

const managedSignerNode1 = new NonceManager(walletSignerNode1);
await managedSignerNode1.signTransaction(tx)
await (await managedSignerNode1.sendTransaction(tx)).wait(1)

const walletSignerNode2 = wallet.connect(provider2);
console.log(
"🚀 ~ file: colors.local.tx.ts ~ line 33 ~ walletSignerNode1",
walletSignerNode2.address,
);

const managedSignerNode2 = new NonceManager(walletSignerNode2);
await managedSignerNode2.signTransaction(tx)
await (await managedSignerNode2.sendTransaction(tx)).wait(1)

const signerProvider1 = provider1.getSigner(firstAccount)
const signerProvider2 = provider2.getSigner(firstAccount)

const colorContract = new ethers.Contract(
colorsAddress,
ColorsAbi.abi
)

const colorsNode1 = ['0x70F3FF', '0xB2B2B2']
const colorsNode2 = ['0xFF8787', '0x00ABB3']
const colorsToHexNode1 = colorsNode1.map(color => toHex(color, 32))
colorsToHexNode1.forEach(color => {
console.log("🚀 ~ file: setColors.ts ~ line 47 ~ setColor ~ color node 1", color)
})
const colorsToHexNode2 = colorsNode2.map(color => toHex(color, 32))
colorsToHexNode2.forEach(color => {
console.log("🚀 ~ file: setColors.ts ~ line 47 ~ setColor ~ color node 2", color)
})
const depositData = toHex(bridgeAdmin, 32)

for await (let colorHexed of colorsToHexNode1) {
try {
await (
await colorContract.connect(signerProvider1).setColor(depositData, colorHexed)
).wait(1)
console.log(`Success to setup color ${colorHexed} on Node 1`)
} catch (e) {
console.log("Error on setting up color", e)
}
}

for await (let colorsHexed of colorsToHexNode2) {
try {
await (
await colorContract.connect(signerProvider2).setColor(depositData, colorsHexed)
).wait(1)
console.log(`Success to setup color ${colorsHexed} on Node 2`)
} catch (e) {
console.log("Error on setting up color", e)
}
}

const balanceFirstAccountProvider1 = (await signerProvider1.getBalance()).toString()
const balanceFirstAccountProvider2 = (await signerProvider2.getBalance()).toString()

console.log("Balance on Node 1", balanceFirstAccountProvider1)
console.log("Balance on Node 2", balanceFirstAccountProvider2)

}

setColor()
14 changes: 14 additions & 0 deletions examples/generic-node-example/src/sygmaInstance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Setup, Sygma } from '@buildwithsygma/sygma-sdk-core'
import {
bridgeSetup,
} from './bridgeSetup'

const setupSygma = async (signerAddress: string): Promise<Sygma> => {
const setup: Setup = { bridgeSetupList: [], bridgeSetup }
const sygma = new Sygma(setup)

const sygmaConnected = await sygma.initializeConnectionRPC(signerAddress)
return sygmaConnected
}

export { setupSygma }
Loading

0 comments on commit 247dd7b

Please sign in to comment.