Giter VIP home page Giter VIP logo

paraswap-sdk's Introduction

SDK for the ParaSwap API

Refer to the documentation of the ParaSwap API: https://developers.paraswap.network

Features

Versatility: works with both web3 and ethers without direct dependency

Canonical: bring only the functions you actually need

Lightweight: 400B Gzipped for the minimal variant

Installing ParaSwap SDK

yarn add @paraswap/sdk

Using ParaSwap SDK

There are multiple ways to use ParaSwap SDK, ranging from a simple construct-and-use approach to a fully composable bring what you need approach which allows for advanced tree-shaking and minimizes bundle size.

Simple SDK

Can be created by providing chainId and either axios or window.fetch (or alternative fetch implementation). The resulting SDK will be able to use all methods that query the API.

  import { constructSimpleSDK } from '@paraswap/sdk';
  import axios from 'axios';

  // construct minimal SDK with fetcher only
  const paraSwapMin = constructSimpleSDK({chainId: 1, axios});
  // or
  const paraSwapMin = constructSimpleSDK({chainId: 1, fetch: window.fetch});

  const ETH = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
  const DAI = '0x6B175474E89094C44Da98b954EedeAC495271d0F';

  async function swapExample() {
    //                                     or any other signer/provider 
    const signer: JsonRpcSigner = ethers.Wallet.fromMnmemonic('__your_mnemonic__');
    const senderAddress = signer.address;

    const priceRoute = await paraSwapMin.swap.getRate({
      srcToken: ETH,
      destToken: DAI,
      amount: srcAmount,
      userAddress: senderAddress,
      side: SwapSide.SELL,
    });

    const txParams = await paraSwapMin.swap.buildTx(
      {
        srcToken,
        destToken,
        srcAmount,
        destAmount,
        priceRoute,
        userAddress: senderAddress,
        partner: referrer,
      }     
    );

    const transaction = {
      ...txParams,
      gasPrice: '0x' + new BigNumber(txParams.gasPrice).toString(16),
      gasLimit: '0x' + new BigNumber(5000000).toString(16),
      value: '0x' + new BigNumber(txParams.value).toString(16),
    };

    const txr = await signer.sendTransaction(transaction);
  }

If optional providerOptions is provided as the second parameter, then the resulting SDK will also be able to approve Tokens for swap.

  // with ethers.js
  const providerOptionsEther = {
    ethersProviderOrSigner: provider, // JsonRpcProvider
    EthersContract: ethers.Contract,
    account: senderAddress,
  };

  // or with web3.js
  const providerOptionsWeb3 = {
    web3, // new Web3(...) instance
    account: senderAddress,
  };

  const paraSwap = constructSimpleSDK({chainId: 1, axios}, providerOptionsEther);

  // approve token through sdk
  const txHash = await paraSwap.approveToken(amountInWei, DAI);

  // await tx somehow
  await provider.waitForTransaction(txHash);

Full SDK

import { constructFullSDK, constructAxiosFetcher, constructEthersContractCaller } from '@paraswap/sdk';

const signer = ethers.Wallet.fromMnmemonic('__your_mnemonic__'); // or any other signer/provider 
const account = '__signer_address__';

const contractCaller = constructEthersContractCaller({
  ethersProviderOrSigner: signer,
  EthersContract: ethers.Contract,
}, account); // alternatively constructWeb3ContractCaller
const fetcher = constructAxiosFetcher(axios); // alternatively constructFetchFetcher

const paraswap = constructFullSDK({
  chainId: 1,
  fetcher,
  contractCaller,
});

Partial SDK

For bundle-size savvy developers, you can construct a lightweight version of the SDK and bring only the functions you need.

e.g. for only getting rates and allowances:

import { constructPartialSDK, constructFetchFetcher, constructGetRate, constructGetBalances } from '@paraswap/sdk';

const fetcher = constructFetchFetcher(window.fetch);

const minParaSwap = constructPartialSDK({
  chainId: 1,
  fetcher,
}, constructGetRate, constructGetBalances);

const priceRoute = await minParaSwap.getRate(params);
const allowance = await minParaSwap.getAllowance(userAddress, tokenAddress);

Legacy

The ParaSwap class is exposed for backwards compatibility with previous versions of the SDK.

