Rand Protocol
Documentazione
Riferimento

API dell'explorer

Una sintesi dell'API REST e del feed WebSocket di RandScan su randscan.org: che cosa può offrire l'explorer di una blockchain shielded, gli endpoint e i limiti di frequenza, con un link alla guida completa.

Usa l’API dell’explorer per leggere la chain 20 da uno script, un bot o un backend senza gestire un nodo. La guida completa con ogni campo si trova nel repository dell’explorer, randscan.org/docs/api.md; questa pagina ne è il riepilogo.

URL di basehttps://randscan.org/api/v1
WebSocketwss://randscan.org/ws
anonimo60 richieste al minuto per IP
con una chiave API600 richieste al minuto; le chiavi si ottengono da randscan.org/dashboard e si inviano come Authorization: Bearer rsk_… o X-API-Key

Che cosa può mostrare l’explorer di una chain shielded

In questa API non compaiono da nessuna parte account, saldi, mittenti o destinatari e, dalla chain 14, nemmeno un asset pubblico su un bundle: un trasferimento di RAND e un trasferimento di un qualsiasi token RPL hanno la stessa forma. Ciò che serve è: ogni blocco; il bundle con asset nascosto di ogni transazione così come pubblicato (anchor, quattro nullifier, quattro commitment, commissione, burn_a, burn_r, burn_asset, ora, dimensioni della prova e della busta e, dalla chain 17, l’auth_commit e la dimensione della prova di autorizzazione); l’azione che una transazione conteneva e i suoi campi pubblici, inclusi la registrazione, i mint e i burn di un token RPL, le azioni di governance del bridge e la transizione di stato di un invoke RPL-2; il registro dei token RPL; le celle e il vault di un programma; l’albero dei commitment foglia per foglia; l’insieme dei nullifier; il registro dei validator; l’audit dell’offerta; lo stato pubblico del bridge, inclusi la pausa dei mint e l’insieme dei guardiani PQ. Quale asset abbia spostato un trasferimento è visibile solo a una viewing key o a una transaction key, nel browser. GET /accounts/:address risponde 410 { "error": "no_accounts" }.

Convenzioni: gli importi sono stringhe decimali di unità. Un importo il cui asset_index indica un token diverso da RAND (indice 0) è espresso nella più piccola unità di quel token, non nei nove decimali di RAND; risolvi l’indice tramite GET /tokens/:id prima di dividere. registration_fee e next_index sono i due campi che l’explorer serve come semplici numeri JSON; hash, id di programma, commitment e nullifier sono 64 caratteri esadecimali minuscoli; gli indirizzi dei validator sono in base58; le altezze sono interi decimali a partire da 0; vengono indicizzati solo i blocchi confermati, quindi un blocco presente nell’API è definitivo. Le liste accettano page (da 1) e limit (da 1 a 100, predefinito 20), restituiscono { "data": [...], "pagination": { page, limit, total, total_pages, has_next, has_prev } }, dal più recente. Gli errori sono { "error", "message", "code" } con 400, 404, 410, 429 o 500.

Endpoint

