๐ŸฐSDK Example

Basic SDK Example for Integrating Rango Exchange

Overview

You could read this guide to understand the flow of integrating Rango-Basic-SDK. If you prefer to dive directly into the code and explore it there, you can use the links below.

Install TS SDK

If you decide not to use our TypeScript SDK and prefer integration in other programming languages, feel free to skip this step.

To integrate Rango SDK inside your dApp or wallet, you need to install rango-sdk-basic using npm or yarn.

npm install --save rango-sdk-basic
# or 
yarn add rango-sdk-basic

Then you need to instantiate RangoClient and use it in the next steps.

import { RangoClient } from "rango-sdk-basic"

const rango = new RangoClient(RANGO_API_KEY)

Get Tokens & Blockchains Data

To get the list of available blockchains, tokens, and protocols (dex or bridge) supported by Rango, you could use the meta method like this:

const meta = await rango.meta()

Get Quote

Using information retrieved from the meta, you could implement your own SwapBox including your blockchain and token selector. The next step is to show the preview of the best route possible when the user selects the source and the destination tokens.

The blockchain and symbol names must be exactly what is fetched from Rango's Meta API.

// Converting 0.1 BSC BNB to AVAX_CCHAIN USDT.E 
const quote = await rango.quote({
  from: {
    "blockchain": "BSC", 
    "address": null
  },
  to: {
    "blockchain": "AVAX_CCHAIN", 
    "address": "0xc7198437980c041c805a1edcba50c1ce5db95118"
  },
  amount: "100000000000000000" 
})

You could call this method periodically to get the updated route before the user confirms the swap.

Creating Transaction

Whenever the user decides to accept the quote and submit the swap, you should call the SDK swap method to get the latest route and transaction data needed to proceed.

// Swap 0.1 BSC BNB to AVAX_CCHAIN USDT.E 
const quote = await rango.swap({
  from: {
    "blockchain": "BSC", 
    "address": null
  },
  to: {
    "blockchain": "AVAX_CCHAIN", 
    "address": "0xc7198437980c041c805a1edcba50c1ce5db95118"
  },
  amount: "100000000000000000",
  fromAddress: "0xbe807dddb074639cd9fa61b47676c064fc50d62c",
  toAddress: "0xbe807dddb074639cd9fa61b47676c064fc50d62c",
  slippage: 1.5,
  disableEstimate: false, 
  referrerAddress: null,  // your dApp wallet address for referral
  referrerFee: null,      // your dApp desired referral fee percent  
})

The route field in response is similar to what you've seen in the quote section and the tx field section is the data of the transaction that needed to be passed to the proper wallet to be signed by the user.

Tracking Swap Status

After signing the transaction by the user and receiving transaction hash, you could periodically call Rango check-status API to track the transaction status. In Rango, each swap step could have 3 different states: running, failed and success. You only need to keep checking the status until you find out whether the transaction failed or succeeded.

Here's a sample request for the check-status API, along with the corresponding response it receives:

const transaction = await rango.status({
    requestId: "b3a12c6d-86b8-4c21-97e4-809151dd4036",
    txId: '0xfa88b705a5b4049adac7caff50c887d9600ef023ef1a937f8f8b6f44e90042b5',
})

Complete Code Flow

Node.JS Example
// run `node --import=tsx index.ts` in the terminal

import { RangoClient, TransactionStatus, TransactionType } from "rango-sdk-basic";
import { findToken } from './utils/meta.js'
import { TransactionRequest, ethers } from "ethers";
import { setTimeout } from 'timers/promises'

// setup wallet & RPC provider
const privateKey = 'YOUR_PRIVATE_KEY';
const wallet = new ethers.Wallet(privateKey);
const rpcProvider = new ethers.JsonRpcProvider('https://bsc-dataseed1.defibit.io');
const walletWithProvider = wallet.connect(rpcProvider);

// initiate sdk using your api key
const API_KEY = "c6381a79-2817-4602-83bf-6a641a409e32"
const rango = new RangoClient(API_KEY)


// some example tokens for test purpose
const sourceBlockchain = "BSC"
const sourceTokenAddress = "0x55d398326f99059ff775485246999027b3197955"
const targetBlockchain = "BSC"
const targetTokenAddress = null
const amount = "10000000000000"

// get quote
const quoteRequest = {
  from: { blockchain: sourceBlockchain, address: sourceTokenAddress },
  to: { blockchain: targetBlockchain, address: targetTokenAddress },
  amount,
  slippage: 1.0,
}
const quote = await rango.quote(quoteRequest)

const swapRequest = {
  ...quoteRequest,
  fromAddress: wallet.address,
  toAddress: wallet.address,
}

// create transaction
const swap = await rango.swap(swapRequest)
const tx = swap.tx

if (!tx) {
  throw new Error(`Error creating the transaction ${swap.error}`)
}

if (tx.type === TransactionType.EVM) {
  if (tx.approveData && tx.approveTo) {
    // sign the approve transaction
    const approveTransaction: TransactionRequest = {
      from: tx.from,
      to: tx.approveTo,
      data: tx.approveData,
      maxFeePerGas: tx.maxFeePerGas,
      maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
      gasPrice: tx.gasPrice,
    }
    const { hash } = await walletWithProvider.sendTransaction(approveTransaction);
    
    // wait for approval
    while (true) {
      await setTimeout(10_000)
      const { isApproved, currentApprovedAmount, requiredApprovedAmount, txStatus } = await rango.isApproved(swap.requestId, hash)
      if (isApproved)
        break
      else if (txStatus === TransactionStatus.FAILED)
        throw new Error('Approve transaction failed in blockchain')
      else if (txStatus === TransactionStatus.SUCCESS)
        throw new Error(`Insufficient approve, current amount: ${currentApprovedAmount}, required amount: ${requiredApprovedAmount}`)
    }
  }
  
  // signing the main transaction
  const transaction: TransactionRequest = {
    from: tx.from,
    to: tx.txTo,
    data: tx.txData,
    value: tx.value,
    gasLimit: tx.gasLimit,
    maxFeePerGas: tx.maxFeePerGas,
    maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
    gasPrice: tx.gasPrice,
  }
  const { hash } = await walletWithProvider.sendTransaction(transaction);

  // track swap status
  while (true) {
    await setTimeout(10_000)
    const state = await rango.status({
      requestId: swap.requestId,
      txId: hash
    })

    const status = state.status
    if (status && [TransactionStatus.FAILED, TransactionStatus.SUCCESS].includes(status)) {
      break
    }
  }
}

Last updated