Skip to content

Commit 8789459

Browse files
RyRy79261FSM1Tbautansermino
authored
Abstrating Network provider logic (#70)
* Added provider selector * Reworked app.tsx * Working on adaptors * Working on new interfaces * EVM wired * Compiles now * Tinkering * Refactored home adapter to context (#73) * Refactored again * Refactored modal * Included * Compiles * Can connect again * It connects now * Trying to set destination * Context for the destination chain * Destination is provider * Compiles * Mostly works * Refactored wrap & network unsuported modal * Substrate provider init * Added in * Version issue * Polkadot.js is a dumpster fire * Updating comments * Polkadot... * Balance fetched * Selecting token * Transfer sub to evm works * Added test listener logic * Web3 issues * Revert * Web3 eish * fix EVM home chain * setup for GETH chainId 5 * Present state * Unsubscribe logic * update onbaord to latest version * Init mutex * Mutex test * Block status not reported * Fixed cycle in evm * Removed consoles * step 1 * fix typo * add substrate destination event handlers * cleanup * Update src/Modules/TransferActiveModal.tsx * substrate address formatting * Cleared * Added disconnect * Resolved * Token values matching * Reset functionall * Removed keyring * auto set destination network * Spruced * clean up config, add validation, add more readme * Adapter modularity refactor (#77) * Refactors apis and cleanup a bit. Adds scripts for centrifuge * Renames setup cmds * more fixes Co-authored-by: Michael Yankelev <[email protected]> * update readme and config * update readme, clean up Chainbridge API * fix relayer config and substrate deposit decimals * use correct BN lib * make adaptors dynamic * update readme * clear all warnings * fix package json scripts typo * make function name generic * update readme * Apply suggestions from code review Co-authored-by: David Ansermino <[email protected]> Co-authored-by: Michael Yankelev <[email protected]> Co-authored-by: Thibaut Sardan <[email protected]> Co-authored-by: Thibaut Sardan <[email protected]> Co-authored-by: Michael Yankelev <[email protected]> Co-authored-by: David Ansermino <[email protected]>
1 parent c32e723 commit 8789459

36 files changed

+5107
-2139
lines changed

README.md

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,28 @@ For running a local instance use the command:
3737
yarn start
3838
```
3939

40+
The codebase is configured to be run against the Geth <> Substrate node that can be set up by following the guide [here](https://chainbridge.chainsafe.io/local/) or executing:
41+
42+
- `yarn start:substrate` to start,
43+
- `yarn setup:example` to initialize
44+
45+
Should the substrate chain you are targetting require different type definitions, the type definitions file should be added to `src/Contexts/Adaptors/SubstrateApis/` and the file name for the types set in the substrate bridge configs.
46+
4047
### Build
4148

4249
Update the configs for the bridge in `src/chainbridgeContext.ts`. There should be at least 2 chains configured for correct functioning of the bridge. Each chain accepts the following configuration parameters:
4350

4451
```
45-
type BridgeConfig = {
46-
chainId: number // The bridge's chainId.
47-
networkId: number // The networkId of this chain.
48-
name: string // The human readable name of this chain.
49-
bridgeAddress: string // The address on the brdige contract deployed on this chain.
50-
erc20HandlerAddress: string // The ERC20 handler address.
51-
rpcUrl: string // An RPC URL for this chain.
52-
type: "Ethereum" | "Substrate" // The type of chain.
53-
tokens: TokenConfig[] // An object to configure the tokens this bridge can transfer. See the TokenConfig object below.
54-
nativeTokenSymbol: string // The native token symbol of this chain.
55-
blockExplorer?: string //This should be the full path to display a tx hash, without the trailing slash, ie. https://etherscan.io/tx
56-
}
52+
export type BridgeConfig = {
53+
networkId?: number; // The networkId of this chain.
54+
chainId: number; // The bridge's chainId.
55+
name: string; // The human readable name of this chain.
56+
rpcUrl: string; // An RPC URL for this chain.
57+
type: ChainType; // The type of chain.
58+
tokens: TokenConfig[]; // An object to configure the tokens (see below)
59+
nativeTokenSymbol: string; // The native token symbol of this chain.
60+
decimals: number;
61+
};
5762
```
5863

5964
```
@@ -67,6 +72,33 @@ type TokenConfig = {
6772
};
6873
```
6974

75+
EVM Chains should additionally be configured with the following params
76+
77+
```
78+
export type EvmBridgeConfig = BridgeConfig & {
79+
bridgeAddress: string;
80+
erc20HandlerAddress: string;
81+
type: "Ethereum";
82+
nativeTokenSymbol: string;
83+
// This should be the full path to display a tx hash, without the trailing slash, ie. https://etherscan.io/tx
84+
blockExplorer?: string;
85+
defaultGasPrice?: number;
86+
deployedBlockNumber?: number;
87+
};
88+
```
89+
90+
Substrate chains should be configured with the following
91+
92+
```
93+
export type SubstrateBridgeConfig = BridgeConfig & {
94+
type: "Substrate";
95+
chainbridgePalletName: string; // The name of the chainbridge palette
96+
transferPalletName: string; // The name of the pallet that should initiate transfers
97+
transferFunctionName: string; // The name of the method to call to initiate a transfer
98+
typesFileName: string; // The name of the Substrate types file. The file should be located in `src/Contexts/Adaptors/SubstrateApis`
99+
};
100+
```
101+
70102
Run `yarn build`.
71103

72104
Deploy the contents of the `/build` folder to any static website host (eg. S3, Azure storage) or IPFS.

craco.config.js renamed to craco.config.cjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ module.exports = {
3838
}),
3939
],
4040
},
41+
module: {
42+
rules: [
43+
...webpackConfig.module.rules,
44+
{
45+
test: /\.mjs$/,
46+
include: /node_modules/,
47+
type: "javascript/auto",
48+
},
49+
],
50+
},
4151
devtool: "source-map",
4252
}),
4353
},

docker-compose-centrifuge.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright 2020 ChainSafe Systems
2+
# SPDX-License-Identifier: LGPL-3.0-only
3+
4+
version: "3"
5+
services:
6+
geth1:
7+
image: "chainsafe/chainbridge-geth:20200505131100-5586a65"
8+
container_name: geth1
9+
ports:
10+
- "8545:8545"
11+
12+
sub-chain:
13+
image: "centrifugeio/centrifuge-chain:20201204140308-0809a17"
14+
container_name: sub-chain
15+
command: centrifuge-chain --dev --alice --ws-external --rpc-external
16+
ports:
17+
- "9944:9944"

docker-compose-substrate.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright 2020 ChainSafe Systems
2+
# SPDX-License-Identifier: LGPL-3.0-only
3+
4+
version: "3"
5+
services:
6+
geth1:
7+
image: "chainsafe/chainbridge-geth:20200505131100-5586a65"
8+
container_name: geth1
9+
ports:
10+
- "8545:8545"
11+
12+
sub-chain:
13+
image: "chainsafe/chainbridge-substrate-chain:v1.3.0"
14+
container_name: sub-chain
15+
command: chainbridge-substrate-chain --dev --alice --ws-external --rpc-external
16+
ports:
17+
- "9944:9944"

package.json

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,22 @@
66
"@babel/core": "^7.12.3",
77
"@babel/runtime": "^7.12.1",
88
"@chainsafe/chainbridge-contracts": "1.0.5",
9-
"@chainsafe/web3-context": "1.2.0",
109
"@chainsafe/common-components": "1.0.26",
1110
"@chainsafe/common-theme": "1.0.10",
11+
"@chainsafe/web3-context": "1.2.0",
1212
"@material-ui/styles": "4.10.0",
13+
"@polkadot/api": "3.11.1",
14+
"@polkadot/extension-dapp": "0.37.1",
15+
"@polkadot/keyring": "5.6.3",
16+
"@polkadot/networks": "5.6.3",
17+
"@polkadot/types": "3.9.3",
18+
"@polkadot/ui-keyring": "0.69.1",
19+
"@polkadot/ui-settings": "0.69.1",
20+
"@polkadot/util": "5.6.3",
21+
"@polkadot/util-crypto": "5.6.3",
1322
"@sentry/react": "^5.26.0",
1423
"@types/history": "^4.7.8",
15-
"bnc-onboard": "1.19.2",
24+
"bnc-onboard": "1.26.1",
1625
"clsx": "^1.1.1",
1726
"dayjs": "^1.9.1",
1827
"ethers": "5.0.32",
@@ -25,6 +34,7 @@
2534
"yup": "^0.29.3"
2635
},
2736
"devDependencies": {
37+
"@polkadot/typegen": "^4.11.2",
2838
"@sentry/cli": "1.58.0",
2939
"@testing-library/jest-dom": "^5.11.4",
3040
"@testing-library/react": "^11.0.4",
@@ -52,8 +62,13 @@
5262
"clean:dist": "rm -rf ./*/**/dist && rm -rf ./*/**/build && rm -rf ./*/**/storybook-static",
5363
"clean": "yarn clean:dependencies && yarn clean:dist",
5464
"prettier": "prettier --config .prettierrc 'packages/**/src/**/*.{ts,tsx,js,jsx,md}' --write",
55-
"start:tunnel": "./ngrok http https://localhost:3000"
65+
"start:tunnel": "./ngrok http https://localhost:3000",
66+
"start:substrate": "docker-compose -f ./docker-compose-substrate.yml up -V",
67+
"start:centrifuge": "docker-compose -f ./docker-compose-centrifuge.yml up -V",
68+
"setup:example": "./scripts/setup-eth-example.sh && node --experimental-json-modules ./scripts/setup-sub-example.mjs",
69+
"setup:centrifuge": "./scripts/setup-eth-centrifuge.sh"
5670
},
71+
"cracoConfig": "./craco.config.cjs",
5772
"eslintConfig": {
5873
"extends": "react-app"
5974
},

relayer-config.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"chains": [
3+
{
4+
"name": "eth",
5+
"type": "ethereum",
6+
"id": "0",
7+
"endpoint": "ws://localhost:8545",
8+
"from": "0xff93B45308FD417dF303D6515aB04D9e89a750Ca",
9+
"opts": {
10+
"bridge": "0x62877dDCd49aD22f5eDfc6ac108e9a4b5D2bD88B",
11+
"erc20Handler": "0x3167776db165D8eA0f51790CA2bbf44Db5105ADF",
12+
"erc721Handler": "0x3f709398808af36ADBA86ACC617FeB7F5B7B193E",
13+
"genericHandler": "0x2B6Ab4b880A45a07d83Cf4d664Df4Ab85705Bc07",
14+
"gasLimit": "1000000",
15+
"maxGasPrice": "20000000"
16+
}
17+
},
18+
{
19+
"name": "sub",
20+
"type": "substrate",
21+
"id": "1",
22+
"endpoint": "ws://localhost:9944",
23+
"from": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
24+
"opts": {
25+
"useExtendedCall": "true"
26+
}
27+
}
28+
]
29+
}

scripts/bridgeTypes.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"chainbridge::ChainId": "u8",
3+
"ChainId": "u8",
4+
"ResourceId": "[u8; 32]",
5+
"DepositNonce": "u64",
6+
"ProposalVotes": {
7+
"votes_for": "Vec<AccountId>",
8+
"votes_against": "Vec<AccountId>",
9+
"status": "enum"
10+
},
11+
"Erc721Token": {
12+
"id": "TokenId",
13+
"metadata": "Vec<u8>"
14+
},
15+
"TokenId": "U256",
16+
"Address": "AccountId",
17+
"LookupSource": "AccountId"
18+
}

scripts/setup-eth-centrifuge.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/sh
2+
3+
cb-sol-cli deploy --all --relayerThreshold 1
4+
cb-sol-cli bridge register-resource --resourceId "0x00000000000000000000000000000009e974040e705c10fb4de576d6cc261900" --targetContract "0x21605f71845f372A9ed84253d2D024B7B10999f4"
5+
cb-sol-cli bridge set-burn --tokenContract "0x21605f71845f372A9ed84253d2D024B7B10999f4"
6+
cb-sol-cli erc20 add-minter --minter "0x3167776db165D8eA0f51790CA2bbf44Db5105ADF"

scripts/setup-eth-example.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/sh
2+
3+
cb-sol-cli deploy --all --relayerThreshold 1
4+
cb-sol-cli bridge register-resource --resourceId "0x000000000000000000000000000000c76ebe4a02bbc34786d860b355f5a5ce00" --targetContract "0x21605f71845f372A9ed84253d2D024B7B10999f4"
5+
cb-sol-cli bridge set-burn --tokenContract "0x21605f71845f372A9ed84253d2D024B7B10999f4"
6+
cb-sol-cli erc20 add-minter --minter "0x3167776db165D8eA0f51790CA2bbf44Db5105ADF"

scripts/setup-sub-example.mjs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { ApiPromise, WsProvider, Keyring } from "@polkadot/api";
2+
import types from "./bridgeTypes.json";
3+
4+
const keyring = new Keyring({ type: "sr25519" });
5+
const wsProvider = new WsProvider("ws://127.0.0.1:9944");
6+
const api = await ApiPromise.create({ provider: wsProvider, types: types });
7+
const ALICE = keyring.addFromUri("//Alice");
8+
9+
const addRelayer = (relayer) => {
10+
return api.tx.sudo.sudo(api.tx.chainBridge.addRelayer(relayer));
11+
};
12+
13+
const whitelistChain = (chainId) => {
14+
return api.tx.sudo.sudo(api.tx.chainBridge.whitelistChain(chainId));
15+
};
16+
17+
const registerResource = (rId, method) => {
18+
return api.tx.sudo.sudo(api.tx.chainBridge.setResource(rId, method));
19+
};
20+
21+
(async function () {
22+
let nonce = await api.rpc.system.accountNextIndex(ALICE.address);
23+
let txHash = await addRelayer(ALICE.address).signAndSend(ALICE, { nonce });
24+
console.log(`Added relayer ALICE in tx ${txHash}`);
25+
26+
nonce = await api.rpc.system.accountNextIndex(ALICE.address);
27+
txHash = await whitelistChain(0).signAndSend(ALICE, { nonce });
28+
console.log(`Whitelisted chain 0 in tx ${txHash}`);
29+
30+
nonce = await api.rpc.system.accountNextIndex(ALICE.address);
31+
txHash = await registerResource(
32+
"0x000000000000000000000000000000c76ebe4a02bbc34786d860b355f5a5ce00",
33+
"0x4578616d706c652e7472616e73666572"
34+
).signAndSend(ALICE, { nonce });
35+
console.log(`Registered resource in tx ${txHash}`);
36+
37+
await api.disconnect();
38+
})();

0 commit comments

Comments
 (0)