๐Ÿ”ขExecution

Executing the swap

Here is a sample code of how passing the swap response containing an EVM transaction to the wallet, sign it by the user, and track it using the rango client. You could check the full working example on Github.

Sample EVM Execution
import { ethers } from 'ethers'
import {
  EvmTransaction,
  RangoClient,
} from 'rango-sdk-basic'


const provider = new ethers.providers.Web3Provider(window.ethereum)
const signer = provider.getSigner()

const swapRequest = {
  from: {
    "blockchain": "BSC", 
    "symbol": "BNB", 
    "address": null
  },
  to: {
    "blockchain": "FANTOM", 
    "symbol": "FUSDT", 
    "address": "0x049d68029688eabf473097a2fc38ef61633a3c7a"
  },
  amount: "100000000000000000",
  fromAddress: "0xbe807dddb074639cd9fa61b47676c064fc50d62c",
  toAddress: "0xbe807dddb074639cd9fa61b47676c064fc50d62c",
  slippage: '1.0',
  disableEstimate: false, 
  referrerAddress: null,  // your dApp wallet address for referral
  referrerFee: null,      // your dApp desired referral fee percent 
}

const swap = await rangoClient.swap(swapRequest)

if (!!swap.error || swap.resultType !== 'OK') {
  const msg = 
    `Error swapping, message: ${swap.error}, status: ${swap.resultType}`
  throw new Error(msg)
}

const evmTransaction = swap.tx as EvmTransaction

// needs approving the tx
if (swap.approveTo && swap.approveData) {
  const approveTx = prepareEvmTransaction(evmTransaction, true)
  const approveTxHash = (await signer.sendTransaction(approveTx)).hash
  await checkApprovalSync(swap.requestId, approveTxHash, rangoClient)
}

// main transaction
const mainTx = prepareEvmTransaction(evmTransaction, false)
const mainTxHash = (await signer.sendTransaction(mainTx)).hash
const txStatus = await checkTransactionStatusSync(
  swap.requestId,
  mainTxHash,
  rangoClient
)

And here you can see a sample implementation of utility functions including prepareEvmTransaction , checkTransactionStatusSync, and checkApprovalSync which are used in the above code:

Utility functions
import {TransactionRequest} from "@ethersproject/abstract-provider/src.ts/index";
import {
  RangoClient, 
  EvmTransaction, 
  TransactionStatus
} from "rango-sdk-basic";

export function prepareEvmTransaction(
  evmTx: EvmTransaction, 
  isApprove: boolean
): TransactionRequest {
  const gasPrice = !!evmTx.gasPrice && !evmTx.gasPrice.startsWith('0x') ?
      '0x' + parseInt(evmTx.gasPrice).toString(16) : null,
  const manipulatedTx = {
    ...evmTx,
    gasPrice
  }

  let tx = {}
  if (!!manipulatedTx.from) tx = { ...tx, from: manipulatedTx.from }
  if (isApprove) {
    if (!!manipulatedTx.approveTo) tx = {...tx, to: manipulatedTx.approveTo}
    if (!!manipulatedTx.approveData) tx = {...tx, data: manipulatedTx.approveData}
  } else {
    if (!!manipulatedTx.txTo) tx = { ...tx, to: manipulatedTx.txTo }
    if (!!manipulatedTx.txData) tx = { ...tx, data: manipulatedTx.txData }
    if (!!manipulatedTx.value) tx = { ...tx, value: manipulatedTx.value }
    if (!!manipulatedTx.gasLimit) tx = { ...tx, gasLimit: manipulatedTx.gasLimit }
    if (!!manipulatedTx.gasPrice) tx = { ...tx, gasPrice: manipulatedTx.gasPrice }
  }
  return tx
}

export async function checkApprovalSync(
  requestId: string, 
  txId: string, 
  rangoClient: RangoClient
) {
  while (true) {
    const approvalResponse = await rangoClient.isApproved(requestId, txId)
    if (approvalResponse.isApproved) {
      return true
    }
    await sleep(3000)
  }
}

const checkTransactionStatusSync = async (
  requestId: string,
  txId: string,
  rangoClient: RangoClient
) => {
  while (true) {
    const txStatus = await rangoClient.status({
      requestId,
      txId,
    })
    .catch(error) => {
      console.log({ error })
    })
    if (!!txStatus) {
      // show latest status of the transaction to the user
      console.log({ txStatus })
      if (
        !!txStatus.status &&
        [TransactionStatus.FAILED, TransactionStatus.SUCCESS].includes(
          txStatus.status
        )
      ) {
        return txStatus
      }
    }
    await sleep(3000)
  }
}

Last updated