Para desenvolvedores / APIs das aplicações

APIs das aplicações

Quatro serviços de primeira parte ficam ao lado da cadeia. Nenhum deles é a cadeia, nenhum é versionado, e cada um falha à sua maneira - é para isso que esta seção serve.

O que são

A interface da cadeia é o JSON-RPC. Tudo o que está nestas páginas é algo que uma aplicação construiu para si mesma e depois deixou alcançável: um índice Postgres sobre o spool de logs do sequenciador, um processo que detém uma chave, um laço de jogo. É prático, é de primeira parte, e não é autoritativo.

Uma leitura aqui não é uma leitura da cadeia

Todo número aqui passou por um indexador, um cache, ou os dois. Um indexador parado continua respondendo com o seu último estado e nenhum campo da resposta diz isso; as únicas rotas que contam são as rotas de saúde, e você tem que perguntar a elas. Se a resposta decide dinheiro, leia a cadeia.

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.

Pilha
Python, standard-library ThreadingHTTPServer, psycopg pool of at most 8 connections, HTTP/1.1
Montado em
/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.

Pilha
Python, standard-library ThreadingHTTPServer, psycopg pool of at most 12 connections, plus live reads against the node
Montado em
/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.

Pilha
Python, standard-library SimpleHTTPRequestHandler serving a static site as well as the API, signing with eth-account
Montado em
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.

Pilha
Node, `ws` in noServer mode behind a plain http server, one event loop for eight game rooms
Montado em
/api/ and /ws/ on the arcade origin

Onde respondem

ServiçoURL de base
API do exploradorhttps://explorer.picklechain.xyz/api/também montada em /api/ pelos sites do serviço de nomes e da caixa de ferramentas
API do DEX Pepperhttps://pepper.picklechain.xyz/api/somente mesma origem; um navegador em outra origem não consegue chamá-la
Faucethttps://faucet.picklechain.xyza origem inicial reexpõe POST /drip e GET /faucet-status
Arcadehttps://minigame.picklechain.xyz/api/e o socket em wss://minigame.picklechain.xyz/ws/<room>

Nenhum desses serviços tem um nome de host próprio. Cada um é uma montagem /api/ na origem de uma interface, o que faz da base pública um fato do nginx e não um fato do serviço: uma implantação que move um site move a API dele junto, e o caminho interno continua o mesmo. Numa pilha que você mesmo roda, os mesmos serviços respondem no loopback, na porta que a página de cada um nomeia.

Nenhum versionamento, em lugar nenhum

Não há /v1, nem cabeçalho de versão, nem política de depreciação em nenhum dos quatro. Também não há documento OpenAPI nem JSON Schema no repositório, então um campo pode mudar de forma entre duas implantações sem nada com que comparar. Leia defensivamente: ignore as chaves que você não conhece, e não falhe por causa de uma chave que sumiu.

Autenticação

Nenhum dos quatro pede autenticação, e a diferença que conta é o que cada um consegue fazer sem ela.

  • O explorador, a API do DEX e o arcade não pedem nenhuma. São somente de leitura e públicos. O explorador responde 405 a todo POST; a API do DEX não implementa nenhum verbo além de GET.
  • O faucet também não pede nenhuma, e ele escreve na cadeia. É toda a razão pela qual a cota dele é estrita e é reservada antes de qualquer assinatura.

O socket do arcade não tem autenticação nenhuma e o processo detém uma chave

Não há camada de autenticação na frente dele e nenhuma está prevista: o proxy repassa o upgrade e é só. O que o protege é que toda dimensão de uma conexão é limitada - quantidade, origem, tamanho de quadro, taxa de mensagens, bytes em buffer - e todo transbordamento é descartado em vez de enfileirado. Nada do que um cliente diz nesse socket autoriza coisa alguma; são os contratos que decidem quem pode jogar.

Chamar um deles de um navegador

O CORS é ajustado serviço a serviço e eles não concordam entre si, então a primeira coisa a estabelecer é se uma página da sua origem consegue chamar aquele que você quer.

  • A API do DEX não envia nenhum cabeçalho CORS e não tem manipulador OPTIONS. Um fetch de outra origem a partir de um navegador falha de cara enquanto a mesma requisição a partir de um servidor tem sucesso, que é a forma de bug que se costuma culpar na rede. Passe por um proxy, ou chame-a de um backend.
  • O explorador e o faucet mantêm listas de permissões. Um preflight vindo de uma origem que não está na lista é recusado com 403, o que pelo menos é uma resposta clara.
  • O arcade confere o Origin no upgrade e recusa 403 antes do aperto de mão, então o socket nunca abre em vez de abrir e ficar calado.

Limites e paginação

Só o explorador limita a taxa de requisições. Os outros três se apoiam numa trava, numa cota ou num teto de conexões.

ServiçoLimite
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.

Uma lista travada é, em silêncio, uma lista curta

Peça mil swaps à API do DEX e você recebe quinhentos, com um 200 e nada que diga que a resposta foi cortada. Peça duzentos blocos ao explorador e você recebe cem. Nenhum dos dois serviços devolve um total na maioria das rotas de lista, então não há campo com que comparar o tamanho da sua página - o único sinal de que existe mais é ter recebido exatamente o valor da trava.

Onde há paginação, ela é limit e offset, não um cursor. Isso quer dizer que uma lista que cresce pela cabeça desliza debaixo de você entre duas páginas: linhas já vistas reaparecem, e linhas nunca vistas podem ser puladas. Para qualquer coisa que precise ser completa, pagine por uma chave que você controla - um número de bloco, um hash - e não por um offset.

Convenções

ConvençãoValue
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.

Os montantes são strings, e alguns são com sinal

Montantes de tokens, wei e saldos voltam em toda parte como STRINGS decimais, porque não sobrevivem a um double. Analise-os com um tipo de inteiro grande. Nas rotas dos pools concentrados os montantes são além disso com sinal - uma perna de cada swap é negativa, e é isso que diz para que lado a negociação foi - então uma soma que não toma os valores absolutos reduz um mercado inteiro a nada.

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

Quando um está fora do ar

Cada um dos quatro falha de um jeito, e só uma dessas falhas se parece com uma falha vista de fora.

  • A API do DEX responde 503 index not ready quando o banco de dados está inalcançável ou o indexador nunca rodou, então as tabelas não existem. Esse é o caso honesto. O desonesto é um indexador que PAROU: todas as rotas continuam respondendo com o estado a que ele chegou, e só o lagBlocks em /health diz isso.
  • O explorador continua servindo o índice quando o nó está inalcançável, e as partes de uma resposta que exigem uma leitura ao vivo - um saldo, um registro do serviço de nomes, o saldo pendente do roteador de taxas - voltam nulas ou ausentes em vez de dar erro. O campo indexLag em /stats é o número a vigiar.
  • O faucet responde 502 quando o nó não responde, e nada foi assinado. Um 503 quer dizer que ele está sem fundos, ou que o drip deu revert.
  • O /ready do arcade responde 503 quando o socket dele para o nó caiu, ou quando o último minibloco que ele APLICOU tem mais de cinco segundos. Medir a chegada no lugar disso deixava um processo travado responder 200 sem que nada se mexesse.
Tente de novo o status, não a escrita

Só o faucet escreve, e um 502 da parte dele significa que nada foi submetido - esse é seguro de repetir. Um 503 depois que a transação saiu não é: o drip pode ter chegado e a reserva de cota já foi desfeita, então sonde a cadeia pelo recibo em vez de enviar de novo.

O que está documentado em outro lugar

  • 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.