Pour les développeurs / API des applications
API des applications
Quatre services de première partie se tiennent à côté de la chaîne. Aucun n'est la chaîne, aucun n'est versionné, et chacun échoue à sa façon - c'est à cela que sert cette section.
Ce que c'est
L'interface de la chaîne est le JSON-RPC. Tout ce qui est sur ces pages est quelque chose qu'une application s'est construit puis a laissé joignable : un index Postgres sur le spool de logs du séquenceur, un processus qui détient une clé, une boucle de jeu. C'est pratique, c'est de première partie, et ce n'est pas faisant autorité.
Une lecture ici n'est pas une lecture de la chaîne
Chaque chiffre ici est passé par un indexeur, un cache, ou les deux. Un indexeur arrêté continue de répondre avec son dernier état et aucun champ de la réponse ne le dit ; les seules routes qui vous le disent sont les routes de santé, et il faut les interroger. Si la réponse décide de l'argent, lisez la chaîne.
A read-only view of what the Pepper indexer has derived from the chain's logs: constant-product pools, concentrated pools, swaps, liquidity events and positions. It reads Postgres rather than the chain, deliberately.
- Pile
- Python, standard-library ThreadingHTTPServer, psycopg pool of at most 8 connections, HTTP/1.1
- Montée sur
- /api/ on the Pepper origin
The archive the node deliberately is not. Blocks, mini-blocks, transactions, receipts, logs, call traces, decoded transfers, accounts, tokens, NFTs and the name-service record, all from a Postgres index fed by the sequencer's own log spool.
- Pile
- Python, standard-library ThreadingHTTPServer, psycopg pool of at most 12 connections, plus live reads against the node
- Montée sur
- /api/ on the explorer origin
The only first-party service that WRITES to the chain. It holds the faucet operator key and submits the drip on your behalf, which is why the page needs no wallet.
- Pile
- Python, standard-library SimpleHTTPRequestHandler serving a static site as well as the API, signing with eth-account
- Montée sur
- its own origin; the home origin re-exposes two of its routes
A WebSocket server for the games, with a small HTTP surface beside it for health and for the figures the site's chrome draws. The socket is the interface; the HTTP routes are a snapshot of it.
- Pile
- Node, `ws` in noServer mode behind a plain http server, one event loop for eight game rooms
- Montée sur
- /api/ and /ws/ on the arcade origin
Où ils répondent
| Service | URL de base |
|---|---|
| API de l'explorateur | https://explorer.picklechain.xyz/api/aussi montée sur /api/ par les sites du service de noms et de la boîte à outils |
| API du DEX Pepper | https://pepper.picklechain.xyz/api/même origine seulement ; un navigateur sur une autre origine ne peut pas l'appeler |
| Faucet | https://faucet.picklechain.xyzl'origine d'accueil réexpose POST /drip et GET /faucet-status |
| Arcade | https://minigame.picklechain.xyz/api/et le socket sur wss://minigame.picklechain.xyz/ws/<room> |
Aucun de ces services n'a de nom d'hôte à lui. Chacun est un montage /api/ sur l'origine d'une interface, ce qui fait de la base publique un fait nginx plutôt qu'un fait de service : un déploiement qui déplace un site déplace son API avec lui, et le chemin à l'intérieur reste le même. Sur une pile que vous faites tourner vous-même, les mêmes services répondent sur le bouclage, sur le port que nomme la page de chacun d'eux.
Il n'y a pas de /v1, pas d'en-tête de version et pas de politique de dépréciation sur les quatre. Il n'y a pas non plus de document OpenAPI ni de JSON Schema dans le dépôt, donc un champ peut changer de forme entre deux déploiements sans rien contre quoi comparer. Lisez défensivement : ignorez les clés que vous ne connaissez pas, et n'échouez pas sur une clé qui a disparu.
Authentification
Aucun des quatre ne demande d'authentification, et la différence qui compte est ce que chacun peut faire sans.
- L'explorateur, l'API du DEX et l'arcade n'en prennent aucune. Ils sont en lecture seule et publics. L'explorateur répond
405à tout POST ; l'API du DEX n'implémente aucun verbe sauf GET. - Le faucet n'en prend aucune non plus, et il écrit sur la chaîne. C'est toute la raison pour laquelle son quota est strict et est réservé avant toute signature.
Le socket de l'arcade n'a aucune authentification et le processus détient une clé
Il n'y a pas de couche d'authentification devant lui et aucune n'est prévue : le proxy transmet la montée en WebSocket et c'est tout. Ce qui le protège, c'est que chaque dimension d'une connexion est bornée - nombre, origine, taille de trame, débit de messages, octets tamponnés - et que chaque débordement est éjecté plutôt que mis en file. Rien de ce qu'un client dit sur ce socket n'autorise quoi que ce soit ; ce sont les contrats qui décident qui peut jouer.
En appeler un depuis un navigateur
Le CORS est réglé service par service et ils ne sont pas d'accord entre eux, donc la première chose à établir est si une page de votre origine peut appeler celui que vous voulez.
- L'API du DEX n'envoie aucun en-tête CORS et n'a pas de gestionnaire OPTIONS. Un
fetchmulti-origine depuis un navigateur échoue net alors que la même requête depuis un serveur réussit, ce qui est la forme de bug qu'on impute au réseau. Passez par un proxy, ou appelez-la depuis un backend. - L'explorateur et le faucet tiennent des listes d'autorisation. Un préflight venu d'une origine absente de la liste est refusé
403, ce qui est au moins une réponse claire. - L'arcade vérifie l'Origin à la montée en WebSocket et refuse
403avant la poignée de main, donc le socket ne s'ouvre jamais plutôt que de s'ouvrir et de se taire.
Limites et pagination
Seul l'explorateur limite le débit des requêtes. Les trois autres s'appuient sur un écrêtage, un quota ou un plafond de connexions.
| Service | Limite |
|---|---|
| Pepper DEX API | `limit` is clamped to 1..500 on every list route and defaults to 50. There is no request-rate limit in the service. |
| Explorer API | 300 requests per minute per client address, then 429. Request bodies are capped at 600,000 bytes. Live streams are capped at 32 concurrent. |
| Faucet | Quota is reserved before the transaction is signed: 5 a day per address seen, 2 a day per funded address, 1000 a day in total. Request bodies are capped at 4096 bytes. |
| Arcade server | 256 sockets in total and 8 per source address, then the upgrade is refused 429. Inbound frames are 4 KiB at most and rate-limited per socket. A socket more than 512 KiB behind is cut. |
Une liste écrêtée est une liste courte en silence
Demandez mille swaps à l'API du DEX et vous en obtenez cinq cents, avec un 200 et rien pour dire que la réponse a été coupée. Demandez deux cents blocs à l'explorateur et vous en obtenez cent. Aucun des deux services ne renvoie de total sur la plupart des routes de liste, il n'y a donc aucun champ auquel comparer la longueur de votre page - le seul signal qu'il en existe davantage est d'avoir obtenu exactement l'écrêtage.
Là où la pagination existe, c'est limit et offset, pas un curseur. Cela veut dire qu'une liste qui grandit par la tête glisse sous vous entre deux pages : des lignes déjà vues réapparaissent, et des lignes jamais vues peuvent être sautées. Pour tout ce qui doit être complet, paginez sur une clé que vous contrôlez - un numéro de bloc, un hash - plutôt que sur un offset.
Conventions
| Convention | Value |
|---|---|
| Versioning | None of them is versionedno /v1, no version header, no deprecation policy. A field can change shape between two deployments. Read defensively and pin nothing. |
| Schema | There is no OpenAPI documentand no JSON Schema anywhere in the repository. Every shape documented here was read out of a route handler, which is why each record names the line. |
| Errors | {"error": "..."}a human-readable string, occasionally with a second key. There are no error codes and no stable error strings - match on the HTTP status, never on the message. |
| Caching | cache-control: no-storeon every route of all four services, without exception. Nothing here is safe to cache, and nothing offers you an ETag to revalidate against. |
| Content type | JSONwith two exceptions: the explorer's logo route returns raw image bytes, and its live route is an event stream. |
| Units | not uniformtoken amounts and wei are DECIMAL STRINGS, not numbers, because they do not survive a double. Mini-block timestamps are in MICROSECONDS. Concentrated-pool swap amounts are SIGNED. |
Les montants sont des chaînes, et certains sont signés
Les montants de jetons, les wei et les soldes reviennent partout comme des CHAÎNES décimales, parce qu'ils ne survivent pas à un double. Analysez-les avec un type de grand entier. Sur les routes des pools concentrés, les montants sont en plus signés - une jambe de chaque swap est négative, et c'est cela qui dit dans quel sens l'échange est allé - donc une somme qui ne prend pas les valeurs absolues réduit tout un marché à rien.
// The shape of a careful call against any of these: a timeout, a status check
// before the body, and a big-integer parse of anything that looks like money.
const res = await fetch(`${BASE}/pools`, { signal: AbortSignal.timeout(5000) });
if (!res.ok) throw new Error(`pools: ${res.status}`); // never the message
const { pools } = await res.json(); // an object, not an array
const reserve0 = BigInt(pools[0].reserve0); // a decimal stringQuand l'un est en panne
Chacun des quatre échoue différemment, et un seul de ces échecs ressemble à un échec vu de l'extérieur.
- L'API du DEX répond
503 index not readyquand la base de données est injoignable ou que l'indexeur n'a jamais tourné, donc que les tables n'existent pas. C'est le cas honnête. Le cas malhonnête est un indexeur qui s'est ARRÊTÉ : toutes les routes continuent de répondre avec l'état qu'il a atteint, et seullagBlockssur/healthle dit. - L'explorateur continue de servir l'index quand le nœud est injoignable, et les parties d'une réponse qui demandent une lecture en direct - un solde, un enregistrement du service de noms, le solde en attente du routeur de frais - reviennent nulles ou absentes plutôt qu'en erreur. Le champ
indexLagsur/statsest le chiffre à surveiller. - Le faucet répond
502quand le nœud ne répond pas, et rien n'a été signé. Un503veut dire qu'il est à court de fonds, ou que le drip a revert. - Le
/readyde l'arcade répond 503 quand son socket vers le nœud est tombé, ou quand le dernier mini-bloc qu'il a APPLIQUÉ a plus de cinq secondes. Mesurer l'arrivée à la place laissait un processus coincé répondre 200 sans que rien ne bouge.
Seul le faucet écrit, et un 502 de sa part signifie que rien n'a été soumis - celui-là est sûr à réessayer. Un 503 après le départ de la transaction ne l'est pas : le drip peut avoir atterri et la réservation de quota a déjà été annulée, donc sondez la chaîne pour le reçu plutôt que de renvoyer.
Ce qui est documenté ailleurs
- The node. Chain state, transactions, logs and subscriptions are JSON-RPC and are documented in this reference's own RPC pages, not here.
- Contracts. What the pools, the faucet and the games actually do on chain - their functions, their events and their revert reasons - is the contract reference.
- Prices. Several answers here carry a dollar figure or a price snapshot. Those fields come from a layer this page does not own; read its own reference for what the number means, how old it is and when it is absent.