Skip to content

Instantly share code, notes, and snippets.

@leon-do
Created January 27, 2025 18:49
Show Gist options
  • Save leon-do/79031d956c24013ced18070aea4a6b0f to your computer and use it in GitHub Desktop.
Save leon-do/79031d956c24013ced18070aea4a6b0f to your computer and use it in GitHub Desktop.
OToken Swap API
import { ethers } from "ethers";
import "dotenv/config";
const QUOTER_CONTRACT_ADDRESS = "0x0880484412B5bAa18B3fa2904a500c08f0fE79D2";
// prettier-ignore
const QUOTER_ABI = [ { "inputs": [ { "internalType": "address", "name": "_factory", "type": "address" }, { "internalType": "address", "name": "_WETH9", "type": "address" } ], "stateMutability": "nonpayable", "type": "constructor" }, { "inputs": [], "name": "WETH9", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "factory", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "bytes", "name": "path", "type": "bytes" }, { "internalType": "uint256", "name": "amountIn", "type": "uint256" } ], "name": "quoteExactInput", "outputs": [ { "internalType": "uint256", "name": "amountOut", "type": "uint256" }, { "internalType": "uint160[]", "name": "sqrtPriceX96AfterList", "type": "uint160[]" }, { "internalType": "uint32[]", "name": "initializedTicksCrossedList", "type": "uint32[]" }, { "internalType": "uint256", "name": "gasEstimate", "type": "uint256" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "components": [ { "internalType": "address", "name": "tokenIn", "type": "address" }, { "internalType": "address", "name": "tokenOut", "type": "address" }, { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, { "internalType": "uint24", "name": "fee", "type": "uint24" }, { "internalType": "uint160", "name": "sqrtPriceLimitX96", "type": "uint160" } ], "internalType": "struct IQuoterV2.QuoteExactInputSingleParams", "name": "params", "type": "tuple" } ], "name": "quoteExactInputSingle", "outputs": [ { "internalType": "uint256", "name": "amountOut", "type": "uint256" }, { "internalType": "uint160", "name": "sqrtPriceX96After", "type": "uint160" }, { "internalType": "uint32", "name": "initializedTicksCrossed", "type": "uint32" }, { "internalType": "uint256", "name": "gasEstimate", "type": "uint256" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "bytes", "name": "path", "type": "bytes" }, { "internalType": "uint256", "name": "amountOut", "type": "uint256" } ], "name": "quoteExactOutput", "outputs": [ { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, { "internalType": "uint160[]", "name": "sqrtPriceX96AfterList", "type": "uint160[]" }, { "internalType": "uint32[]", "name": "initializedTicksCrossedList", "type": "uint32[]" }, { "internalType": "uint256", "name": "gasEstimate", "type": "uint256" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "components": [ { "internalType": "address", "name": "tokenIn", "type": "address" }, { "internalType": "address", "name": "tokenOut", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "uint24", "name": "fee", "type": "uint24" }, { "internalType": "uint160", "name": "sqrtPriceLimitX96", "type": "uint160" } ], "internalType": "struct IQuoterV2.QuoteExactOutputSingleParams", "name": "params", "type": "tuple" } ], "name": "quoteExactOutputSingle", "outputs": [ { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, { "internalType": "uint160", "name": "sqrtPriceX96After", "type": "uint160" }, { "internalType": "uint32", "name": "initializedTicksCrossed", "type": "uint32" }, { "internalType": "uint256", "name": "gasEstimate", "type": "uint256" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "int256", "name": "amount0Delta", "type": "int256" }, { "internalType": "int256", "name": "amount1Delta", "type": "int256" }, { "internalType": "bytes", "name": "path", "type": "bytes" } ], "name": "uniswapV3SwapCallback", "outputs": [], "stateMutability": "view", "type": "function" } ]
const provider = new ethers.JsonRpcProvider("https://rpc.o.xyz/");
const quoterContract = new ethers.Contract(
QUOTER_CONTRACT_ADDRESS,
QUOTER_ABI,
provider
);
const signer = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
const params = {
tokenIn: "0xc7C3cff325c6976965edfEB05c024584e4e4BBDD", // WETH https://explorer.o.xyz/address/0xc7C3cff325c6976965edfEB05c024584e4e4BBDD
tokenOut: "0x91d70c3adde2f0f0c4fb0b2de69f37a7c7e326df", // USDC https://explorer.o.xyz/address/0x91D70c3Adde2f0f0C4fB0b2De69f37a7c7E326DF
fee: 3000,
recipient: signer.address,
deadline: Math.floor(new Date().getTime() / 1000 + 60 * 10),
amountIn: ethers.parseUnits("0.01"),
sqrtPriceLimitX96: 0,
};
main();
async function main() {
const transaction =
await quoterContract.quoteExactInputSingle.populateTransaction(params);
console.log({ transaction });
const receipt = await signer.sendTransaction(transaction);
console.log({ receipt });
}
@leon-do
Copy link
Author

leon-do commented Jan 27, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment