TerminalPad
Connect wallet

Integrations

A coin here is an ordinary NEP-141 token in an ordinary Rhea Finance DCL pool on NEAR mainnet. If your tooling swaps on Rhea DCL, it already speaks TerminalPad.

Not deployed yet. TerminalPad's own contracts are not on NEAR yet; their account ids are set at deployment and will be listed in Architecture. The Rhea DCL, USDC and v1.signer accounts on this page are live on NEAR mainnet today (read 2026-09-25).

The chain, for integrators

  • RPC. https://rpc.mainnet.near.org (rate-limited) and https://free.rpc.fastnear.com; for anything serious, use a keyed endpoint. NEAR's JSON-RPC has no batch call: run views concurrently.
  • Blocks about every 0.6 s, final in about 1.2 s. A contract call that calls other contracts completes over several receipts, possibly several blocks; read a transaction's outcome receipt by receipt, not only its top-level status.
  • Gas and storage are NEAR. A transaction may carry at most 1 PGas (the bond needs all of it). Storage costs 1 NEAR per 100 kB, staked and refundable; a token can only be sent to an account that has registered storage on it (storage_deposit, NEP-145).
  • USDC is an ordinary NEP-141 (Circle's, 6 decimals) at 17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1. Do not confuse it with USDC.e at a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48.factory.bridge.near, the older bridged token: no pool or contract here uses it.
  • Tokens are received by push. ft_transfer_call calls the receiver's ft_on_transfer, which returns what it did not use; that part is refunded. A receiver that panics refunds everything — the transaction still "succeeds", so check the receipts.
  • Events are NEP-297 logs (EVENT_JSON:{…}), standards flake (launchpad), flake-lt (vaults), flake-lt-factory and flake-hedge.

Trading

Swap on Rhea DCL (dclv2.ref-labs.near) with ft_transfer_call on the input token, receiver_id DCL:

{"Swap": {"pool_ids": ["<pool>"], "output_token": "<coin or USDC>", "min_output_amount": "…", "skip_unwrap_near": true}}

DCL sends the output back to the sender with a plain ft_transfer, so the sender must be registered on the output token first (a coin's storage is about 0.00125 NEAR).

  • Before the bond, one pool: <USDC>|<coin>|10000.
  • After, two pools in the same pool_ids: to buy, <USDC>|<tracker>|400 (the tracker's reference pool, 0.04%) then <tracker>|<coin>|10000; to sell, the reverse. The tracker in between never lands in the wallet.

The first leg of a buy can also be done off-pool: usdc.ft_transfer_call(<tracker>, amount, '{"mint":{"min_shares_out":"…"}}') mints the tracker at its NAV, with no slippage on that leg (a first mint to an account must be at least 1 USDC). It fails while the vault is paused or its NAV is stale, and the USDC is refunded.

The pool's current coin is always token_y and USDC or the tracker always token_x: USDC's id (17208628…) sorts before every named account, tracker ids start with a digit and coin ids with a letter, and DCL orders a pool's tokens by account id. The side of a swap is therefore known without reading the pool. The same holds for a reference pool: USDC is token_x, the tracker token_y.

Quote with DCL's view quote {pool_ids, input_token, output_token, input_amount} → {amount}, over the whole path at once. One warning from our own mistakes: chaining a multi-leg quote by quoting each leg on its own gives nonsense, because each leg quotes against the current state rather than the state the previous leg would have left.

Discovering coins

The launchpad is the registry. No indexer required:

launchpad.coins_count()                  → u32
launchpad.list_coins(from_index, limit)  → [coin account id]
launchpad.get_launch(coin)               → {creator, params, step, quote, pool_id, usdc_pool_id,
                                            lt, lt_pool_id, left, top, open_point, liquidity,
                                            seed_usdc, lpt_id, extra_lpt_id, bond, …}
launchpad.config()                       → {usdc, dcl, treasury, min_seed_usdc, pool_fee,
                                            launch_cost, bond_cost, lt_factory, bond_backing_usdc, paused, …}

quote tells you the stage: "Usdc" before the bond, "Lt" after. pool_id is always the coin's current pool — the USDC pool, then the tracker pool. lt is filled in from launch either way. params carries the name, ticker, icon, the ipfs:// metadata reference, the underlying, the side and the multiple. A coin is listed once step is "Live"; a launch still running or stalled shows its step in get_launch.

The backing is the quote side of the position: DCL's get_pool(pool_id).total_x (6-decimal USDC before the bond, 18-decimal tracker after), or, for the bond check, the USDC principal computed from the position's liquidity between the current point and top.

Launching programmatically

Two calls, which a wallet can sign together:

  1. launchpad.prepare_launch({params}) with 0.35 NEAR attached (the excess is refunded), about 30 TGas. params: name (1–64 bytes), symbol (1–16), optional icon (≤ 2 kB data URI) and reference (≤ 512 bytes), price_usd_e18 (the opening price, USD × 10¹⁸), underlying (a catalogue key, e.g. "NVDA"), is_short, leverage (1–5). One prepared launch per creator at a time; cancel_prepared() withdraws it and returns the 0.35 NEAR.
  2. usdc.ft_transfer_call(launchpad, seed, '{"seed":{}}') with at least 400 TGas (the app sends 450). The seed must be at least config().min_seed_usdc. This runs the launch.

The creator is the account that calls both: the seed payer, the recipient of the seed coins and the owner of the fee stream. The coin's account id is drawn at launch (<ticker>-<6 hex>.<launchpad>) and appears in the flake events of the transaction's receipts. A stalled launch is continued by resume_launch(coin) (anyone, 300 TGas); before anything reached the pool, the creator may abandon_launch(coin).

Events

StandardEventMeaning
flakelaunch_prepared {creator, symbol}parameters stored
flakepool_created {coin, pool_id, open_point, left, top}the pool exists at the seed's price
flakecoin_created {coin, creator}the coin account exists
flakelaunched {coin, creator, pool_id, lpt_id, seed_usdc, seed_fee_usdc, usdc_in_pool, coin_to_creator, underlying, is_short, leverage}the position is live
flakelaunch_stalled {coin, step, reason}a step failed; resume_launch continues it
flakebond_started, bonded {coin, lt, pool_id, lpt_id, usdc_principal, lt_minted, lt_in_pool, coin_in_pool, open_point}, bond_stalledthe bond, step by step; after bonded the market is a new pool
flakefees_collected {coin, quote_token, quote, coin_amount}swap fees claimed from the position and booked
flakecreator_fees_claimed {coin, creator, token, amount}a creator withdrew their share, one token per event
flake-lt-factorylt_created {lt}, lt_bonded {lt}a tracker exists; a tracker bonded (NAV live, hedge enabled)
flake-ltnav_posted {nav, hedge_equity_usd, underlying_price, timestamp_secs}a fresh signed NAV
flake-ltminted, redeemed, redeem_prepared, redeem_executed, redeem_skipped, redeem_cancelledmint, redeem and the queue
flake-lthedge_funded {to, amount}, hedge_returned {from, amount}USDC to the hedge contract, and back
flake-lthedge_funder_updated {funder}the hedge contract changed; null is the kill switch
flake-hedgefunded, deposit_to_venue, return_requested, signed, return_settled, return_cancelled, sign_failedevery leg of the hedge

bonded on the launchpad is the one to handle carefully: the pool changes, so a tape built on the old pool ends there and a new one begins. The coin is the stable identifier across both.

Indexing the tape

The pool is the tape. Every swap on a coin is a transfer of the coin between DCL and the trader, so a trade placed by a bot you have never heard of is visible exactly like one placed on our own front. NearBlocks' API (api.nearblocks.io/v1/fts/<coin>/txns) lists them; DCL's own pool counters (get_pool: volume_x_in, volume_x_out, total_fee_x_charged) give all-time volume and fees.

Coins show up on DexScreener and GeckoTerminal under the network near; GeckoTerminal names a Rhea DCL pool refv2-<token_x>:<token_y>:<fee> (https://www.geckoterminal.com/near/pools/refv2-…). After a bond, look the coin up again by its new pool.

The site reads NEAR directly; there is no subgraph of ours on NEAR yet. Wallet login on the site is through NEAR Connect, with any NEAR wallet that can sign several transactions at once.

Reading a tracker's position

A tracker's position is not on NEAR. It sits in the Hyperliquid master account the hedge contract controls. What NEAR does record is the routing and every dollar that leaves a vault or comes back to it:

factory.underlying(symbol)      → {market_id, max_leverage, listed}   // market_id = "xyz:NVDA"
factory.max_leverage_for(symbol)
factory.lt_for(underlying, is_short, leverage) → tracker account, if it exists
factory.list_lts(from_index, limit), factory.get_lt(lt) → {underlying, is_short, leverage, market_id, live, bonded}
vault.state()                   → usdc_held, hedge_outstanding, hedge_funder, buffer_bps, fees_bps, paused, …
vault.fundable_usdc(), vault.max_redeem_now(), vault.preview_mint(usdc), vault.preview_redeem(shares)
vault.peek_nav()                → {nav, hedge_equity_usd, underlying_price, updated_at_secs, stale, bond_gated, bonded}
vault.nav()                     → the NAV mint and redeem use; panics when stale or paused
hedge.book(vault)               → {managed, idle, on_venue, returning}
hedge.state(), hedge.master_address()

The master account is public on Hyperliquid. Its info API (POST https://api.hyperliquid.xyz/info) serves, with no key:

  • {"type": "clearinghouseState", "user": "<master>", "dex": "xyz"} — the master account's xyz balance and positions;
  • {"type": "metaAndAssetCtxs", "dex": "xyz"} — every xyz market with its mark, funding, open interest and maximum leverage;
  • {"type": "fundingHistory", …} — settled hourly funding.

Hyperliquid's own numeric ids for xyz markets change as markets are listed; the factory stores the market's name (xyz:NVDA), and so should you. The split of the master account between trackers is not on either chain: it rests on the keeper's ledger, stated per tracker in each NAV post's hedge_equity_usd. See The hedge book.

Permissions

Everything a trader, a creator or an integrator needs is permissionless: swap, quote, launch, read, bond a coin (bond, 0.05 NEAR) or a tracker (poke_bond), resume a launch or a bond, collect fees, claim protocol fees to the treasury, mint and redeem trackers at NAV, execute the redemption queue (execute_redemptions), re-centre a tracker's reference pool once due (rebalance), measure what 1Click delivered to the hedge contract (sync_balance), and relay a NAV the keeper has already signed (post_nav). The restricted calls are:

  • claim_creator_fees, abandon_launch — the creator of that coin;
  • the launchpad's set_paused — its owner, for new launches only;
  • the factory's get_or_create_lt — its owner or an authorised launcher; its listing, defaults, reference pools, bond depth and direct bond — its owner;
  • a vault's fund_hedge — its owner or its hedge contract, paying only the hedge contract;
  • a vault's set_hedge_funder, set_paused, set_fees, set_risk_params, set_nav_signer and other settings — its owner;
  • the hedge contract's deposit_to_venue, request_return, settle_return, cancel_return — its operator (or owner); approve_agent, set_caps, set_operator, set_vault, set_paused — its owner;
  • a reference pool's forced rebalance and withdraw_idle — its owner;
  • cancel_redeem — the holder who queued the redeem.