import { ParaSwap } from '@paraswap/sdk';
import axios from 'axios';
import Web3 from 'web3';

const web3Provider = new Web3(window.ethereum);
const account = '__user_address__';

const paraswap = new ParaSwap({chainId: 1, web3Provider, account, axios});

Or you can use ethers in place of web3

import { ParaSwap } from '@paraswap/sdk';
import { ethers } from "ethers";

const ethersProvider = new ethers.providers.Web3Provider(window.ethereum)
const account = '__user_address__';

const paraswap = new ParaSwap({
  chainId: 1,
  account,
  ethersDeps: {
    ethersProviderOrSigner: ethersProvider;
    EthersContract: ethers.Contract;
  },
  fetch: window.fetch,
 });

By analogy to constructPartialSDK, you can leverage a lightweight version of the sdk for fetching only.

import { ParaSwap } from '@paraswap/sdk';

const paraswap = new ParaSwap({chainId: 1, fetch: window.fetch});

Refer to this README for depecreated documentation for functions usage.

Refer to SDK API documentation for detailed documentation on the methods provided in this SDK.

Tests

To run yarn test it is necessary to provide PROVIDER_URL=<mainnet_rpc_url> environment variable. If it is necessary to run tests against a different API endpoint, provide API_URL=url_to_API environment variable.

paraswap-sdk's People

Contributors

aburkut avatar alethander avatar alexshchur avatar anxolin avatar cbrzn avatar colonelj avatar dependabot[bot] avatar fadomire avatar khangle27 avatar mindrunner avatar mounibec avatar mwamedacen avatar nduchak avatar oshchurtt avatar ppoliani avatar sakulstra avatar sameepsi avatar samthomson avatar shresthagrawal avatar velenir avatar verisana avatar xiphiness 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

paraswap-sdk's Issues

transactions api in v5 will throw a generic 400 when the deadline parameter has expired

I've found the transactions API to have a very consistent contract with strong validation until I ran into a scenario where I was only receiving "error: unable to process transaction" as a 400...nothing else. When i executed the OpenAPI example in the docs, the transactions api received a 200.

I had to work backwards comparing the two payloads until I landed here to realize the "deadline" parameter was involved. It would be helpful if explicit, clear validation was provided to enhance the user experience.

image

seems like it doesn't support etherjs's provider?

im using etherjs and i want to use paraswap sdk but i found some function send transaction using web3 provider, for example approveToken actually i just need to know the approve that contract address. i prefer to use some interface like buildTx which did not depend on any other libs

Confusion in usage and documentation of query parameters for transactions api in v5

I'm not really sure of the use case and decision behind making the transactions API do a GET operation with a POST call. Provided two layers of parameters, those for use in the body and others for use as query parameters further adds confusion since POST requests traditionally do not use query parameters. To illustrate how its easy to be confused, in the below screenshot you will see that I have included the query parameters for "ignoreChecks" yet the API still informed me I dont have enough for the transaction. This was because, by default, I put the "ignoreChecks" parameter in the body payload as well and forgot about it. If you include the ignoreChecks parameter in both the querystring and body, it will no longer consider the fact its included in the querystring. This is a bug and has room for improvement.

image

Avalanche Only Supports Old WBTC Bridge

