Copy
import { ethers } from "ethers";
import axios from "axios";
import * as dotenv from "dotenv";
dotenv.config();
// Load environment variables from .env file
const privateKey: string = process.env.PRIVATE_KEY!;
const integratorId: string = process.env.INTEGRATOR_ID!;
const FROM_CHAIN_RPC: string = process.env.FROM_CHAIN_RPC_ENDPOINT!;
// Define chain and token addresses
const fromChainId = "56"; // BNB
const toChainId = "42161"; // Arbitrum
const fromToken = "0x55d398326f99059fF775485246999027B3197955"; // USDT
const toToken = "0xaf88d065e77c8cC2239327C5EDb3A432268e5831"; // USDC
// Define the amount to be sent
const amount = "1000000000000000";
// Set up JSON RPC provider and signer
const provider = new ethers.providers.JsonRpcProvider(FROM_CHAIN_RPC);
const signer = new ethers.Wallet(privateKey, provider);
// Function to get the optimal route for the swap using Squid API
const getRoute = async (params: any) => {
try {
const result = await axios.post(
"https://v2.api.squidrouter.com/v2/route",
params,
{
headers: {
"x-integrator-id": integratorId,
"Content-Type": "application/json",
},
}
);
const requestId = result.headers["x-request-id"]; // Retrieve request ID from response headers
return { data: result.data, requestId: requestId };
} catch (error) {
if (error.response) {
console.error("API error:", error.response.data);
}
console.error("Error with parameters:", params);
throw error;
}
};
// Function to get the status of the transaction using Squid API
const getStatus = async (params: any) => {
try {
const result = await axios.get("https://v2.api.squidrouter.com/v2/status", {
params: {
transactionId: params.transactionId,
requestId: params.requestId,
fromChainId: params.fromChainId,
toChainId: params.toChainId,
},
headers: {
"x-integrator-id": integratorId,
},
});
return result.data;
} catch (error) {
if (error.response) {
console.error("API error:", error.response.data);
}
console.error("Error with parameters:", params);
throw error;
}
};
// Function to periodically check the transaction status until it completes
const updateTransactionStatus = async (txHash: string, requestId: string) => {
const getStatusParams = {
transactionId: txHash,
requestId: requestId,
fromChainId: fromChainId,
toChainId: toChainId,
};
let status;
const completedStatuses = ["success", "partial_success", "needs_gas", "not_found"];
const maxRetries = 10; // Maximum number of retries for status check
let retryCount = 0;
do {
try {
status = await getStatus(getStatusParams);
console.log(`Route status: ${status.squidTransactionStatus}`);
} catch (error) {
if (error.response && error.response.status === 404) {
retryCount++;
if (retryCount >= maxRetries) {
console.error("Max retries reached. Transaction not found.");
break;
}
console.log("Transaction not found. Retrying...");
await new Promise((resolve) => setTimeout(resolve, 5000)); // Wait for 5 seconds before retrying
continue;
} else {
throw error; // Rethrow other errors
}
}
if (!completedStatuses.includes(status.squidTransactionStatus)) {
await new Promise((resolve) => setTimeout(resolve, 5000)); // Wait for 5 seconds before checking the status again
}
} while (!completedStatuses.includes(status.squidTransactionStatus));
};
// Set up parameters for swapping tokens
(async () => {
const params = {
fromAddress: signer.address,
fromChain: fromChainId,
fromToken: fromToken,
fromAmount: amount,
toChain: toChainId,
toToken: toToken,
toAddress: signer.address,
slippage: 1,
slippageConfig: {
autoMode: 1,
},
};
console.log("Parameters:", params);
// Get the swap route using Squid API
const routeResult = await getRoute(params);
const route = routeResult.data.route;
const requestId = routeResult.requestId;
console.log("Calculated route:", route);
console.log("requestId:", requestId);
const transactionRequest = route.transactionRequest;
// Execute the swap transaction
const tx = await signer.sendTransaction({
to: transactionRequest.target,
data: transactionRequest.data,
value: transactionRequest.value,
gasPrice: await provider.getGasPrice(),
gasLimit: transactionRequest.gasLimit,
});
console.log("Transaction Hash:", tx.hash);
const txReceipt = await tx.wait();
// Show the transaction receipt with Axelarscan link
const axelarScanLink = "https://axelarscan.io/gmp/" + txReceipt.transactionHash;
console.log(`Finished! Check Axelarscan for details: ${axelarScanLink}`);
// Update transaction status until it completes
await updateTransactionStatus(txReceipt.transactionHash, requestId);
})();