Skip to main content

Wallet utilities

The small things a bot needs around its trades. All free, all keyless. The write endpoints return an unsigned transaction like a trade does: sign it with the wallet and send it through your own RPC. Each one is also available as an action inside a multi-action transaction.

POST /api/transfer

SOL, or any SPL token, to another wallet. A token transfer creates the recipient's token account when it does not exist yet, paid by the sender.

{ "publicKey": "<sender>", "to": "<recipient>", "amount": 0.1 }
{ "publicKey": "<sender>", "to": "<recipient>", "mint": "<mint>", "amount": "100%" }
FieldNotes
mintOmit for SOL.
amountSOL or tokens in normal units, or a percentage of the balance: "100%", "25%".
priorityFee, jitoTipOptional, SOL.
{ "tx": "<base64>", "blockhash": "…", "mint": null, "amount": 0.1, "amountRaw": 100000000, "feeLamports": 0 }

POST /api/burn

Destroys tokens for good. Burning everything also closes the token account, which refunds its rent.

{ "publicKey": "<wallet>", "mint": "<mint>", "amount": "100%" }

POST /api/wrap-sol

Moves SOL into the wallet's wrapped-SOL account, or unwraps by closing that account; unwrapping always returns every lamport in it.

{ "publicKey": "<wallet>", "action": "wrap", "amount": 0.5 }
{ "publicKey": "<wallet>", "action": "unwrap" }

GET /api/balances?publicKey=…

SOL plus every token account of the wallet, both token programs, largest first. Frozen accounts carry "frozen": true, which is what a scam token looks like from the holder's side.

{
"publicKey": "…",
"sol": 1.2345,
"lamports": 1234500000,
"tokens": [
{ "mint": "…pump", "account": "…", "amount": 12345.6, "amountRaw": "12345600000", "decimals": 6, "tokenProgram": "spl-token" }
]
}

This one read lists accounts by owner, an indexed query some public RPCs refuse; the API sends it to a dedicated RPC (INDEXED_RPC_URL).

GET /api/token-info?mint=…

Decimals, supply and token program from the chain; name, symbol, launchpad, active pool and the last price from the data API's own registry.

{
"mint": "…pump",
"decimals": 6,
"tokenProgram": "spl-token",
"totalSupply": 1000000000,
"totalSupplyRaw": "1000000000000000",
"name": "…", "symbol": "…", "uri": "…",
"protocol": "PUMPFUN",
"pool": "<bonding curve or pool>",
"graduated": false,
"quote": "So11111111111111111111111111111111111111112",
"price": 3.2e-8,
"marketCap": 32.1,
"priceUSD": 0.0000031,
"marketCapUSD": 3100,
"priceTime": 1789126483,
"solPriceUSD": 98.9,
"holderReward": false,
"mayhemMode": false,
"cashbackCoin": false
}

On a pump.fun coin the curve's flags are read live: holderReward, mayhemMode, cashbackCoin, and creatorFeeBps when a custom-pair coin sets its own. quote is the curve's quote mint.

price is in the quote asset (SOL for most coins). The price fields appear once the token has traded since the API started watching it; a coin nobody has touched yet reports only the chain facts.

Copy this

const base = "https://sol.shrine.trade";

// Read
const bal = await (await fetch(`${base}/api/balances?publicKey=${wallet.publicKey}`)).json();
const info = await (await fetch(`${base}/api/token-info?mint=${mint}`)).json();

// Write: build, sign, send
const { tx } = await (await fetch(`${base}/api/transfer`, {
method: "POST", headers: { "content-type": "application/json" },
body: JSON.stringify({ publicKey: wallet.publicKey.toBase58(), to: friend, mint, amount: "100%" }),
})).json();
const t = VersionedTransaction.deserialize(Buffer.from(tx, "base64"));
t.sign([wallet]);
await conn.sendRawTransaction(t.serialize());