turbos-finance / turbos-clmm-sdk

12 stars 7 forks source link

Swap example #35

Open artembruh opened 1 month ago

artembruh commented 1 month ago

Hello. After playing around with sdk for a couple of days without a working example and code references across github i came out with following code:

    const convertSuiTypesToArray = (type) => {
      return type.replace('>', '').split('<')[1]?.split(/,\s*/) || [];
    };
    const pairAddress =
      '0xbd85f61a1b755b6034c62f16938d6da7c85941705d9d10aa1843b809b0e35582'; // FUD / SUI
    const isBuy = true; // Change this according to operation (buy/sell)
    const turbosSdk = new TurbosSdk(Network.mainnet, suiClient); // Where suiClient is an instance of sui rpc connection
    const pool = await suiClient.getObject({
      id: pairAddress,
      options: { showContent: true },
    });
    const types = convertSuiTypesToArray(pool.data.content.type);
    const [coinA, coinB] = types.filter((p) => !p.includes('fee'));
    const isCoinASuiCoin = coinA === '0x2::sui::SUI';
    const tokenAddress = isCoinASuiCoin ? coinB : coinA;
    const a2b = (isCoinASuiCoin && isBuy) || (!isCoinASuiCoin && !isBuy);

    const [swapResult] = await turbosSdk.trade.computeSwapResultV2({
      pools: [
        {
          pool: pairAddress,
          a2b,
          amountSpecified: '100000', // Amount must be converted using decimals
        },
      ],
      address: <YOUR_WALLET_ADDRESS>,
      amountSpecifiedIsInput: true,
    });

    const [coinTypeA, amountA, coinTypeB, amountB] = a2b
      ? [
          tokenAddress,
          swapResult.amount_a,
          '0x2::sui::SUI',
          swapResult.amount_b,
        ]
      : [
          '0x2::sui::SUI',
          swapResult.amount_b,
          tokenAddress,
          swapResult.amount_a,
        ];

    const params = {
      routes: [
        {
          pool: swapResult.pool,
          a2b: swapResult.a_to_b,
          nextTickIndex: turbosSdk.math.bitsToNumber(
            swapResult.tick_current_index.bits,
            64,
          ),
        },
      ],
      coinTypeA,
      coinTypeB,
      address: swapResult.recipient,
      amountA,
      amountB,
      amountSpecifiedIsInput: swapResult.is_exact_in,
      slippage: String(25), // 25% Slippage
      deadline: 60000,
    };

    const tx = await turbosSdk.trade.swap(params);
    // Proceed to signing and sending to blockchain...

Works pretty fine for me for buying and selling.

ohanovdmytro commented 1 month ago

Well, i'm using a similar one and i can easily swap SUI -> USDC on their pool but i get a lot of troubles with USDC -> SUI. Here are tx hashes and my code:

https://suivision.xyz/txblock/BzE7bHMTPwWtetxuc8zkhTmSAj8PqcwFJfyAzz8Bhem https://suivision.xyz/txblock/HfMAS64xqWuH1pMoB6prnXTV2tz97LvFaXnX3u7Mqoxc

const poolId =
    "0x77f786e7bbd5f93f7dc09edbcffd9ea073945564767b65cf605f388328449d50";

  const poolinfo = await sdk.pool.getPool(poolId);

  const swapResult = await sdk.trade.computeSwapResultV2({
    pools: [
      {
        pool: poolId,
        a2b: false,
        amountSpecified: amountToSend,
      },
    ],
    address: senderAddress,
    amountSpecifiedIsInput: true,
  });

  const nextTickIndex = sdk.math.bitsToNumber(
    poolinfo.tick_current_index.fields.bits
  );

  const routes = [
    {
      pool: poolId,
      a2b: false,
      nextTickIndex,
    },
  ];

  const transaction = new Transaction();
  transaction.setSender(senderAddress);

  console.log(poolinfo.types);

  const tx = await sdk.trade.swap({
    routes,
    coinTypeA: poolinfo.types[1],
    coinTypeB: poolinfo.types[0],
    address: senderAddress,
    amountA: swapResult[0].amount_a,
    amountB: swapResult[0].amount_b,
    amountSpecifiedIsInput: true,
    slippage: "25",
    txb: transaction,
  });

  const senderKeypair = Ed25519Keypair.fromSecretKey(senderPrivateKey);

  const gasLimit = +(await client.getReferenceGasPrice()).toString() * 30_000;
  tx.setGasBudget(gasLimit);

  const signedTxBlock = await tx.sign({
    signer: senderKeypair,
    client,
  });

  const response = await client.executeTransactionBlock({
    transactionBlock: signedTxBlock.bytes,
    signature: signedTxBlock.signature,
  });

  console.log(response);
Nebula-Spark commented 1 month ago

Hello. After playing around with sdk for a couple of days without a working example and code references across github i came out with following code:

    const convertSuiTypesToArray = (type) => {
      return type.replace('>', '').split('<')[1]?.split(/,\s*/) || [];
    };
    const pairAddress =
      '0xbd85f61a1b755b6034c62f16938d6da7c85941705d9d10aa1843b809b0e35582'; // FUD / SUI
    const isBuy = true; // Change this according to operation (buy/sell)
    const turbosSdk = new TurbosSdk(Network.mainnet, suiClient); // Where suiClient is an instance of sui rpc connection
    const pool = await suiClient.getObject({
      id: pairAddress,
      options: { showContent: true },
    });
    const types = convertSuiTypesToArray(pool.data.content.type);
    const [coinA, coinB] = types.filter((p) => !p.includes('fee'));
    const isCoinASuiCoin = coinA === '0x2::sui::SUI';
    const tokenAddress = isCoinASuiCoin ? coinB : coinA;
    const a2b = (isCoinASuiCoin && isBuy) || (!isCoinASuiCoin && !isBuy);

    const [swapResult] = await turbosSdk.trade.computeSwapResultV2({
      pools: [
        {
          pool: pairAddress,
          a2b,
          amountSpecified: '100000', // Amount must be converted using decimals
        },
      ],
      address: <YOUR_WALLET_ADDRESS>,
      amountSpecifiedIsInput: true,
    });

    const [coinTypeA, amountA, coinTypeB, amountB] = a2b
      ? [
          tokenAddress,
          swapResult.amount_a,
          '0x2::sui::SUI',
          swapResult.amount_b,
        ]
      : [
          '0x2::sui::SUI',
          swapResult.amount_b,
          tokenAddress,
          swapResult.amount_a,
        ];

    const params = {
      routes: [
        {
          pool: swapResult.pool,
          a2b: swapResult.a_to_b,
          nextTickIndex: turbosSdk.math.bitsToNumber(
            swapResult.tick_current_index.bits,
            64,
          ),
        },
      ],
      coinTypeA,
      coinTypeB,
      address: swapResult.recipient,
      amountA,
      amountB,
      amountSpecifiedIsInput: swapResult.is_exact_in,
      slippage: String(25), // 25% Slippage
      deadline: 60000,
    };

    const tx = await turbosSdk.trade.swap(params);
    // Proceed to signing and sending to blockchain...

Works pretty fine for me for buying and selling.

Thanks a lot , 👍

It would be really awesome if u can add an example for ADD and remove Liquidity ! I Hope So...

artembruh commented 1 month ago