metodo e percorsorestituisce
GET /healthstato dell’explorer e ritardo dell’indexer
GET /statschain id, altezza, view, dimensione dell’albero, numero di validator, stake totale, offerta, numero di programmi, tempo medio di blocco, epoch, l’hash di genesi e la build del nodo; hc_bundle e hc_auth; limits (i cinque limiti di genesi, poi envelope_bytes, hardening_v6, hc_auth, i gas_price e byte_price di genesi, gas_metering, bundle_gas_limit, adjust_bps e, su un nodo dalla v0.6.8, program_state); gas_prices, i prezzi correnti in punta alla chain. limits non include gli altri nuovi campi della v0.6.8 (binding_domain, proof_window_blocks, i tetti di prezzo, admission_by_vote, testnet): leggili da rand_getLimits del nodo
GET /supplyl’audit dell’offerta del nodo alla lettera, inclusi i quattro contatori vesting_*, tutti "0" sulla chain 20, il cui genesi non ha una sezione vesting, e program_rand_out e program_rand_held di RPL-2, i RAND pagati dai vault dei programmi e i RAND che questi ancora detengono
GET /bridgelo stato pubblico del bridge: emitter, emitters, guardian_set_index, guardians, pq_guardians, mint_paused, pause_nonce, list_nonce, pause_key, registration_fee, burn_sequence, next_index (null dalla chain 14), rotation_nonce, rules_v2 (con global_minted_in_window e global_mint_headroom), min_inbound_sequence, assets ed endpoints, la rappresentazione propria dell’explorer di ciascun emitter così come la stampa la chain di origine. Non serve i campi fees, rotation_rules e pending_rotations della v0.6.8 del nodo: leggili da rand_getBridgeState
GET /bridge/assetsuna riga per backing: la riga del registro (index, chain, token, asset_id, locked, minted_today, mint_cap_per_day e, su un nodo v0.6.8, minted_in_window, mint_window_secs e mint_headroom, il deposito più grande che i limiti ammettono ora) unita a symbol, name, decimals e backings, e ai totali indicizzati. Per backing: burns, burned, outstanding (il locked del registro) e deposits/deposited solo quando il token ha un unico backing (null altrimenti: un deposito indica il token che ha coniato, non la moneta bloccata per esso). Per token, identici su ogni riga con lo stesso index: token_deposits, token_deposited, token_burns, token_burned, first_height, last_height; conta ogni index una sola volta quando calcoli i totali
GET /bridge/tokensla allowlist dei token, una lista statica: USDT e USDC su Ethereum, BSC, Tron e Solana, con USDC su Tron dismesso
GET /tokensl’intero registro dei token RPL come memorizzato in cache dal nodo: enabled, registration_fee, next_index, tokens
GET /tokens/:idun token per indice di registro, id di 64 caratteri esadecimali o forma testuale rpl1…, più deploy_tx e supply_history; 404 se nessuno corrisponde
GET /nodesil nodo dell’explorer e i suoi peer, con geolocalizzazione
GET /proversi prover delegati noti all’explorer (il suo elenco; la chain non ne tiene traccia): se ciascuno risponde al proprio prover_info, la sua capacità e commissione, e dove si trovano i suoi host
GET /blocks?page&limit&proposer, GET /blocks/latest?limit, GET /blocks/:idblocchi, per altezza o hash
GET /transactions?page&limit&kind&height&validator&program, GET /transactions/latest, GET /transactions/:hashtransazioni; kind è transfer, mint, deploy, call, bond, unbond, withdraw, bridge_attest, bridge_burn, register_token, token_mint, set_authority, token_burn, pause_mints, unpause_mints, register_bridged_token, list_backing, invoke. Non esiste token_transfer: il trasferimento di un qualsiasi token RPL è transfer
GET /transactions/:hash/envelopesle note create da una transazione con le relative buste: i quattro slot del bundle, dummy inclusi, più le note calcolate dalla chain che vengono aggiunte da un deposito bridge_attest, da un token_mint, dal mint iniziale di un register_token o dai pagamenti di un invoke; per una call, h_in e la trascrizione sigillata dell’input
GET /envelopes?from_leaf&limitfoglie con buste, dalla più vecchia, fino a 1.000 per pagina, per la scansione della cronologia
GET /notes?page&limit, GET /notes/:idfoglie dell’albero, per commitment o indice di foglia
GET /nullifiers/:nfla transazione che ha pubblicato un nullifier
GET /validators, GET /validators/:addressil registro, con share_percent, blocks_proposed, ultima altezza proposta
GET /programs?page&limit, GET /programs/:idprogrammi distribuiti (base_pc, words_len, code_hash, public_words_len, public_digest) con il numero di call e invoke; le call e gli invoke recenti di un programma e il suo program_state, letto in tempo reale dal nodo: vault (per asset), le prime 100 cells in ordine di chiave e cells_next
GET /programs/:id/cells?after&limituna pagina delle celle del programma in ordine di chiave, in tempo reale dal nodo (limit da 1 a 1.000, predefinito 100): { "cells", "next" }; 404 su una chain senza sezione program_state
GET /search?q=blocchi, transazioni, programmi, note, nullifier e validator
curl -s https://randscan.org/api/v1/stats
curl -s https://randscan.org/api/v1/tokens/1
curl -s https://randscan.org/api/v1/transactions/8aa13d1f76d28f63a46c30bb09ef44b1ba35083ca80ba7301997f98e5f783666

