joshstevens19 / simple-uniswap-sdk

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.
MIT License
190 stars 97 forks source link

feat: BSC support #33

Open mburger81 opened 2 years ago

mburger81 commented 2 years ago

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);

mburger81 commented 2 years ago

I checked the source code and so that we have for sure to setting NativeNetwork, but what I not understand, we try to use the angular components which mainly we configure the supportedNetworkTokens.

How should I configure the tokens with our custom BSC router? can you perhaps help? @vm06007 @joshstevens19

mburger81 commented 2 years ago

@joshstevens19 @vm06007 So finally I understood when I would like to use your angular components I can configure the UniswapPairsettings also in the UniswapDappSharedLogiContext to configure. See below for configuration

But there are still two issues 1) in this scenario EthersProvider always calls InfuraProvider which doesn't work for BSC, I can omit this if I costumize uniswap-dapp-shared-logic to

if (this.supportedNetwork) {
      this._tokensFactoryPublic = new TokensFactoryPublic({
        chainId: this.chainId,
        providerUrl: 'https://bsc-dataseed1.defibit.io'
      });
    }

2) but at the end I'm running in the multi call into a ``` UniswapError: invalid from or to contract tokens UniswapError: invalid from or to contract tokens


**BTW** I'm not sure what I have to configure  tor `factoryAddress` and `pairAddress`

this.uniswapDappSharedLogicContext = {

  supportedNetworkTokens: [
    {
      chainId: 56,
      defaultInputToken: '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c', // BNB
      defaultOutputToken: '0x1fd13bB00d80986adc121d5bEF287Bf2ED5C31AF', // GRY
      supportedTokens: [
        { contractAddress: '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c' }, // BNB
        { contractAddress: '0x1fd13bB00d80986adc121d5bEF287Bf2ED5C31AF' }, // GRY
      ]
    }
  ],
  ethereumAddress: accounts[0],
  ethereumProvider: this.web3Service.provider,
  settings: {
    slippage: 0.01  ,
    deadlineMinutes: 20,
    disableMultihops: false,
    uniswapVersions: [UniswapVersion.v2],
    cloneUniswapContractDetails: {
      v2Override: {
        routerAddress: "0x0317d3B54c4FF8050E30Fe0e56585d2179586580",
        factoryAddress: "0xc35dadb65012ec5796536bd9864ed8773abc74c4",
        pairAddress: "0xc35dadb65012ec5796536bd9864ed8773abc74c4"
      }
    },
    customNetwork: {
      nameNetwork: !testnet ? "bsc" : "bsctest",
      multicallContractAddress: !testnet
        ? "0xfF6FD90A470Aaa0c1B8A54681746b07AcdFedc9B"
        : "0x8F3273Fb89B075b1645095ABaC6ed17B2d4Bc576",
      nativeCurrency: {
        name: "BNB",
        symbol: "BNB"
      },
      nativeWrappedTokenInfo: {
        chainId: !testnet ? 56 : 97,
        contractAddress: "0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c",
        decimals: 18,
        symbol: "WBNB",
        name: "Wrapped BNB"
      }
    }
  },
  theming: {
    backgroundColor: 'red',
    button: { textColor: 'white', backgroundColor: 'blue' },
    panel: { textColor: 'black', backgroundColor: 'yellow' },
    textColor: 'orange',
  }
};
vm06007 commented 2 years ago

factoryAddress and pairAddress of PancakeSwap:

      pairAddress: '0xca143ce32fe78f1f7019d7d551a6402fc5350c73',
      factoryAddress: '0xca143ce32fe78f1f7019d7d551a6402fc5350c73'

try to use this multicall address: 0x41263cba59eb80dc200f3e2544eda4ed6a90e76c

mburger81 commented 2 years ago

@vm06007 thx you for your response

should be pairAddress and factoryAddress the same?

when I try this, I get two errors 1. MetaMask - RPC Error: Internal JSON-RPC error. {code: -32603, message: 'Internal JSON-RPC error.', data: {…}} and as before 2. UniswapError: invalid from or to contract tokens

and I alsways have to set manually the provider url in the share lib

if (this.supportedNetwork) {
      this._tokensFactoryPublic = new TokensFactoryPublic({
        chainId: this.chainId,
        providerUrl: 'https://bsc-dataseed1.defibit.io'
      });
    }

EDIT: I could resolve error 1 and I figured out that I can debug better the second error

It's comming from https://github.com/uniswap-integration/simple-uniswap-sdk/blob/1629b680e615ce9851a4f7e7a3ba0187beac8261/src/factories/token/token.factory.ts#L80 and the error is call revert exception (method="tryBlockAndAggregate(bool,(address,bytes)[])", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.5.0)

vm06007 commented 2 years ago

@mburger81 Yes, factoryAddress usually includes pair code implementation, so they can stay the same, you might be missing the router address and you may need to specify the wethAddress of wrapped BNB token, here is my configuration for that:

      pairAddress: '0xca143ce32fe78f1f7019d7d551a6402fc5350c73',
      factoryAddress: '0xca143ce32fe78f1f7019d7d551a6402fc5350c73',
      routerAddress: '0x10ED43C718714eb63d5aA57B78B54704E256024E',
      daiAddress: '0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3',
      wethAddress: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c',

invalid from or to contract tokens sounds like the token addresses you are trying to pass for the trade might not be actual contracts on BSC