Hello. After playing around with sdk for a couple of days without a working example and code references across github i came out with following code:

    const convertSuiTypesToArray = (type) => {
      return type.replace('>', '').split('<')[1]?.split(/,\s*/) || [];
    };
    const pairAddress =
      '0xbd85f61a1b755b6034c62f16938d6da7c85941705d9d10aa1843b809b0e35582'; // FUD / SUI
    const isBuy = true; // Change this according to operation (buy/sell)
    const turbosSdk = new TurbosSdk(Network.mainnet, suiClient); // Where suiClient is an instance of sui rpc connection
    const pool = await suiClient.getObject({
      id: pairAddress,
      options: { showContent: true },
    });
    const types = convertSuiTypesToArray(pool.data.content.type);
    const [coinA, coinB] = types.filter((p) => !p.includes('fee'));
    const isCoinASuiCoin = coinA === '0x2::sui::SUI';
    const tokenAddress = isCoinASuiCoin ? coinB : coinA;
    const a2b = (isCoinASuiCoin && isBuy) || (!isCoinASuiCoin && !isBuy);

    const [swapResult] = await turbosSdk.trade.computeSwapResultV2({
      pools: [
        {
          pool: pairAddress,
          a2b,
          amountSpecified: '100000', // Amount must be converted using decimals
        },
      ],
      address: <YOUR_WALLET_ADDRESS>,
      amountSpecifiedIsInput: true,
    });

    const [coinTypeA, amountA, coinTypeB, amountB] = a2b
      ? [
          tokenAddress,
          swapResult.amount_a,
          '0x2::sui::SUI',
          swapResult.amount_b,
        ]
      : [
          '0x2::sui::SUI',
          swapResult.amount_b,
          tokenAddress,
          swapResult.amount_a,
        ];

    const params = {
      routes: [
        {
          pool: swapResult.pool,
          a2b: swapResult.a_to_b,
          nextTickIndex: turbosSdk.math.bitsToNumber(
            swapResult.tick_current_index.bits,
            64,
          ),
        },
      ],
      coinTypeA,
      coinTypeB,
      address: swapResult.recipient,
      amountA,
      amountB,
      amountSpecifiedIsInput: swapResult.is_exact_in,
      slippage: String(25), // 25% Slippage
      deadline: 60000,
    };

    const tx = await turbosSdk.trade.swap(params);
    // Proceed to signing and sending to blockchain...

Works pretty fine for me for buying and selling.

Thanks a lot , 👍

It would be really awesome if u can add an example for ADD and remove Liquidity ! I Hope So...

Actually i did not look into add/remove liquidity, so i can't help with this one, sorry

artembruh commented 1 month ago

Well, i'm using a similar one and i can easily swap SUI -> USDC on their pool but i get a lot of troubles with USDC -> SUI. Here are tx hashes and my code:

https://suivision.xyz/txblock/BzE7bHMTPwWtetxuc8zkhTmSAj8PqcwFJfyAzz8Bhem https://suivision.xyz/txblock/HfMAS64xqWuH1pMoB6prnXTV2tz97LvFaXnX3u7Mqoxc

const poolId =
    "0x77f786e7bbd5f93f7dc09edbcffd9ea073945564767b65cf605f388328449d50";

  const poolinfo = await sdk.pool.getPool(poolId);

  const swapResult = await sdk.trade.computeSwapResultV2({
    pools: [
      {
        pool: poolId,
        a2b: false,
        amountSpecified: amountToSend,
      },
    ],
    address: senderAddress,
    amountSpecifiedIsInput: true,
  });

  const nextTickIndex = sdk.math.bitsToNumber(
    poolinfo.tick_current_index.fields.bits
  );

  const routes = [
    {
      pool: poolId,
      a2b: false,
      nextTickIndex,
    },
  ];

  const transaction = new Transaction();
  transaction.setSender(senderAddress);

  console.log(poolinfo.types);

  const tx = await sdk.trade.swap({
    routes,
    coinTypeA: poolinfo.types[1],
    coinTypeB: poolinfo.types[0],
    address: senderAddress,
    amountA: swapResult[0].amount_a,
    amountB: swapResult[0].amount_b,
    amountSpecifiedIsInput: true,
    slippage: "25",
    txb: transaction,
  });

  const senderKeypair = Ed25519Keypair.fromSecretKey(senderPrivateKey);

  const gasLimit = +(await client.getReferenceGasPrice()).toString() * 30_000;
  tx.setGasBudget(gasLimit);

  const signedTxBlock = await tx.sign({
    signer: senderKeypair,
    client,
  });

  const response = await client.executeTransactionBlock({
    transactionBlock: signedTxBlock.bytes,
    signature: signedTxBlock.signature,
  });

  console.log(response);

Please, compare my code with your and you'll notice the problems easily