biatec-router
v1.0.1
Published
Biatec Router NPM library
Readme
Biatec Router
Biatec router allows users to swap efficiently from one asset to another.
At the time of writing it is the most efficient DEX aggregator on Algorand as it allows to do trades at Pact.Fi, TinyMan and Biatec DEX. Other DEX aggregators does not handle Biatec DEX - the first concentrated liquidity AMM on Algorand.
Authentication
Biatec Router is using ARC14 authentication header which prevents the DDOS attacks and allows incentivization of good actors. Any user or app is required to sign the algorand authentication transaction with realm BiatecRouter#ARC14.
Base setup
// Setup Algorand Client
const token = process.env.ALGOD_TOKEN || "";
const server =
process.env.ALGOD_SERVER || "https://testnet-api.algonode.cloud";
const port = process.env.ALGOD_PORT || "";
const algodClient = new algosdk.Algodv2(token, server, port);
// Setup Account
const email = process.env.ARC76_EMAIL;
const password = process.env.ARC76_PASSWORD;
if (!email || !password) {
throw new Error("ARC76_EMAIL and ARC76_PASSWORD must be defined in .env");
}
const account = await generateAlgorandAccount(password, email);
// Fetch params
const params= await algodClient.getTransactionParams().do()
Get auth tx
import { biatecRouter, authTransaction} from "biatec-router";
import {makeArc14AuthHeader} from "arc14";
...
const authTx = await authTransaction(account.addr.toString(), params);
const signed = arc14Tx.signTxn(account.sk);
const authHeader = makeArc14AuthHeader(signed);
biatecRouter.OpenAPI.HEADERS = { 'Authorization': authHeader };Request quotes
Use the same endpoint as for route execution and calculate the quotes.
const requestBody = {
sender: account.addr.toString(),
fromAsset: 0,
toAsset: 452399768,
swapAmount: 5_000_000,
receiveMinimum: 0,
routesCount: 1,
maxHops: 3,
};
const response = await biatecRouter.RouterService.postApiV1RouterRouteTxs(requestBody);
if (!response.routes || response.routes.length === 0) {
console.log("No routes found.");
return;
}
const route = response.routes[0]
console.log("route",route)Execute quotes
Always use receiveMinimum when you want to execute the swap to protect your funds.
const requestBody = {
sender: account.addr.toString(),
fromAsset: 0,
toAsset: 452399768,
swapAmount: 5_000_000,
receiveMinimum: 300_000_000,
routesCount: 1,
maxHops: 3,
};
const response = await biatecRouter.RouterService.postApiV1RouterRouteTxs(requestBody);
if (!response.routes || response.routes.length === 0) {
console.log("No routes found.");
return;
}
const route = response.routes[0]
console.log("route",route)
if (!route.txsToSign || route.txsToSign.length === 0) {
console.log("No transactions to sign in the route.");
return;
}
// Decode Transactions
const transactions: algosdk.Transaction[] = [];
for (const txBase64 of route.txsToSign) {
let txBytes = new Uint8Array(Buffer.from(txBase64, "base64"));
const tx = algosdk.decodeUnsignedTransaction(txBytes);
transactions.push(tx);
}
transactions.forEach((tx) => {tx.group = undefined;});
const groupId = algosdk.computeGroupID(transactions);
transactions.forEach((tx) => (tx.group = groupId));
const signedTxs: Uint8Array[] = [];
for (const tx of transactions) {
const signedTx = tx.signTxn(account.sk);
signedTxs.push(signedTx);
}
const txResponse = await algodClient
.sendRawTransaction(signedTxs)
.do();
// Wait for confirmation
const result = await algosdk.waitForConfirmation(
algodClient,
txId,
4
);