GithubHelp home page GithubHelp logo

joshstevens19 / simple-uniswap-sdk Goto Github PK

View Code? Open in Web Editor NEW
189.0 9.0 96.0 568 KB

Uniswap SDK which handles the routes automatically for you, changes in trade quotes reactive subscriptions, exposure to formatted easy to understand information, bringing back the best trade quotes automatically, generating transactions for you and much more.

License: MIT License

TypeScript 99.88% JavaScript 0.12%

simple-uniswap-sdk's Introduction

simple-uniswap-sdk

npm version downloads

Uniswap SDK which handles the routes automatically for you, changes in trade quotes reactive subscriptions, exposure to formatted easy to understand information, bringing back the best trade quotes automatically, generating transactions for you and much more. All the uniswap logic for you in a simple to easy understand interface to hook straight into your dApp without having to understand how it all works.

Please note this is not owned or maintained by uniswap and is a open source package for anyone to use freely.

Features ๐Ÿš€

๐Ÿš€ Supports uniswap v2 and v3 prices together and returns you the best price, so you do not need to query both yourself
๐Ÿš€ Queries all the best routes and finds the best price for you
๐Ÿš€ Exposes all the route paths it tried so you can see every detail in how it worked out the best price
๐Ÿš€ Factor in the cost of the transaction into the quotes with 1 config change
๐Ÿš€ Easy subscriptions to get alerted when the price moves or the trade expires
๐Ÿš€ The transaction is generated for you, just fill it with the gas details and send it on its way
๐Ÿš€ All the figures are all formatted for you, no need to worry about timing it back to its decimal formatted place, just render it straight onto your UI
๐Ÿš€ Exposes all the tokens metadata for you, name, symbol, decimals
๐Ÿš€ Uses multicall for every on chain lookup, so even though it could be doing 100 JSONRPC calls it is all put into a few calls meaning it can stay very fast
๐Ÿš€ Tidy bundle size
๐Ÿš€ Fully typescript supported with full generated typings
๐Ÿš€ query many tokens in 1 jsonrpc call perfect to get token metadata fast
๐Ÿš€ and much more!!

Motivation

As a ethereum dApp developer you try to get your dApp experience as integrated as possible, Ethereum right now is hard to show in a web2.0 world as it is. On top of this as a developer you have to learn all the complex stuff for the blockchain which can take its toll on you.

When I was integrating uniswap on our wallet I found that their SDK was a bit too much for what I needed. Deepdown from the dApp point of view I only really cared about getting the best price for the user with all the fees related. I also found myself having to write a lot of custom code which I thought could be abstracted away so nobody has to deal with that again. A lot of the uniswap features like routing is all done in their client itself which is great but not when you want to use it in a more integrated approach in your on dApp.

Uniswap is one of the BEST projects on ethereum and one of my favourites. My motivation here is to create a library which allows more people to integrate it on their dApp without having to worry about how their amazing software links together. This makes the whole user experience better and allows more developers to get involved integrating uniswap in their dApp with a web2.0 experience, and on top of this also growing the usage of it.

p.s I have huge love for unicorns

Installing

npm

$ npm install simple-uniswap-sdk

yarn

$ yarn add simple-uniswap-sdk

SDK guide

Creating a uniswap pair factory

The uniswap pair factory is an instance which is joint together with the from token and the to token, it is all self contained in the instance and exposes easy methods for you to call to start using uniswap.

export class UniswapPair {
  constructor(
    private _uniswapPairContext:
      | UniswapPairContextForChainId
      | UniswapPairContextForProviderUrl
      | UniswapPairContextForEthereumProvider
)
// can support any network using the `CustomNetwork` and `CloneUniswapContractDetails` properties
export enum ChainId {
  MAINNET = 1,
  ROPSTEN = 3,
  RINKEBY = 4,
  Gร–RLI = 5,
  KOVAN = 42,
}

interface UniswapPairContextBase {
  fromTokenContractAddress: string;
  toTokenContractAddress: string;
  ethereumAddress: string;
  settings?: UniswapPairSettings | undefined;
}

export interface UniswapPairContextForEthereumProvider
  extends UniswapPairContextBase {
  // can take any ethers provider, web3 provider or custom ethereum provider
  ethereumProvider: any;
}

export interface UniswapPairContextForChainId extends UniswapPairContextBase {
  chainId: ChainId | number;
}

export interface UniswapPairContextForProviderUrl
  extends UniswapPairContextForChainId {
  providerUrl: string;
}
export interface GasSettings {
  getGasPrice: () => Promise<number>;
}

export type IRouterMethods = {
  [key in IRouterMethodName]: string;
};

export interface CloneUniswapContractDetailsV2 {
  routerAddress: string;
  factoryAddress: string;
  pairAddress: string;
  routerAbi?: JsonFragment[];
  routerMethods?: Partial<IRouterMethods>;
}

export interface CloneUniswapContractDetailsV3 {
  routerAddress: string;
  factoryAddress: string;
  quoterAddress: string;
}

export interface CloneUniswapContractDetails {
  v2Override?: CloneUniswapContractDetailsV2 | undefined;
  v3Override?: CloneUniswapContractDetailsV3 | undefined;
}

export interface Token {
  chainId: ChainId;
  contractAddress: string;
  decimals: number;
  symbol: string;
  name: string;
}

export interface NativeCurrencyInfo {
  name: string;
  symbol: string;
}

export interface CustomNetwork {
  nameNetwork: string;
  multicallContractAddress: string;
  nativeCurrency: NativeCurrencyInfo;
  nativeWrappedTokenInfo: Token;
  // defined your base tokens here if any for your custom network!
  baseTokens?: {
    usdt?: Token | undefined;
    dai?: Token | undefined;
    comp?: Token | undefined;
    usdc?: Token | undefined;
    wbtc?: Token | undefined;
  };
}

export class UniswapPairSettings {
  slippage: number;
  deadlineMinutes: number;
  disableMultihops: boolean;
  uniswapVersions: UniswapVersion[] = [UniswapVersion.v2, UniswapVersion.v3];
  gasSettings?: GasSettings = undefined;
  // can be used to pass in a fork of uniswap contract details
  cloneUniswapContractDetails?: CloneUniswapContractDetails = undefined;
  // can be used to define unsupported networks
  customNetwork?: CustomNetwork = undefined;

  constructor(settings?: {
    slippage?: number | undefined;
    deadlineMinutes?: number | undefined;
    disableMultihops?: boolean | undefined;
    uniswapVersions?: UniswapVersion[] | undefined;
    gasSettings?: GasSettings | undefined;
    cloneUniswapContractDetails?: CloneUniswapContractDetails | undefined;
    customNetwork?: CustomNetwork | undefined;
  }) {
    this.slippage = settings?.slippage || 0.0005;
    this.deadlineMinutes = settings?.deadlineMinutes || 20;
    this.disableMultihops = settings?.disableMultihops || false;
    this.gasSettings = settings?.gasSettings;
    this.cloneUniswapContractDetails = settings?.cloneUniswapContractDetails;
    this.customNetwork = settings?.customNetwork;

    if (
      Array.isArray(settings?.uniswapVersions) &&
      settings?.uniswapVersions.length === 0
    ) {
      throw new UniswapError(
        '`uniswapVersions` must not be an empty array',
        ErrorCodes.uniswapVersionsMustNotBeAnEmptyArray
      );
    }

    if (
      settings &&
      Array.isArray(settings.uniswapVersions) &&
      settings.uniswapVersions.length > 0
    ) {
      this.uniswapVersions = settings?.uniswapVersions;
    }
  }
}

With only the chainId

This will use a infura endpoint without you having to pass in a node

import { UniswapPair, ChainId, UniswapVersion, ETH } from 'simple-uniswap-sdk';

const uniswapPair = new UniswapPair({
  // the contract address of the token you want to convert FROM
  fromTokenContractAddress: ETH.MAINNET().contractAddress,
  // the contract address of the token you want to convert TO
  toTokenContractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
  // the ethereum address of the user using this part of the dApp
  ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
  chainId: ChainId.MAINNET,
  settings: new UniswapPairSettings({
    // if not supplied it will use `0.0005` which is 0.5%
    // please pass it in as a full number decimal so 0.7%
    // would be 0.007
    slippage: 0.0005,
    // if not supplied it will use 20 a deadline minutes
    deadlineMinutes: 20,
    // if not supplied it will try to use multihops
    // if this is true it will require swaps to direct
    // pairs
    disableMultihops: false,
    // for example if you only wanted to turn on quotes for v3 and not v3
    // you can only support the v3 enum same works if you only want v2 quotes
    // if you do not supply anything it query both v2 and v3
    uniswapVersions: [UniswapVersion.v2, UniswapVersion.v3],
  }),
});

// now to create the factory you just do
const uniswapPairFactory = await uniswapPair.createFactory();

With your own provider url

This will use your node you pass in you must pass us the chainId as well, this stops the ethers instance calling pointless JSONRPC calls to get the chain id before every JSONRPC call.

import { UniswapPair, ChainId, UniswapVersion, ETH } from 'simple-uniswap-sdk';

const uniswapPair = new UniswapPair({
  // the contract address of the token you want to convert FROM
  fromTokenContractAddress: ETH.MAINNET().contractAddress,
  // the contract address of the token you want to convert TO
  toTokenContractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
  // the ethereum address of the user using this part of the dApp
  ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
  chainId: ChainId.MAINNET,
  providerUrl: YOUR_PROVIDER_URL,
  settings: new UniswapPairSettings({
    // if not supplied it will use `0.0005` which is 0.5%
    // please pass it in as a full number decimal so 0.7%
    // would be 0.007
    slippage: 0.0005,
    // if not supplied it will use 20 a deadline minutes
    deadlineMinutes: 20,
    // if not supplied it will try to use multihops
    // if this is true it will require swaps to direct
    // pairs
    disableMultihops: false,
    // for example if you only wanted to turn on quotes for v3 and not v3
    // you can only support the v3 enum same works if you only want v2 quotes
    // if you do not supply anything it query both v2 and v3
    uniswapVersions: [UniswapVersion.v2, UniswapVersion.v3],
  }),
});

// now to create the factory you just do
const uniswapPairFactory = await uniswapPair.createFactory();

Custom Ethereum provider

This will use your ethereum provider you pass in. This will work with any web3 provider, ethers provider or custom provider. For example when using MetaMask you can pass in the window.ethereum and it work. You must supply the ethereum address and the wallet be approved to use for the dApp and unlocked before passing it in. The uniswap sdk makes those assumptions without them it will not work as MetaMask is not allowed access to your dApp. Any change of network or ethereum address change you will need to handle in your dApp and regenerate the uniswap pair context. Most the time the contract addresses for your tokens are different anyway.

import { UniswapPair, ChainId, UniswapVersion, ETH } from 'simple-uniswap-sdk';

const uniswapPair = new UniswapPair({
  // the contract address of the token you want to convert FROM
  fromTokenContractAddress: ETH.MAINNET().contractAddress,
  // the contract address of the token you want to convert TO
  toTokenContractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
  // the ethereum address of the user using this part of the dApp
  ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
  ethereumProvider: YOUR_WEB3_ETHERS_OR_CUSTOM_ETHEREUM_PROVIDER,
  settings: new UniswapPairSettings({
    // if not supplied it will use `0.0005` which is 0.5%
    // please pass it in as a full number decimal so 0.7%
    // would be 0.007
    slippage: 0.0005,
    // if not supplied it will use 20 a deadline minutes
    deadlineMinutes: 20,
    // if not supplied it will try to use multihops
    // if this is true it will require swaps to direct
    // pairs
    disableMultihops: false,
    // for example if you only wanted to turn on quotes for v3 and not v3
    // you can only support the v3 enum same works if you only want v2 quotes
    // if you do not supply anything it query both v2 and v3
    uniswapVersions: [UniswapVersion.v2, UniswapVersion.v3],
  }),
});

// now to create the factory you just do
const uniswapPairFactory = await uniswapPair.createFactory();

Catching error

I know randomly throwing errors with no error codes is a pain when writing dApps. In this package when we throw we have our own custom error. This has error codes you can map to what actually happened to allow your dApp to handle them gracefully.

export class UniswapError extends Error {
  public name = 'UniswapError';
  public code: ErrorCodes;
  public message: string;
  constructor(message: string, code: ErrorCodes) {
    super(message);
    this.message = message;
    this.code = code;
  }
}
export enum ErrorCodes {
  noRoutesFound = 1,
  canNotFindChainId = 2,
  tokenChainIdContractDoesNotExist = 3,
  tradePathIsNotSupported = 4,
  generateApproveMaxAllowanceDataNotAllowed = 5,
  fromTokenContractAddressRequired = 6,
  fromTokenContractAddressNotValid = 7,
  toTokenContractAddressRequired = 8,
  toTokenContractAddressNotValid = 9,
  ethereumAddressRequired = 10,
  ethereumAddressNotValid = 11,
  invalidPairContext = 12,
  invalidFromOrToContractToken = 13,
  uniswapVersionNotSupported = 14,
  uniswapVersionsMustNotBeAnEmptyArray = 15,
  canNotFindProviderUrl = 16,
  wrongEthersProviderContext = 17,
  chainIdNotSupported = 18,
  chainIdCanNotBeFound = 19,
}

Uniswap pair factory

Trade

This will generate you the trade with all the information you need to show to the user on the dApp. It will find the best route price for you automatically. we generate the transaction for you but you will still need to sign and send the transaction on your dApp once they confirm the swap.

Please note ROPSTEN, RINKEBY, Gร–RLI and KOVAN will only use ETH as a main currency unlike MAINNET which uses everything, so you will get less routes on those testnets.