mburger81 commented 2 years ago

@vm06007 I share with you all my configuration, I try to get work with PCK so once this is working I can try to get it work with our dex and our router

I really dont know what I'm missing

 this.uniswapDappSharedLogicContext = {

      supportedNetworkTokens: [
        {
          chainId: 56,
          defaultInputToken: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c_ETH', // BNB
          defaultOutputToken: '0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82', // CAKE
          supportedTokens: [
            { contractAddress: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c_ETH' }, // BNB
            { contractAddress: '0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82' }, // CAKE
          ]
        }
      ],
      ethereumAddress: accounts[0],
      ethereumProvider: this.web3Service.provider,
      settings: {
        slippage: 0.01  ,
        deadlineMinutes: 20,
        disableMultihops: false,
        uniswapVersions: [ UniswapVersion.v2 ],
        cloneUniswapContractDetails: {
          v2Override: {
            routerAddress: "0x10ED43C718714eb63d5aA57B78B54704E256024E",
            factoryAddress: "0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73",
            pairAddress: "0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73"
          }
        },
        customNetwork: {
          nameNetwork: !testnet ? "BSC Mainnet" : "BSC Testnet",
          // https://github.com/makerdao/multicall
          multicallContractAddress: !testnet
            ? "0x41263cba59eb80dc200f3e2544eda4ed6a90e76c"
            : "0xae11C5B5f29A6a25e955F0CB8ddCc416f522AF5C",
          nativeCurrency: {
            name: "BNB",
            symbol: "BNB"
          },
          nativeWrappedTokenInfo: {
            chainId: !testnet ? 56 : 97,
            contractAddress: "0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c",
            decimals: 18,
            symbol: "WBNB",
            name: "Wrapped BNB"
          }
        }
      },
      theming: {
        backgroundColor: 'red',
        button: { textColor: 'white', backgroundColor: 'blue' },
        panel: { textColor: 'black', backgroundColor: 'yellow' },
        textColor: 'orange',
      }
    };
vm06007 commented 2 years ago

here is my configuration dynamic setup

    const details = chainDetails(
        provider, 
        chainId
    );

    const WETH_ADDRESS = details.wethAddress;
    const DAI_ADDRESS = details.daiAddress;

    const fromToken = findTokenStrict(details.tokensIn, fromCurrency, WETH_ADDRESS);
    const toToken = findTokenStrict(details.tokensOut, toCurrency, DAI_ADDRESS);

    const targets = {
        v2Override: {
            routerAddress: details.routerAddress,
            factoryAddress: details.factoryAddress,
            pairAddress: details.pairAddress,
        },
    };

    let customNetworkData;
    let providerUrl;

    if (chainId === 56) {
        (providerUrl = 'https://bsc-dataseed1.ninicoin.io'),
        (customNetworkData = {
            nameNetwork: 'Binance',
            multicallContractAddress: '0x65e9a150e06c84003d15ae6a060fc2b1b393342c',
            nativeCurrency: {
                name: 'BNB Token',
                symbol: 'BNB',
            },
            nativeWrappedTokenInfo: {
                chainId,
                contractAddress: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c',
                decimals: 18,
                symbol: 'WBNB',
                name: 'Wrapped BNB',
            },
        });
    }

    try {
        const uniswapPair = new UniswapPair({
            fromTokenContractAddress: fromToken,
            toTokenContractAddress: toToken,
            ethereumAddress: userAddress,
            providerUrl,
            chainId,
            settings: new UniswapPairSettings({
                slippage: 0.01,
                deadlineMinutes: 15,
                disableMultihops,
                uniswapVersions: [UniswapVersion.v2],
                cloneUniswapContractDetails: targets,
                customNetwork: customNetworkData,
            }),
        });
        const pair = await uniswapPair.createFactory();
        return pair;
    } catch (e) {
        console.log(e);
    }

perhaps I've given wrong multicallContractAddress ?? try 0x65e9a150e06c84003d15ae6a060fc2b1b393342c

mburger81 commented 2 years ago

Yeah the multicallContractAddress was the wrong address, strange I got the same as you send me before from this page https://github.com/makerdao/multicall which seems the not right one.

I took a lot of time to give you a response because I would like to finish my implementation. I saw that the simple-uniswap-sdk works well with different chains, but the integration example doesnt work very well, so in the last days I took a couple of changes which I would like to push the next days

btw. can you share with me also your configuration for the BSC TESTNET, still the same problem with unknown multicallAddress and whats about the router? is it the same as on BSC MAINNET?

thx @vm06007

vm06007 commented 2 years ago

I'm not dealing with BSC testnet

niZmosis commented 2 years ago

If your looking for pancake swap on BSC, I have the addresses here https://github.com/uniswap-integration/simple-uniswap-sdk/issues/34

RobAnon commented 2 years ago

Took a very long time, but I found the solution. You have to use this list of multicall contracts, else it will fail.

mburger81 commented 2 years ago

@vm06007 can you share the implementation of functions

vm06007 commented 2 years ago

those are simple array lookup functions with .find

const chainDetails = (provider, chainId = 1) => {
    return (
        provider.supportedChains.find((chain) => chain.chainId === chainId)
    );
};
const findTokenStrict = (
    array,
    value,
    defaultValue
) => {
    const result = array.find((item) => item.value === value);
    return result?.token || defaultValue;
};