IPO Leaderboard API

Queue positions for the token allocation program, ranked from on-chain pool deposits with a time-in-queue multiplier and an optional trading-volume bonus. Read-only except for wallet linking; ranking runs on its own interval.

Leaderboard

Responses carry queue position and deposited amounts. Multipliers, volume and scores are never served: a public score reads as an allocation promise.

GET /health

Service health plus latest-snapshot metadata.

{ "ok": true, "latestSnapshotId": 42, "asOf": 1756677600, "users": 1337,
  "volumeFetchedAt": 1756677000, "volumeDegraded": false,
  "relayer": { "wallets": 2, "redisHealthy": true } }

GET /leaderboard?limit=50&offset=0

The current queue, paginated.

{ "snapshotId": 42, "asOf": 1756677600, "users": 1337,
  "totalDepositsUsd": 523000, "limit": 50, "offset": 0,
  "rows": [ { "rank": 1, "user": "0xabc…", "depositUsd": 12000 }, … ] }

GET /leaderboard/:address

One user's queue position.

{ "snapshotId": 42, "asOf": 1756677600, "users": 1337, "user": "0xabc…", "rank": 17 }

GET /snapshots?limit=20

Ids of retained past rankings, newest first (limit max 100).

{ "snapshotIds": [42, 41, 40, …] }

GET /snapshots/:id?limit=50&offset=0

A past ranking, same shape as /leaderboard.

Pool metadata

Static presentation data for the IPO page — name, ticker, funding history, links — from a catalog committed with the service. Dollar figures are display strings. Nothing here changes at runtime.

GET /pools

Every indexed pool with metadata, as { pools: [ { pool, …metadata } ] }.

GET /pools/:address

One pool's metadata.

{ "pool": "0x033d…0973", "name": "Anthropic", "ticker": "ANTH", "logoUrl": null,
  "description": "Anthropic is an AI safety and research company…",
  "marketCapEstimate": { "low": "$1.5T", "high": "$2.5T" }, "closeTime": null,
  "links": { "website": "https://www.anthropic.com", "x": "https://x.com/anthropicai" },
  "details": { "sector": "Artificial Intelligence / Enterprise Software", "founded": 2021,
    "founder": "Dario Amodei", "headquarters": "San Francisco, CA",
    "type": "Public Benefit Corporation" },
  "fundingRounds": [ { "label": "Series F", "year": 2025, "amountUsd": "$183B" }, … ],
  "totalRaise": "$44B+", "lastValuation": "$1.3T" }

Gasless deposits and withdrawals

The user signs; the service submits and pays the gas. Present only when a relayer key is configured — check relayer on /health first, and fall back to the user calling the pool directly. Every consequential field is inside the signature, so the relayer cannot redirect a deposit or withdrawal; it is only ever msg.sender. Amounts, nonces and deadlines are decimal STRINGS in every body: they exceed Number.MAX_SAFE_INTEGER, and a JSON number would round the signed value into one that no longer matches the signature (400).

POST /relayDeposit

Relay a Permit2-signed deposit. Body: { pool, owner, beneficiary, amount, permitNonce, deadline, signature }.

// domain — Permit2's, and it has NO version field
{ "name": "Permit2", "chainId": <CHAIN_ID>,
  "verifyingContract": "0x000000000022d473030f116ddee9f6b43ac78ba3" }
// types
PermitWitnessTransferFrom(TokenPermissions permitted, address spender, uint256 nonce, uint256 deadline, TokenAllocationDeposit witness)
TokenPermissions(address token, uint256 amount)
TokenAllocationDeposit(address owner, address beneficiary, address pool)
// message
{ "permitted": { "token": <quoteToken>, "amount": <amount> },
  "spender": <DEPOSIT_ADAPTER>, "nonce": <permitNonce>, "deadline": <unix seconds>,
  "witness": { "owner": <owner>, "beneficiary": <owner>, "pool": <pool> } }
// primaryType: PermitWitnessTransferFrom

// additionalAllowances[0].signature signs the TOKEN's domain (read it
// via eip712Domain(); the nonce is the token's nonces(owner)):
Permit(address owner, address spender, uint256 value, uint256 nonce, uint256 deadline)
// message: { "owner": <owner>, "spender": "0x000000000022d473030f116ddee9f6b43ac78ba3",
//   "value": <value>, "nonce": <token.nonces(owner)>, "deadline": <unix seconds> }

// → { "txHash": "0x…", "relayer": "0x…", "pool": "0x…", "owner": "0x…",
//     "beneficiary": "0x…", "amount": "25000000000", "permitTxHash": "0x…"? }