 /**
   * Generate trade - this will return amount but you still need to send the transaction
   * if you want it to be executed on the blockchain
   * @param amount The amount you want to swap formatted. Aka if you want to swap 1 AAVE you pass in 1
   * @param direction The direction you want to get the quote from
   */
async trade(amount: string, direction: TradeDirection = TradeDirection.input): Promise<TradeContext>

Trade direction

Trade direction is a way to ask for quotes for input and output.

  • input = information for the quote from the FROM
  • ouput = information for the quote from the TO

for example if i was swapping AAVE > ETH if i pass in amount 1 and trade direction input, the information would be how much ETH you will get back from 1 AAVE. if i pass in amount 1 and trade direction ouput, the information would be how much AAVE you will get back from 1 ETH.

export interface TradeContext {
  // this tells you the uniswap version the best quotes is at so for example
  // you sometimes may get better quotes on v2 then v3.
  uniswapVersion: UniswapVersion;
  // This will tell you what the trade direction is
  // input = information for the quote from the FROM
  // ouput = information for the quote from the TO
  // for example if i was swapping AAVE > ETH
  // if i pass in amount 1 and trade direction input, the information
  // would be how much ETH you will get back from 1 AAVE.
  // if i pass in amount 1 and trade direction ouput, the information
  // would be how much AAVE you will get back from 1 ETH.
  quoteDirection: TradeDirection;
  // the amount you requested to convert
  // this will be formatted in readable number
  // so you can render straight out the box
  baseConvertRequest: string;
  // the min amount you will receive taking off the slippage
  // if the price changes below that then
  // the uniswap contract will throw
  // this will be formatted in readable number
  // so you can render straight out the box
  // if you have done a output trade direction then this will be null
  minAmountConvertQuote: string | null;
  // the maximum amount it will send when doing an output trade direction
  // will be null if you have done a input trade direction
  maximumSent: string | null;
  // the expected amount you will receive
  // this will be formatted in readable number
  // so you can render straight out the box
  expectedConvertQuote: string;
   // A portion of each trade goes to
  // liquidity providers as a protocol of incentive
  // v2 always = (0.3%)
  // v3 always = (0.0%) for v3, use `liquidityProviderFeesV3`
  liquidityProviderFee: string;
  // A portion of each trade goes to
  // liquidity providers as a protocol of incentive
  // v2 always = (0.3%)
  // v3 always = (0.0%) for v3, use `liquidityProviderFeePercentsV3`
  liquidityProviderFeePercent: number;
  // A portion of each trade goes to
  // liquidity providers as a protocol of incentive
  // length must be routePath.length - 1
  // v2 always = []
  // v3 depends on the fee amount sent on that pool
  // - low = 0.05%
  // - medium = 0.3%
  // - high = 1%
  // For multihop swap
  // Sequence of Fees 
  // ex: USDC>USDT>WETH>WBTC => [(USDC-USDT fee), (USDT-WETH fee), (WETH-WBTC fee)]
  liquidityProviderFeesV3: string[];
  // A portion of each trade goes to
  // liquidity providers as a protocol of incentive
  // v2 always = []
  // v3 depends on the fee amount sent on that pool
  // - low = 0.05%
  // - medium = 0.3%
  // - high = 1%
  // the amount will always come back as full figures
  // aka 0.05% = 0.0005
  // 0.3% = 0.003
  // 1% = 0.01
  liquidityProviderFeePercentsV3: number[];
  // A unix datestamp in when this trade expires
  // if it does expiry while looking at it as long
  // as you are hooked onto `quoteChanged$` that will
  // emit you a new valid quote
  tradeExpires: number;
  // the route path mapped with full token info
  routePathTokenMap: Token[];
  // the route text so you can display it on the dApp easily
  routeText: string;
  // the pure route path, only had the arrays in nothing else
  routePath: string[];
  // full list of every route it tried with the expected convert quotes
  // this will be ordered from the best expected convert quote to worse [0] = best
  allTriedRoutesQuotes: {
    expectedConvertQuote: string;
    expectedConvertQuoteOrTokenAmountInMaxWithSlippage: string;
    transaction: Transaction;
    // if you have enabled to factor in the transaction cost in the quotes
    // then this is the gas price in gwei we used to estimate the transactions
    // it only be defined by the ones it decided to pick depending on the hops abouts
    gasPriceEstimatedBy: string | undefined;
    tradeExpires: number;
    routePathArrayTokenMap: Token[];
    routeText: string;
    routePathArray: string[];
    uniswapVersion: UniswapVersion;
    liquidityProviderFee: number;
    liquidityProviderFeesV3: number[];
    quoteDirection: TradeDirection;
  }[];
  // if the allowance approved for moving tokens is below the amount sending to the
  // uniswap router this will be false if not true
  // this is not reactive so if you get the trade quote
  // and this returns false but then you do the approval
  // transaction, this old context will still say false
  hasEnoughAllowance: boolean;
  // this is the transaction you need to send first if approve the swap
  // but do not have any allowance for the router to move the token on their
  // behalf.
  approvalTransaction:
    | {
        to: string;
        from: string;
        data: string;
        value: string;
      }
    | undefined;
  // the from token info
  fromToken: Token;
  // holds the from balance context
  // this is not reactive so if they top
  // up their account after this is generated
  // then you need to query that yourself
  // or regen the trade info
  fromBalance: {
    // if the balance of the users has enough to perform this trade, does not consider gas prices
    // right now if your doing ETH > ERC20
    hasEnough: boolean;
    // the total balance that user has on the from formatted for you already
    balance: string;
  };
  // the to token info
  toToken: Token;
  // the total balance that user has on the to formatted for you already
  toBalance: string;
  // this is the transaction you need to send to execute the trade
  transaction: {
    to: string;
    from: string;
    data: string;
    value: string;
  };
  // if you have enabled to factor in the transaction cost in the quotes
  // then this is the gas price in gwei we used to estimate the transactions
  gasPriceEstimatedBy: string | undefined;
  // this is a stream which emits if the quote has changed, this will emit
  // not matter what you should listen to this for the source of truth
  // for a reactive dApp. If you dont listen to this the user could end up
  // sending a uniswap transaction which price is now out of date
  quoteChanged$: Observable<TradeContext>;
  // when you generate a trade it does more then just return data, it makes
  // sure your data stays in sync with the `quoteChanged$`, so once you have
  // finished with a trade please call this to do a general clear up so we do
  // not keep timeouts and streams running.
  // when you call this it will kill all `quoteChanged$` subscriptions and
  // some watcher timeouts. If you execute a new trade with a new amount on
  // the same instance it will clear it for you.
  destroy: () => void;
}
export interface Token {
  chainId: ChainId;
  contractAddress: string;
  decimals: number;
  symbol: string;
  name: string;
}

export enum ChainId {
  MAINNET = 1,
  ROPSTEN = 3,
  RINKEBY = 4,
  Gร–RLI = 5,
  KOVAN = 42,
}

export enum UniswapVersion {
  v2 = 'v2',
  v3 = 'v3',
}

Usage

ethers example

import { ethers } from 'ethers';
import { ChainId, UniswapPair } from 'simple-uniswap-sdk';

const etherTradeExample = async () => {
  const uniswapPair = new UniswapPair({
    // the contract address of the token you want to convert FROM
    fromTokenContractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
    // the contract address of the token you want to convert TO
    toTokenContractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
    // the ethereum address of the user using this part of the dApp
    ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
    // you can pass in the provider url as well if you want
    // providerUrl: YOUR_PROVIDER_URL,
    // OR if you want to inject your own ethereum provider (no need for chainId if so)
    // ethereumProvider: YOUR_WEB3_ETHERS_OR_CUSTOM_ETHEREUM_PROVIDER,
    chainId: ChainId.MAINNET,
  });

  // this example shows erc20 > erc20 but its a simple change for eth > erc20
  // or erc20 > eth example below by using `ETH.MAINNET().contractAddress`
  // which can be imported within `simple-uniswap-sdk`
  // aka > import { ETH } from 'simple-uniswap-sdk';

  //   ETH > ERC20
  // const uniswapPair = new UniswapPair({
  //   fromTokenContractAddress: ETH.MAINNET().contractAddress,
  //   toTokenContractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
  //   ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
  //   chainId: ChainId.RINKEBY,
  // });

  //   ERC20 > ETH
  // const uniswapPair = new UniswapPair({
  //   fromTokenContractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
  //   toTokenContractAddress: ETH.MAINNET().contractAddress,,
  //   ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
  //   chainId: ChainId.RINKEBY,
  // });

  // now to create the factory you just do
  const uniswapPairFactory = await uniswapPair.createFactory();

  // the amount is the proper entered amount
  // so if they enter 10 pass in 10
  // it will work it all out for you
  const trade = await uniswapPairFactory.trade('10');

  // can also pass in a trade direction here, for example if you want the output
  // aka your doing ETH > AAVE but want to know how much you get for 5 AAVE.
  // const trade = await uniswapPairFactory.trade('10', TradeDirection.output);

  // you should probably check this before they confirm the swap again
  // this is just so its simple to read
  if (!trade.fromBalance.hasEnough) {
    throw new Error('You do not have enough from balance to execute this swap');
  }

  // subscribe to quote changes this is just in example so your dont miss it
  trade.quoteChanged$.subscribe((value: TradeContext) => {
    // value will hold the same info as below but obviously with
    // the new trade info.
  });

  // obviously dont create your provider + wallet everytime again and again!
  // this is just like this for ease of reading!
  const provider = new ethers.providers.JsonRpcProvider(
    uniswapPairFactory.providerUrl
  );
  const wallet = new ethers.Wallet(YOUR_PRIVATE_KEY, provider);

  // Please note when you do your trade if `approvalTransaction` is defined the user does not have enough allowance to perform this trade
  // aka the router can not move their erc20 tokens on their behalf of the user.
  // This will generate the transaction for the approval of moving tokens for the user.
  // This uses the max hex possible which means they will not have to do this again if they want to swap from the SAME from token again later.
  // If they have only approved moving on uniswap v2 and try to execute a v3 trade they would have to approve that but again once approved
  // the v3 router then they will not have to again for that version.
  // Please note the approval is per each erc20 token, so if they picked another from token after they swapped they would need to do this again.
  // You have to send and sign the transaction from within your dApp. Remember when they do not have enough allowance it will mean doing 2 transaction,
  // 1 to allow uniswap to move tokens on their behalf then the next one to actually execute the trade.
  // On `eth` > `erc20` the `approvalTransaction` will always be undefined as you only need to do this when moving `erc20 > eth` and `erc20 > erc20`.
  if (trade.approvalTransaction) {
    const approved = await wallet.sendTransaction(trade.approvalTransaction);
    console.log('approved txHash', approved.hash);
    const approvedReceipt = await approved.wait();
    console.log('approved receipt', approvedReceipt);
  }

  const tradeTransaction = await wallet.sendTransaction(trade.transaction);
  console.log('trade txHash', tradeTransaction.hash);
  const tradeReceipt = await tradeTransaction.wait();
  console.log('trade receipt', tradeReceipt);

  // once done with trade aka they have sent it and you don't need it anymore call
  trade.destroy();
};

etherTradeExample();

web3 example

import { ChainId, TradeContext, UniswapPair } from 'simple-uniswap-sdk';
import Web3 from 'web3';

const web3TradeExample = async () => {
  const uniswapPair = new UniswapPair({
    // the contract address of the token you want to convert FROM
    fromTokenContractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
    // the contract address of the token you want to convert TO
    toTokenContractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
    // the ethereum address of the user using this part of the dApp
    ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
    // you can pass in the provider url as well if you want
    // providerUrl: YOUR_PROVIDER_URL,
    // OR if you want to inject your own ethereum provider (no need for chainId if so)
    // ethereumProvider: YOUR_WEB3_ETHERS_OR_CUSTOM_ETHEREUM_PROVIDER,
    chainId: ChainId.RINKEBY,
  });

  // this example shows erc20 > erc20 but its a simple change for eth > erc20
  // or erc20 > eth example below by using `ETH.MAINNET().contractAddress`
  // which can be imported within `simple-uniswap-sdk`
  // aka > import { ETH } from 'simple-uniswap-sdk';

  //   ETH > ERC20
  // const uniswapPair = new UniswapPair({
  //   fromTokenContractAddress: ETH.MAINNET().contractAddress,
  //   toTokenContractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
  //   ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
  //   chainId: ChainId.RINKEBY,
  // });

  //   ERC20 > ETH
  // const uniswapPair = new UniswapPair({
  //   fromTokenContractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
  //   toTokenContractAddress: ETH.MAINNET().contractAddress,,
  //   ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
  //   chainId: ChainId.RINKEBY,
  // });

  // now to create the factory you just do
  const uniswapPairFactory = await uniswapPair.createFactory();

  // the amount is the proper entered amount
  // so if they enter 10 pass in 10
  // it will work it all out for you
  // can also pass in a trade direction here if you want for the output
  const trade = await uniswapPairFactory.trade('10');

  // can also pass in a trade direction here, for example if you want the output
  // aka your doing ETH > AAVE but want to know how much you get for 5 AAVE.
  // const trade = await uniswapPairFactory.trade('10', TradeDirection.output);

  // can also pass in a trade direction here, for example if you want the output
  // aka your doing ETH > AAVE but want to know how much you get for 5 AAVE.
  // const trade = await uniswapPairFactory.trade('10', TradeDirection.output);

  // you should probably check this before they confirm the swap again
  // this is just so its simple to read
  if (!trade.fromBalance.hasEnough) {
    throw new Error('You do not have enough from balance to execute this swap');
  }

  // subscribe to quote changes this is just in example so your dont miss it
  trade.quoteChanged$.subscribe((value: TradeContext) => {
    // value will hold the same info as below but obviously with
    // the new trade info.
  });

  // obviously dont create your web3 instance everytime again and again!
  // this is just like this for ease of reading!
  const web3 = new Web3(uniswapPairFactory.providerUrl);

  // Please note when you do your trade if `approvalTransaction` is defined the user does not have enough allowance to perform this trade
  // aka the router can not move their erc20 tokens on their behalf of the user.
  // This will generate the transaction for the approval of moving tokens for the user.
  // This uses the max hex possible which means they will not have to do this again if they want to swap from the SAME from token again later.
  // If they have only approved moving on uniswap v2 and try to execute a v3 trade they would have to approve that but again once approved
  // the v3 router then they will not have to again for that version.
  // Please note the approval is per each erc20 token, so if they picked another from token after they swapped they would need to do this again.
  // You have to send and sign the transaction from within your dApp. Remember when they do not have enough allowance it will mean doing 2 transaction,
  // 1 to allow uniswap to move tokens on their behalf then the next one to actually execute the trade.
  // On `eth` > `erc20` the `approvalTransaction` will always be undefined as you only need to do this when moving `erc20 > eth` and `erc20 > erc20`.
  if (trade.approvalTransaction) {
    const signedTransaction = await web3.eth.accounts.signTransaction(
      trade.approvalTransaction,
      YOUR_PRIVATE_KEY
    );

    if (!signedTransaction.rawTransaction) {
      throw new Error('Could not find tx');
    }

    web3.eth
      .sendSignedTransaction(signedTransaction.rawTransaction)
      .once('transactionHash', (transactionHash) => {
        console.log('approved txHash', transactionHash);
      })
      .once('receipt', async (receipt) => {
        console.log('approved receipt', receipt);
        await executeTrade(web3, trade);
      })
      .on('error', async (error: any) => {
        console.log(`ERROR ${error.message}`);
      });
  } else {
    console.log(
      'already has approved uniswap to move tokens on your behalf or its eth > erc20 token swap'
    );
    await executeTrade(web3, trade);
  }
};

const executeTrade = async (web3: Web3, trade: TradeContext) => {
  const signedTransaction = await web3.eth.accounts.signTransaction(
    trade.transaction,
    YOUR_PRIVATE_KEY
  );

  if (!signedTransaction.rawTransaction) {
    throw new Error('Could not find tx');
  }

  web3.eth
    .sendSignedTransaction(signedTransaction.rawTransaction)
    .once('transactionHash', (transactionHash) => {
      console.log('trade txHash', transactionHash);
    })
    .once('receipt', (receipt) => {
      console.log('trade receipt', receipt);
      // once done with trade aka they have sent it and you don't need it anymore call
      trade.destroy();
    })
    .on('error', async (error: any) => {
      console.log(`ERROR ${error.message}`);
    });
};

web3TradeExample();

Including gas fees in the trade response

The library has the ability to work out the best trade including gas fees. As expected this does add around about 700MS onto the response time due to the need to have to query eth_estimateGas an the top 3 quotes to work out the best result. How it works is:

