API

Lookup tables

Launch with up to 16 buyers in one block: a lookup table lets several wallets buy in one transaction.

A Jito bundle holds 5 transactions, so a plain launch bundle is the create plus 4 buyers. An address lookup table lists the accounts a coin's buys touch (its curve accounts, each wallet's token account), so one transaction can carry about 4 buyers instead of one, and a bundle about 16. The table lives on chain under your wallet; its rent (about 0.002 SOL plus 32 bytes per address) comes back when you close it after the launch.

Order of events: create the table and wait until it is ready (one slot after the last extend, about a second) → build the bundle with buyers entries that name the table → send the bundle → later, deactivate and close the table to get the rent back.
POSThttps://api.trenchytools.lol/api/sol/lut

1. Create the table

FieldTypeDescription
authoritystringThe wallet that owns the table and pays its rent (the dev wallet is a good choice).
mintstringThe coin (it may not exist yet: pass the new mint's public key).
walletsstring[]Every wallet that will buy (up to 60).
creatorstringThe coin's creator (defaults to authority); needed when the coin does not exist yet.

You get the table's address and one or more unsigned transactions: the first creates the table and adds the first addresses, the others add more. Sign each with authority and send them in order with /api/sol/send, waiting for the first to confirm.

const { lookupTable, transactions, rentSol } = await fetch(`${BASE}/api/sol/lut?api-key=${API_KEY}`, {
  method: 'POST', headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ authority: dev.publicKey.toBase58(), mint: mint.publicKey.toBase58(), wallets: buyers.map((b) => b.publicKey.toBase58()) }),
}).then((r) => r.json())

for (const b64 of transactions) {
  const tx = VersionedTransaction.deserialize(Buffer.from(b64, 'base64'))
  tx.sign([dev])
  const { signature } = await fetch(`${BASE}/api/sol/send?api-key=${API_KEY}`, {
    method: 'POST', headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ transaction: Buffer.from(tx.serialize()).toString('base64') }),
  }).then((r) => r.json())
  // wait for it: GET /api/sol/tx/:signature until confirmed
}
// then poll GET /api/sol/lut/:lookupTable until ready === true
Response
{ "lookupTable": "…", "addresses": 14, "rentSol": 0.0043, "transactions": ["base64…"], "encoding": "base64" }

2. Check it is ready

cURL
curl "https://api.trenchytools.lol/api/sol/lut/LOOKUP_TABLE?api-key=YOUR_API_KEY"
Response
{ "lookupTable": "…", "authority": "…", "addresses": ["…"], "lastExtendedSlot": 3812, "ready": true, "deactivated": false }

3. Build the bundle with buyers entries

In /api/sol/trade-local a bundle entry may carry buyers: [{ publicKey, amount }, …] plus lookupTable instead of a single publicKey. Up to 6 buyers per entry are accepted; about 4 fit in 1232 bytes (every signer still costs an address and a signature). Each buyer signs; the first one pays the network fee. Buyers are priced in order on the same curve.

JavaScript
const txs = await fetch(`${BASE}/api/sol/trade-local?format=json&api-key=${API_KEY}`, {
  method: 'POST', headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify([
    { publicKey: dev.publicKey.toBase58(), action: 'create', mint: mint.publicKey.toBase58(),
      tokenMetadata: { name: 'My Coin', symbol: 'MYC', uri: metadataUri }, amount: 0.5, denominatedInSol: 'true', slippage: 10, priorityFee: 0.002 },
    { action: 'buy', mint: mint.publicKey.toBase58(), lookupTable, denominatedInSol: 'true', slippage: 25,
      buyers: buyers.slice(0, 4).map((b) => ({ publicKey: b.publicKey.toBase58(), amount: 0.2 })) },
    { action: 'buy', mint: mint.publicKey.toBase58(), lookupTable, denominatedInSol: 'true', slippage: 25,
      buyers: buyers.slice(4, 8).map((b) => ({ publicKey: b.publicKey.toBase58(), amount: 0.2 })) },
  ]),
}).then((r) => r.json())   // { transactions: [{ transaction, expected, perBuyer: [{ publicKey, tokens, sol }] }, …] }

const signed = txs.transactions.map((t, i) => {
  const tx = VersionedTransaction.deserialize(bs58.decode(t.transaction))
  tx.sign(i === 0 ? [dev, mint] : buyers.slice((i - 1) * 4, i * 4))
  return bs58.encode(tx.serialize())
})
// POST /api/sol/bundle { transactions: signed }

4. Get the rent back

POST /api/sol/lut/:address/deactivate { authority } returns a transaction to sign and send. About four minutes later (513 slots), POST /api/sol/lut/:address/close { authority, recipient? } returns the one that closes the table and refunds the rent. Too early gets 409 cooling_down with the seconds left.