Buy or sell from your wallet
Example
This is an example. Every value in it (names, amounts, addresses) is there to show you how; change any of them to suit you. It’s swap.mjs from developers/examples, as it is. Anything that sends waits for SEND=1: there is no testnet, so a sent transaction spends real ETH.
// Buy or sell a coin from your own wallet. The API finds the best route and simulates the exact transaction; your// key signs it here and never leaves this process. Without SEND=1 it only builds and prints.// PRIVATE_KEY=0x… COIN=0x… SIDE=buy AMOUNT=0.001 SEND=1 node swap.mjsimport { JsonRpcProvider, Wallet } from 'ethers';
const API = process.env.UPRALLY_API ?? 'https://uprally.co/api/v1';const chain = await (await fetch(`${API}/chain`)).json(); // the network and its node: never hard-codedconst wallet = new Wallet(process.env.PRIVATE_KEY, new JsonRpcProvider(chain.rpc, chain.chainId));
async function post(path, body) { const res = await fetch(`${API}${path}`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) }); const json = await res.json(); if (!res.ok) throw new Error(`${json.error.code}: ${json.error.message} ${json.error.fix ?? ''}`); return json;}
async function send(tx) { const sent = await wallet.sendTransaction({ to: tx.to, data: tx.data, value: BigInt(tx.value), gasLimit: tx.gas ? BigInt(tx.gas) : undefined, chainId: tx.chainId }); const receipt = await sent.wait(); if (receipt.status !== 1) throw new Error(`reverted: ${chain.explorer}/tx/${sent.hash}`); return sent.hash;}
const order = { wallet: wallet.address, token: process.env.COIN, side: process.env.SIDE ?? 'buy', amount: process.env.AMOUNT ?? '0.001', slippageBps: 100 };let built = await post('/swap', order);console.log(`${built.amountIn.amount} ${built.amountIn.symbol} → ${built.amountOut.amount} ${built.amountOut.symbol} (at least ${built.minOut.amount})`);if (process.env.SEND !== '1') { console.log('Built, not sent (set SEND=1 to send).', built.requires.length ? `First: ${built.requires.map((r) => r.step).join(', ')}.` : ''); console.log('RESULT built'); process.exit(0);}// A sale's first time: the approvals, in order, each confirmed. Then built again: the swap is simulated once they are in place.if (built.requires.length) { for (const step of built.requires) console.log(step.step, await send(step.tx)); built = await post('/swap', order);}const hash = await send(built.tx);console.log(`done: ${chain.explorer}/tx/${hash}`);console.log(`RESULT ${hash}`);