  • It gets the best expected trade quotes as it normally does
  • IF you do not have enough balance or enough allowance it will not estimate gas because it be a always failing transaction and the node will throw an error.
  • ALSO IF the token your swapping does not have a fiat price in coin gecko then again it ignores the below as it can not do the math without a base currency.
  • IF you have enough balance and allowance then finds the best 3 of the different hop options:
    • best direct trade aka ETH/TOKEN > TOKEN_YOU_WANT
    • best trade which jumps 2 hops aka ETH/TOKEN > TOKEN > TOKEN_YOU_WANT
    • beat trade which jumps 3 hops aka ETH/TOKEN > TOKEN > OTHER_TOKEN > TOKEN_YOU_WANT
  • It then eth_estimateGas those 3 transactions and takes off the tx fee from the expected quote
  • It then returns the trade which is the highest left amount, meaning it has taken into consideration gas within the quote

Do not worry if you want to use this feature but worried that first time customers before they approve ability for uniswap to move the tokens will not be able to benefit from this, as soon as you have approved uniswap to be able to move tokens on their behalf a new trade will be emitted within the quoteChanged$ stream so you can still get all the benefit on first time swaps.

The beauty of this is its very easy to setup just pass in a gasSettings object including a getGasPrice async function (IT MUST BE A PROMISE) which returns the gas price in Gwei which you want to use for the working out. This must be a string number aka 30 = 30 Gwei it does not handle passing in hex strings. This can be dynamic aka we call this everytime we go and work out the trades, so if you want this to hit an API or etherscan or return a fixed gas price, its completely up to you.

import {
  ChainId,
  TradeContext,
  UniswapPair,
  UniswapPairSettings,
} from 'simple-uniswap-sdk';
const uniswapPair = new UniswapPair({
  // the contract address of the token you want to convert FROM
  fromTokenContractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
  // the contract address of the token you want to convert TO
  toTokenContractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
  // the ethereum address of the user using this part of the dApp
  ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
  // you can pass in the provider url as well if you want
  // providerUrl: YOUR_PROVIDER_URL,
  // OR if you want to inject your own ethereum provider (no need for chainId if so)
  // ethereumProvider: YOUR_WEB3_ETHERS_OR_CUSTOM_ETHEREUM_PROVIDER,
  chainId: ChainId.RINKEBY,
  settings: new UniswapPairSettings({
    gasSettings: {
      getGasPrice: async () => {
        return 'GWEI_GAS_PRICE';
      },
    },
  }),
});

That's it now you get trades which bring you back the best trades minus the tx cost.

ERC20 > ERC20 Output example

import { UniswapPair, ChainId, TradeContext } from 'simple-uniswap-sdk';

const uniswapPair = new UniswapPair({
  // the contract address of the token you want to convert FROM
  // if you want to ever swap native erc20 WETH then import WETH
  // from the simple-uniswap-sdk then use the correct network yours on object
  // so if i was on mainnet i would use WETH.MAINNET().contractAddress
  fromTokenContractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
  // the contract address of the token you want to convert TO
  toTokenContractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
  // the ethereum address of the user using this part of the dApp
  ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
  // you can pass in the provider url as well if you want
  // providerUrl: YOUR_PROVIDER_URL,
  // OR if you want to inject your own ethereum provider (no need for chainId if so)
  // ethereumProvider: YOUR_WEB3_ETHERS_OR_CUSTOM_ETHEREUM_PROVIDER,
  chainId: ChainId.MAINNET,
});

// now to create the factory you just do
const uniswapPairFactory = await uniswapPair.createFactory();

// the amount is the proper entered amount
// so if they enter 10 pass in 10
// it will work it all out for you
const trade = await uniswapPairFactory.trade('10');

// subscribe to quote changes
trade.quoteChanged$.subscribe((value: TradeContext) => {
  // value will hold the same info as below but obviously with
  // the new trade info.
});

console.log(trade);
{
  uniswapVersion: 'v3',
  quoteDirection: 'input'
  baseConvertRequest: '10',
  minAmountConvertQuote: '0.014400465273974444',
  maximumSent: null,
  expectedConvertQuote: '0.014730394044348867',
  liquidityProviderFee: 0,
  liquidityProviderFeePercent: 0,
  liquidityProviderFeesV3: ['0.030000000000000000','0.0000500000000000000','0.030000000000000000'],
  liquidityProviderFeePercentsV3: [0.003, 0.0005, 0.003],
  tradeExpires: 1612189240,
  routePathTokenMap: [
     {
       chainId: 1,
       contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
       decimals: 8,
       symbol: 'FUN',
       name: 'FunFair'
     },
     {
       chainId: 1,
       contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
       decimals: 18,
       symbol: 'DAI',
       name: 'Dai Stablecoin'
     },
     {
       chainId: 1,
       contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
       decimals: 18,
       symbol: 'WETH',
       name: 'Wrapped Ether'
     },
     {
       chainId: 1,
       contractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
       decimals: 18,
       symbol: 'REP',
       name: 'Reputation'
     }
   ],
  routeText: 'FUN > DAI > WETH > REP',
  routePath:['0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b', '0x6B175474E89094C44Da98b954EedeAC495271d0F', '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2','0x1985365e9f78359a9B6AD760e32412f4a445E862' ],
  allTriedRoutesQuotes: [
      {
        expectedConvertQuote: '0.014730394044348867',
        routePathArrayTokenMap: [
          {
            chainId: 1,
            contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
            symbol: FUN,
            decimals: 8,
            name: 'FunFair',
          },
          {
            chainId: 1,
            contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
            decimals: 18,
            symbol: 'WETH',
            name: 'Wrapped Ether',
          },
          {
            chainId: 1,
            contractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
            symbol: 'REP',
            decimals: 18,
            name: 'Reputation',
          },
        ],
        routeText: 'FUN > WETH > REP',
        routePathArray: [
          '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          '0x1985365e9f78359a9B6AD760e32412f4a445E862',
        ],
        uniswapVersion: 'v2',
        liquidityProviderFee: 0.003,
        liquidityProviderFeesV3: [],
      },
      {
        expectedConvertQuote: '0.014606303273323544',
        routePathArrayTokenMap: [
          {
            chainId: 1,
            contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
            symbol: 'FUN',
            decimals: 8,
            name: 'FunFair',
          },
          {
            chainId: 1,
            contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
            decimals: 18,
            symbol: 'DAI',
            name: 'Dai Stablecoin',
          },
          {
            chainId: 1,
            contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
            decimals: 18,
            symbol: 'WETH',
            name: 'Wrapped Ether',
          },
          {
            chainId: 1,
            contractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
            symbol: 'REP',
            decimals: 18,
            name: 'Reputation',
          },
        ],
        routeText: 'FUN > DAI > WETH > REP',
        routePathArray: [
          '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          '0x1985365e9f78359a9B6AD760e32412f4a445E862',
        ],
        uniswapVersion: 'v3',
        liquidityProviderFee: 0,
        liquidityProviderFeesV3: [0.003, 0.0005, 0.003],
      },
      {
        expectedConvertQuote: '0.013997397994408657',
        routePathArrayTokenMap: [
          {
            chainId: 1,
            contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
            symbol: 'FUN',
            decimals: 8,
            name: 'FunFair',
          },
          {
            chainId: 1,
            contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
            decimals: 18,
            symbol: 'USDC',
            name: 'USD Coin',
          },
          {
            chainId: 1,
            contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
            decimals: 18,
            symbol: 'WETH',
            name: 'Wrapped Ether',
          },
          {
            chainId: 1,
            contractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
            symbol: 'REP',
            decimals: 18,
            name: 'Reputation',
          },
        ],
        routeText: 'FUN > USDC > WETH > REP',
        routePathArray: [
          '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          '0x1985365e9f78359a9B6AD760e32412f4a445E862',
        ],
        uniswapVersion: 'v3',
        liquidityProviderFee: 0,
        liquidityProviderFeesV3: [0.0005, 0.0005, 0.003],
      },
      {
        expectedConvertQuote: '0.000000298264906505',
        routePathArrayTokenMap: [
          {
            chainId: 1,
            contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
            symbol: 'FUN',
            decimals: 8,
            name: 'FunFair',
          },
          {
            chainId: 1,
            contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
            decimals: 18,
            symbol: 'USDT',
            name: 'Tether USD',
          },
          {
            chainId: 1,
            contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
            decimals: 18,
            symbol: 'WETH',
            name: 'Wrapped Ether',
          },
          {
            chainId: 1,
            contractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
            symbol: 'REP',
            decimals: 18,
            name: 'Reputation',
          },
        ],
        routeText: 'FUN > USDT > WETH > REP',
        routePathArray: [
          '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          '0x1985365e9f78359a9B6AD760e32412f4a445E862',
        ],
        uniswapVersion: 'v3',
        liquidityProviderFee: 0,
        liquidityProviderFeesV3: [0.003, 0.0005, 0.0005],
      },
  ],
  hasEnoughAllowance: true,
  approvalTransaction: undefined,
  toToken: {
    chainId: 1,
    contractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
    decimals: 18,
    symbol: 'REP',
    name: 'Reputation'
  },
  toBalance: '1500.2632',
  fromToken: {
    chainId: 1,
    contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
    decimals: 8,
    symbol: 'FUN',
    name: 'FunFair'
  },
  fromBalance: {
    hasEnough: true,
    balance: "3317.73129463"
  },
  transaction: {
    to: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D",
    from: "0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9",
    data:"0x38ed1739000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000359578d85cf61000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000b1e6079212888f0be0cf55874b2eb9d7a5e02cd900000000000000000000000000000000000000000000000000000000601683e30000000000000000000000000000000000000000000000000000000000000003000000000000000000000000419d0d8bdd9af5e606ae2232ed285aff190e711b000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000001985365e9f78359a9b6ad760e32412f4a445e862",
    value: "0x00"
  }
}

// once done with trade aka they have sent it and you don't need it anymore call
trade.destroy();

ETH > ERC20 Output example

import { UniswapPair, ETH, ChainId, TradeContext } from 'simple-uniswap-sdk';

const uniswapPair = new UniswapPair({
  // use the ETH import from the lib, bare in mind you should use the
  // network which yours on, so if your on rinkeby you should use
  // ETH.RINKEBY
  fromTokenContractAddress: ETH.MAINNET().contractAddress,
  // the contract address of the token you want to convert TO
  toTokenContractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
  // the ethereum address of the user using this part of the dApp
  ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
  // you can pass in the provider url as well if you want
  // providerUrl: YOUR_PROVIDER_URL,
  // OR if you want to inject your own ethereum provider (no need for chainId if so)
  // ethereumProvider: YOUR_WEB3_ETHERS_OR_CUSTOM_ETHEREUM_PROVIDER,
  chainId: ChainId.MAINNET,
});

// now to create the factory you just do
const uniswapPairFactory = await uniswapPair.createFactory();

// the amount is the proper entered amount
// so if they enter 10 pass in 10 and
// it will work it all out for you
const trade = await uniswapPairFactory.trade('10');


// subscribe to quote changes
trade.quoteChanged$.subscribe((value: TradeContext) => {
  // value will hold the same info as below but obviously with
  // the new trade info.
});

console.log(trade);
{
  uniswapVersion: 'v3',
  quoteDirection: 'input',
  baseConvertRequest: '10',
  minAmountConvertQuote: '446878.20758208',
  maximumSent: null,
  expectedConvertQuote: '449123.82671566',
  liquidityProviderFee: 0,
  liquidityProviderFeePercent: 0,
  liquidityProviderFeesV3: ['0.030000000000000000'],
  liquidityProviderFeePercentsV3: [0.003],
  tradeExpires: 1612189240,
  routePathTokenMap: [
    {
      chainId: 1,
      contractAddress: 'NO_CONTRACT_ADDRESS',
      symbol: 'ETH',
      decimals: 18,
      name: 'Ethers'
    },
    {
      chainId: 1,
      contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      symbol: 'FUN',
      decimals: 8,
      name: 'FunFair',
    },
  ],
  routeText: 'ETH > FUN',
  routePath: [
    '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
    '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
  ],
  hasEnoughAllowance: true,
  approvalTransaction: undefined,
  toToken: {
    chainId: 1,
    contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
    symbol: 'FUN',
    decimals: 8,
    name: 'FunFair',
  },
  toBalance: '1500.2634',
  fromToken: {
    chainId: 1,
    contractAddress: 'NO_CONTRACT_ADDRESS',
    symbol: 'ETH',
    decimals: 18,
    name: 'Ethers'
  },
  fromBalance: {
    hasEnough: false,
    balance: '0.008474677789598637',
  },
  transaction: {
    to: '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
    from: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
    data:
      '0x7ff36ab5000000000000000000000000000000000000000000000000000028a4b1ae9cc00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000b1e6079212888f0be0cf55874b2eb9d7a5e02cd90000000000000000000000000000000000000000000000000000000060168ee30000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000419d0d8bdd9af5e606ae2232ed285aff190e711b',
    value: '0x8ac7230489e80000',
  },
  allTriedRoutesQuotes: [
    {
      expectedConvertQuote: '449123.82671566',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v2',
      liquidityProviderFee: 0.003,
      liquidityProviderFeesV3: []
    },
    {
      expectedConvertQuote: '446400.4834047',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDC > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.01]
    },
    {
      expectedConvertQuote: '446400.4834047',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDC > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.01]
    },
    {
      expectedConvertQuote: '446356.68778218',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDT > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.0005]
    },
    {
      expectedConvertQuote: '446356.68778218',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDT > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.0005]
    },
    {
      expectedConvertQuote: '446345.24608428',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > DAI > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003]
    },
    {
      expectedConvertQuote: '446345.24608428',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > DAI > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003]
    },
    {
      expectedConvertQuote: '347402.73288796',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > DAI > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003]
    },
    {
      expectedConvertQuote: '346246.52439964',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDC > DAI > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '346246.52439964',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDC > DAI > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '346246.52439964',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDC > DAI > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '345845.48248206',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDT > DAI > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '345845.48248206',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDT > DAI > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '345845.48248206',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDT > DAI > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '153353.27776886',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDC > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.01]
    },
    {
      expectedConvertQuote: '153171.51955671',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > DAI > USDC > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.0005, 0.0005]
    },
    {
      expectedConvertQuote: '153171.51955671',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > DAI > USDC > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.0005, 0.0005]
    },
    {
      expectedConvertQuote: '153171.51955671',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > DAI > USDC > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.0005, 0.0005]
    },
    {
      expectedConvertQuote: '153099.84287111',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDT > USDC > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '153099.84287111',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDT > USDC > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '153099.84287111',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDT > USDC > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '10090.42827381',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
          decimals: 18,
          symbol: 'COMP',
          name: 'Compound',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > COMP > DAI > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xc00e94Cb662C3520282E6f5717214004A7f26888',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '10090.42827381',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
          decimals: 18,
          symbol: 'COMP',
          name: 'Compound',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > COMP > DAI > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xc00e94Cb662C3520282E6f5717214004A7f26888',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '176.25846115',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
          decimals: 18,
          symbol: 'COMP',
          name: 'Compound',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > COMP > USDC > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xc00e94Cb662C3520282E6f5717214004A7f26888',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '176.25846115',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
          decimals: 18,
          symbol: 'COMP',
          name: 'Compound',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > COMP > USDC > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xc00e94Cb662C3520282E6f5717214004A7f26888',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '0.00167195',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDC > USDT > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '0.00167195',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > DAI > USDT > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.0005, 0.003]
    },
    {
      expectedConvertQuote: '0.00167195',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDC > USDT > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '0.00167195',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDT > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.0005]
    },
    {
      expectedConvertQuote: '0.00167195',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
          decimals: 18,
          symbol: 'COMP',
          name: 'Compound',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > COMP > USDT > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xc00e94Cb662C3520282E6f5717214004A7f26888',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '0.00167195',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > DAI > USDT > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.0005, 0.003]
    },
    {
      expectedConvertQuote: '0.00167195',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > DAI > USDT > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.0005, 0.003]
    },
    {
      expectedConvertQuote: '0.00167195',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
          decimals: 18,
          symbol: 'COMP',
          name: 'Compound',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > COMP > USDT > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xc00e94Cb662C3520282E6f5717214004A7f26888',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '0.00167195',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: 'NO_CONTRACT_ADDRESS',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers'
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
      ],
      routeText: 'ETH > USDC > USDT > FUN',
      routePathArray: [
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
  ],
}

