The SimpleBridge just transfers tokens from a user to another wallet (could be themselves) on a different chain. Since no calldata is involved, no target contract is needed.
In this example, SimpleBridge has two functions:
xTransfer bridges any ERC20 token
The user must first approve a spending allowance of the token to the SimpleBridge contract.
relayerFee is paid in native ETH so when xTransfer is called, msg.value MUST be passed in equal to the specified relayerFee. Informaation for calculating relayer fees can be found on Estimating Fees page.
xTransferEth bridges ETH (for origin/destination chains whose native asset is ETH)
To send and receive native ETH, the flow is a bit different. Since Connext doesn't accept native ETH as the bridged asset, ETH should be first wrapped into WETH on the origin domain and then the delivered WETH on destination should be unwrapped back to ETH.
An Unwrapper contract that implements IXReceive already exists on all supported networks to be used as the _to target in xcall. The final recipient on destination should be encoded into the callData param for the Unwrapper to send ETH to (demonstrated on line 92 below).
When sending ETH, msg.value = relayerFee + amount. See example below (note: in Etherscan, the payable field is in ether while the other fields are specified in wei).
// SPDX-License-Identifier: UNLICENSEDpragmasolidity ^0.8.15;import {IConnext} from"@connext/interfaces/core/IConnext.sol";import {IERC20} from"@openzeppelin/contracts/token/ERC20/IERC20.sol";interface IWETH {functiondeposit() externalpayable;functionapprove(address guy,uint wad) externalreturns (bool);}/** * @title SimpleBridge * @notice Example of a cross-domain token transfer. */contract SimpleBridge {// The connext contract on the origin domain IConnext publicimmutable connext;constructor(address_connext) { connext =IConnext(_connext); }/** * @notice Transfers non-native assets from one chain to another. * @dev User should approve a spending allowance before calling this. * @param token Address of the token on this domain. * @param amount The amount to transfer. * @param recipient The destination address (e.g. a wallet). * @param destinationDomain The destination domain ID. * @param slippage The maximum amount of slippage the user will accept in BPS. * @param relayerFee The fee offered to relayers. */functionxTransfer(address token,uint256 amount,address recipient,uint32 destinationDomain,uint256 slippage,uint256 relayerFee ) externalpayable { IERC20 _token =IERC20(token);require( _token.allowance(msg.sender,address(this)) >= amount,"User must approve amount" );// User sends funds to this contract _token.transferFrom(msg.sender,address(this), amount);// This contract approves transfer to Connext _token.approve(address(connext), amount); connext.xcall{value: relayerFee}( destinationDomain,// _destination: Domain ID of the destination chain recipient,// _to: address receiving the funds on the destination token,// _asset: address of the token contract msg.sender,// _delegate: address that can revert or forceLocal on destination amount,// _amount: amount of tokens to transfer slippage,// _slippage: the maximum amount of slippage the user will accept in BPS (e.g. 30 = 0.3%)bytes("") // _callData: empty bytes because we're only sending funds ); }/** * @notice Transfers native assets from one chain to another. * @param destinationUnwrapper Address of the Unwrapper contract on destination. * @param weth Address of the WETH contract on this domain. * @param amount The amount to transfer. * @param recipient The destination address (e.g. a wallet). * @param destinationDomain The destination domain ID. * @param slippage The maximum amount of slippage the user will accept in BPS. * @param relayerFee The fee offered to relayers. */functionxTransferEth(address destinationUnwrapper,address weth,uint256 amount,address recipient,uint32 destinationDomain,uint256 slippage,uint256 relayerFee ) externalpayable {// Wrap ETH into WETH to send with the xcallIWETH(weth).deposit{value: amount}();// This contract approves transfer to ConnextIWETH(weth).approve(address(connext), amount);// Encode the recipient address for calldatabytesmemory callData = abi.encode(recipient);// xcall the Unwrapper contract to unwrap WETH into ETH on destination connext.xcall{value: relayerFee}( destinationDomain,// _destination: Domain ID of the destination chain destinationUnwrapper,// _to: Unwrapper contract weth,// _asset: address of the WETH contract msg.sender,// _delegate: address that can revert or forceLocal on destination amount,// _amount: amount of tokens to transfer slippage,// _slippage: the maximum amount of slippage the user will accept in BPS (e.g. 30 = 0.3%) callData // _callData: calldata with encoded recipient address ); }}
Information like asset addresses be found in the Deployments page.