Work in base units as bigint. Parse the response with a reviver so large amounts do not pass through a double.
const BASE = "https://swap-api.sodae.io";const bigintFields = new Set(["in_atoms", "out_atoms", "min_out_atoms", "amount"]);const parse = (text: string) => JSON.parse(text, (k, v) => (bigintFields.has(k) && typeof v === "number" ? BigInt(v) : v));async function get<T>(path: string): Promise<T> { const res = await fetch(BASE + path); const body = parse(await res.text()); if (!res.ok) throw Object.assign(new Error(body.error ?? res.statusText), { status: res.status, body }); return body;}
JSON.parse has already rounded a number above 2^53 by the time the reviver sees it. For tokens with very large supplies, parse with a bigint-aware library such as json-bigint instead.
The transaction is format v1. Decode it with a v1-aware library. @solana/web3.js 1.x throws on the version byte.
const bytes = Uint8Array.from(atob(swap.tx_base64), (c) => c.charCodeAt(0));// Decode, sign with the key for user_wallet, and serialize with your v1-aware library.const signed = await signV1Transaction(bytes, wallet);const sig = await rpc.sendTransaction(signed, { encoding: "base64" });
In a browser with a Wallet Standard wallet, pass the decoded transaction to the wallet’s sign method. The wallet signs and you send the bytes it returns.Confirm against swap.last_valid_block_height. Once the chain is past it, request a new swap rather than resending.