// once done with trade aka they have sent it and you don't need it anymore call
trade.destroy();

ERC20 > ETH Output example

import { UniswapPair, ETH, ChainId, TradeContext } from 'simple-uniswap-sdk';

const uniswapPair = new UniswapPair({
  // the contract address of the token you want to convert FROM
  fromTokenContractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
  // use the ETH import from the lib, bare in mind you should use the
  // network which yours on, so if your on rinkeby you should use
  // ETH.RINKEBY
  toTokenContractAddress: ETH.MAINNET().contractAddress,
  // the ethereum address of the user using this part of the dApp
  ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
  // you can pass in the provider url as well if you want
  // providerUrl: YOUR_PROVIDER_URL,
  // OR if you want to inject your own ethereum provider (no need for chainId if so)
  // ethereumProvider: YOUR_WEB3_ETHERS_OR_CUSTOM_ETHEREUM_PROVIDER,
  chainId: ChainId.MAINNET,
});

// now to create the factory you just do
const uniswapPairFactory = await uniswapPair.createFactory();

// the amount is the proper entered amount
// so if they enter 10 pass in 10
// it will work it all out for you
const trade = await uniswapPairFactory.trade('10');

// subscribe to quote changes
trade.quoteChanged$.subscribe((value: TradeContext) => {
  // value will hold the same info as below but obviously with
  // the new trade info.
});

console.log(trade);
{
  uniswapVersion: 'v3',
  quoteDirection: 'input',
  baseConvertRequest: '10',
  minAmountConvertQuote: '0.00022040807282109',
  maximumSent: null,
  expectedConvertQuote: '0.00022151807282109',
  liquidityProviderFee: 0,
  liquidityProviderFeePercent: 0,
  liquidityProviderFeesV3: ['0.03000000', '0.000500000', '0.03000000'],
  liquidityProviderFeePercentsV3: [0.003, 0.0005, 0.003],
  tradeExpires: 1612189240,
  routePathTokenMap: [
    {
      chainId: 1,
      contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
      symbol: 'FUN',
      decimals: 8,
      name: 'FunFair',
    },
    {
      chainId: 1,
      contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
      decimals: 18,
      symbol: 'DAI',
      name: 'Dai Stablecoin',
    },
    {
      chainId: 1,
      contractAddress: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
      decimals: 18,
      symbol: 'COMP',
      name: 'Compound',
    },
    {
      chainId: 1,
      contractAddress: 'NO_CONTRACT_ADDRESS',
      symbol: 'ETH',
      decimals: 18,
      name: 'Ethers'
    },
  ],
  routeText: 'FUN > DAI > COMP > ETH',
  routePath: [
    '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
    '0x6B175474E89094C44Da98b954EedeAC495271d0F',
    '0xc00e94Cb662C3520282E6f5717214004A7f26888',
    '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
  ],
  allTriedRoutesQuotes: [
    {
      expectedConvertQuote: '0.00022151807282109',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
          decimals: 18,
          symbol: 'COMP',
          name: 'Compound',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > DAI > COMP > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xc00e94Cb662C3520282E6f5717214004A7f26888',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v2',
      liquidityProviderFee: 0.003,
      liquidityProviderFeesV3: []
    },
    {
      expectedConvertQuote: '0.00022151807282109',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
          decimals: 18,
          symbol: 'COMP',
          name: 'Compound',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > DAI > COMP > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xc00e94Cb662C3520282E6f5717214004A7f26888',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.003, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '0.000217400884509221',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005]
    },
    {
      expectedConvertQuote: '0.000216692105524981',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > DAI > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003]
    },
    {
      expectedConvertQuote: '0.000216165414503092',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > DAI > USDC > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.0005, 0.0005]
    },
    {
      expectedConvertQuote: '0.000216165414503092',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > DAI > USDC > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.0005, 0.0005]
    },
    {
      expectedConvertQuote: '0.000216165414503092',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > DAI > USDC > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.0005, 0.0005]
    },
    {
      expectedConvertQuote: '0.000216113740987982',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > DAI > USDT > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '0.000216113740987982',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > DAI > USDT > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '0.000216113740987982',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > DAI > USDT > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '0.000207416610491746',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDC > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.0005]
    },
    {
      expectedConvertQuote: '0.000206879660311982',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDC > USDT > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '0.000206879660311982',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDC > USDT > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '0.000206879660311982',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDC > USDT > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '0.000206675889551395',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDC > DAI > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '0.000206675889551395',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDC > DAI > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '0.000206675889551395',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDC > DAI > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '0.000201332888879835',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
          decimals: 18,
          symbol: 'COMP',
          name: 'Compound',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDC > COMP > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0xc00e94Cb662C3520282E6f5717214004A7f26888',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '0.000201332888879835',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
          decimals: 18,
          symbol: 'COMP',
          name: 'Compound',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDC > COMP > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0xc00e94Cb662C3520282E6f5717214004A7f26888',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '0.00000000454541448',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
          decimals: 18,
          symbol: 'COMP',
          name: 'Compound',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDT > COMP > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0xc00e94Cb662C3520282E6f5717214004A7f26888',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '0.00000000454541448',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
          decimals: 18,
          symbol: 'COMP',
          name: 'Compound',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDT > COMP > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0xc00e94Cb662C3520282E6f5717214004A7f26888',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '0.000000004421040886',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDT > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003]
    },
    {
      expectedConvertQuote: '0.000000004406314787',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDT > DAI > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '0.000000004406314787',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDT > DAI > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '0.000000004406314787',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
          decimals: 18,
          symbol: 'DAI',
          name: 'Dai Stablecoin',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDT > DAI > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0x6B175474E89094C44Da98b954EedeAC495271d0F',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.003]
    },
    {
      expectedConvertQuote: '0.000000003689610342',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDT > USDC > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '0.000000003689610342',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDT > USDC > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
    {
      expectedConvertQuote: '0.000000003689610342',
      routePathArrayTokenMap: [
        {
          chainId: 1,
          contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
          symbol: 'FUN',
          decimals: 8,
          name: 'FunFair',
        },
        {
          chainId: 1,
          contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
          decimals: 18,
          symbol: 'USDT',
          name: 'Tether USD',
        },
        {
          chainId: 1,
          contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 18,
          symbol: 'USDC',
          name: 'USD Coin',
        },
        {
          chainId: 1,
          contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
          symbol: 'ETH',
          decimals: 18,
          name: 'Ethers',
        },
      ],
      routeText: 'FUN > USDT > USDC > ETH',
      routePathArray: [
        '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
        '0xdAC17F958D2ee523a2206206994597C13D831ec7',
        '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
        '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
      ],
      uniswapVersion: 'v3',
      liquidityProviderFee: 0,
      liquidityProviderFeesV3: [0.0005, 0.003, 0.0005]
    },
  ],
  hasEnoughAllowance: true,
  approvalTransaction: undefined,
  toToken: {
    chainId: 1,
    contractAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
    symbol: 'ETH',
    decimals: 18,
    name: 'Ethers',
  },
  toBalance: '1.564',
  fromToken: {
    chainId: 1,
    contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
    symbol: 'FUN',
    decimals: 8,
    name: 'FunFair',
  },
  fromBalance: {
    hasEnough: true,
    balance: '3317.73129463',
  },
  transaction: {
    to: '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
    from: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
    data:
      '0x18cbafe5000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000c875c0e2d96200000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000b1e6079212888f0be0cf55874b2eb9d7a5e02cd90000000000000000000000000000000000000000000000000000000060168fe80000000000000000000000000000000000000000000000000000000000000004000000000000000000000000419d0d8bdd9af5e606ae2232ed285aff190e711b0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000c00e94cb662c3520282e6f5717214004a7f26888000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
    value: '0x00',
  },
}

