# Getting Started

### Installation

1.Install the package

```bash
npm install @wardenswap/bestrate-sdk
```

2\. Install additional dependencies. If already installed, ensure the version of ethers ≥ 5.4.0

```bash
npm install ethers
```

### Implementation

This tutorial focuses on the implementation for BNB Chain. However, it can be applied to the other network in the same way, by changing provider, contract addresses and token list.

Depending on the use cases, you might not need to implement all the steps provided here. However, to integrate the swap page into your own, you will need 1. Getting Quote 2. Approval and 3. Swap.

{% hint style="info" %}
For Ethereum and Polygon, it has the same implementation as BNB Chain except the parameters mentioned in [here](#usage-for-ethereum-or-polygon).
{% endhint %}

#### 1. Getting Quote

You can use SDK to easily get quote.

```jsx
import {
  initProvider,
  WardenBestRate,
} from "@wardenswap/bestrate-sdk";
import { ethers } from "ethers";

async function getQuote() {
  const provider = initProvider("https://bsc-dataseed.binance.org");
  const warden = new WardenBestRate(provider, "bsc");

  const src = "0xe9e7cea3dedca5984780bafc599bd69add087d56"; // source Token Address: BUSD
  const srcDecimals = 18; // source token's decimals
  const dest = "0x0feadcc3824e7f3c12f40e324a60c23ca51627fc"; // destination Token Address: WAD
  const amountIn = ethers.utils.parseUnits("100", srcDecimals); // amount of source token
  const gasPrice = await provider.getGasPrice()

  // Get BEST RATE!
  const quote = await warden.getQuote(src, dest, amountIn, gasPrice, {
    enableSplit: true,
  });

  console.log(JSON.stringify(quote, null, 2))

  return {
    quote,
    warden,
  }
}
```

JSON-RPC URL can be found in the document: [BSC JSON-RPC](https://docs.binance.org/smart-chain/developer/rpc.html)

The quote response will looks like this. You can use `amountOut` to preview to the user, including building the swap params.

```json
{
  "type": "strategies",
  "path": {
    "routes": [
      {
        "address": "0x0dEa19CAb88f45301a83C6b5eAa18E8387546afE",
        "id": "0",
        "name": "WARDEN"
      }
    ],
    "tokens": []
  },
  "amountOut": "565042446063757949355",
  "gasFees": {
    "dest": "1913868530378129232",
    "unit": "166401",
    "usd": "0.338591545617514122"
  },
  "blockNumber": 16875978,
  "routerAddress": "0x451ef8d6b645a60115eb8b8bea76b39c0c761004",
  "swapAddress": "0x9cbd1322c3d029d32357808665dcae5c286c7081",
  "depositAddress": "0xc95B1750043FCE5dfCc8539835Ea3830Ec002A89"
}
```

#### 2. Approving Transaction to swap (Metamask with web3-react)

Before the token can be swapped, the user has to approve it first. This part shows the example integrated with the web3-react. After integrating web3-react to our app, we can do this. And we need to connect to user wallet first to let the user confirm approving.

> *Read about using React to connect wallets like Metamask here:* [*https://medium.com/coinmonks/web3-react-connect-users-to-metamask-or-any-wallet-from-your-frontend-241fd538ed39*](https://medium.com/coinmonks/web3-react-connect-users-to-metamask-or-any-wallet-from-your-frontend-241fd538ed39)

```jsx
import React from 'react';
import { ethers } from 'ethers'
import erc20Abi from './abi/ERC20.abi.json'
import { useWeb3React, Web3ReactProvider } from '@web3-react/core';
import { Web3Provider } from "@ethersproject/providers";
import { WardenBestRate } from '@wardenswap/bestrate-sdk';

function SwapComponent({ wardenClient, srcAddr, destAddr, amountIn }) {
  const { active, account, library } = useWeb3React()

  const handleApprove = async () => {
    if (!active) {
      alert("please connect wallet")
      return
    }

    // init erc20 contract for token
    const signer = library.getSigner(account).connectUnchecked()

    try {
      // amountIn can be omitted to approve with MaxUint256 allowance
      // return null if no need to be approved
      const tx = await wardenClient.approve(signer, srcAddr, amountIn)
      console.log("[handleApprove] approve result:", tx)
      if (tx !== null) {
        await tx.wait()
      }
    } catch (err) {
      console.error("[handleApprove] error:", err)
      alert(`Approve error: ${JSON.stringify(err)}`)
    }
  }

  return (
    <>
      <button onClick={handleApprove}>Approve</button>
    </>
  )
}
```

> ERC20 ABI JSON Can be downloaded [here](https://gist.github.com/veox/8800debbf56e24718f9f483e1e40c35c)

#### 3.1. Sending Basic Swap Transaction (Metamask with web3-react)

After getting quote, we can send the transaction to the contract to swap with the strategies or split type method depending on the quote result.

```jsx
import React from 'react';
import { ethers } from 'ethers'
import erc20Abi from './abi/ERC20.abi.json'
import { useWeb3React, Web3ReactProvider } from '@web3-react/core';
import { Web3Provider } from "@ethersproject/providers";
import { WardenBestRate } from '@wardenswap/bestrate-sdk';

function SwapComponent({ wardenClient, srcAddr, destAddr, amountIn }: { wardenClient: WardenBestRate, srcAddr: string, destAddr: string, amountIn: ethers.BigNumber }) {
  const { active, account, library } = useWeb3React()

  const handleApprove = async () => { ... }
  
  const handleSwap = async () => {
      if (!active) {
          alert('please connect wallet')
          return
      }

      const signer = library.getSigner(account).connectUnchecked()
      try {
          const { quote, warden } = await getQuote(srcAddr, destAddr, amountIn)
          console.log('[handleSwap] quote:', quote)

          // Allow 2% slippage for amount out
          const minAmountOut = ethers.BigNumber.from(quote.amountOut).mul(98).div(100)
          const tx = await warden.swap(signer, srcAddr, destAddr, amountIn, minAmountOut, quote)
          await tx.wait()
      } catch (err) {
          console.error('[handleSwap] error:', err)
          alert(`Swap error: ${JSON.stringify(err)}`)
      }
  }

  return (
    <>
      <button onClick={handleApprove}>Approve</button>
      <button onClick={handleSwap}>Swap</button>
    </>
  )
}

function getQuote(src, dest, amountIn, amountInDecimal) {	
	...
}
```

> The WardenSwap ABI JSON v2.0 can be retrieved from [BSCScan](https://bscscan.com/address/0x451ef8D6B645a60115EB8b8bEa76B39C0C761004) or downloaded [here](https://gist.github.com/AncientWarden/4aeae54509dd21020ab29a13c804cb57).

#### 3.2. Sending Swap with Native currency (BNB, Ether, Matic)

As the general convention, the native currency or gas will be represented with the address `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` .

**Ref:**

* [Ethers.js Overrides](https://docs.ethers.io/v5/single-page/#/v5/api/contract/contract/-%23-contract-functionsSend)

### Full Example for Swap Page (React TypeScript)

Code Example:

<https://gist.github.com/wardenluna/a46bd21540060958fa3003aa349ebd58>

### Usage for Ethereum or Polygon

To use SDK with Polygon, we need to input the different parameters from BSC, as shown in this example.

```javascript
// This params map is showing the difference params needed for each chain. 
// The token address is also different, despite the same symbol. 
// See token list for addresses and decimal places
const params = {
    // ethereum mainnet chain id: 1
    1: {
        CHAIN_NAME: 'ethereum',
        JSON_RPC_URL: 'YOUR_RPC_URL',
        ROUTER_ADDRESS: '0x39f97198c5DbC193EB962c4B3B7e447091A18eAB',
        FROM_AMOUNT: ethers.utils.parseUnits('10', 6), // 10 USDC in BigNumber
        FROM_ADDR: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
        TO_ADDR: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', // ETH
    },
    // bsc chain id: 56
    56: {
        CHAIN_NAME: 'bsc',
        JSON_RPC_URL: 'https://bsc-dataseed.binance.org/'
        ROUTER_ADDRESS: '0x451ef8D6B645a60115EB8b8bEa76B39C0C761004',
        FROM_AMOUNT: ethers.utils.parseUnits('20', 18), // 20 BUSD in BigNumber
        FROM_ADDR: '0xe9e7cea3dedca5984780bafc599bd69add087d56', // BUSD
        TO_ADDR: '0x0feadcc3824e7f3c12f40e324a60c23ca51627fc', // WAD 
    },
    // polygon chain id: 137
    137: { 
        CHAIN_NAME: 'polygon',
        JSON_RPC_URL: 'https://rpc-mainnet.matic.quiknode.pro',
        ROUTER_ADDRESS: '0x030B8b7bF245E762736e65c0903295447B898c30',
        FROM_AMOUNT: ethers.utils.parseUnits('20', 6), // 20 USDC in BigNumber
        FROM_ADDR: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', // USDC
        TO_ADDR: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619', // ETH
    }
}

// given the params are using for Polygon
const currentParams = params[137]

// get quote
const provider = new ethers.providers.JsonRpcProvider(currentParams.JSON_RPC_URL)
const wardenClient = new WardenBestRate(provider, currentParams.CHAIN_NAME)
const quote = await wardenClient.getQuote(...)
...

// approval
const allowance = await erc20Contract.allowance(account, currentParams.ROUTER_ADDRESS)
...

// swap
const wardenContract = new ethers.Contract(wardenRouterAddress, wardenRouter2Abi, signer)
const swap = await wardenClient.swap(...)

```

Note: you may detect the chain ID to switch the parameters accordingly.

### Usage for Optimism & Arbitrum

To use SDK with Optimism and Arbitrum (coming soon), we need to Input both `gasPrice` and `gasPriceL2` as shown below.

```typescript
const quote = await wardenClient.getQuote(
    srcAddr, 
    destAddr, 
    amountIn, 
    gasPrice, // 👈 this should be L1 gas price (Ethereum gas price)
    { gasPriceL2: ethers.utils.parseUnits("0.001", "gwei") }
)
```

### Troubleshooting

#### TypeError: Cannot convert a BigInt value to a number

Sometimes certain tools will output `Math.pow(BigInt(2), BigInt(128)) - BigInt(1)` because they have `@babel/plugin-transform-exponentiation-operator` included.

If you are using `@babel/preset-env`, you can exclude it like this to fix:

```javascript
    presets: [
      [
        '@babel/preset-env',
        {
          ...
          exclude: [
            ...
            'transform-exponentiation-operator', // << this line here
          ],
        },
      ],
    ],
```

Ref: <https://github.com/hirosystems/stacks.js/issues/1096#issuecomment-929362393>

#### **TypeError: Argument of type 'JsonRpcProvider' is not assignable to parameter of type 'Provider'**

This error can be caused by the version of Ethers.js not matching the library. We suggest to update the Ethers.js to version newer than 5.4.0

In case you are comfortable to use the latest version of Ethers.js, run this command to upgrade.

```
npm install ethers@latest
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.wardenswap.finance/warden/wardenswap-sdk/getting-started.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