Un riepilogo di transazione (un mint del faucet di 10 RAND all’altezza 102.197 della chain 18):

{
  "hash": "a20b…feb5", "height": 102197, "block_hash": "f362…a06f", "tx_index": 0,
  "kind": "mint", "fee": "0", "timestamp_ms": 1790777106034,
  "has_bundle": false, "program": null, "validator": "EdrEC2QRQrQF64iRXxF9927jNj6RidiHHByzx5xD6F1e",
  "amount": "10000000000", "asset_index": null
}

amount è valorizzato solo per i tipi con un importo pubblico — mint, bond, unbond, withdraw, bridge_attest, bridge_burn, token_mint, token_burn e un register_token con un mint iniziale — ed è null per un trasferimento, il cui asset_index è sempre null a sua volta. has_bundle è false per mint, unbond, withdraw, pause_mints e unpause_mints, che non portano alcun bundle e non pagano commissione. Il dettaglio aggiunge chain_id, bundle e, per ciascun tipo: words_len di un deploy; call_proof_len, input_envelope_len e receipt (tx, program, tier, outputs, height, index, h_in, h_pub) di una call; registered di un bond; action_nonce di un unbond o di un withdraw; attestation_len, recipient, note_time, deposit_r, commitment, pq_signers di un’attestazione del bridge; relayer_fee, to_chain, bridge_to, bridge_token di un burn del bridge; token_action di un’azione RPL (i campi propri dell’azione, etichettati da kind), con recipient, note_time, deposit_r per una nota coniata e action_nonce per un token_mint o un set_authority; bridge_governance di un’azione di governance del bridge, con pq_signers su tutte tranne pause_mints; call_proof_len, input_envelope_len, receipt e transition di un invoke (la rappresentazione del nodo: le celle lette e scritte, l’inflow e ogni nota pays e mints con il suo recipient, time, r e cm). Un tipo della v0.6.8 che questa build dell’explorer non conosce (admit_validator, slash_equivocation, le rotazioni _v2, cancel_rotation) è other.

Sulla chain 20, con le commissioni del bridge, l’amount di un bridge_attest e di un bridge_burn è l’importo lordo: quello firmato dai guardiani o quello bruciato dal bundle. L’explorer non serve il deposito netto, l’importo rilasciato né la nota di commissione; leggili da rand_getTransaction del nodo (deposit_amount, release_amount, fee_note) e da rand_getBridgeBurn. Il burn di 0,999 zUSD all’altezza 2.899 qui risulta "amount": "99900000"; i guardiani hanno firmato un rilascio di 99800100.

Il bundle nel dettaglio di una transazione è il bundle con asset nascosto, senza campo asset e senza un secondo bundle su un burn. Questo ha pagato la call dell’esempio curl qui sopra, all’altezza 98.335 della chain 18; quella transazione non esiste sulla chain 20, dove il terzo curl risponde 404:

"bundle": {
  "anchor": "b814…b1ed",
  "nullifiers": ["49d4…a766", "3363…61ea", "aac0…fcfc", "546c…3efd"],
  "commitments": ["b52b…4f7b", "9ddd…0448", "5fa7…1630", "2827…8343"],
  "fee": "6191437", "burn_a": "0", "burn_r": "0", "burn_asset": 0, "time": 98185,
  "proof_len": 1504260, "envelope_len": [1860, 1860, 1860, 1860],
  "auth_commit": "0bda…6512", "auth_proof_len": 1367303
}

auth_commit e auth_proof_len sono l’autorizzazione divisa (chain 17 e successive, dove limits.hc_auth è impostato): la prova del bundle è costruita a partire dalla viewing key e pubblica auth_commit, e una seconda, piccola prova sulla spend key, legata alla stessa transazione, deve corrispondervi. Entrambe le prove sono riportate solo per lunghezza. Ogni busta sulla chain 20 è di 1.860 byte (limits.envelope_bytes) e porta un memo cifrato; le chain fino alla 17 sigillavano 1.348 byte. Il limite di gas dichiarato di una call è un valore pubblico della sua prova, non un campo della receipt, quindi l’explorer non lo mostra per transazione; la commissione pagata è in fee.