// once done with trade aka they have sent it and you don't need it anymore call
trade.destroy();

toToken

This exposes the to token contract information, like decimals, symbol and name.

get toToken(): Token
export interface Token {
  chainId: ChainId;
  contractAddress: string;
  decimals: number;
  symbol: string;
  name: string;
}

Usage

import { UniswapPair, ChainId } from 'simple-uniswap-sdk';

const uniswapPair = new UniswapPair({
  // the contract address of the token you want to convert FROM
  fromTokenContractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
  // the contract address of the token you want to convert TO
  toTokenContractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
  // the ethereum address of the user using this part of the dApp
  ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
  // you can pass in the provider url as well if you want
  // providerUrl: YOUR_PROVIDER_URL,
  // OR if you want to inject your own ethereum provider (no need for chainId if so)
  // ethereumProvider: YOUR_WEB3_ETHERS_OR_CUSTOM_ETHEREUM_PROVIDER,
  chainId: ChainId.MAINNET,
});

// now to create the factory you just do
const uniswapPairFactory = await uniswapPair.createFactory();

const toToken = uniswapPairFactory.toToken;
console.log(toToken);
// toToken:
{
  chainId: 1,
  contractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
  decimals: 18,
  symbol: 'REP',
  name: 'Reputation'
}

fromToken

This exposes the from token contract information, like decimals, symbol and name.

get fromToken(): Token
export interface Token {
  chainId: ChainId;
  contractAddress: string;
  decimals: number;
  symbol: string;
  name: string;
}

Usage

import { UniswapPair, ChainId } from 'simple-uniswap-sdk';

const uniswapPair = new UniswapPair({
  // the contract address of the token you want to convert FROM
  fromTokenContractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
  // the contract address of the token you want to convert TO
  toTokenContractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
  // the ethereum address of the user using this part of the dApp
  ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
  // you can pass in the provider url as well if you want
  // providerUrl: YOUR_PROVIDER_URL,
  // OR if you want to inject your own ethereum provider (no need for chainId if so)
  // ethereumProvider: YOUR_WEB3_ETHERS_OR_CUSTOM_ETHEREUM_PROVIDER,
  chainId: ChainId.MAINNET,
});

// now to create the factory you just do
const uniswapPairFactory = await uniswapPair.createFactory();

const fromToken = uniswapPairFactory.fromToken;
console.log(fromToken);
// fromToken:
{
  chainId: 1,
  contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
  decimals: 8,
  symbol: 'FUN',
  name: 'FunFair'
}

providerUrl

This exposes the provider url it is using will be undefined if you injected a ethereum provider

get providerUrl(): string | undefined

Usage

import { UniswapPair, ChainId } from 'simple-uniswap-sdk';

const uniswapPair = new UniswapPair({
  // the contract address of the token you want to convert FROM
  fromTokenContractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
  // the contract address of the token you want to convert TO
  toTokenContractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
  // the ethereum address of the user using this part of the dApp
  ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
  // you can pass in the provider url as well if you want
  // providerUrl: YOUR_PROVIDER_URL,
  // OR if you want to inject your own ethereum provider (no need for chainId if so)
  // ethereumProvider: YOUR_WEB3_ETHERS_OR_CUSTOM_ETHEREUM_PROVIDER,
  chainId: ChainId.MAINNET,
});

// now to create the factory you just do
const uniswapPairFactory = await uniswapPair.createFactory();

const providerUrl = uniswapPairFactory.providerUrl;
console.log(providerUrl);
// https://mainnet.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161

TokenFactoryPublic

Along side the above we also have exposed some helpful erc20 token calls.

getToken

This method will return you the token information like decimals, name etc.

async getToken(): Promise<Token>
export interface Token {
  chainId: ChainId;
  contractAddress: string;
  decimals: number;
  symbol: string;
  name: string;
}

Usage

import { TokenFactoryPublic, ChainId } from 'simple-uniswap-sdk';

const tokenContractAddress = '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b';

const tokenFactoryPublic = new TokenFactoryPublic(
  toTokenContractAddress,
  // this can take the same interface as pair context aka
  // `ChainIdAndProvider` | `EthereumProvider`
  // so you can pass in a providerUrl or a ethereumProvider
  { chainId: ChainId.MAINNET }
);

const token = await tokenFactoryPublic.getToken();
console.log(token);
{
  chainId: 1,
  contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
  decimals: 8,
  symbol: 'FUN',
  name: 'FunFair',
},

allowance

This method will return the allowance the user has allowed to be able to be moved on his behalf. Uniswap needs this allowance to be higher then the amount swapping for it to be able to move the tokens for the user. This is always returned as a hex and not formatted for you.

async allowance(uniswapVersion: UniswapVersion, ethereumAddress: string): Promise<string>

Usage

import {
  TokenFactoryPublic,
  ChainId,
  UniswapVersion,
} from 'simple-uniswap-sdk';

const tokenContractAddress = '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b';

const tokenFactoryPublic = new TokenFactoryPublic(
  toTokenContractAddress,
  // this can take the same interface as pair context aka
  // `ChainIdAndProvider` | `EthereumProvider`
  // so you can pass in a providerUrl or a ethereumProvider
  { chainId: ChainId.MAINNET }
);

const ethereumAddress = '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9';

const allowance = await tokenFactoryPublic.allowance(
  UniswapVersion.v3,
  ethereumAddress
);
console.log(allowance);
// '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff';

balanceOf

This method will return the balance this user holds of this token. This always returned as a hex and not formatted for you.

async balanceOf(ethereumAddress: string): Promise<string>

Usage

import { TokenFactoryPublic, ChainId } from 'simple-uniswap-sdk';

const tokenContractAddress = '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b';

const tokenFactoryPublic = new TokenFactoryPublic(
  toTokenContractAddress,
  // this can take the same interface as pair context aka
  // `ChainIdAndProvider` | `EthereumProvider`
  // so you can pass in a providerUrl or a ethereumProvider
  { chainId: ChainId.MAINNET }
);

const ethereumAddress = '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9';

const balanceOf = await tokenFactoryPublic.balanceOf(ethereumAddress);
console.log(balanceOf);
// '0x00';

totalSupply

This method will return the total supply of tokens which exist. This always returned as a hex.

async totalSupply(): Promise<string>

Usage

import { TokenFactoryPublic, ChainId } from 'simple-uniswap-sdk';

const tokenContractAddress = '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b';

const tokenFactoryPublic = new TokenFactoryPublic(toTokenContractAddress, {
  chainId: ChainId.MAINNET,
  // you can pass in the provider url as well if you want
  // providerUrl: YOUR_PROVIDER_URL,
});

const totalSupply = await tokenFactoryPublic.totalSupply();
console.log(totalSupply);
// '0x09195731e2ce35eb000000';

generateApproveAllowanceData

This method will generate the data for the approval of being able to move tokens for the user. You have to send the transaction yourself, this only generates the data for you to send.

generateApproveAllowanceData(spender: string, value: string): string

Usage

import { TokenFactoryPublic, ChainId } from 'simple-uniswap-sdk';

const tokenContractAddress = '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b';

const tokenFactoryPublic = new TokenFactoryPublic(
  tokenContractAddress,
  // this can take the same interface as pair context aka
  // `ChainIdAndProvider` | `EthereumProvider`
  // so you can pass in a providerUrl or a ethereumProvider
  { chainId: ChainId.MAINNET }
);

// the contract address for which you are allowing to move tokens on your behalf
const spender = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D';

// the amount you wish to allow them to move, this example just uses the max
// hex. If not each time they do a operation which needs to move tokens then
// it will cost them 2 transactions, 1 to approve the allowance then 1 to actually
// do the contract call to move the tokens.
const value =
  '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff';

const data = tokenFactoryPublic.generateApproveAllowanceData(spender, value);
console.log(data);
// '0x095ea7b30000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff';

getAllowanceAndBalanceOf

This method will get the allowance and balance for the token in a multicall request. Will return as hex and NOT formatted for you.

async getAllowanceAndBalanceOf(uniswapVersion: UniswapVersion, ethereumAddress: string): Promise<AllowanceAndBalanceOf>
export interface AllowanceAndBalanceOf {
  allowance: string;
  balanceOf: string;
}

Usage

import { TokenFactoryPublic, ChainId, UniswapVersion } from 'simple-uniswap-sdk';

const tokenContractAddress = '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b';

const tokenFactoryPublic = new TokenFactoryPublic(
  tokenContractAddress,
  // this can take the same interface as pair context aka
  // `ChainIdAndProvider` | `EthereumProvider`
  // so you can pass in a providerUrl or a ethereumProvider
  { chainId: ChainId.MAINNET }
);

const ethereumAddress = '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9';

const result = await tokenFactoryPublic.getAllowanceAndBalanceOf(
  UniswapVersion.v3,
  ethereumAddress
);
console.log(result);
{
  allowance: '0x2386f01852b720',
  balanceOf: '0x4d3f3832f7'
}

TokensFactoryPublic

Along side the TokenFactoryPublic we also have exposed a way to call many contracts at once, this uses multicall so its super fast.

getTokens

This method will return you the tokens information like decimals, name etc.

async getTokens(tokenContractAddresses: string[]): Promise<Token[]>
export interface Token {
  chainId: ChainId;
  contractAddress: string;
  decimals: number;
  symbol: string;
  name: string;
}

Usage

import { TokensFactoryPublic, ChainId } from 'simple-uniswap-sdk';

const tokensFactoryPublic = new TokensFactoryPublic(
  // this can take the same interface as pair context aka
  // `ChainIdAndProvider` | `EthereumProvider`
  // so you can pass in a providerUrl or a ethereumProvider
  { chainId: ChainId.MAINNET }
);

const tokens = await tokensFactoryPublic.getTokens([
  '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
  '0x1985365e9f78359a9B6AD760e32412f4a445E862',
]);
console.log(tokens);
[
  {
    chainId: 1,
    contractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
    symbol: 'REP',
    decimals: 18,
    name: 'Reputation',
  },
  {
    chainId: 1,
    contractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
    symbol: 'FUN',
    decimals: 8,
    name: 'FunFair',
  },
];

Tests

The whole repo is covered in tests output below:

Test Suites: 25 passed, 25 total
Tests:       5 skipped, 234 passed, 239 total
Snapshots:   0 total
Time:        33.238s
Ran all test suites.

Issues

Please raise any issues in the below link.

https://github.com/joshstevens19/uniswap-sdk/issues

Thanks And Support

This package is brought to you by Josh Stevens. My aim is to be able to keep creating these awesome packages to help the Ethereum space grow with easier-to-use tools to allow the learning curve to get involved with blockchain development easier and making Ethereum ecosystem better. If you want to help with that vision and allow me to invest more time into creating cool packages or if this package has saved you a lot of development time donations are welcome, every little helps. By donating, you are supporting me to be able to maintain existing packages, extend existing packages (as Ethereum matures), and allowing me to build more packages for Ethereum due to being able to invest more time into it. Thanks, everyone!

Direct donations

Direct donations any token accepted - Eth address > 0x699c2daD091ffcF18f3cd9E8495929CA3a64dFe1