I'm trying to use the SDK with the Avalanche network. When I list the available tokens with getTokens() the only version of WBTC available is 0x408D4cD0ADb7ceBd1F1A1C33A0Ba2098E1295bAB(which is the old WBTC bridge), however, it's clear that the new WBTC.e bridge version (at address 0x50b7545627a5162F82A992c33b87aDc75187B218 is allowed since it appears on the web interface for Paraswap on Avalanche. This seems like a problem with the SDK.

Here is snowtrace link for context (https://snowtrace.io/address/0x408d4cd0adb7cebd1f1a1c33a0ba2098e1295bab)

Impossible to make it work

I'm following the sdk but it's impossible for me to make the software work.

Im using this code:

   const priceRoute = await paraSwapMin.swap.getRate({
        srcToken: USDT,
        destToken: CAKE,
        amount: srcAmount,
        userAddress: wallet.address,
        side: SwapSide.SELL,
        options: {
            otherExchangePrices: true,
        }
    });

    console.log(priceRoute)

    const { bestRoute, others } = priceRoute;
    const swapExchange = bestRoute[0]?.swaps[0]?.swapExchanges[0];
    console.log("Swap Exchange: " + swapExchange.exchange)
    console.log("GAS USD: " + swapExchange.data.gasUSD)


    const destAmountFixed = new BigNumber(priceRoute.destAmount).times(0.99).toFixed(0); //get a little lower.
    const txParams = await paraSwapMin.swap.buildTx(
        {
            USDT,
            CAKE,
            srcAmount,
            destAmountFixed,
            priceRoute,
            userAddress: wallet.address,
            partner: 'sdk-test',
        }
    );

    const transaction = {
        ...txParams,
        gasPrice: '0x' + new BigNumber(txParams.gasPrice).toString(16),
        gasLimit: '0x' + new BigNumber(5000000).toString(16),
        value: '0x' + new BigNumber(txParams.value).toString(16),
    };

const txResponse = await wallet.sendTransaction(transaction);
    console.log(txResponse)
    const receipt = await txResponse.wait()

and although it's exact like the manual (and the test) i get data: { error: 'Validation failed: "srcToken" is required' }
I tried to add the key names as well, and it bypasses this error but then later i get

reason: 'chainId address mismatch',
code: 'INVALID_ARGUMENT',
argument: 'transaction',

Don't know what is the problem.

Problem with buildTx apiv5

Hey!

I noticed a strange error, the buildTx method always returns the error "The rate has changed, please re-query the latest Price"
This error always occurs when exchanging stablecoins. In example: Network(Polygon), USDC/DAI

Also, if when initializing the class new ParaSwap(137, 'https://api.paraswap.io') with an address not on apiv5, then the same method with the same parameters was created successfully once, but then again the same error

Code example:

const paraSwap = new ParaSwap(137, 'https://api.paraswap.io')
const priceRoute: OptimalRate = await paraSwap.getRate(
       0x2791bca1f2de4661ed88a30c99a7a9449aa84174,
       0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063,
       1000000,
       side: SELL,
       network: 137
)

const txParams = await paraSwap.buildTx(
        0x2791bca1f2de4661ed88a30c99a7a9449aa84174,
        0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063,
        100000,
        99835030397689696,
        priceRoute,
        userAddress,
)

Response: error: "The rate has changed, please re-query the latest Price"

Cannot Swap & Send when doing a BUY transaction

Hi, we are integrating paraswap and it seems to work fine in SELL cases, however when attempting to do a BUY transaction with a swap & send functionality (receiver is different), It throws an error saying Got an error when building a TX: This transaction has some errors and may fail. Please contact support for more details

Ethereum ROPSTEN: This transaction has some errors and may fail. Please contact support for more details

Ethereum mainet && Polygon works, but in Testnet (Ethereum Ropsten) it breaks.

Error:

image


transactionRequestOrError {
  status: 500,
  message: 'This transaction has some errors and may fail. Please contact support for more details',
  data: {
    error: 'This transaction has some errors and may fail. Please contact support for more details'
  }
}

Code example:

import { ParaSwap, NetworkID } from "paraswap";

import BigNumber from "bignumber.js";
import { OptimalRate, SwapSide } from "paraswap-core";

const USER_ADDRESS = {
  ropsten: "0xE1c5b0F5B85f0Fad577377cb242098f5d730dead",
  mainnet: "0xBaeD383EDE0e5d9d72430661f3285DAa77E9439F",
  polygon: "0x7a0FCdC56cC29Af0bf9FeB289b337085C3CAE2C3"
};

const PARTNER = "chucknorris";
const SLIPPAGE = 1; // 1%

enum Networks {
  MAINNET = 1,
  POLYGON = 137,
  ROPSTEN = 3
}

interface MinTokenData {
  decimals: number;
  symbol: string;
  address: string;
}

const web3ProividersURLs: Partial<Record<number, string>> = {
  [Networks.MAINNET]:
    "https://mainnet.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161",
  [Networks.POLYGON]: "https://polygon-rpc.com",
  [Networks.ROPSTEN]:
    "https://ropsten.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161"
};

const tokens: Record<number, MinTokenData[]> = {
  [Networks.MAINNET]: [
    {
      decimals: 18,
      symbol: "ETH",
      address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
    },
    {
      decimals: 6,
      symbol: "USDC",
      address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
    },
    {
      decimals: 18,
      symbol: "DAI",
      address: "0x6B175474E89094C44Da98b954EedeAC495271d0F"
    },
    {
      decimals: 18,
      symbol: "WETH",
      address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
    }
  ],
  [Networks.POLYGON]: [
    {
      decimals: 18,
      symbol: "MATIC",
      address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
    },
    {
      decimals: 8,
      symbol: "WBTC",
      address: "0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6"
    }
  ],
  [Networks.ROPSTEN]: [
    {
      decimals: 18,
      symbol: "ETH",
      address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
    },
    {
      decimals: 18,
      symbol: "WETH",
      address: "0xc778417E063141139Fce010982780140Aa0cD5Ab"
    },
    {
      decimals: 18,
      symbol: "DAI",
      address: "0xaD6D458402F60fD3Bd25163575031ACDce07538D"
    }
  ]
};

function getToken(symbol: Symbol, networkID: Networks): MinTokenData {
  const token = tokens[networkID]?.find((t) => t.symbol === symbol);

  if (!token)
    throw new Error(`Token ${symbol} not available on network ${networkID}`);
  return token;
}

/**
 * @type ethereum address
 */
type Address = string;
/**
 * @type Token symbol
 */
type Symbol = string;
/**
 * @type number as string
 */
type NumberAsString = string;

interface TransactionParams {
  to: Address;
  from: Address;
  value: NumberAsString;
  data: string;
  gasPrice: NumberAsString;
  gas?: NumberAsString;
  chainId: number;
}

interface Swapper {
  getRate(params: {
    srcToken: Pick<MinTokenData, "address" | "decimals">;
    destToken: Pick<MinTokenData, "address" | "decimals">;
    srcAmount: NumberAsString;
    userAddress: Address;
    partner?: string;
  }): Promise<OptimalRate>;
  buildSwap(params: {
    srcToken: Pick<MinTokenData, "address" | "decimals">;
    destToken: Pick<MinTokenData, "address" | "decimals">;
    srcAmount: NumberAsString;
    minAmount: NumberAsString;
    priceRoute: OptimalRate;
    userAddress: Address;
    receiver?: Address;
    partner?: string;
  }): Promise<TransactionParams>;
}

function createSwapper(networkID: number, apiURL?: string): Swapper {
  const paraswap = new ParaSwap(
    networkID as NetworkID,
    apiURL,
    web3ProividersURLs[networkID]
  );

  const getRate: Swapper["getRate"] = async ({
    srcToken,
    destToken,
    srcAmount,
    userAddress,
    partner = PARTNER
  }) => {
    const priceRouteOrError = await paraswap.getRate(
      srcToken.address,
      destToken.address,
      srcAmount,
      userAddress,
      SwapSide.SELL,
      { partner },
      srcToken.decimals,
      destToken.decimals
    );

    if ("message" in priceRouteOrError) {
      throw new Error(priceRouteOrError.message);
    }

    return priceRouteOrError;
  };

  const buildSwap: Swapper["buildSwap"] = async ({
    srcToken,
    destToken,
    srcAmount,
    minAmount,
    priceRoute,
    userAddress,
    receiver,
    partner
  }) => {
    const transactionRequestOrError = await paraswap.buildTx(
      srcToken.address,
      destToken.address,
      srcAmount,
      minAmount,
      priceRoute,
      userAddress,
      partner,
      undefined,
      undefined,
      receiver
    );

    if ("message" in transactionRequestOrError) {
      throw new Error(transactionRequestOrError.message);
    }

    return transactionRequestOrError as TransactionParams;
  };

  return { getRate, buildSwap };
}

interface GetSwapTxInput {
  srcToken: Symbol;
  destToken: Symbol;
  srcAmount: NumberAsString; // in srcToken denomination
  networkID: number;
  slippage?: number;
  partner?: string;
  userAddress: Address;
  receiver?: Address;
}

export async function getSwapTransaction({
  srcToken: srcTokenSymbol,
  destToken: destTokenSymbol,
  srcAmount: _srcAmount,
  networkID,
  slippage = SLIPPAGE,
  userAddress,
  ...rest
}: GetSwapTxInput): Promise<TransactionParams> {
  try {
    const srcToken = getToken(srcTokenSymbol, networkID);
    const destToken = getToken(destTokenSymbol, networkID);

    const srcAmount = new BigNumber(_srcAmount)
      .times(10 ** srcToken.decimals)
      .toFixed(0);

    const ps = createSwapper(networkID);

    const priceRoute = await ps.getRate({
      srcToken,
      destToken,
      srcAmount,
      userAddress
    });

    const minAmount = new BigNumber(priceRoute.destAmount)
      .times(1 - slippage / 100)
      .toFixed(0);

    const transactionRequest = await ps.buildSwap({
      srcToken,
      destToken,
      srcAmount,
      minAmount,
      priceRoute,
      userAddress,
      ...rest
    });

    console.log("TransactionRequest", transactionRequest);

    return transactionRequest;
  } catch (error) {
    console.error(error);
    throw error;
  }
}

export const getExampleSwapTransaction = () =>
  getSwapTransaction({
    srcAmount: "1",
    srcToken: "ETH",
    destToken: "WETH",
    networkID: Networks.ROPSTEN,
    userAddress: USER_ADDRESS.ropsten
  });

param 'excludeContractMethods' does not work in paraswap getRate method

https://developers.paraswap.network/api/get-rate-for-a-token-pair
version: paraswap-sdk 5.0.0

const priceRoute = await paraSwap.getRate(from.address, to.address, srcAmount.toString(), '0x0000000000000000000000000000000000000000', SwapSide.SELL, {
        excludeContractMethods: [
          'swapOnZeroXv2',
          'swapOnZeroXv4',
          'swapOnUniswap',
          'swapOnUniswapFork'
        ],
        partner: 'PIGGY'
      }, from.decimals, to.decimals)

It has no error, but it still return the swapOnZeroXv4 swap method,
param 'excludeContractMethods' does not work in paraswap getRate method

ParaSwap.buildTx not working with SwapSide.BUY

Language version: Node.js 12.20.1
ParaSwap version: 3.0.0
Method: paraswap.buildTx()

I have been trying to implement paraswap.buildTx method and it works just fine when providing values from paraswap.getRate(token0, token1, amount, SwapSide.SELL). However, if I try paraswap.getRate(token0, token1, amount, SwapSide.BUY), or even paraswap.getRate(token1, token0, amount, SwapSide.BUY), the buildTx method always throws 403: ERROR_BUILDING_TRANSACTION.
Both tokens are approved and I can build Transaction selling token0 for token1 or vice versa. It is just the buy-side that is giving the error. I have tried posting the request directly to https://api.paraswap.io/v2/transactions/1 with mixed results. Sometimes it returns the built transaction parameters, sometimes it fails.

Edit:

This is an example of a failed request:
Method: POST
Url: https://apiv2.paraswap.io/v2/transactions/1
Body:
{ "srcToken": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "destToken": "0x00a8b738e453ffd858a7edf03bccfe20412f0eb0", "srcAmount": "149899762437779855", "destAmount": "400000000000000000000", "priceRoute":{ "side": "BUY", "destAmount": "400000000000000000000", "srcAmount": "154535837564721500", "bestRoute": [ { "exchange": "Balancer", "destAmount": "400000000000000000000", "srcAmount": "154535837564721500", "percent": 100, "data": { "tokenFrom": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "tokenTo": "0x00a8b738e453ffd858a7edf03bccfe20412f0eb0", "swaps": [ { "pool": "0x564f10f2e5deb8d475c20b418c5b6ed071855f2b", "tokenInParam": "115792089237316195423570985008687907853269984665640564039457584007913129639935", "tokenOutParam": "400000000000000000000", "maxPrice": "115792089237316195423570985008687907853269984665640564039457584007913129639935" } ], "exchangeProxy": "0x6317c5e82a06e1d8bf200d21f4510ac2c038ac81", "gasUSD": "16.3591849706544" }, "srcAmountNoFeeAdded": "154535837564721500", "destAmountNoFeeAdded": "400000000000000000000" } ], "others": [ { "exchange": "Balancer", "rate": "154535837564721500", "unit": "386130531242590", "data": { "tokenFrom": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "tokenTo": "0x00a8b738e453ffd858a7edf03bccfe20412f0eb0", "swaps": [ { "pool": "0x564f10f2e5deb8d475c20b418c5b6ed071855f2b", "tokenInParam": "115792089237316195423570985008687907853269984665640564039457584007913129639935", "tokenOutParam": "400000000000000000000", "maxPrice": "115792089237316195423570985008687907853269984665640564039457584007913129639935" } ], "exchangeProxy": "0x6317c5e82a06e1d8bf200d21f4510ac2c038ac81", "gasUSD": "16.3591849706544" }, "rateNoFeeAdded": "154535837564721500", "unitNoFeeAdded": "386130531242590" }, { "exchange": "UniswapV2", "rate": "155871503924965570", "unit": "389561667232421", "data": { "tokenFrom": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "tokenTo": "0x00a8b738e453ffd858a7edf03bccfe20412f0eb0", "path": [ "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "0xdac17f958d2ee523a2206206994597c13d831ec7", "0x00a8b738e453ffd858a7edf03bccfe20412f0eb0" ], "router": "0x86d3579b043585A97532514016dCF0C2d6C4b6a1", "gasUSD": "53.1673511546268" }, "rateNoFeeAdded": "155871503924965570", "unitNoFeeAdded": "389561667232421" } ], "blockNumber": 11862233, "details": { "tokenFrom": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "tokenTo": "0x00a8b738e453ffd858a7edf03bccfe20412f0eb0", "destAmount": "400000000000000000000", "srcAmount": "154535837564721500" }, "fromUSD": "277.2017929075", "toUSD": "277.0596000000", "priceWithSlippage": "156081195940368715", "bestRouteGasCostUSD": "46", "bestRouteGas": "272154", "srcAmountNoFeeAdded": "154535837564721500", "destAmountNoFeeAdded": "400000000000000000000", "fromUSDNoFeeAdded": "277.2017929075", "toUSDNoFeeAdded": "277.0596000000", "multiRoute": [] }, "userAddress": WALLET_ADDRESS, "referrer": REFERRER }

Response:
{"error":"ERROR_BUILDING_TRANSACTION"}

This is an example of a working request:
Method: POST
Url: https://apiv2.paraswap.io/v2/transactions/1
Body:
{ "srcToken": "0x00a8b738e453ffd858a7edf03bccfe20412f0eb0", "destToken": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "srcAmount": "400000000000000000000", "destAmount": "151875359988307982", "priceRoute":{ "side": "SELL", "destAmount": "156572536070420670", "srcAmount": "400000000000000000000", "bestRoute": [ { "exchange": "Balancer", "destAmount": "156572536070420670", "srcAmount": "400000000000000000000", "percent": 100, "data": { "tokenFrom": "0x00a8b738e453ffd858a7edf03bccfe20412f0eb0", "tokenTo": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "swaps": [ { "pool": "0x0d88b55317516b84e78fbba7cde3f910d5686901", "tokenInParam": "400000000000000000000", "tokenOutParam": "0", "maxPrice": "115792089237316195423570985008687907853269984665640564039457584007913129639935" } ], "exchangeProxy": "0x6317c5e82a06e1d8bf200d21f4510ac2c038ac81", "gasUSD": "79.45503965476" }, "destAmountFeeDeducted": "156572536070420670" } ], "others": [ { "exchange": "Bancor", "rate": "40281165024612370", "unit": "291605893794032", "data": { "tokenFrom": "0x00a8b738e453ffd858a7edf03bccfe20412f0eb0", "tokenTo": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "path": [ "0x00a8b738E453fFd858a7edf03bcCfe20412f0Eb0", "0x01697e379E6B2dA6A6D052BAa09F98488433e167", "0xdAC17F958D2ee523a2206206994597C13D831ec7", "0x5365B5BC56493F08A38E5Eb08E36cBbe6fcC8306", "0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C", "0xb1CD6e4153B2a390Cf00A6556b0fC1458C4A5533", "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" ], "gasUSD": "198.6375991369" }, "rateFeeDeducted": "40281165024612370", "unitFeeDeducted": "291605893794032" }, { "exchange": "Balancer", "rate": "156572536070420670", "unit": "391716441758619", "data": { "tokenFrom": "0x00a8b738e453ffd858a7edf03bccfe20412f0eb0", "tokenTo": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "swaps": [ { "pool": "0x0d88b55317516b84e78fbba7cde3f910d5686901", "tokenInParam": "400000000000000000000", "tokenOutParam": "0", "maxPrice": "115792089237316195423570985008687907853269984665640564039457584007913129639935" } ], "exchangeProxy": "0x6317c5e82a06e1d8bf200d21f4510ac2c038ac81", "gasUSD": "79.45503965476" }, "rateFeeDeducted": "156572536070420670", "unitFeeDeducted": "391716441758619" }, { "exchange": "UniswapV2", "rate": "156210118343161340", "unit": "390581909462435", "data": { "tokenFrom": "0x00a8b738e453ffd858a7edf03bccfe20412f0eb0", "tokenTo": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "path": [ "0x00a8b738e453ffd858a7edf03bccfe20412f0eb0", "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" ], "router": "0x86d3579b043585A97532514016dCF0C2d6C4b6a1", "gasUSD": "129.114439438985" }, "rateFeeDeducted": "156210118343161340", "unitFeeDeducted": "390581909462435" } ], "blockNumber": 11862290, "details": { "tokenFrom": "0x00a8b738e453ffd858a7edf03bccfe20412f0eb0", "tokenTo": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "destAmount": "156572536070420670", "srcAmount": "400000000000000000000" }, "fromUSD": "278.6840000000", "toUSD": "282.7381150528", "priceWithSlippage": "155006810709716463", "bestRouteGasCostUSD": "123", "bestRouteGas": "148919", "destAmountFeeDeducted": "156572536070420670", "toUSDFeeDeducted": "282.7381150528", "multiRoute": [] }, "userAddress": WALLET_ADDRESS, "referrer": REFFERER }

Response:
{ "from": WALLET_ADDRESS, "to": "0xf90e98F3D8Dce44632E5020ABF2E122E0f99DFAb", "data": RESPONSE_DATA, "chainId": 1, "value": "0", "gas": "385750", "gasPrice": "174200000000" }

ts-essentials usage

Hey!

I was casually browsing over ts-essentials dependency usage and had a look how it's used here

I just found that you import Merge

import { Merge } from 'ts-essentials';

But don't use it

Do you mind if I fix it? Or do you have plans to use it later?

Massive USDT Approval costs

Hey everyone,

i integrated the paraswap api into my dapp. Everything is looking good and running fine. I can approve and exchange various ERC20 tokens on Ethereum as well as Polygon with "normal" expected gas costs.

I am facing an unexpected problem by approving the paraswap api for USDT access. The fees for an approval transaction is 300 - 1000 times higher than for other tokens.

The function call looks like this:

await paraswap.approveToken("100", <senderAddress>, "0xdAC17F958D2ee523a2206206994597C13D831ec7");

To find the root of the problem i tried to fire the approve transaction separately on Etherscan. Weirdly, approving any random address has expectable gas cost except of the paraswap transferrer contract. By calling the approve function on USDT contract with paraswap contract as spender (0x216B4B4Ba9F3e719726886d34a177484278Bfcae) the gas costs are just exploding.

Hopefully anybody can help me out.

Support for non ERC20 tokens

Calling const tokens = await paraSwap.getTokens(); only returns ERC20 tokens. Is there any support coming for non ERC20 tokens (specifically looking for polygon).

post transaction: The rate has changed

Hi,

I'm calling paraSwapMin.swap.getRate right before building the tx: paraSwapMin.swap.buildTx

For some tokens, like this one: destToken: 0xb6a5ae40e79891e4deadad06c8a7ca47396df21c I always get the error:
{"error":"The rate has changed, please re-query the latest Price"}.
What could cause this and how should I deal with it?

axios limitation < 1.0.0

Hi,

first of all thanks for your awesome work ๐Ÿ‘

I want to use use paraswap-sdk in my project, but my axios lib version is up to date (currently: v1.2.0) and because of that I can't install your SDK. I think it would be bad to downgrade my version of Axios because of Paraswap SDK ๐Ÿ˜Ÿ

image

incorrect gasCost when calculating a route on arbitrum

I'm trying to make a swap tx (between usdc and dai) using paraswap sdk on arbitrum (chain id: 42161). But, the api/sdk returns the gasCost which is very low. When i propagate this transaction, i get gas too low from the rpc node. This happens only for arbitrum chain (for other chains, it works fine).

Is there a way around this? Any help is appreciated in resolving this.

Can't approve erc20 token for swap. Error: the method eth_sendTransaction does not exist/is not available. Chain info: Ethereum ropsten

Problem

Trying to approve before swap LINK (ERC-20 token) to ETH on Ethereum ropsten testnet.

Error msg

Error: Returned error: The method eth_sendTransaction does not exist/is not available

Logs

Source amount: 500000000000000000
User address: 0x57d91Eae4C6Db82f6D92BC2344eed7DB8cD4eA28
ERC-20 token address: 0xb4f7332ed719Eb4839f091EDDB2A3bA309739521

Code example:


private async approveToken(
    srcAmount: string,
    userAddress: string,
    erc20tokenAddress: string
  ): Promise<string> {
    try {
      /**
       * @Tx hash of approved token amount of user address with the particular amount
       */
      console.log("Source amount:", srcAmount);
      console.log("User address:", userAddress);
      console.log("ERC-20 token address:", erc20tokenAddress);
      return await this.paraSwap.approveToken(
        srcAmount,
        userAddress,
        erc20tokenAddress
      );
    } catch (error) {
      throw new Error(getErrorMessage(error, "Failed to approve token"));
    }
  }

[docs] add possible error codes & docs on what they mean

Started integrating paraswap into our application & want to ahndle errors properly.
Would be great if the docs would contain a list of possible error codes & a short explanation on what they mean.

Till now i only faced:
ESTIMATED_LOSS_GREATER_THAN_MAX_IMPACT, but I'd assume there are more.

don't swallow responses on errors

I tried integrating with paraswap SDK, but felt like debugging is relatively hard.

When the api responds with an error code the complete response is swallowed making debugging kinda hellish.
I'd suggest do serve the response alongside the error instead of throwing it away as in the case of slippage errors like here: https://apiv2.paraswap.io/v2/prices/?from=0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9&to=0x6b175474e89094c44da98b954eedeac495271d0f&amount=30000000000000000000000&side=BUY it might make sense to display some sort of feedback in the ui.

Can we "import" tokens?

Maybe I'm doing something wrong but it appears like this SDK only allows swapping of the built in tokens, or the tokens available via getTokens(). Is this true?

I'm getting a 400 / Token not found error when I try to swap a valid token that exists on Avalanche network. In the paraswap.io UI we have the option of "importing" new tokens... Is there a way to do that with the SDK? seems odd to whitelist token addresses... but again, maybe I'm doing something wrong.

gasLimit in the Build Transaction response

I'm using the ParaSwap API and I noticed that the response object (in Build Transaction API call) does not include the estimated gasLimit value.

Example from your docs:

{
  "from": "0xaa013bA141Faa58F0a8FCA1FEE3bC96d44Af869e",
  "to": "0x1bD435F3C054b6e901B7b108a0ab7617C808677b",
  "chainId": 1,
  "value": "1000000000000000000",
  "data": "0xcfc0...",
  "gasPrice": "119000000000"
}

Including the gasLimit value in this response would be very beneficial, because it is hard to get it via the ethers library. I was only able to get the gas limit estimate when swapping a native coin (like ETH or MATIC on Polygon), but not when swapping ERC-20 tokens.

Is it possible to add gasLimit to the Build Transaction API response?

APIv5 txOrigin option and estimateGas issues

SDK does not provide support for the txOrigin option to be passed in the API for the event whereby a smart contract interacts with the Augustus Swapper, and not an EOA. This is documented in the developer docs (with room for much expansion on documentation), however Swagger also doesn't have a txOrigin option.

  1. Is the txOrigin actually required? If not, could all the documentation actually be updated?
  2. The gas checking parameters create issues when simulating the transaction, as a smart contract interacting with Paraswap may have no ETH balance, and therefore the simulation fails.

The specific use case that I have is:

  1. Keeper EOA that holds ETH. All transacitions originate from this EOA.
  2. A smart contract with logic deployed on chain that integrates multiple liquidity sources (including paraswap). This smart contract is the one that calls paraswap, and it has no ETH balance.

So - how do I use Paraswap to achieve the above? I have managed to simulate some transactions however as a forked network for testing diverges from mainnet, it's difficult to know if the transactions that I've simulated correctly have succeeded out of chance, or out of correct logic.

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.