How to Integrate Front-end Bridges

Summary: For many dapps, it would create a better user experience if they could transfer assets cross-chain in the appropriate context, rather than rely on Multichain's platform to do this and having to open a separate dapp. Here we show how to achieve that for Bridged assets.

Multichain Bridge

To use an existing Bridge, the first task is to retrieve the Bridge information for the chain that it is being sent to. For instance you can get an object describing the Fantom Bridge (chainID: 250)

This is JSON describing all token bridges from all chains to Fantom. This is a very large object, but if we are interested in one particular token, say SHIBA INU, bridged from Ethereum, we can find the object member describing it

"shibv4": {
    "srcChainID":"1",
    "destChainID":"250",
    "logoUrl":"https://assets.coingecko.com/coins/images/11939/large/SHIBLOGO.png",
    "name":"SHIBAINU",
    "symbol":"SHIB",
    "PairID":"SHIBv4",
        "SrcToken": {
            "ID":"ERC20",
            "Name":"SHIBERC20",
            "Symbol":"SHIB",
            "Decimals":18,
            "Description":"ERC20 SHIB",
            "DepositAddress":"0xC564EE9f21Ed8A2d8E7e76c085740d5e4c5FaFbE",
            "DcrmAddress":"0xC564EE9f21Ed8A2d8E7e76c085740d5e4c5FaFbE",
            "ContractAddress":"0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE",
            "MaximumSwap":620000000000,
            "MinimumSwap":1112500,
            "BigValueThreshold":130000000000,
            "SwapFeeRate":0,
            "MaximumSwapFee":0,
            "MinimumSwapFee":0,
            "PlusGasPricePercentage":10,
            "DisableSwap":false,
            "IsDelegateContract":false,
            "BaseFeePercent":0
        },
        "DestToken":{
            "ID":"SHIB",
            "Name":"SHIBA INU",
            "Symbol":"SHIB",
            "Decimals":18,
            "Description":"cross chain bridge SHIB with SHIB",
            "DcrmAddress":"0xC564EE9f21Ed8A2d8E7e76c085740d5e4c5FaFbE",
            "ContractAddress":"0x65e66a61d0a8f1e686c2d6083ad611a10d84d97a",
            "MaximumSwap":620000000000,
            "MinimumSwap":28000000,
            "BigValueThreshold":130000000000,
            "SwapFeeRate":0.001,
            "MaximumSwapFee":14000000,
            "MinimumSwapFee":1112500,
            "PlusGasPricePercentage":1,
            "DisableSwap":false,
            "IsDelegateContract":false,
            "BaseFeePercent":0
        }
},

If we look at the SrcToken first, we see the ContractAddress is just the ERC20 contract on Ethereum https://etherscan.io/address/0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE

The DcrmAddress is generated by the SMPC network and is the address to which SHIB (and all other tokens being sent from Ethereum to Fantom) is transferred to. This can be a normal send transaction, though if it is a smart contract sending the tokens, it's address must be whitelisted before this can occur (contact team).

In the DestToken, we see that the SHIB token created on Fantom is the AnyswapV5ERC20 contract https://ftmscan.com/address/0x65e66a61d0a8f1e686c2d6083ad611a10d84d97a

If you look at this contract, you see two types of transaction in addition to the normal Transfer and Approve functions: Swapin and Swapout.

The Swapin is the contract receiving instructions from the SMPC network, which detected that the DcrmAddress had been sent SHIB on Ethereum. The contract will then mint SHIB on Fantom.

The Swapout function is when a user sends SHIB back to Ethereum. The contract method swapout is called, which will cause the contract to burn the SHIB and the SMPC network will release SHIB to the destination address on Ethereum.

The standard wrapped asset contract is called AnyswapV5ERC20 and is a superset of the standard ERC20 token. Here is the AnyswapV5ERC20 Contract

In this we can see the two functions swapin and swapout and we see the calls for _mint for swapin and to _burn for the swapout

function Swapin(bytes32 txhash, address account, uint256 amount) public onlyAuth returns (bool) {
        _mint(account, amount);
        emit LogSwapin(txhash, account, amount);
        return true;
}

function Swapout(uint256 amount, address bindaddr) public returns (bool) {
        require(!_vaultOnly, "AnyswapV4ERC20: onlyAuth");
        require(bindaddr != address(0), "AnyswapV3ERC20: address(0x0)");
        _burn(msg.sender, amount);
        emit LogSwapout(msg.sender, bindaddr, amount);
        return true;
}

The other parameters in the SrcToken and DestToken objects are related to fees and limits on transaction amounts.

  • MaximumSwap and MinimumSwap are the min and max amounts that can be swapped in wei,

  • BigValueThreshold is the amount after which a transfer will trigger a requirement for a manual authorization ("Big Amount")

  • SwapFeeRate is the percentage fee for amounts between the minumum and maximum fee.

  • PlusGasPricePercentage is how much gas beyond the estimated gas to pay to ensure that transactions are picked up from the mem pool.

  • DisableSwap is whether the Bridge is disabled or not ("false" for normal usage).

The coder can use an API to check the transaction status for a source transaction hash. An example of this is for this transaction sending BNB from BSC to Fantom https://bscscan.com/tx/0x76c4f...9981. You can interrogate the status for this cross chain transaction https://bridgeapi.anyswap.exchange/v2/history/details?params=0x76c4f...9981 and we see that the returned JSON has "msg":"Success" and a lot more information about the cross chain transfer too.

There is more information on the github regarding the API here, including how to get the history for tokens and addresses Bridge-api-for-frontend

Last updated