Cross-Chain Contract Calls and Deposits
Contract Calls allow developers to execute complex transactions on the same chain or across different blockchains as one single transaction. This enables deposits into staking, lending or liquidity protocols from any token as a single transaction which otherwise would have taken anywhere between 2-10 transactions.
Swing supports both same chain and cross chain contract calls. Swing seamlessly connects to bridges, DEXes and protocols to execute complex on-chain transactions.
Our contracts were audited on 31 May 2023, by Peckshield Audit. view audit report Monetize your integration by collecting partner fees up to 10% of the transaction volume. Learn More
Steps: Executing a Contract Call
The steps to executing a contract call are the same as executing a bridge or swap transaction, with the added exception that you’ll need to generate the callData
for the contract where the funds will be deposited:
- 1) Gather the Transaction Info:
- Gather info on the source chain and token, destination chain and token, amount, and projectId
- See Gathering transaction info
- 2) Generate Contract CallData:
- Generate unsigned callData transaction for target contract.
- See Generating Contract CallData
- 3) Request a Quote:
- Endpoint: /quote
- Get a quote from one of Swing's integrated partners.
- See Requesting a Contract-Call Quote
- 4) Approve ERC20 Tokens (Optional):
- Endpoint: /allowance
- Get approval for non-native token transfers/swaps.
- See Requesting Approval Calldata for Contract Calls
- 5) Sign Approval CallData (Optional):
- Endpoint: /approve
- Execute approval callData smart contract transaction using a wallet.
- See Requesting Approval Calldata for Contract Calls
- 6) Send a Transaction:
- Endpoint: /send
- Intiating transaction given the prior quote on a specific bridge.
- See Sending a Transaction
- 7) Sign Transaction CallData:
- Execute send callData smart contract transaction using a wallet.
- See Signing Transaction CallData
- 8) Poll Transaction Status:
- Endpoint: /status
- Wait for transaction to complete by polling for transaction status
- See Checking Transaction Status
Making a Request
POST: https://swap.prod.swing.xyz/v0/transfer/send
Body Parameters:
Key | Example | Description |
---|---|---|
fromChain | ethereum | The blockchain where the transaction originates. |
fromTokenAddress | 0x0000000000000000000000000000000000000000 | Source Token Address |
fromUserAddress | 0x018c15DA1239B84b08283799B89045CD476BBbBb | Sender's wallet address |
tokenSymbol | ETH | Source token slug |
toTokenAddress | 0x0000000000000000000000000000000000000000 | Destination token address. |
toChain | polygon | Destination chain |
toTokenAmount | 4376081 | Amount of the destination token to be received. |
toTokenSymbol | MATIC | Destination Chain slug |
toUserAddress | 0x018c15DA1239B84b08283799B89045CD476BBbBb | Receiver's wallet address |
tokenAmount | 1000000000000000000 | Amount of the source token being sent (in wei for ETH). |
projectId | replug | Your project's ID |
route | see Get Qoute | Selected route |
contractCallInfo | see Generating Contract Calldata section | Target contract info for deposits |
Sample Request
Generating Contract Calldata
For Contract Calls, Swing's /send
endpoint gives us the option to instruct the system on what to do with our funds post swap.
For example, we can instruct Swing to deposit our funds into a smart contract of our choosing. A more practical instruction would be to stake our funds into a staking contract, and then send us that staking contract's LP token. We can achieve this using the contractCallInfo
array parameter in the /send
endpoint.
To execute a contract call via Swing, we'll need three (3) parameters to be passed our contractCallInfo
Array:
Property | Example | Description | |
---|---|---|---|
toContractAddress | 0x9ee91F9f426fA633d227f7a9b000E28b9dfd8599 | required | Smart Contract address we'll deposit your funds into |
toContractCallData | 0xa9059cbb0000000000000000000000abcdef........ | required | Calldata to be passed to Swing |
outputTokenAddress | 0x018c15DA1239B84b08283799B89045CD476BBbBb | optional | Address of Liquidity Provider Token to be received by sender |
When executing a contract call transaction, you are required to provide the contract calldata for the contract to which you wish to send your funds.
Let's say we've got some USDC on the Polygon chain and want to stake some ETH into LIDO's Ethereum staking contracts via Swing. The following will take place to make this transaction to be possible:
- Swing will start the transaction by deducting the necessary funds from the
fromUserAddress
. - Swing will then bridge our USDC (
tokenSymbol
) from the Polygon chain (fromChain
) to the Ethereum Chain (toChain
). - Swing will then swap that USDC (
tokenSymbol
) to ETH (toTokenSymbol
) on the destination chain (toChain
) and send it to wallet address supplied to thetoUserAddress
. - Using the
contractCallInfo
parameter, Swing will then execute a function on a target Smart Contract and deposit your funds. - Optionally, If the target smart contract emits any token to the sender's wallet like an LP token, Swing can then send those token to the address supplied to the
toUserAddress
.
If you omit the
toUserAddress
parameter, Swing will default it's value to whatever value you supply to thefromUserAddress
.
To get started, we'll first need to generate the necessary callData
by using LIDO's staking contract ABI:
It's very important to remember what we're trying to achieve here. We want Swing to interact with LIDO's contract immediately after swapping our funds. When Swing is done swapping our assets, we want Swing to call the submit
function on LIDO's contract.
For this example, we'll be using ethers.js to generate the callData
required for our contract call example.
Using ethers to generate our callData is fairly straight forward. First we'll load up LIDO's staking smart contract using it's ABI and contract address:
Next, we'll encode the function data by using the encodeFunctionData()
method to generate the final callData for the submit()
function in LIDO's staking contract.
LIDO's submit()
function takes two parameters, namely:
_amount
— the amount of tokens to be staked_referral
— an address for incentivisation reward
Putting it all together into a function called generateCallData()
:
Executing a Contract Call Transaction
Next, let's generate our callData and make a request to Swing to get our transaction ready to be sent over to the network:
Since executing a contract call will change the state of a user's wallet, the next step of this process requires invoking a contract-level function on the wallet address you supply to the fromUserAddress
parameter. Swing only returns the necessary call-data that will need to be signed and executed by the local wallet (i.e. Metamask, WalletConnect, Coinbase Wallet).