orca-so / typescript-sdk

The Orca SDK contains a set of simple to use APIs to allow developers to integrate with the Orca platform.
155 stars 49 forks source link

Swap through multiple pools in one transaction #107

Open laptrinhbockchain opened 2 years ago

laptrinhbockchain commented 2 years ago

I can't find a way how to swap through multiple pools in one transaction. For example, I want to swap from GST to USDC, then USDC to USDT and do it in 1 transaction

staccDOTsol commented 1 year ago

Swapping through multiple pools in one transaction is possible in Orca. To do this, you can use the multi-hop feature.

Here's an example of how you can swap from GST to USDC, then USDC to USDT in one transaction:

  1. First, you need to get the route for the trade. You can get the route by calling the getRoute function on the TokenSwap program. The getRoute function takes two arguments: the from token address and the to token address. You can get the token addresses from the Orca website or from the Solana Explorer.

  2. Once you have the route, you can call the swap function on the TokenSwap program. The swap function takes several arguments, including the from token address, the to token address, the amountIn (the amount of the from token you want to swap), the minimumAmountOut (the minimum amount of the to token you want to receive), and the deadline (the deadline for the trade).

  3. To swap through multiple pools, you can call the swap function multiple times, passing the output token from the previous swap as the input token for the next swap.

Here's an example of how you can swap from GST to USDC, then USDC to USDT in one transaction using the Solana CLI:

# Get the route for the first trade (GST to USDC)
solana program call --address <TOKEN_SWAP_ADDRESS> --data "<GET_ROUTE_DATA>" --no-verify

# Swap GST to USDC
solana program call --address <TOKEN_SWAP_ADDRESS> --data "<SWAP_DATA>" --no-verify

# Get the route for the second trade (USDC to USDT)
solana program call --address <TOKEN_SWAP_ADDRESS> --data "<GET_ROUTE_DATA>" --no-verify

# Swap USDC to USDT
solana program call --address <TOKEN_SWAP_ADDRESS> --data "<SWAP_DATA>" --no-verify

You will need to replace <TOKEN_SWAP_ADDRESS>, <GET_ROUTE_DATA>, and <SWAP_DATA> with the appropriate values for your trade.

staccDOTsol commented 1 year ago

To swap through multiple pools in one transaction, you can use the multihop feature of Uniswap V3. This feature allows you to swap between two tokens through multiple pools in a single transaction.

Here's an example of how you can use the multihop feature to swap from GST to USDC, then USDC to USDT:

  1. First, you need to identify the pools that you want to use for the swap. In this case, you need to find a pool that has GST and USDC, and another pool that has USDC and USDT.

  2. Once you have identified the pools, you need to get the current prices of the tokens in each pool. You can use the getTick, getSqrtRatioAtTick, and tickSpacing functions to get the current prices of the tokens.

  3. Next, you need to calculate the optimal route for the swap. You can use the Route struct to define the route for the swap. In this case, the route would be GST -> USDC -> USDT.

  4. After defining the route, you can use the exactInput function to execute the swap. This function takes the following parameters:

  1. Finally, you can call the exactInput function with the appropriate parameters to execute the swap.

Here's some sample code that demonstrates how to use the multihop feature to swap from GST to USDC, then USDC to USDT:

// Define the route for the swap
let route = Route::new(
    vec![
        PoolAddress::new("0x...")?, // Pool with GST and USDC
        PoolAddress::new("0x...")?, // Pool with USDC and USDT
    ],
    Token::new("0x...", 18), // GST
    Token::new("0x...", 6), // USDT
)?;

// Get the current prices of the tokens in each pool
let tick0 = pool0.getTick(tickSpacing)?;
let tick1 = pool1.getTick(tickSpacing)?;
let sqrtRatioX96_0 = getSqrtRatioAtTick(tick0)?;
let sqrtRatioX96_1 = getSqrtRatioAtTick(tick1)?;

// Calculate the optimal input amount for the swap
let amountIn = calculateInputAmount(
    TokenAmount::new(U256::from(1000), 18), // 1000 GST
    sqrtRatioX96_0,
    sqrtRatioX96_1,
    route.fee,
)?;

// Execute the swap
exactInput(
    &route,
    TokenAmount::new(amountIn, 18), // Input amount in GST
    TokenAmount::new(U256::from(0), 6), // Minimum output amount in USDT
    recipient,
    U256::from(1234567890), // Deadline
)?;

Note that you will need to replace the pool and token addresses with the actual addresses of the pools and tokens that you want to use for the swap.