burn_a è l’asset privato bruciato, diverso da zero solo in un token_burn, in un bridge_burn o in un invoke che deposita o brucia un token, con burn_asset che indica l’indice del registro; burn_r sono i RAND bruciati, diversi da zero solo in un bond o in un invoke che deposita RAND nel vault del programma.

Sulla chain 20 zUSD (“Shielded USD”, otto decimali) si trova all’indice 1, elencato nel genesis con tutti e sette i backing (registered_at 0, quindi deploy_tx è null) e riportato dalla chain 14 con lo stesso asset id. GET /bridge/assets restituisce quindi sette righe sotto l’indice 1. Altri cinque token sono stati registrati sulla chain 20 nel suo primo giorno, agli indici da 2 a 6, tre dei quali con un programma come autorità di mint; GET /tokens li elenca. Sulla chain 20 GET /bridge riporta rules_v2 con un tetto globale di mint di 4,000 zUSD ("400000000000") per finestra di 86,400 secondi, rotation_nonce 0, burn_sequence 13 al genesis e un min_inbound_sequence di 3 per le chain di origine 2, 3 e 4 e di 7 per la chain di origine 5 (1 e 4 sulla chain 19): la soglia minima di replay del genesis, ovvero la sequenza di lock più bassa che l’attestazione di una chain di origine può riportare per essere coniata qui. Sulla chain 14 è stato registrato all’altezza 256 da un register_bridged_token, con gli altri sei backing aggiunti da transazioni list_backing.

Aprire le envelope nel browser

Un’envelope è un dato pubblico della chain e l’explorer non detiene alcuna chiave. La sua pagina della transazione e la pagina History aprono le envelope nel browser con una build WebAssembly del codice stesso del nodo (crates/randscan-viewing): incolla una viewing key (nk, 64 hex) per vedere ogni nota inviata o ricevuta da quella parte, una chiave di transazione per aprire un singolo pagamento, una chiave di chiamata per aprire gli input di una singola chiamata, oppure un file di chiavi del wallet, del quale viene conservata solo la viewing key derivata. Una nota aperta viene verificata ricalcolandone l’impegno. Il suo asset divulgato è l’indice del registro dei token, risolto tramite GET /tokens per ottenere simbolo e decimali; è l’unico punto in cui, per un trasferimento, un importo è legato a un asset. Uno slot fittizio non si apre con nessuna chiave e appare identico a una nota che non è tua. Nulla di una chiave transita sulla rete; per costruire lo stesso strumento, recupera /envelopes e /transactions/:hash/envelopes e usa il crate.

Feed WebSocket

Connettiti a wss://randscan.org/ws e sottoscrivi blocks, transactions o stats:

{ "type": "subscribe", "channel": "blocks" }
{ "type": "new_block", "block": { … BlockSummary … } }
{ "type": "new_transaction", "transaction": { … TransactionSummary … } }
{ "type": "stats_update", "stats": { … } }

Invia { "type": "ping" } ogni 30 secondi attraverso i proxy. Il feed non prevede replay: in caso di disconnessione, riconnettiti e recupera i dati mancanti con GET /transactions?height=.

Eseguire il proprio explorer

Tutto ciò che è qui descritto è servito dall’explorer open source in randprotocol/randscan.org; l’indexer richiede solo il JSON-RPC rand_* di un nodo e un database PostgreSQL.

Ultima verifica rispetto al commit c0878c3f del fullnode (chain 21) il 2026-10-12 e randscan commit fffa404 (docs/api.md), the live API at randscan.org, 2026-09-20, the live API at randscan.org on chain 18, 2026-09-30, the live API at randscan.org on chain 19, 2026-10-01, randscan commit 4390731 (docs/api.md: RPL-2, BRG-19 and `/provers`) and the live API at randscan.org on chain 20, 2026-10-01; `/stats` on chain 21, 2026-10-12. Dove il codice e questa pagina non concordano, ha ragione il codice; segnalacelo.