> ## Documentation Index
> Fetch the complete documentation index at: https://docs.saucerswap.finance/llms.txt
> Use this file to discover all available pages before exploring further.

# Swap Quote

> Get a token swap quote based on an input or output value

Below are the two methods to get a quote for a swap from a given route:

* [Get output quote from exact input amount](/v/developer/saucerswap-v2/swap-operations/swap-quote#get-output-quote-from-exact-input-amount)
* [Get input quote from exact output amount](/v/developer/saucerswap-v2/swap-operations/swap-quote#get-output-quote-from-exact-input-amount)

<Info>
  **Contract ID:** [SaucerSwapV2QuoterV2](https://hashscan.io/mainnet/contract/0.0.3949424)
</Info>

<Tip>
  When providing HBAR in the path array, use the wrapped HBAR token ID ([WHBAR](https://hashscan.io/mainnet/token/0.0.1456986)).
</Tip>

<Tip>
  For production environments, it's highly recommended to use a paid Mirror Node provider for commercial and high-traffic purposes. While Hedera's public mirror node offers free REST API and JSON API endpoints, they have global rate limits. These are best suited for development or low rate usage scenarios.
</Tip>

## Get Output Quote from Exact Input Amount

Get the output amount from a given exact input amount and a swap route.

Function name: **quoteExactInput** ⛽ *No gas cost*

| Parameter Name     | Description                                 |
| ------------------ | ------------------------------------------- |
| *bytes path*       | Route path containing pair swap fees        |
| *uint256 amountIn* | Exact input amount in token's smallest unit |

<CodeGroup>
  ```solidity IQuoterV2.sol theme={null}
  /// @notice Returns the amount out received for a given exact input swap without executing the swap
  /// @param path The path of the swap, i.e. each token pair and the pool fee
  /// @param amountIn The amount of the first token to swap
  /// @return amountOut The amount of the last token that would be received
  /// @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path
  /// @return initializedTicksCrossedList List of the initialized ticks that the swap crossed for each pool in the path
  /// @return gasEstimate The estimate of the gas that the swap consumes
  function quoteExactInput(bytes memory path, uint256 amountIn)
    external
    returns (
      uint256 amountOut,
      uint160[] memory sqrtPriceX96AfterList,
      uint32[] memory initializedTicksCrossedList,
      uint256 gasEstimate
    );
  ```

  ```solidity QuoterV2.sol theme={null}
  function quoteExactOutput(bytes memory path, uint256 amountOut)
    public
    override
    returns (
      uint256 amountIn,
      uint160[] memory sqrtPriceX96AfterList,
      uint32[] memory initializedTicksCrossedList,
      uint256 gasEstimate
    )
  {
    sqrtPriceX96AfterList = new uint160[](path.numPools());
    initializedTicksCrossedList = new uint32[](path.numPools());

    uint256 i = 0;
    while (true) {
      (address tokenOut, address tokenIn, uint24 fee) = path.decodeFirstPool();

      // the inputs of prior swaps become the outputs of subsequent ones
      (
        uint256 _amountIn,
        uint160 _sqrtPriceX96After,
        uint32 _initializedTicksCrossed,
        uint256 _gasEstimate
      ) = quoteExactOutputSingle(
          QuoteExactOutputSingleParams({
            tokenIn: tokenIn,
            tokenOut: tokenOut,
            amount: amountOut,
            fee: fee,
            sqrtPriceLimitX96: 0
          })
        );

      sqrtPriceX96AfterList[i] = _sqrtPriceX96After;
      initializedTicksCrossedList[i] = _initializedTicksCrossed;
      amountOut = _amountIn;
      gasEstimate += _gasEstimate;
      i++;

      // decide whether to continue or terminate
      if (path.hasMultiplePools()) {
        path = path.skipToken();
      } else {
        return (amountOut, sqrtPriceX96AfterList, initializedTicksCrossedList, gasEstimate);
      }
    }
  }
  ```
</CodeGroup>

<Info>
  The data passed to the 'path' parameter follows this format: \[token, fee, token, fee, token, ...], with each 'token' in the route being 20 bytes long and each 'fee' being 3 bytes long. Example, 0x0001F4 for a 0.05% fee.
</Info>

### Code Overview

<Tabs>
  <Tab title="JSON RPC">
    **Resources:**

    * [SaucerSwap deployed contract IDs](/developerx/contract-deployments)
    * [Ethers.js docs (v6)](https://docs.ethers.org/v6/)
    * [Hedera JSON RPC Relay](https://docs.hedera.com/hedera/core-concepts/smart-contracts/deploying-smart-contracts/json-rpc-relay)

    ```typescript Typescript theme={null}
    import * as ethers from 'ethers'; //V6

    //Set one of Hedera's JSON RPC Relay as the provider
    const provider = new ethers.JsonRpcProvider(hederaJsonRelayUrl, '', {
      batchMaxCount: 1, //workaround for V6
    });

    //load ABI data containing QuoterV2 functions
    const abiInterfaces = new ethers.Interface(abi);

    //QuoterV2.sol contract
    const quoterEvmAddress = `0x${ContractId.fromString(quoterContractId).toSolidityAddress()}`;  

    //swap path
    const pathData:string[] = [];
    pathData.push(inputToken.toSolidityAddress()); 
    pathData.push(feeHexStr);
    pathData.push(outputToken.toSolidityAddress());

    const encodedPathData = hexToUint8Array(pathData.join(''));

    const data = abiInterfaces.encodeFunctionData('quoteExactInput', [
      encodedPathData, 
      inputAmountInSmallestUnit.toString()
    ]);

    //Send a call to the JSON-RPC provider directly
    const result = await provider.call({
      to: quoterEvmAddress,
      data: data,
    });

    const decoded = abiInterfaces.decodeFunctionResult('quoteExactInput', result); 
    const finalOutputAmount = decoded.amountOut; //in token's smallest unit

    ```
  </Tab>

  <Tab title="REST API">
    **Resources:**

    * [SaucerSwap deployed contract IDs](/developerx/contract-deployments)
    * [Ethers.js docs (v6)](https://docs.ethers.org/v6/)
    * [Hedera REST API](https://docs.hedera.com/hedera/sdks-and-apis/rest-api)

    ```typescript Typescript theme={null}
    //Typescript
    import * as ethers from 'ethers'; //V6

    //load ABI data containing QuoterV2 functions
    const abiInterfaces = new ethers.Interface(abi);

    //QuoterV2.sol contract
    const quoterContract = ContractId.fromString(quoterContractId);

    //swap path
    const path:string[] = [];
    path.push(inputToken.toSolidityAddress());
    path.push(feeHexStr);
    path.push(outputToken.toSolidityAddress());

    //get encoded Uint8Array data for path hex
    const encodedPathData = hexToUint8Array(path.join(''));

    //quoteExactInput params
    const params = [encodedPathData, inputAmountInSmallestUnit];

    //Get encoded function data
    const encodedData = abiInterfaces.encodeFunctionData(interfaces.getFunction('quoteExactInput')!, params);    

    const url = `${mirrorNodeBaseUrl}/api/v1/contracts/call`;
    const data = {
      'block': 'latest',
      'data': encodedData,
      'to': quoterContract.toSolidityAddress(),
    };

    const response = await axios.post(url, data, { headers: {'content-type': 'application/json'} });
    const result = abiInterfaces.decodeFunctionResult('quoteExactInput', response.data.result); 
    const finalAmountOut = result.amountOut; //in token's smallest unit
    ```
  </Tab>
</Tabs>

***

## Get Input Quote from Exact Output Amount

Get the input amount from a given exact output amount and a swap route.

Function name: **quoteExactOutput** ⛽ *No gas cost*

| Parameter Name      | Description                                    |
| ------------------- | ---------------------------------------------- |
| *bytes path*        | Route path containing pair swap fees, reversed |
| *uint256 amountOut* | Exact output amount in token's smallest unit   |

<CodeGroup>
  ```solidity IQuoterV2.sol theme={null}
  /// @notice Returns the amount in required for a given exact output swap without executing the swap
  /// @param path The path of the swap, i.e. each token pair and the pool fee. Path must be provided in reverse order
  /// @param amountOut The amount of the last token to receive
  /// @return amountIn The amount of first token required to be paid
  /// @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path
  /// @return initializedTicksCrossedList List of the initialized ticks that the swap crossed for each pool in the path
  /// @return gasEstimate The estimate of the gas that the swap consumes
  function quoteExactOutput(bytes memory path, uint256 amountOut)
    external
    returns (
      uint256 amountIn,
      uint160[] memory sqrtPriceX96AfterList,
      uint32[] memory initializedTicksCrossedList,
      uint256 gasEstimate
    );

    struct QuoteExactOutputSingleParams {
      address tokenIn;
      address tokenOut;
      uint256 amount;
      uint24 fee;
      uint160 sqrtPriceLimitX96;
    }
  ```

  ```solidity QuoterV2.sol theme={null}
  function quoteExactOutput(bytes memory path, uint256 amountOut)
    public
    override
    returns (
      uint256 amountIn,
      uint160[] memory sqrtPriceX96AfterList,
      uint32[] memory initializedTicksCrossedList,
      uint256 gasEstimate
    )
  {
    sqrtPriceX96AfterList = new uint160[](path.numPools());
    initializedTicksCrossedList = new uint32[](path.numPools());

    uint256 i = 0;
    while (true) {
      (address tokenOut, address tokenIn, uint24 fee) = path.decodeFirstPool();

      // the inputs of prior swaps become the outputs of subsequent ones
      (
        uint256 _amountIn,
        uint160 _sqrtPriceX96After,
        uint32 _initializedTicksCrossed,
        uint256 _gasEstimate
      ) = quoteExactOutputSingle(
          QuoteExactOutputSingleParams({
            tokenIn: tokenIn,
            tokenOut: tokenOut,
            amount: amountOut,
            fee: fee,
            sqrtPriceLimitX96: 0
          })
        );

      sqrtPriceX96AfterList[i] = _sqrtPriceX96After;
      initializedTicksCrossedList[i] = _initializedTicksCrossed;
      amountOut = _amountIn;
      gasEstimate += _gasEstimate;
      i++;

      // decide whether to continue or terminate
      if (path.hasMultiplePools()) {
        path = path.skipToken();
      } else {
        return (amountOut, sqrtPriceX96AfterList, initializedTicksCrossedList, gasEstimate);
      }
    }
  }
  ```
</CodeGroup>

<Note>
  The data passed to the 'path' parameter follows this format: \[token, fee, token, fee, token, ...], but **reversed** (i.e. the first token in the array should be output token), with each 'token' in the route being 20 bytes long and each 'fee' being 3 bytes long. Example, `0x000BB8` for a 0.30% fee.
</Note>

### Code Overview

<Tabs>
  <Tab title="JSON RPC">
    **Resources:**

    * [SaucerSwap deployed contract IDs](/developerx/contract-deployments)
    * [Ethers.js docs (v6)](https://docs.ethers.org/v6/)
    * [Hedera JSON RPC Relay](https://docs.hedera.com/hedera/core-concepts/smart-contracts/deploying-smart-contracts/json-rpc-relay)

    ```typescript Typescript theme={null}
    import * as ethers from 'ethers'; //V6

    //Set one of Hedera's JSON RPC Relay as the provider
    const provider = new ethers.JsonRpcProvider(hederaJsonRelayUrl, '', {
      batchMaxCount: 1, //workaround for V6
    });

    //load ABI data containing QuoterV2 functions
    const abiInterfaces = new ethers.Interface(abi);

    //QuoterV2.sol contract
    const quoterEvmAddress = `0x${ContractId.fromString(quoterContractId).toSolidityAddress()}`;  

    //swap path
    const pathData:string[] = [];
    pathData.push(inputToken.toSolidityAddress());  
    pathData.push(feeHexStr);
    pathData.push(outputToken.toSolidityAddress());

    //reverse the path
    pathData.reverse();

    //get encoded Uint8Array data for path hex
    const encodedPathData = hexToUint8Array(pathData.join(''));

    const data = abiInterfaces.encodeFunctionData('quoteExactOutput', [
      encodedPathData, 
      outputAmountInSmallestUnit
    ]);

    //Send a call to the JSON-RPC provider directly
    const result = await provider.call({
      to: quoterEvmAddress,
      data: data,
    });

    const decoded = abiInterfaces.decodeFunctionResult('quoteExactOutput', result); 
    const finalAmountIn = decoded.amountIn; //in token's smallest unit
    ```
  </Tab>

  <Tab title="REST API">
    **Resources:**

    * [SaucerSwap deployed contract IDs](/developerx/contract-deployments)
    * [Ethers.js docs (v6)](https://docs.ethers.org/v6/)
    * [Hedera REST API](https://docs.hedera.com/hedera/sdks-and-apis/rest-api)

    ```typescript Typescript theme={null}
    import * as ethers from 'ethers'; //V6

    //load ABI data containing QuoterV2 functions
    const abiInterfaces = new ethers.Interface(abi);

    //QuoterV2.sol contract
    const quoterContract = ContractId.fromString(quoterContractId);

    const path:string[] = [];
    path.push(inputToken.toSolidityAddress());
    path.push(feeHexStr);
    path.push(outputToken.toSolidityAddress());

    //reverse the path
    path.reverse();

    //get encoded Uint8Array data for path hex
    const encodedPathData = hexToUint8Array(path.join(''));

    //quoteExactOutput params
    const params = [encodedPathData, outputAmountInSmallestUnit];

    //Get encoded function data
    const encodedData = abiInterfaces.encodeFunctionData(interfaces.getFunction('quoteExactOutput')!, params);    

    const url = `${mirrorNodeBaseUrl}/api/v1/contracts/call`;
    const data = {
      'block': 'latest',
      'data': encodedData,
      'to': quoterContract.toSolidityAddress(),
    };

    const response = await axios.post(url, data, { headers: {'content-type': 'application/json'} });
    const result = abiInterfaces.decodeFunctionResult('quoteExactOutput', response.data.result); 
    const finalAmountIn = result.amountIn; //in token's smallest unit
    ```
  </Tab>
</Tabs>
