Chromia bridge client setup
This topic will walk you through setting up the Chromia Bridge Client to facilitate token transfers between Chromia and Ethereum Virtual Machine (EVM) networks.
Prerequisites
Before you begin, ensure you have the following:
TokenBridge
contract: You need the address of aTokenBridge
contract deployed on an EVM network.- ERC20 token: The address of an ERC20 token on the same EVM network.
- Chromia blockchain: The blockchain RID of a Chromia blockchain using the
hbridge
Rell library.
Configuration checklist
Approve ERC20 token
The ERC20 token must be approved by the TokenBridge
contract owner using the allowToken
function. You can accomplish
this with the @chromia/bridge-client
using the allowToken
method:
const contractTransactionResponse = await bcl.allowToken(token);
Check spending allowance
Verify the spending allowance with the checkAllowance
method:
const allowance: bigint = await bcl.checkAllowance();
Set blockchain RID
Use the setBlockchainRid
function in the TokenBridge
contract to set the blockchain RID. You can use the built-in
method setBlockchainRid
with @chromia/bridge-client
:
const contractTransactionResponse = await bcl.setBlockchainRid(rid);
Validator configuration
Convert the public keys of the validating nodes in the Chromia network to EVM addresses and configure them in the
Validator contract, either during deployment or by calling the updateValidators
function.
Work with the client
To handle all Chromia-related queries and operations, the bridge client requires an active Session
. However, you don't
need to instantiate it with a session immediately.
Set up your application with @chromia/ft4
:
Set up a connection to Postchain
codeconst pcl = await createClient({
nodeUrlPool: 'YOUR_NODE_URL_POOL',
blockchainRid: 'YOUR_BLOCKCHAIN_RID',
});
Create an account
const evmKeyStore = await createWeb3ProviderEvmKeyStore(window.ethereum);
const ad = createSingleSigAuthDescriptorRegistration([AuthFlag.Account, AuthFlag.Transfer], evmKeyStore.id);
const response = await registerAccount(pcl, evmKeyStore, registrationStrategy.open(ad));
User login
const evmKeyStoreInteractor = createKeyStoreInteractor(pcl, evmKeyStore);
const accounts = await evmKeyStoreInteractor.getAccounts();
const session = await evmKeyStoreInteractor.getSession(accounts[0].id);
Ensure that you save your evmKeyStore
in your application state, as some methods in @chromia/bridge-client
will
require it.
With your Session
object ready, you can initialize the bridge client. You will also need to provide an EVM Provider,
either a BrowserProvider
or a JsonRpcProvider
:
const provider = new BrowserProvider(window.ethereum);
const bcl = await bridgeClient(
{ bridgeAddress: "YOUR_BRIDGE_ADDRESS", tokenAddress: "YOUR_TOKEN_ADDRESS" },
provider,
session
);
If your application setup prevents having an active Session
when instantiating the bridge client, you can still set up
the client without it:
const provider = new BrowserProvider(window.ethereum);
const bcl = await bridgeClient({ bridgeAddress: "YOUR_BRIDGE_ADDRESS", tokenAddress: "YOUR_TOKEN_ADDRESS" }, provider);
Later, when you have access to the Session
, you can set it on the client with setSession(session: Session)
:
bcl.setSession(session);
Example usage: Bridge from EVM to Chromia and vice versa
Bridge from EVM to Chromia
Approve token spending
Ensure the user approves token spending by the token bridge:
const approvalResponse = await bcl.approveDepositAmount(BigInt(10));
Deposit to Chromia EVM bridge
Use the depositToEvmBridgeContract
method, specifying the number of tokens to bridge:
const contractTransactionResponse = await bcl.depositToEvmBridgeContract(BigInt(100));
Link EVM account
After a deposit, link the EVM account with the corresponding FT4 account created during the deposit process. Provide the
evmKeyStore
you created earlier:
const accountLinkingResponse = await bcl.linkEvmEoaAccount(evmKeyStore);
If the EVM account is linked, it will be returned to the accountLinkingResponse
. An EVM account can have multiple FT4
accounts linked to it.
Bridge from Chromia to EVM
Bridge from Chromia
Call the bridgeFromChromia
method with the amount and the asset ID:
// Network ID does not need to be provided as it will be fetched from the provider
const transactionResponse = await bcl.bridgeFromChromia(BigInt(10), Buffer.from("YOUR_ASSET_ID", "hex"));
Request withdrawal from EVM bridge
Create a pending withdrawal request
This needs to be accepted by the user to start the withdrawal process using the requestEvmWithdraw
method:
const erc20WithdrawalInfo = await bcl.getErc20WithdrawalByTransactionRid(
transactionResponse.receipt.transactionRid,
opIndex
);
// Get event proof for withdrawal
const eventProof = await bcl.getWithdrawRequestEventProof(erc20WithdrawalInfo.event_hash);
// Request withdrawal
const requestedWithdraw = await bcl.requestEvmWithdraw(eventProof);
Check withdrawal status
Depending on the bridge contract configuration, the user must wait a certain number of blocks on EVM to complete their
withdrawal. This can be done using the getPendingWithdrawFromProof
method:
const { block_number } = await getPendingWithdrawFromProof(eventProof);
Once the block_number
has been reached on the target EVM chain, the user can withdraw their tokens:
const withdrawal = await bcl.evmWithdraw(eventProof.leaf as Buffer);
Additional methods
getErc20Deposits(filter?: DepositFilter, pageSize?: number, pageCursor?: string)
: Returns all deposits specified by the filter.getErc20Withdrawals(filter?: WithdrawFilter, pageSize?: number, pageCursor?: string)
: Returns all withdrawals from the EVM bridge specified by the filter.setBlockchainRid(blockchainRid: Buffer)
: Sets the blockchain RID.