Search
K

Destination Actions (Zaps)

Enable Cross-Chain Zaps with Socket 🔌

Introduction

  • Destination Actions enable developers to perform arbitrary transactions on the destination chain in addition to bridging tokens.
  • Developers can pass the calldata on the source chain that will be executed post-bridging on the destination chain. You’ll also need to estimate and pass the gasLimit of this destination transaction.
  • Accordingly, users would pay additional gas fees on the source chain which will cover the destination fees of the relayer.
  • This calldata will be executed on the destination chain in the same transaction in which the bridged funds are transferred.
  • Destination Actions has limited bridge support to begin with and will support more bridges/tokens in upcoming updates

Chain Support

The destination action integration flow mostly follows Single Transaction Bridging & Multi Transaction Bridging flows. The only changes are in the Quote Step and Build-Tx Step. In case you haven’t checked out either guides, please check it first.

Passing calldata to API

1. Generating calldata

  • You need to build the bytes calldata to be executed on the destination chain & estimate the gasLimit of executing this transaction before-hand
  • Considerations for the targetContract
    • Currently, destination actions only supports ERC20 tokens as the receiving token. Support for native assets will be added in upcoming releases.
    • The receiver contract increases the token allowance of bridged ERC20 by amountLD (bridged output amount) for targetContract
    • The function being executed on targetContract must have a transferFrom function which transfers the bridged ERC20 token from the receiverContract to targetContract
EXAMPLE
Depositing sUSD into Lyra on Optimism
  • calldata for calling initiateDeposit() function on Lyra contracts post-bridging
import { ethers } from 'ethers';
// Calldata for depositing 1000 sUSD with benificiary 0x58Daefe2A4224966535dfbBca1f3c90D09919c2D
const lyraContractAddress = '0x5Db73886c4730dBF3C562ebf8044E19E8C93843e';
async function generateLyraData() {
const provider = new ethers.providers.JsonRpcProvider('https://mainnet.optimism.io');
const contract = new ethers.Contract(lyraContractAddress, lyraAbi, provider);
const beneficiary = '0x58Daefe2A4224966535dfbBca1f3c90D09919c2D';
const amount = '1000000000000000000000'
const txData = await contract.populateTransaction.initiateDeposit(beneficiary, amount);
return txData;
}
// Output
// 0xec55234600000000000000000000000058daefe2a4224966535dfbbca1f3c90d09919c2d00000000000000000000000000000000000000000000003635c9adc5dea00000
// Estimated gasLimit
// ~ 285K

2. Fetching Bridging Quote with destination calldata

  • You can request a bridging quote as usual with selected fromChainId, toChainId, fromTokenAddress, toTokenAddress. More on fetching quotes here.
  • When calling the Quote endpoint, you need to pass 4 additional params for executing destination transactions
    Param
    Description
    recipient
    Address of targetContract on destination chain where calldata will be executed
    destinationPayload
    calldata to be executed on destination chain
    destinationGasLimit
    gasLimit required to post-bridging tx + 30k extra gas
    singleTxOnly
    Must be set to true
  • IMPORTANT
    Please add 30,000 gas units to the estimated destinationGasLimit. This covers the cost of the receiver contract on the destination chain. For e.g if the estimated gasLimit to execute your destination tx is 570K, add destinationGasLimit as 600K.
EXAMPLE REQUEST
Example Quote Request for bridging 1000 sUSD from Ethereum to Optimism & depositing into Lyra
https://api.socket.tech/v2/quote?fromChainId=1&fromTokenAddress=0x57Ab1ec28D129707052df4dF418D58a2D46d5f51&toChainId=10&toTokenAddress=0x8c6f28f2F1A3C87F0f938b96d27520d9751ec8d9&fromAmount=1000000000000000000000&userAddress=0x58Daefe2A4224966535dfbBca1f3c90D09919c2D&recipient=0x5Db73886c4730dBF3C562ebf8044E19E8C93843e&uniqueRoutesPerBridge=true&includeBridges=&sort=output&singleTxOnly=true&destinationPayload=0xec55234600000000000000000000000058daefe2a4224966535dfbbca1f3c90d09919c2d00000000000000000000000000000000000000000000003635c9adc5dea00000&destinationGasLimit=310000
EXAMPLE RESPONSE
{
"success": true,
"result": {
"routes": [
{
// Route Object to be used
}
],
"destinationCallData": {
"destinationPayload": "0xec55234600000000000000000000000058daefe2a4224966535dfbbca1f3c90d09919c2d00000000000000000000000000000000000000000000003635c9adc5dea00000",
"destinationGasLimit": "310000"
}, // DestinationCallData to be used
...
}
}

3. Building transaction for source chain

(This guide uses the POST /build-tx endpoint)
  • The selected route’s object and destinationCallData returned in the quote response can be used to build the transaction to be executed on the source chain
  • More details on the POST /build-tx endpoint
