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

ServiceURL de base
API de l'explorateurhttps://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 Pepperhttps://pepper.picklechain.xyz/api/même origine seulement ; un navigateur sur une autre origine ne peut pas l'appeler
Faucethttps://faucet.picklechain.xyzl'origine d'accueil réexpose POST /drip et GET /faucet-status
Arcadehttps://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.

Aucun versionnement, nulle part

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 fetch multi-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 403 avant 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.

ServiceLimite
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 API300 requests per minute per client address, then 429. Request bodies are capped at 600,000 bytes. Live streams are capped at 32 concurrent.
FaucetQuota 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 server256 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

ConventionValue
VersioningNone of them is versionedno /v1, no version header, no deprecation policy. A field can change shape between two deployments. Read defensively and pin nothing.
SchemaThere 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.
Cachingcache-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 typeJSONwith two exceptions: the explorer's logo route returns raw image bytes, and its live route is an event stream.
Unitsnot 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.

javascript
// 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 string

Quand 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 ready quand 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 seul lagBlocks sur /health le 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 indexLag sur /stats est le chiffre à surveiller.
  • Le faucet répond 502 quand le nœud ne répond pas, et rien n'a été signé. Un 503 veut dire qu'il est à court de fonds, ou que le drip a revert.
  • Le /ready de 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.
Réessayez le statut, pas l'écriture

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.