Github sponsors

sponsor me via github using fiat money

simple-uniswap-sdk's People

Contributors

joshstevens19 avatar liu-zhipeng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

simple-uniswap-sdk's Issues

Using this library to provide liquidity

Hello,

I have a question regarding the use of this library and would like to get some directions. I'm trying to create a liquidity pool for, lets say an artificail pair ETH > $TOKEN. How should I procceed? Is this supported from the library? I took a look in the source code and found that the required functionalities are implemented, but what classes should I use? uniswap-router-contract.factory.v2.ts already contains the method addLiquidity. From what I understand the following steps should be followed:

  1. Create a UniswapPair instance
  2. Create a UniswapRouterContractFactoryV2 instance
  3. Call addLiquidity method of UniswapRouterContractFactoryV2 instance and provide the token parameters from UniswapPair instance.
  4. Check for approval
  5. Send the transaction to network using a web3/ethers provider.

Is my assumptions correct? There might be the case that we also need to have a deployed contract for the desired liquidity pool, but I am not sure. I read the uniswap documentations but could not figure how to procceed. You take a very important step by creating this library, which is so much simpler to use than the official Uniswap SDK, so I took the initiate to ask for help here.

feat: BSC support

Hey as you told me previously your simple-pancake-sdk is deprecated and we should us this lib, also you told me
"my uniswap sdk I created actually now letโ€™s you map custom networks with full contract addresses (which means it supports forks like pancake)", as I'm not an epxert on blockchain I understand there that I can use custom networks like BSC.

But when I try to do your angular example settings like this

this.uniswapDappSharedLogicContext = {

      supportedNetworkTokens: [
        {
          chainId: 0x38, // 56
          defaultInputToken: '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c', // BNB
          defaultOutputToken: '0x1fd13bB00d80986adc121d5bEF287Bf2ED5C31AF', // GRY
          supportedTokens: [
            { contractAddress: '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c' }, // BNB
            { contractAddress: '0x1fd13bB00d80986adc121d5bEF287Bf2ED5C31AF' }, // GRY
            { contractAddress: '0xd293a7064e7e3b61bfbf2728f976d2500206dc73' }, // GRF
            { contractAddress: '0x6813e7d721694d8f8a2990a3e0a389b326169c6e' }, // FDOX
            { contractAddress: '0x8a3937e12155e07f3a06a84ec4dfdd3ec40d1e6a' }, // Nigels
          ],
        }
      ],
      ethereumAddress: accounts[0],
      ethereumProvider: this.web3Service.provider
      // ,
      // theming: {
      //   backgroundColor: 'red',
      //   button: { textColor: 'white', backgroundColor: 'blue' },
      //   panel: { textColor: 'black', backgroundColor: 'yellow' },
      //   textColor: 'orange',
      // },
    };

I'm running always in the unsupported network error because the simple-uniswap-sdk checks also for chainId, like this and others
ETH.info(this.chainId);

Price impact

Has anyone already implemented the functionality of getting a price impact in this library?

Prices vary slightly

The price I get through the sdk call is slightly different from the price on uniswap. For example, the current 1000USDT can be exchanged for 279.157 SUSHI, but the quote in the SDK is 273.387. I want to know where this difference comes from, thanks

TokensFactoryPublic with customNetwork not working

I am attempting to get getAllowanceAndBalanceOfForContracts working with the TokensFactoryPublic for BSC. The constructor takes in a custom network but it doesn't seem to be taking the property as the factory logs out its custom network as undefined.

Code example:
const tokensFactoryPublic = new TokensFactoryPublic({
ethereumProvider: provider,
customNetwork: {
nameNetwork: 'Binance Smart Chain Testnet',
multicallContractAddress: '0x8F3273Fb89B075b1645095ABaC6ed17B2d4Bc576',
nativeCurrency: {
name: 'Binance Coin',
symbol: 'tBNB', // BNB
decimals: 18
},
nativeWrappedTokenInfo: {
chainId: provider._network.chainId,
contractAddress: '0xae13d989dac2f0debff460ac112a837c89baa7cd',
decimals: 18,
symbol: 'WBNB',
name: 'Wrapped BNB'
}
}
})

    console.log(tokensFactoryPublic)

Here is what it logs out:
TokensFactoryPublic {
_ethersProvider: EthersProvider {
_providerContext: { ethereumProvider: [JsonRpcProvider], customNetwork: [Object] },
_ethersProvider: JsonRpcProvider {
_isProvider: true,
_events: [],
_emitted: [Object],
disableCcipRead: false,
formatter: [Formatter],
anyNetwork: false,
_network: [Object],
_maxInternalBlockNumber: -1024,
_lastBlockNumber: -2,
_maxFilterBlockRange: 10,
_pollingInterval: 4000,
_fastQueryDate: 0,
connection: [Object],
_nextId: 42
}
},
_customNetwork: undefined,
_cloneUniswapContractDetails: undefined,
_multicall: CustomMulticall {
_options: {
ethersProvider: [JsonRpcProvider],
tryAggregate: true,
multicallCustomContractAddress: undefined
},
ABI: [ [Object], [Object] ],
_executionType: 'ethers'
}
}

UniswapError: No routes found on Mainnet

Created liquidity pool at pair MTT > USDT on Mainnet.
Set up disableMultihops: false, but it still works only at MTT <-> USDT, on any other pair i got an error like:
UniswapError: No routes found for MTT > DAI

On uniswap app works great with any other tokens.

fromTokenContractAddress: '0xe0c15f5066FCbAfad6d1972125fB0cC1d2200bbe',
toTokenContractAddress: '0x6b175474e89094c44da98b954eedeac495271d0f',
uniswapVersions: [UniswapVersion.v2, UniswapVersion.v3],
chainId: 1,
settings: new UniswapPairSettings({
	slippage: 0.01,
	deadlineMinutes: 20,
	disableMultihops: false,
	uniswapVersions: [UniswapVersion.v2, UniswapVersion.v3]
})

I am stuck, please help to find out solution.

feat: support multiple exchanges and search for best route

Hello again,

I have a feature request or maybe its even already implemented.

Is there a way to get best route to exchange token if there are different liquidity pools on different exchanges?

In our case we have already a LP on TraderJoye and would like to add another to Pangolin (both and Avalanche C-Chain).
Is there a way we can do this?

Or even, bogged.finance has an AGGREGATOR which is already doing the job, is there a way to use the AGGREGATOR instead of a router?

@joshstevens19 @liu-zhipeng @vm06007

Gas limit override feature

Hello, thanks for the awesome project!
Simple-uniswap-sdk is really useful!

I have a problem with the automatic gas limit detection. It is often set for a too-small value, so I keep getting the Warning! Error encountered during contract execution [Out of gas] on my trade transactions. Is there any way to manually set the Gas Limit?

Make it possible to put in metamask provider

Thanks for this awesome simplification of working with uniswap!

I'm working on a dapp and running into issues of a mismatch between metamask and the calls this library does.
E.g. when I switch metamask to localhost or back to mainnet or a testnet, it would be nice if this library just switches transparently.
I've tried everything I could to get an 'underlying' RPC URL from metamask, but this seems to be not possible, and passing a providerUrl is the only API this library currently supports, so this would mean that I need to make a manual mapping somewhere to map current metamask settings to ChainId + URL combinations.

When I look at the code of the library, it in the end also just uses an ethers provider, so would it be possible to pass in the existing provider I got from metamask? Then everything would work without extra code needed.

Must have a `fromTokenContractAddress` on the context

When defining a UniswapPair:

 const uniswapPair = new UniswapPair({
   fromTokenContractAddress: fromTokenContractAddress,
   toTokenContractAddress: toTokenContractAddress,
   walletAddress: walletAddress,
   chainId: ChainId.ROPSTEN,
 });

Exception: Must have a fromTokenContractAddress on the context

C:\Dev\Uniswap-Misc\Uniswap-v3-Contract-WS\node_modules\simple-uniswap-sdk\dist\cjs\common\errors\uniswap-error.js:20
        var _this = _super.call(this, message) || this;
                           ^

Error [UniswapError]: **Must have a `fromTokenContractAddress` on the context**
    at new UniswapError (C:\Dev\Uniswap-Misc\Uniswap-v3-Contract-WS\node_modules\simple-uniswap-sdk\dist\cjs\common\errors\uniswap-error.js:20:28)
    at new UniswapPair (C:\Dev\Uniswap-Misc\Uniswap-v3-Contract-WS\node_modules\simple-uniswap-sdk\dist\cjs\factories\pair\uniswap-pair.js:55:19)
    at etherTradeExample (C:\Dev\Uniswap-Misc\Uniswap-v3-Contract-WS\Uniswap-v3-SimpleSDK1.js:120:26)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  code: 6
}

Node.js v17.3.0

From what I can see, I have used fromTokenContractAddress. Am I missing something?

How to use native currency on custom network

Using ETH.MAINNET().contractAddress works fine for eth, and I am trying to reproduce that for Polygon and BSC. I see it prints out WETHs address with a suffix _ETH. I tried to make my input token the same way for Polygon 0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270_MATIC and it didn't work. My config is below, I have the nativeCurrency setup for the customNetwork. I have swaped tokens and everything so I know it works, I just don't know how to make the Native Coin of each chain as an input.

A few off topic questions. What does the baseTokens parameter do? How do I access them? Does the baseTokens have anything to do with the NativeCurrency?

Is there anyway I can swap using my wallet, but have the swap send the output to a different wallet?

Thanks

`const config = {
name: 'Polygon Mainnet',
nativeCurrency: {
name: 'Polygon',
symbol: 'MATIC',
decimals: 18,
logoUrl: [tokenImageUrlForContract({ tokenContractChainId: maticMainChainId })]
},
nativeWrappedTokenInfo: {
chainId: maticMainChainId,
contractAddress: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',
decimals: 18,
symbol: 'WMATIC',
name: 'Wrapped MATIC'
},
multicallContractAddress: '0x275617327c958bD06b5D6b871E7f491D76113dd8',
defaultPairs: {
inputAddress: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',
outputAddress: '0x8f3cf7ad23cd3cadbd9735aff958023239c6a063'
},
uniswapVersions: [UniswapVersion.v3],
cloneUniswapContractDetails: {
v3Override: {
routerAddress: '0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45',
factoryAddress: '0x1f98431c8ad98523631ae4a59f267346ea31f984',
quoterAddress: '0xb27308f9f90d607463bb33ea1bebb41c27ce5ab6'
}
}
}

async function quote({
chainId,
library,
account,
fromTokenContractAddress,
toTokenContractAddress,
slippage,
deadlineMinutes,
tradeAmount,
tradeDirection
}) {
try {
const {
name,
nativeCurrency,
nativeWrappedTokenInfo,
multicallContractAddress,
uniswapVersions,
cloneUniswapContractDetails
} = config

    let settings = new UniswapPairSettings({
        slippage,
        deadlineMinutes,
        disableMultihops: false,
        uniswapVersions,
        gasSettings: {
            getGasPrice: async () => {
                // TODO update
                const gasPrice = await library.getGasPrice()
                return formatUnits(gasPrice, 'gwei')
            }
        }
    })

    if (!ethChains.includes(chainId)) {
        settings = {
            ...settings,
            cloneUniswapContractDetails,
            customNetwork: {
                nameNetwork: name,
                multicallContractAddress,
                nativeCurrency,
                nativeWrappedTokenInfo
            }
        }
    }

    const uniswapPair = new UniswapPair({
        fromTokenContractAddress,
        toTokenContractAddress,
        ethereumAddress: account,
        ethereumProvider: library,
        settings
    })

    const uniswapPairFactory = await uniswapPair.createFactory()

    const trade = await uniswapPairFactory.trade(tradeAmount, tradeDirection)

    //.......
} catch (error) {
    throw error
}

}
`

custom provider not set with pairfactory

Following the docs I am trying to pass my own chainstack web3 provider to the UniswapPair

const provider = new Web3.providers.HttpProvider(providerUrl);

