Step 3: Get token approval

This section is only applicable to transfers of non-native tokens. Non-native tokens include governance tokens, wrapped tokens, stablecoins, and oracle tokens.

The full API reference for our /approve endpoint can be found in the API reference section.

If you are performing a transfer with a non-native token, our Swing Contract requires the right allowance limit to spend/withdraw funds (denominated in non-native tokens) from the designated wallet address. Depending on the non-native token amount you are looking to transfer, you want to call our /approve endpoint with a limit greater than or equal to the amount you are transferring.

You can use the /allowance endpoint to determine if you have already approved a sufficient limit to allow your non-native token transfer. Importantly, the allowance limit is specific to the token, chain and bridge. So you must approve an allowance limit every time for every unique transfer combination of token, chain or bridge.

Allowance Endpoint

We can query our /allowance endpoint in the following manner to get the allowance limit:

const getAllowance = async (params) => {
  const result = await axios.get(
    'https://swap.prod.swing.xyz/v0/transfer/allowance',
    {
      fromChain: params.fromChain.slug,
      fromChainId: params.fromChain.chainId,
      tokenSymbol: params.fromToken.symbol,
      tokenAddress: params.fromToken.address,
      bridge: params.bridge,
      fromAddress: params.userAddress,
      contractCall: true,
    },
  );
  return result.data.allowance;
};

This will always only return the allowance limit for that specific token, on the specific chain for that specific bridge:

{
  "allowance": "1000000"
}

Approve Endpoint

If you need to approve a higher allowance limit, you can query our /approve endpoint in the following manner:

const getApprovalCallData = async (params) => {
  const result = await axios.get(
    'https://swap.prod.swing.xyz/v0/transfer/approve',
    {
      fromChain: params.fromChain.slug,
      fromChainId: params.fromChain.chainId,
      tokenSymbol: params.fromToken.symbol,
      tokenAddress: params.fromToken.address,
      toChain: params.toChain.slug,
      toChainId: params.toChain.chainId,
      bridge: params.bridge,
      fromAddress: params.userAddress,
      tokenAmount: params.amount,
      contractCall: true,
    },
  );
  return result.data;
};

Since approve is a contract-level function, Swing only returns the necessary call-data that will need to be signed and executed by the local wallet (ie. Metamask, Coinbase Wallet, WalletConnect, etc).

{
  "data": "0x095ea7b30000000000000000000000008ea232420493c05b5dfcb329b33d0c2a334d3eb40000000000000000000000000000000000000000000000004563918244f40000",
  "to": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
  "from": "0x184AbEfBdCa24Ce0Dd964a74f6d5E69CE44D9579",
  "fromChain": {
    "chainId": 1,
    "slug": "ethereum",
    "name": "Ethereum",
    "protocolType": "evm"
  }
}