Deploy a Bridge
The XRPL EVM compatible sidechain implementation is a proof of concept extension to the XRP Ledger protocol and is for development purposes only. There is no official amendment currently and it is not available on the production Mainnet. The EVM compatible sidechain bridge is connected to the XRP Ledger Devnet. Do not send transactions in Mainnet.
Before deploying a bridge, familiarize yourself with the parameters and terms used:
- Currency: The currency used by the bridge. Depending on the token, the bridge has different setups. If the currency is XRP, the door account is called a Native Bridge Door; if the currency is a token, the door account is called a Token Bridge Door.
- Locking Chain: The chain where the token originally exists. If the locking chain is an XRPL chain, the bridge IOU issuer isn't the bridge door account. If the locking chain is an EVM chain, the ERC20 owner isn't the bridge door account.
- Issuing Chain: The chain the token is bridged to. If the issuing chain is an XRPL chain, the bridged IOU issuer is the bridge door account. If the issuing chain is an EVM chain, the bridged ERC20 owner is the bridge door account and can mint/burn tokens.
- Owners: The witnesses addresses. For each witness, you must have its address on both chains.
- Threshold: The amount of attestations needed for each operation.
- Signautre Reward: The reward distributed to witnesses for providing attestations.
- Minimum Create Account: For native XRP bridges, this parameter sets the minimum amount of XRP that needs to be locked in order to execute a create account operation.
Create a Safe Account
Before deploying a bridge, you have to create a Gnosis Safe. The safe is the multisig account that manages all of the bridge's assets.
- Connect a wallet to the Gnosis Safe management platform.
- Click + Create New Safe.
- Give the safe a name to identify it locally.
- The owners are the bridge witnesses.
- The threshold is the amount of signatures required to make a transaction on the bridge.
Before submitting, check your information on the review screen.
A prompt will appear, asking to sign the transaction. Carefully review the transaction details before signing it. Once the transaction is submitted, you'll see a success screen.
Deploy the Bridge Doors
Depending on the bridge currency you want to deploy, there are different steps. Choose the correct bridge type below:
XRP Native Bridge
XRP bridges are a rare case and should only have one bridge per mainchain and sidechain pair. The sidechain specification forces the XRP issuer account to be rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh
.
To deploy an XRP bridge door smart contract, run this typescript command:
import { BridgeDoorNative__factory } from "@peersyst/xrp-evm-contracts/dist/typechain/factories/BridgeDoorNative__factory"; import { xrplAccountToEvmAddress } from "./util/address-derivation"; import { ethers } from "ethers"; const safeAddress = "0x..."; const lockingBridgeAddress = "r1..."; // Address of the XRPL bridge const minRewardAmount = "1"; const minCreateAmount = "50"; const signerWallet = new ethers.Wallet("0..."); // Private key with balance const bridgeDoorNativeFactory = new BridgeDoorNative__factory(signerWallet); const bridgeDoorNative = await bridgeDoorNativeFactory.deploy( safeAddress, ethers.utils.parseEther(minRewardAmount), ethers.utils.parseEther(minCreateAmount), ethers.constants.AddressZero, xrplAccountToEvmAddress(lockingBridgeAddress), ); const bridgeAddress = bridgeDoorNative.address;
Token Bridge
Token bridges are more common than XRP bridges, so you'll most likely deploy this type.
To deploy a token bridge door smart contract, run this typescript command on the locking chain:
import { BridgeDoorNative__factory } from "@peersyst/xrp-evm-contracts/dist/typechain/factories/BridgeDoorNative__factory"; import { xrplAccountToEvmAddress } from "./util/address-derivation"; import { ethers } from "ethers"; const safeAddress = "0x..."; const issuingBridgeAddress = "r1..."; // Address of the XRPL brige const tokenAddress = "0x..."; // Address of the ERC20 to bridge const tokenCode = "PER"; const minRewardAmount = "1"; const minCreateAmount = "50"; const signerWallet = new ethers.Wallet("0..."); // Private key with balance const bridgeDoorTokenFactory = new BridgeDoorToken__factory(signerWallet); const bridgeDoorToken = await bridgeDoorTokenFactory.deploy( safeAddress, ethers.utils.parseEther(minRewardAmount), ethers.constants.AddressZero, tokenAddress, xrplAccountToEvmAddress(issuingBridgeAddress), xrplAccountToEvmAddress(issuingBridgeAddress), tokenCode, "", ); const bridgeAddress = bridgeDoorToken.address;
Next, run this typescript command on the issuing chain:
import { BridgeDoorNative__factory } from "@peersyst/xrp-evm-contracts/dist/typechain/factories/BridgeDoorNative__factory"; import { xrplAccountToEvmAddress } from "./util/address-derivation"; import { ethers } from "ethers"; const safeAddress = "0x..."; const lockingBridgeAddress = "r1..."; // Address of the XRPL brige const lockingTokenAddress = "r2..."; // Address of the IOU issuer or address of the ERC20 in the locking chain const lockingTokenCode = "USD"; const minRewardAmount = "1"; const minCreateAmount = "50"; const signerWallet = new ethers.Wallet("0..."); // Private key with balance const bridgeDoorTokenFactory = new BridgeDoorToken__factory(signerWallet); const bridgeDoorToken = await bridgeDoorTokenFactory.deploy( safeAddress, ethers.utils.parseEther(minRewardAmount), xrplAccountToEvmAddress(lockingBridgeAddress), xrplAccountToEvmAddress(lockingTokenAddress), ethers.constants.AddressZero, ethers.constants.AddressZero, lockingTokenCode, `Bridged ${lockingTokenCode} (${tokenAddress})`, ); const bridgeAddress = bridgeDoorToken.address; const tokenAddress = await bridgeDoorToken._tokenAddress();
Authorize the Bridge Door
Enable the safe module to authorize the bridge door to execute transactions. You can do this from the Gnosis Safe off-chain management platform.
Click Use Transaction Builder.
Enter these fields:
- Enter Address or ENS Name: The address of the safe you created.
- Enter ABI:
[{ "inputs": [ { "internalType": "address", "name": "module", "type": "address" } ], "name": "enableModule", "outputs": [], "stateMutability": "nonpayable", "type": "function" }]
- To Address: The address of the safe you created.
- Contract Method Selector: enableModule
- module (address): The address of the bridge door smart contract you deployed.
Click Add Transaction to add it to the batch.
Click Create Batch.
Review the transaction information is correct before clicking Send Batch.
If the threshold of the safe is one, you can click Submit. Otherwise, the other owners of the safe need to review and sign the transaction before you can submit it to the network.
You can check on the status of signatures from the Transactions tab.
Check the module is enabled from Settings > Modules.
After the module is enabled, witnesses can send attestations and the bridge can begin operating.