Squid API is for devs using a client other than javascript. The API offers nearly the full functionality of the SDK, and is only missing some helper functions for front end work.
Below is the most basic example of building with Squid, a cross-chain swap. In this example, we will cover the key concepts involved in the swap.
To find all examples, please visit our examples repo.
Once you download the example folderevmToEVMSwap use the yarn install to install the necessary packages and create a .env file modeled based off the .env.example folder.
The following actions take place in the index.js:
Loading necessary packages and environmental variables
Defining route parameters, RPC provider, and wallet signer
Creating the route request and the transaction status functions
Defining the route parameters and requesting the route
Executing the route transactions
Checking the status of the transactions
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://apiplus.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://apiplus.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);
})();