For developers / Start here
Endpoints
LiveNine surfaces are served publicly. The rest of the stack binds to loopback on purpose, so this page says which is which rather than listing ports and letting you find out.
Public
Served over TLS by the deployment's own reverse proxy. The RPC endpoint sets Access-Control-Allow-Origin: * and answers the preflight at the edge, because the node implements no CORS and would answer 405 to OPTIONS - a failed preflight fails the request behind it. So a browser page on any origin can call it.
| Surface | Address |
|---|---|
| JSON-RPCPublic | https://rpc.picklechain.xyzhttp://127.0.0.1:8545The chain's HTTP JSON-RPC. nginx supplies the CORS the node does not implement - Access-Control-Allow-Origin *, with the OPTIONS preflight answered at the edge because the node itself would answer 405 and a failed preflight fails the request behind it. |
| WebSocketPublic | wss://rpc.picklechain.xyz/ws/ws://127.0.0.1:8546Subscriptions only live here. Both /ws and /ws/ are served as separate locations with no redirect between them, because a WebSocket client mostly does not follow a 301 on its handshake. This is a hand-written server on its own port, not the HTTP listener - see /rpc/websocket/. |
| ExplorerPublic | https://explorer.picklechain.xyzhttp://127.0.0.1:4000Blocks, transactions, tokens, accounts and call traces. Also where the chain's full history lives - the node itself keeps about two minutes. |
| FaucetPublic | https://faucet.picklechain.xyzhttp://127.0.0.1:3000Test ETH and test PKL. Both have no value. |
| BridgePublic | https://bridge.picklechain.xyzhttp://127.0.0.1:3001ETH between the L1 and Pickle. ETH only - there is no ERC-20 bridging. |
| Mini-block feedPublic | https://mini.picklechain.xyzhttp://127.0.0.1:3002A live view of the preconfirmation stream, and the reference client for the mini-block subscription: WebSocket first, falling back to polling when the socket closes. |
| ToolkitPublic | https://toolkit.picklechain.xyzhttp://127.0.0.1:3003Deploy a token, an NFT or a multisig from a form, and stake. |
| Name servicePublic | https://names.picklechain.xyzhttp://127.0.0.1:3004Register a name instead of using a long address. |
| PepperPublic | https://pepper.picklechain.xyzhttp://127.0.0.1:3005The AMM front end. Whether it has a market to trade is a separate question from whether the site is served - no deployment script seeds a pool. |
| HomePublic | https://picklechain.xyzhttp://127.0.0.1:8080The project site. /testnet there carries the same wallet parameters as /connect/ here. |
Local only
These exist only on a machine running the stack itself. Every ports: entry in the compose file binds 127.0.0.1 deliberately, so they are not reachable even on the deployed host.
| Surface | Address |
|---|---|
| L1 (Anvil)Local only | http://127.0.0.1:8547The development L1, chain ID 31337, with base fee 0 and gas price 1. Phase 1 replaces it with Ethereum Sepolia. Its prefunded accounts are published Anvil keys and are development-only. |
| Replica RPCLocal only | http://127.0.0.1:8555A node that re-derives state from the L1 and the DA layer rather than producing anything. Serves eth_* reads, forwards raw transactions to the leader, and runs no WebSocket server at all. |
| DEX APILocal only | http://127.0.0.1:4020Pepper's indexer API. Bound to loopback, and it sends no CORS headers and implements no OPTIONS handler, so it is a same-origin API reachable through the Pepper front end's own /api/ mount - not an API with a hostname of its own. |
Not routed
These have no host port at all - only an internal name on the container network. Another container can reach them; you cannot, not even from the machine they run on. They are listed because their absence is otherwise indistinguishable from an outage, and because three of them are APIs whose data you can get another way.
| Surface | Address |
|---|---|
| Explorer APINot routed | Port 4010, expose-only. Reachable through the explorer's /api/ mount and through /explorer-api/ on the home origin. It has no base URL of its own; documenting one would invent a hostname. |
| Earn APINot routed | Port 4020, expose-only. Four shipped runtime configs name earn.picklechain.xyz, but no vhost for it exists in the repository, so there is no third-party integrator story to document yet. |
| Data availabilityNot routed | Port 3100, expose-only, and authenticated with a bearer token that is mandatory outside development mode. The sequencer reaches it as http://da:3100. |
| PostgresNot routed | No host port. The explorer's history lives here; read it through the explorer API. |
The explorer and DEX APIs are reachable in practice, but only as an /api/ mount on a front end's own origin - there is no api. host, and the DEX API sends no CORS headers and implements no OPTIONS handler, so it is same-origin only. Documenting either as an API with a base URL would mean inventing a hostname, so their reference pages will describe them as what they are.
Fair use on the public RPC
There is no per-client rate limit
The node's expensive-read guard is a single process-wide token bucket, and its own source calls it a backstop rather than per-client rate limiting, with per-client limits belonging at the reverse proxy. The shipped vhost sets no limit_req and no limit_conn. One heavy client can therefore exhaust the shared budget for everyone, and you should treat the endpoint accordingly: batch politely, back off on -32005, and run your own node if you need guaranteed headroom.
That is stated rather than left silent because silence is the more misleading option: an integrator told nothing will assume per-client isolation, and there is none to assume. The practical advice is the same advice as for any shared endpoint - keep batches under the 32-call limit, back off when you see -32005, and run your own node if you need guaranteed headroom. The errors and limits page has every threshold.
Read from sequencer/src/rpc.rs:555, deploy/nginx/picklechain.xyz.conf:362