GET /relayerWallets

Wallets that may be named as a withdrawal's executor.

{ "wallets": ["0x99…", "0x88…"] }

GET /poolNonce/:pool/:owner

The nonce a withdrawal or allocation-request signature must carry.

{ "pool": "0x033d…0973", "owner": "0xabc…", "nonce": "3" }

POST /relayWithdraw

Relay a signed withdrawal. Body: { pool, owner, recipient, executor, amount, nonce, deadline, signature }.

// domain — the POOL is the verifying contract
{ "name": "TokenAllocationPool", "version": "1",
  "chainId": <CHAIN_ID>, "verifyingContract": <pool> }
// types
Withdraw(address owner, address recipient, address executor, uint256 amount, uint256 nonce, uint256 deadline)
// message
{ "owner": <owner>, "recipient": <owner>, "executor": <from /relayerWallets>,
  "amount": <amount>, "nonce": <from /poolNonce>, "deadline": <unix seconds> }
// primaryType: Withdraw

// → { "txHash": "0x…", "relayer": "0x…", "pool": "0x…", "owner": "0x…",
//     "recipient": "0x…", "amount": "12500000000" }

POST /relayAllocationRequest

Relay a signed allocation request. Body: { pool, user, quoteAmount, maxPriceUsd, slippageBps, waiveCancellationRights, nonce, deadline, signature }.

// domain — the POOL is the verifying contract
{ "name": "TokenAllocationPool", "version": "1",
  "chainId": <CHAIN_ID>, "verifyingContract": <pool> }
// types
AllocationRequest(address user, uint256 quoteAmount, uint256 maxPriceUsd, uint256 slippageBps, bool waiveCancellationRights, uint256 nonce, uint256 deadline)
// message
{ "user": <user>, "quoteAmount": <quoteAmount>, "maxPriceUsd": <1e18 USD>,
  "slippageBps": <bps>, "waiveCancellationRights": <bool>,
  "nonce": <from /poolNonce>, "deadline": <unix seconds> }
// primaryType: AllocationRequest

// → { "txHash": "0x…", "relayer": "0x…", "pool": "0x…", "user": "0x…",
//     "quoteAmount": "5000000", "maxPriceUsd": "25000000000000000000",
//     "slippageBps": "50", "waiveCancellationRights": false }

POST /relayCancelAllocationRequest

Relay a signed cancellation. Body: { pool, user, nonce, deadline, signature }.

// domain — the POOL is the verifying contract
{ "name": "TokenAllocationPool", "version": "1",
  "chainId": <CHAIN_ID>, "verifyingContract": <pool> }
// types
CancelAllocationRequest(address user, uint256 nonce, uint256 deadline)
// message
{ "user": <user>, "nonce": <from /poolNonce>, "deadline": <unix seconds> }
// primaryType: CancelAllocationRequest

// → { "txHash": "0x…", "relayer": "0x…", "pool": "0x…", "user": "0x…" }

POST /relayClaimOfferedTokens

Relay a signed claim of filled offered tokens. Body: { pool, user, nonce, deadline, signature }.

// domain — the POOL is the verifying contract
{ "name": "TokenAllocationPool", "version": "1",
  "chainId": <CHAIN_ID>, "verifyingContract": <pool> }
// types
ClaimOfferedTokens(address user, uint256 nonce, uint256 deadline)
// message
{ "user": <user>, "nonce": <from /poolNonce>, "deadline": <unix seconds> }
// primaryType: ClaimOfferedTokens

// → { "txHash": "0x…", "relayer": "0x…", "pool": "0x…", "user": "0x…" }

Wallet linking

Credits a trading wallet's volume to a depositing account. The wallet (not the account) signs an EIP-712 message; a per-(account, wallet) nonce makes each signature single-use. An account may link at most 20 wallets, and a wallet linked to one account must be unlinked before it can move to another (409 otherwise).

GET /linkedWallets/:address

Wallets currently linked to an account.

{ "account": "0xabc…", "wallets": ["0xdef…"] }

GET /linkNonce/:account/:wallet

The nonce the next link/unlink signature must carry.

{ "account": "0xabc…", "wallet": "0xdef…", "nonce": 3 }

POST /linkWallet

Link a wallet. Body: { account, wallet, nonce, signature }.

// domain
{ "name": "IPO Leaderboard", "version": "1", "chainId": <CHAIN_ID> }
// types
LinkWallet(address account, address wallet, uint256 nonce)
// message: the lowercased account + wallet and the nonce from /linkNonce

POST /unlinkWallet

Unlink a wallet. Same body and signature scheme as /linkWallet.