# SDK Example

## 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.

* [EVM Example](https://github.com/rango-exchange/rango-sdk/tree/master/examples/basic/node-evm)
* [Solana Example](https://github.com/rango-exchange/rango-sdk/tree/master/examples/basic/node-solana)
* [Tron Example](https://github.com/rango-exchange/rango-sdk/tree/master/examples/basic/node-tron)
* [Starknet Example](https://github.com/rango-exchange/rango-sdk/tree/master/examples/basic/node-starknet)

## 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.&#x20;

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

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

&#x20;Then you need to instantiate `RangoClient` and use it in the next steps.

```typescript
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:

```typescript
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.

```typescript
// 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.&#x20;

## 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.

```typescript
// 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.&#x20;

## 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:

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

## Complete Code Flow

{% embed url="<https://github.com/rango-exchange/rango-sdk/tree/master/examples/basic/node-evm>" %}

{% code title="Node.JS Example" %}

```typescript
// 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
    }
  }
}
```

{% endcode %}