const uniswapPair = new UniswapPair({,
ethereumProvider : provider,
........

When I log I still get some infura provider shown in the object and not my custom provider.

const uniswapPairFactory = await uniswapPair.createFactory();
console.log('pairProvider', uniswapPairFactory._uniswapPairFactoryContext.ethersProvider);

UniswapError: invalid from or to contract tokens

Im trying to use one of the examples from this repo but I keep getting this error and I can not find the reason why. I am trying to use my chainstack node provider URL which works with other modules like web3 without issues.

const uniswapPair = new UniswapPair({
// the contract address of the token you want to convert FROM
fromTokenContractAddress : '0xdac17f958d2ee523a2206206994597c13d831ec7',
// the contract address of the token you want to convert TO
toTokenContractAddress : '0x2b591e99afe9f32eaa6214f7b7629768c40eeb39',
// the ethereum address of the user using this part of the dApp
ethereumAddress : '0x1624c82cdac2f518ab47ef34f497af268b6d7916',
chainId : ChainId.MAINNET,
providerUrl :
'myusernamen:[email protected]',
settings : new UniswapPairSettings({
// if not supplied it will use 0.005 which is 0.5%
// please pass it in as a full number decimal so 0.7%
// would be 0.007
slippage : 0.005,
// if not supplied it will use 20 a deadline minutes
deadlineMinutes : 20,
// if not supplied it will try to use multihops
// if this is true it will require swaps to direct
// pairs
disableMultihops : false,
// for example if you only wanted to turn on quotes for v3 and not v3
// you can only support the v3 enum same works if you only want v2 quotes
// if you do not supply anything it query both v2 and v3
uniswapVersions : [
UniswapVersion.v2,
UniswapVersion.v3
]
})
});

findBestRoute method returns wrong value for expected amount

try {
        const uniswapPairFactory = await uniswapPair.createFactory();
        const result = await uniswapPairFactory.findBestRoute(
            amount,
            TradeDirection.input
        );

        return {
            path: result.bestRouteQuote.routePathArray,
            expectedOutput:
                result.bestRouteQuote
                    .expectedConvertQuoteOrTokenAmountInMaxWithSlippage,
        };
    } catch (error) {
        console.log("error: ", error);
        throw error;
    }

I used cloneUniswapContractDetails to make this works on cronos chain and every things works fine. but for a particular token, the result.bestRouteQuote.expectedConvertQuoteOrTokenAmountInMaxWithSlippage gives a very wrong value

[UniswapError: invalid from or to contract tokens]

const uniswapPair = new UniswapPair({
    // the contract address of the token you want to convert FROM
    fromTokenContractAddress: '0x419D0d8BdD9aF5e606Ae2232ed285Aff190E711b',
    // the contract address of the token you want to convert TO
    toTokenContractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
    // the ethereum address of the user using this part of the dApp
    ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
    chainId: ChainId.RINKEBY,
  });
    // now to create the factory you just do
    const uniswapPairFactory = await uniswapPair.createFactory();
    //the amount is the proper entered amount
    // so if they enter 10 pass in 10
    // it will work it all out for you
    const trade = await uniswapPairFactory.trade(10);

I try to get the trade information but it always shows the error: invalid from or to contract tokens.

Please help to check it.

Thanks

Error for token dForce that works on uniswap app

The following findBestRoute fails for token with address 0x431ad2ff6a9C365805eBaD47Ee021148d6f7DBe0, but works on uniswap app. The error is likely related to symbol and name of the contract being a bytes32 instead of string.
https://etherscan.io/address/0x431ad2ff6a9C365805eBaD47Ee021148d6f7DBe0#readContract

Error: UniswapError: invalid from or to contract tokens

Example:

  const fromTokenContractAddress = ETH.MAINNET().contractAddress;
  const toTokenContractAddress = '0x431ad2ff6a9C365805eBaD47Ee021148d6f7DBe0'; 
  
  const ethereumAddress = '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9';

  const uniswapPair = new UniswapPair({
    fromTokenContractAddress,
    toTokenContractAddress,
    ethereumAddress,
    chainId: ChainId.MAINNET,
  });

  const uniswapPairFactory = await uniswapPair.createFactory();

  const trade = await uniswapPairFactory.findBestRoute(
    '0.00000000001',
    TradeDirection.input
  );

sdk creates trade but transaction doesn't happen

it seems to retrieve tokens successfully and my balance from kovan testnet. but I can't see the transaction in my metamask wallet.

image

Is there an additional function that I need to use to confirm the transaction?

Can't use with vite

In a vue + ts + vite setup, importing this module gives the following error:

Module "stream" has been externalized for browser compatibility and cannot be accessed in client code.

Trades not working - insufficient funds for gas * price + value

Hello.

I'm trying to use simple-uniswap-sdk to execute trades on Uniswap.
The library seems to be awesome, but I'm facing some issues using it.
Here is the code:

import simpleUniswapSdk from 'simple-uniswap-sdk';

const {ChainId, UniswapPair} = simpleUniswapSdk;

import Web3 from 'web3';

const PRIVATE_KEY = "XXXXXXXXXXX";
const ADDRESS = "XXXXXXXXXXX";
const FROM_TOKEN = "0xdac17f958d2ee523a2206206994597c13d831ec7";
const TO_TOKEN = "0x85eee30c52b0b379b046fb0f85f4f3dc3009afec";
const AMOUNT = '10';
const PROVIDER_URL = "https://mainnet.infura.io/v3/XXXXXXXXXXX";

const web3TradeExample = async () => {
  const uniswapPair = new UniswapPair({
    // the contract address of the token you want to convert FROM
    fromTokenContractAddress: FROM_TOKEN,
    // the contract address of the token you want to convert TO
    toTokenContractAddress: TO_TOKEN,
    // the ethereum address of the user using this part of the dApp
    ethereumAddress: ADDRESS,
    // you can pass in the provider url as well if you want
    providerUrl: PROVIDER_URL,
    chainId: ChainId.MAINNET,
  });

  // now to create the factory you just do
  const uniswapPairFactory = await uniswapPair.createFactory();
  const web3 = new Web3(uniswapPairFactory.providerUrl);

  // the amount is the proper entered amount
  const trade = await uniswapPairFactory.trade(AMOUNT);
  trade.transaction.gas = 30000;
    console.log(trade);

  if (!trade.fromBalance.hasEnough) {
    throw new Error('You do not have enough from balance to execute this swap');
  }
  trade.quoteChanged$.subscribe((value) => {
    // value will hold the same info as below but obviously with
    // the new trade info.
  });

  if (trade.approvalTransaction) {
    trade.approvalTransaction.gas = 30000;
console.log(trade.approvalTransaction);
    const signedTransaction = await web3.eth.accounts.signTransaction(
      trade.approvalTransaction,
      PRIVATE_KEY
    );

    console.log('signedTransaction');
    console.log(signedTransaction);
    if (!signedTransaction.rawTransaction) {
      throw new Error('Could not find tx');
    }

    web3.eth
      .sendSignedTransaction(signedTransaction.rawTransaction)
      .once('transactionHash', (transactionHash) => {
        console.log('approved txHash', transactionHash);
      })
      .once('receipt', async (receipt) => {
        console.log('approved receipt', receipt);
        await executeTrade(web3, trade);
      })
      .on('error', async (error) => {
        console.log(`ERROR ${error.message}`);
      });
  } else {
    console.log(
      'already has approved uniswap to move tokens on your behalf or its eth > erc20 token swap'
    );
    await executeTrade(web3, trade);
  }
};

const executeTrade = async (web3, trade) => {
  const signedTransaction = await web3.eth.accounts.signTransaction(
    trade.transaction,
    PRIVATE_KEY
  );
console.log('executeTrade signedTransaction')
console.log(signedTransaction)

  if (!signedTransaction.rawTransaction) {
    throw new Error('Could not find tx');
  }

  web3.eth
    .sendSignedTransaction(signedTransaction.rawTransaction)
    .once('transactionHash', (transactionHash) => {
      console.log('trade txHash', transactionHash);
    })
    .once('receipt', (receipt) => {
      console.log('trade receipt', receipt);
      // once done with trade aka they have sent it and you don't need it anymore call
      trade.destroy();
    })
    .on('error', async (error) => {
      console.log(`ERROR ${error.message}`);
    });
};

web3TradeExample();

And the output:

...
fromBalance: { hasEnough: true, balance: '91.085433' },
...
ERROR Returned error: insufficient funds for gas * price + value

Could you please explain what I'm doing wrong? Thanks in advance.

Disable multicall for debug proposes

Hello!

The L2 solution that I'm currently using does not support the multicall v2 contract, so I've disabled the tryAggregate option (it would be useful if it could be set without forking the repo). So I have deployed the multicall v1 version.
There is another problem with the library output. The errors are confusing and it would be useful to add the debug toggle to provide more info for debugging.
The main question is that is it possible to disable multicall? With the following errors, it is almost impossible to determine what is going wrong.

 [error] call revert exception (method="aggregate((address,bytes)[])", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.5.0)

 [error] Error: call revert exception (method="aggregate((address,bytes)[])", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.5.0)
    at Logger.makeError (/project/node_modules/ethereum-multicall/node_modules/@ethersproject/logger/lib/index.js:199:21)
    at Logger.throwError (/project/node_modules/ethereum-multicall/node_modules/@ethersproject/logger/lib/index.js:208:20)
    at Interface.decodeFunctionResult (/project/node_modules/ethereum-multicall/node_modules/@ethersproject/abi/lib/interface.js:384:23)
    at Object.<anonymous> (/project/node_modules/ethereum-multicall/node_modules/@ethersproject/contracts/lib/index.js:390:56)
    at step (/project/node_modules/ethereum-multicall/node_modules/@ethersproject/contracts/lib/index.js:48:23)
    at Object.next (/project/node_modules/ethereum-multicall/node_modules/@ethersproject/contracts/lib/index.js:29:53)
    at fulfilled (/project/node_modules/ethereum-multicall/node_modules/@ethersproject/contracts/lib/index.js:20:58)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

By the way, thanks again for your awesome project!

Invalid from or to address on custom chain?

Both of these addresses definitely exist, but INIT_CODE_HASH on this chan is likely different, so the pair calculation is likely different. Any idea what this error could mean? This is when i make a new UniswapPair and run createFactory on a non-eth chain. I don't have a canonical Multicall address here so I left that blank, is that OK? Or should I deploy my own multicall contract?

Invalid from or to contract tokens

Hi!

I get this error when I make a new UniswapPair and run createFactory on Arbitrum Goerli (chainId === 421613). I have added multicallContractAddress and cloneUniswapContractDetails, but it still doesn't work. And can i skip nativeCurrency and nativeWrappedTokenInfo ?

So, maybe you can see what the problem is ? Thanks !

Screenshot 2023-07-25 at 11 05 10

not working on goerli test network?

const uniswapPair = new UniswapPair({
fromTokenContractAddress: '0xf74a5ca65e4552cff0f13b116113ccb493c580c5',
toTokenContractAddress: '0x2ac3c1d3e24b45c6c310534bc2dd84b5ed576335',
chainId: ChainId.Gร–RLI,
...
})
which returns

UniswapError: invalid from or to contract tokens

Those goerli tokens are from https://explorer.bitquery.io/goerli/tokens which should be valid

How to use native currency on custom network (Arbitrum 42161, Sepolia 11155111, Arbitrum Sepolia 421614)

Failed to trade ETH on custom network. Does anybody know where might be a problem ?

Tried to add _ETH to Sepolia WETH contract (0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14_ETH), but it didn't help.

This is Sepolia network config:

{
chainId: 11155111,
layerZeroChainId: 10161,
network: 'sepolia',
currency: 'ETH',
networkName: 'Sepolia Testnet',
networkNameForAllEnv: NetworksEnum.Sepolia,
explorerUrl: 'https://sepolia.etherscan.io',
apiEndpoint: 'https://api-dev.dev-landx.be/api',
infuraApiKey: 'aaabaa1e74ac4192859455ead7ca6cdd',
providerUrl: 'https://sepolia.infura.io/v3/aaabaa1e74ac4192859455ead7ca6cdd',
contracts: sepoliaDev,
rpcUrl: 'https://ethereum-sepolia-rpc.publicnode.com',
isDefault: true,
isTradeShown: true,
lndxSwapTokensList: [TOKENS.ETH, TOKENS.USDC, TOKENS.USDT],
customChain: {
cloneUniswapContractDetails: {
v3Override: {
routerAddress: '0x9990933B23c0D4e23dA4cb8096A478D42e687CE8',
factoryAddress: '0x0227628f3F023bb0B980b67D528571c95c6DaC1c',
quoterAddress: '0x6Aab9B15DA9Df02b22C8E79a0a5527E520E7D009',
},
},
customNetwork: {
nameNetwork: 'Sepolia',
multicallContractAddress: '0xcA11bde05977b3631167028862bE2a173976CA11',
nativeCurrency: {
name: 'ETH Token',
symbol: 'ETH',
},
nativeWrappedTokenInfo: {
chainId: 11155111,
contractAddress: '0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14',
decimals: 18,
symbol: 'WETH',
name: 'Wrapped ETH',
},
},
},
},

===========

This is Trade method:

public tradeInfo(
chainId: number,
amount: number,
fromTokenContractAddress: string,
toTokenContractAddress: string,
ethereumAddress: string,
network: NetworkInterface,
tradeDirection: TradeDirection = TradeDirection.input,
): Observable {
return new Observable((subscriber: Subscriber) => {
(async () => {
try {
let uniswapPair: UniswapPair;

      if (network?.customChain) {
        uniswapPair = new UniswapPair({
          fromTokenContractAddress,
          toTokenContractAddress,
          ethereumAddress,
          ethereumProvider: this.walletConnectService.walletProvider,
          settings: new UniswapPairSettings({
            slippage: 0.005,
            deadlineMinutes: 20,
            disableMultihops: false,
            uniswapVersions: [UniswapVersion.v3],
            cloneUniswapContractDetails: network.customChain.cloneUniswapContractDetails,
            customNetwork: network.customChain.customNetwork,
          }),
        });
      } else {
        uniswapPair = new UniswapPair({
          fromTokenContractAddress,
          toTokenContractAddress,
          ethereumAddress,
          chainId,
          settings: new UniswapPairSettings({
            slippage: 0.005,
            deadlineMinutes: 20,
            disableMultihops: false,
            uniswapVersions: [UniswapVersion.v2, UniswapVersion.v3],
          }),
        });
      }

      uniswapPair.createFactory()
        .then((factory) => factory.trade(amount.toString(), tradeDirection).catch((error) => {
          console.log(error);
          subscriber.error(error);
          return undefined;
        })).catch((error) => {
          console.log(error);
          subscriber.error(error);
          return undefined;
        })
        .then((trade) => {
          subscriber.next(trade);
          if (trade) {
            trade.destroy();
          }
        })
        .catch((error) => {
          console.log(error);
          subscriber.error(error);
        });
    } catch (error) {
      console.log(error);
      subscriber.error(new Error('errors.contract_error'));
    }
  })();
});

}

Output trade fails on Uniswap V2

I found a potential bug in the code used to get the amountInMax:

https://github.com/uniswap-integration/simple-uniswap-sdk/blob/1629b680e615ce9851a4f7e7a3ba0187beac8261/src/factories/router/uniswap-router.factory.ts#L1935

Not sure why there's a check there for UniswapVersion.v3, but seems like this line causes output trades on Uniswap V2 to fail with EXCESSIVE_INPUT_AMOUNT because it subtracts the slippage, resulting in an amountInMax value lower than the expected amount.

Probably related to issue: #28

bug(avalanche): native token _ETH is not valid

I'm using the simple-uniswap-sdk and your angular swap on the AVALANCHE main net. But there are problems with the NATIVE token.

My config is mainly this:

(customNetworkData = {
          nameNetwork: 'Avalanche',
          multicallContractAddress: '0xed386Fe855C1EFf2f843B910923Dd8846E45C5A4',
          nativeCurrency: {
              name: 'AVAX',
              symbol: 'AVAX',
          },
          nativeWrappedTokenInfo: {
              chainId: 43114,
              contractAddress: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7',
              decimals: 18,
              symbol: 'AVAX', // WAVAX
              name: 'AVAX' // Wrapped AVAX
          },
          baseTokens: {
              usdt: {
                  chainId: 43114,
                  contractAddress: '0xc7198437980c041c805A1EDcbA50c1Ce5db95118',
                  decimals: 6,
                  symbol: 'USDT.e',
                  name: 'USDT.e'
              },
              usdc: {
                  chainId: 43114,
                  contractAddress: '0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664',
                  decimals: 6,
                  symbol: 'USDC.e',
                  name: 'USDC.e'
              },
              wbtc: {
                  chainId: 43114,
                  contractAddress: '0x152b9d0fdc40c096757f570a51e494bd4b943e50',
                  decimals: 8,
                  symbol: 'BTC.b',
                  name: 'BTC.b'
              }
          }
      });

and

this.uniswapDappSharedLogicContext  = {
      supportedNetworkTokens: [
        {
          chainId: 43114,
          // 0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7_ETH
          defaultInputToken: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E', // USDC
          defaultOutputToken: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7_ETH', // FOOK
          supportedTokens: [
            { contractAddress: '0x95923F63dA09B4f7520f7C65a31F318D8228B744', tokenImageContext: { image: tokens.fook.logo , isSvg: false } }, // FOOK
            { contractAddress: '0x71124b9199B97E0E232Aee3909e3B0eC28402611', tokenImageContext: { image: tokens.fook.logo, isSvg: false } }, // FOOKF
            { contractAddress: '0x27301e48aF707F950765d5570d7279a6e3E3BC5B', tokenImageContext: { image: tokens.fookz.logo, isSvg: false } }, // FOOKZ
            { contractAddress: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E', tokenImageContext: { image: tokens.usdc.logo, isSvg: false } }, // USDC
            { contractAddress: '0x152b9d0fdc40c096757f570a51e494bd4b943e50', tokenImageContext: { image: tokens.wbtc.logo, isSvg: false } }, // BTC.b
            // { contractAddress: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7_ETH', tokenImageContext: { image: tokens.avax.logo , isSvg: false } }, // AVAX
            { contractAddress: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7', tokenImageContext: { image: tokens.avax.logo , isSvg: false } } // AVAX
            // { contractAddress: '0xc7198437980c041c805A1EDcbA50c1Ce5db95118' }, // USDT.e
            // { contractAddress: '0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664' } // USDC.e
          ]
        }
      ],
      ethereumAddress: userAddress,
      ethereumProvider: this.web3Service.provider,
      providerUrl: providerUrl,
      settings: new UniswapPairSettings({
          slippage: 0.005,
          deadlineMinutes: 15,
          disableMultihops: false,
          uniswapVersions: [UniswapVersion.v2],
          cloneUniswapContractDetails: targets,
          customNetwork: customNetworkData
      })
  }

It seems that the logic is adding a "_ETH" at the Wrapped WAVAX token address. But once I choose to use this "_ETH" token for the from or to token, so to swap AVAX to another tooken I run into the issue

ERROR Error: Uncaught (in promise): UniswapError: invalid from or to contract tokens
UniswapError: invalid from or to contract tokens
    at new UniswapError (uniswap-error.js:17:28)
    at TokensFactory.<anonymous> (tokens.factory.js:123:31)
    at step (tokens.factory.js:32:23)
    at Object.next (tokens.factory.js:13:53)

@joshstevens19 @liu-zhipeng @vm06007

Work for GetAmountIn

I think this sdk will work for when user entered amount in the first field ,so that we are getting the path of highest amount out of all,But if user entered in the second field we need to get the path which gives lowest amount IN

How to support more chainId๏ผŸ

my code:

// use custom provider:
// Network Name: Heco-Mainnet
// New RPC URL: https://http-mainnet-node.huobichain.com
// ChainID: 128
// Symbol: HT
// Block Explorer URL: https://hecoinfo.com
const rpc_url = "https://http-mainnet-node.huobichain.com";
const provider = new ethers.providers.JsonRpcProvider(rpc_url);

const uniswapPair = new uniswapSimple.UniswapPair({
        fromTokenContractAddress: "0xa71edc38d189767582c38a3145b5873052c3e47a",
        toTokenContractAddress: "0x5545153ccfca01fbd7dd11c0b23ba694d9509a6f",
        ethereumAddress: ethereumAddress,
        ethereumProvider: provider
        // providerUrl: rpc_url,
        // chainId: 128,
});

// throw error
const uniswapPairFactory = await uniswapPair.createFactory();

error:

Error [UniswapError]: ChainId - 128 is not supported. This lib only supports mainnet(1), ropsten(4), kovan(42), rinkeby(4), gรถrli(5) and ropsten(3)

Should I change sdk source code?

Base Network support

How can we use the base network with this package?

I have defined customNetwork and cloneUniswapContractDetails, but when I try to use them, I get the message:

Can not find chain name for 8453. This lib only supports mainnet(1), ropsten(4), kovan(42), rinkeby(4) and gรถrli(5)

This is my config:

 const uniswapPair = new UniswapPair({
  fromTokenContractAddress: "0x4200000000000000000000000000000000000006",
  toTokenContractAddress: "0x347F500323D51E9350285Daf299ddB529009e6AE",
  ethereumAddress: selectedAddress,
  ethereumProvider: metaMaskProvider,
  chainId: 8453,
  settings: new UniswapPairSettings({
   cloneUniswapContractDetails: {
    v2Override: {
     factoryAddress: "0x8909Dc15e40173Ff4699343b6eB8132c65e18eC6",
     routerAddress: "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD",
     pairAddress: "0x0Aa352230c5C05Fa912DAC0B538551f79121e29B",
    },
    v3Override: {
     factoryAddress: "0x33128a8fC17869897dcE68Ed026d694621f6FDfD",
     routerAddress: "0x2626664c2603336E57B271c5C0b26F421741e481",
     quoterAddress: "0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",
    },
   },
   customNetwork: {
    nameNetwork: "Base Mainnet",
    multicallContractAddress: "0x275617327c958bD06b5D6b871E7f491D76113dd8",
    nativeCurrency: {
     name: "Ether",
     symbol: "ETH",
    },
    nativeWrappedTokenInfo: {
     chainId: 8453,
     contractAddress: "0x4200000000000000000000000000000000000006",
     decimals: 18,
     symbol: "WETH",
     name: "Wrapped ETH",
    },
   },
   slippage: 0.0005,
   deadlineMinutes: 10,
   uniswapVersions: [UniswapVersion.v2, UniswapVersion.v3],
  }),
 });

Has anyone used this package with Base network? If so, could you kindly provide the configuration you used?
That would greatly help us; we have been struggling with the Uniswap SDK for almost a month now. We just want to use code to trade, and this package is our last hope. =/

Allow to override tradePath

I'm trying to execute trades from WETH -> other tokens, and I really want to use the WETH that the account already owns.
It seems that the automatic getTradePath then always makes the transaction between unwrapped ETH -> token. For my purpose it would be great if the tokenpair (or createFactory) has an optional parameter to force the tradepath to stay erc20ToErc20 even though one of the tokens is WETH.

Error with MKR token routing

image

Seeing this above error when I try to get routes from MKR token. Here's the code snippet:

const { UniswapPair, ChainId, UniswapVersion, UniswapPairSettings } = require('simple-uniswap-sdk')
const uniswapPair = new UniswapPair({
  fromTokenContractAddress: '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2', //mkr token
  toTokenContractAddress: '0xdac17f958d2ee523a2206206994597c13d831ec7', //usdt token
  ethereumAddress: '0x4cb2b6dcb8da65f8421fed3d44e0828e0abcda60',
  chainId: ChainId.MAINNET,
  settings: new UniswapPairSettings({
    slippage: 0.005,
    deadlineMinutes: 20,
    disableMultihops: false,
    uniswapVersions: [UniswapVersion.v2],
  })
})

const doWork = async () => {
  const uniswapPairFactory = await uniswapPair.createFactory()
  const trade = await uniswapPairFactory.trade('1')
  console.log('TRADE ', trade.transaction)
  console.log('Trade Route', trade.routeText)
  trade.destroy()
}

doWork()

using this sdk on polygon

hello,

is there a special chain id when im on the polygon network? i keep getting SushiswapError: invalid from or to contract tokens

when i do -

////sushiswap
const sushiswapPair = new SushiswapPair({
// the contract address of the token you want to convert FROM
fromTokenContractAddress: '0x111111111117dC0aa78b770fA6A738034120C302',
// the contract address of the token you want to convert TO
toTokenContractAddress: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
// the ethereum address of the user using this part of the dApp
ethereumAddress: '0xB1E6079212888f0bE0cf55874B2EB9d7a5e02cD9',
// you can pass in the provider url as well if you want
providerUrl: url,
chainId: ChainId.MAINNET,
});

// now to create the factory you just do
const sushiswapPairFactory = await sushiswapPair.createFactory();

const toToken = sushiswapPairFactory.toToken;
console.log("toToken", sushiswapPairFactory);

Liquidity pool support?

This SDK has made exchanging tokens easier in Metamask, thank you.

I'm looking for liquidity pool support, where I can get real usable price comparison data for arbitrage opportunities. I see a pools reference in src/factories/uniswap-factory/v3/uniswap-contract.factory.v3.ts but I don't see any related examples. Any additional info on this for this SDK please, and if so, how cold I subscribe to a pool price update event?

Or am I really completely missing something here?

Polygon Main/Mumbai Contracts

Edit: I went with Uniswap instead of Sushi.

I am having a hard time finding the SushiSwap Router, Factory and Multicall contract addresses for these chains. I got all the other chains to work. Anyone have any luck?

Here are the addresses I have tried, mixed together in different ways

MultiCall
0xef0881ec094552b2e128cf945ef17a6752b4ec5d
0xc2edad668740f1aa35e4d8f227fb8e17dca888cd

Router
0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F
0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506

Factory/Pair
0xf1c9881Be22EBF108B8927c4d197d126346b5036
0xc35DADB65012eC5796536bD9864eD8773aBc74C4

Here are the other contracts that work, I am sure they will help someone.

BSC Main PancakeSwap
{ multicallContractAddress: '0x65e9a150e06c84003d15ae6a060fc2b1b393342c', cloneUniswapContractDetails: { v2Override: { routerAddress: '0x10ED43C718714eb63d5aA57B78B54704E256024E', factoryAddress: '0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73', pairAddress: '0xca143ce32fe78f1f7019d7d551a6402fc5350c73' } } }

BSC Testnet PancakeSwap
{ multicallContractAddress: '0x8F3273Fb89B075b1645095ABaC6ed17B2d4Bc576', cloneUniswapContractDetails: { v2Override: { routerAddress: '0xD99D1c33F9fC3444f8101754aBC46c52416550D1', factoryAddress: '0x6725F303b657a9451d8BA641348b6761A6CC7a17', pairAddress: '0x6725F303b657a9451d8BA641348b6761A6CC7a17' } } }

Pulse Chain Testnet Uniswap
{ multicallContractAddress: '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696', cloneUniswapContractDetails: { v2Override: { routerAddress: '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D', factoryAddress: '0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95', pairAddress: '0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95' } } }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.