REQUEST BODY
{
"route": {
// Insert selected route object here
},
"destinationCallData": {
// Insert selected destinationCallData from the Quote response here
}
}
EXAMPLE REQUEST
  • Using the route returned in the Quote Example above
REQUEST BODY
{
"route":{
"routeId":"49de2227-346f-4234-96c8-f892e4f9a46f",
"isOnlySwapRoute":false,
"fromAmount":"1000000000000000000000",
"toAmount":"999780563000000000000",
"usedBridgeNames":[
"stargate"
],
"minimumGasBalances":{
"1":"30000000000000000",
"10":"1800000000000000"
},
"chainGasBalances":{
"1":{
"minGasBalance":"30000000000000000",
"hasGasBalance":false
},
"10":{
"minGasBalance":"1800000000000000",
"hasGasBalance":false
}
},
"totalUserTx":1,
"sender":"0x58Daefe2A4224966535dfbBca1f3c90D09919c2D",
"recipient":"0x5Db73886c4730dBF3C562ebf8044E19E8C93843e",
"totalGasFeesInUsd":21.0896694041751,
"receivedValueInUsd":979.680670595825,
"userTxs":[
{
"userTxType":"fund-movr",
"txType":"eth_sendTransaction",
"chainId":1,
"toAmount":"999780563000000000000",
"toAsset":{
"chainId":10,
"address":"0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9",
"symbol":"SUSD",
"name":"Synthetic sUSD",
"decimals":18,
"icon":"https://assets.coingecko.com/coins/images/5013/small/sUSD.png?1616150765",
"logoURI":"https://assets.coingecko.com/coins/images/5013/small/sUSD.png?1616150765",
"chainAgnosticId":null
},
"stepCount":1,
"routePath":"0-27",
"sender":"0x58Daefe2A4224966535dfbBca1f3c90D09919c2D",
"approvalData":{
"minimumApprovalAmount":"1000000000000000000000",
"approvalTokenAddress":"0x57ab1ec28d129707052df4df418d58a2d46d5f51",
"allowanceTarget":"0x6cf8d2bf45fe99e369db145faf6fb606a50b27f3",
"owner":"0x58Daefe2A4224966535dfbBca1f3c90D09919c2D"
},
"steps":[
{
"type":"bridge",
"protocol":{
"name":"stargate",
"displayName":"Stargate",
"icon":"https://s2.coinmarketcap.com/static/img/coins/128x128/18934.png",
"securityScore":3,
"robustnessScore":3
},
"bridgeSlippage":0.5,
"fromChainId":1,
"fromAsset":{
"chainId":1,
"address":"0x57ab1ec28d129707052df4df418d58a2d46d5f51",
"symbol":"SUSD",
"name":"Synth sUSD",
"decimals":18,
"icon":"https://assets.coingecko.com/coins/images/5013/small/sUSD.png?1616150765",
"logoURI":"https://assets.coingecko.com/coins/images/5013/small/sUSD.png?1616150765",
"chainAgnosticId":null
},
"fromAmount":"1000000000000000000000",
"toChainId":10,
"toAsset":{
"chainId":10,
"address":"0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9",
"symbol":"SUSD",
"name":"Synthetic sUSD",
"decimals":18,
"icon":"https://assets.coingecko.com/coins/images/5013/small/sUSD.png?1616150765",
"logoURI":"https://assets.coingecko.com/coins/images/5013/small/sUSD.png?1616150765",
"chainAgnosticId":null
},
"minAmountOut":"994781660000000000000",
"toAmount":"999780563000000000000",
"protocolFees":{
"asset":{
"chainId":1,
"address":"0x57ab1ec28d129707052df4df418d58a2d46d5f51",
"symbol":"SUSD",
"name":"Synth sUSD",
"decimals":18,
"icon":"https://assets.coingecko.com/coins/images/5013/small/sUSD.png?1616150765",
"logoURI":"https://assets.coingecko.com/coins/images/5013/small/sUSD.png?1616150765",
"chainAgnosticId":null
},
"feesInUsd":0,
"amount":"219437000000000000"
},
"gasFees":{
"gasAmount":"12607331020364000",
"asset":{
"chainId":1,
"address":"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"symbol":"ETH",
"name":"Ethereum",
"decimals":18,
"icon":"https://maticnetwork.github.io/polygon-token-assets/assets/eth.svg",
"logoURI":"https://maticnetwork.github.io/polygon-token-assets/assets/eth.svg",
"chainAgnosticId":null
},
"gasLimit":420000,
"feesInUsd":21.0896694041751
},
"serviceTime":60,
"maxServiceTime":7200
}
],
"gasFees":{
"gasAmount":"12607331020364000",
"feesInUsd":21.0896694041751,
"asset":{
"chainId":1,
"address":"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"symbol":"ETH",
"name":"Ethereum",
"decimals":18,
"icon":"https://maticnetwork.github.io/polygon-token-assets/assets/eth.svg",
"logoURI":"https://maticnetwork.github.io/polygon-token-assets/assets/eth.svg",
"chainAgnosticId":null
},
"gasLimit":420000
},
"serviceTime":60,
"recipient":"0x5Db73886c4730dBF3C562ebf8044E19E8C93843e",
"maxServiceTime":7200,
"bridgeSlippage":0.5,
"userTxIndex":0
}
],
"serviceTime":60,
"maxServiceTime":7200,
"integratorFee":{
"amount":"0",
"asset":{
"chainId":1,
"address":"0x57ab1ec28d129707052df4df418d58a2d46d5f51",
"symbol":"SUSD",
"name":"Synth sUSD",
"decimals":18,
"icon":"https://assets.coingecko.com/coins/images/5013/small/sUSD.png?1616150765",
"logoURI":"https://assets.coingecko.com/coins/images/5013/small/sUSD.png?1616150765",
"chainAgnosticId":null
}
}
},
"destinationCallData":{
"destinationPayload":"0xec55234600000000000000000000000058daefe2a4224966535dfbbca1f3c90d09919c2d00000000000000000000000000000000000000000000003635c9adc5dea00000",
"destinationGasLimit":"310000"
}
}
EXAMPLE RESPONSE
{
"success": true,
"result": {
"userTxType": "fund-movr",
"txType": "eth_sendTransaction",
"txData": "0xa44bbb150000000000000000000000000000000000000000000000000000000000000020000000000000000000000000ddc3a2bc1d6252d09a82814269d602d84ca3e7ae000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057ab1ec28d129707052df4df418d58a2d46d5f5100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b00000000000000000000000000000000000000000000000000025381a1c4f9c100000000000000000000000057ab1ec28d129707052df4df418d58a2d46d5f51000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000003b4b29dc000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000058daefe2a4224966535dfbbca1f3c90d09919c2d000000000000000000000000000000000000000000000000000000000004baf000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000005db73886c4730dbf3c562ebf8044e19e8c93843e00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000044ec55234600000000000000000000000058daefe2a4224966535dfbbca1f3c90d09919c2d00000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000000000000000",
"txTarget": "0xc30141B657f4216252dc59Af2e7CdB9D8792e1B0",
"chainId": 1,
"userTxIndex": 0,
"value": "0x025381a1c4f9c1",
"approvalData": {
"minimumApprovalAmount": "1000000000000000000000",
"approvalTokenAddress": "0x57ab1ec28d129707052df4df418d58a2d46d5f51",
"allowanceTarget": "0x6cf8d2bf45fe99e369db145faf6fb606a50b27f3",
"owner": "0x58Daefe2A4224966535dfbBca1f3c90D09919c2D"
}
}
}
If you’re using the GET /build-tx instead
If you’re following the Single Transaction Bridging guide & using the GET Build-Tx endpoint
  • Check out the GET build-tx for more details
  • In addition to passing all the request params, you’ll also need to pass the recipient,destinationPayload and destinationGasLimit returned in the Quote Response in the destinationCallData object.
  • Example Request
    https://api.socket.tech/v2/build-tx?sender=0x58Daefe2A4224966535dfbBca1f3c90D09919c2D&recipient=0x5Db73886c4730dBF3C562ebf8044E19E8C93843e&routePath=0-27&fromChainId=1&toChainId=10&fromTokenAddress=0x57ab1ec28d129707052df4df418d58a2d46d5f51&toTokenAddress=0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9&fromAmount=1000000000000000000000&toAmount=999893238000000000000&bridgeInputTokenAddress=0x57ab1ec28d129707052df4df418d58a2d46d5f51&destinationPayload=0xec55234600000000000000000000000058daefe2a4224966535dfbbca1f3c90d09919c2d00000000000000000000000000000000000000000000003635c9adc5dea00000&destinationGasLimit=310000
If you’re using the POST /route/start instead
If you’re following the Multi Transaction Bridging guide & using the /Route endpoints
  • When starting the route, you need to add the desintinationCallData object, same as the POST /build-tx endpoint
  • More on the /route/start endpoint
    {
    "route": {
    // Insert selected route object here
    },
    "destinationCallData": {
    // Insert selected destinationCallData from the Quote response here
    }
    }

4. In-flight & Post Bridging

Glossary

Payload
calldata to be executed on the destination chain
Receiver Contract
Socket’s contract on the destination chain that receives tokens and calls targetContract
Target Contract
Contract on destination chain which is being called in calldata

Debugging failed transactions

In case the tokens are bridged and sent to the Receiver Contract but the destination calldata isn’t executed, check if there’s a CachedSwapSaved event emitted. This generally means the calldata was faulty and couldn’t be executed or the gasLimit was insufficient to cover the cost of the transaction. Please reach out to us if your transaction fails and we can help debug.
Last modified 4mo ago