Setup
This page will guide you through setting up an ERC20 bridge to a Kwil database. There are a few prerequisites you will need:
- An ERC20 token contract that is already deployed. The token cannot be a Rebase Token
- A list of Ethereum addresses (1-10) which will make up the multisig that controls tokens held in escrow, and the threshold for the multisig. Alternatively, you can provide an already-deployed Safe multisig address.
Step 1: Deploy the Escrow Contract and Relayer
The first step is to deploy the escrow contract and run the relayer. The escrow contract is responsible for holding tokens, and releasing them in batch when the multisig approves a release. The relayer is responsible for submitting transactions to the escrow contract on behalf of the multisig. The relayer itself is not part of the multisig and cannot unilaterally release funds, and is merely responsible for expending ETH gas to submit transactions. Therefore, the relayer can be run by anyone, and does not need to be a trusted party.
To deploy the bridge Solidity contracts, see the guide in the source repo.
To run the relayer service, see the documentation.
Step 2: Deploy Kwil Validators with Bridge Oracles
The kwild
node software comes with a built-in bridge oracle that allows the Kwil node to listen to and come to consensus on Ethereum events.
Greater than 1/2 of your network's validator power must be running a Kwil node with the bridge oracle enabled in order for deposits to be processed.
To configure the bridge oracle, node operators will need to have an Ethereum RPC from which they can read events. There are three configurations that
can be set for each chain:
rpc
[required]: The Ethereum RPC endpoint from which to read events. It must be a websocket endpoint.block_sync_chunk_size
[optional]: The number of blocks to sync in each chunk. To allow fast syncing between the Kwil node and the target chain, Kwil nodes will sync blocks in chunks, where all events for a single chunk are retrieved in one request to the Ethereum RPC. The default value is 1000000. For bridges with a high volume of transfers, it may be necessary to decrease this value as to not overload the Ethereum RPC.
Below are example configurations showing how a validator can configure Ethereum RPCs. It assumes that the target chain is the Ethereum Sepolia testnet:
config.toml
# ...
# ERC20 bridge configuration
[erc20_bridge]
# REQUIRED: evm websocket RPC; format: chain_name='rpc_url'
[erc20_bridge.rpc]
sepolia = "wss://YOUR_ETHEREUM_SEPOLIA_PROVIDER"
# OPTIONAL: rpc option block sync chunk size; format: chain_name='chunk_size'
[erc20_bridge.block_sync_chuck_size]
sepolia = "1000000"
# ...
kwild command
kwild start <...> --erc20-bridge.rpc 'sepolia=wss://YOUR_ETHEREUM_SEPOLIA_PROVIDER' \
--erc20-bridge.block_sync_chunk_size 'sepolia=1000000'
Step 3: Deploy Kwil Nodes with the Multisig
All keys in the multisig must run their own local Kwil node to sign transactions authoring the release of tokens. The nodes do not have to be validators, and can instead be read-only sentry nodes. There are two configurations needed for each multisig:
rpc
[required]: The Kwil RPC endpoint to which the multisig will submit transactions. This is the same configuration as therpc
config in the section above.signer
[required]: The filepath of the private key that is part of the Safe multisig wallet.
Below are example configurations showing how a multisig can configure Kwil nodes. It assumes that the Kwil network is running on the localhost talking
to Sepolia, and that the bridge is targeting USDC on Sepolia, and we have an escrow contract for the USDC
at 0x1234567890abcdef1234567890abcdef12345678
:
config.toml
This step can be performed after the Kwil nodes have been set up. Your node's configuration can reference an
extension that does not yet exist.
More information on the erc20_bridge USE
statement can be found in the Usage docs.
# ...
# ERC20 bridge configuration
[erc20_bridge]
# REQUIRED: kwil websocket RPC; format: chain_name='rpc_url'
[erc20_bridge.rpc]
sepolia = "wss://YOUR_ETHEREUM_SEPOLIA_PROVIDER"
# REQUIRED: signer option; format: chain_name='signer_file'
[erc20_bridge.signer]
my_bridged_usdc = "/path/to/your/signer/key"
# ...
kwild command
kwild start <...> --erc20-bridge.rpc 'sepolia=wss://YOUR_ETHEREUM_SEPOLIA_PROVIDER' \
--erc20-bridge.signer 'my_bridged_usdc=/path/to/your/signer/key'
Once our Kwil node is properly configured, we can initialize the bridge extension. The name we give the extension
(referenced using the AS keyword) must be the same as the name we give the signer in the configuration. For example,
if we have a signer configuration my_bridged_usdc
, we must initialize the bridge with the same name:
Initializing the Bridge
USE erc20_bridge {
chain: 'sepolia',
escrow: '0x1234567890abcdef1234567890abcdef12345678',
} AS my_bridged_usdc;
There is no required order for setting up the bridge. You can execute the USE statement without having the signer configuration in place, and vice versa. If you execute USE before enough nodes have signers and bridges configured, it simply will wait until enough nodes are configured.