The deploy and verify commands for Bike NFT, Escrow and Pay-to-Play can select an endpoint from the repository's RPC catalog. List the exact network names, chain IDs and service URL templates with:
make release/rpc/list
The network reference table shows mainnets and their application testnets with fixed indexes, chain IDs, gas tokens, explorers, RPC services, and authoritative references. Switch between mainnets and testnets without changing row indexes or links. It reads the same catalog as the release commands; it does not maintain another network list.
The table loads the catalog automatically from the source repository. It does not contact any RPC service.
Use a catalog endpoint
Add these settings to your existing release configuration:
export RPC_CHAIN=base-sepolia
export RPC_SERVICE=public
export PAY_TO_PLAY_RELEASE_EXPECTED_CHAIN_ID=84532
make pay-to-play/release/deploy
The other required release settings still apply: CAM publication, intended owners, funded deployer, protected signing-key file, confirmation and output directory. See the release ceremony.
public selects the shared no-key endpoint recorded for that chain. It does not search for alternatives or promise unlimited capacity. For an Alchemy endpoint, use an owner-only API-key file outside the repository:
export RPC_CHAIN=base-sepolia
export RPC_SERVICE=alchemy
export RPC_API_KEY_FILE=/absolute/path/to/alchemy-api-key
make pay-to-play/release/deploy
The file contains just the API key, optionally followed by one newline, not a URL or JSON document. The resolver accepts 1–256 ASCII letters, digits, underscores or hyphens. Do not put the key into a command-line argument.
Use the same RPC_CHAIN, RPC_SERVICE and optional RPC_API_KEY_FILE settings with any app's release/verify command. Verification still needs its deployment artifact and checks the live chain against that artifact. Ethereum Sepolia, Base Sepolia, Arbitrum Sepolia and OP Sepolia are separate chains with separate balances and deployments.
Use a custom endpoint
For Quicknode, another provider, or your own public HTTPS node, copy the complete issued URL into an owner-only file and select it explicitly:
unset RPC_CHAIN RPC_SERVICE RPC_API_KEY_FILE
export RPC_URL_FILE=/absolute/path/to/rpc-url
make pay-to-play/release/deploy
Conversely, unset RPC_URL_FILE before selecting a catalog endpoint. Mixing the two modes, supplying a key for public, missing an Alchemy key, or selecting an unknown/unavailable entry is an error. The commands never fall back to another service. A service omitted from a network’s services object is unavailable for that network.
Resolution and release checks
The release uses the catalog and resolver from its archived clean Git commit. Resolution runs in an offline Python container. Its only source mounts are the JSON catalog and resolver; API-key bytes arrive through stdin. It checks the selected chain against the deployment's explicit expected chain ID and writes the resolved URL with mode 0600 into a dedicated directory within the private ceremony directory. Existing RPC proxies read that file; ceremony cleanup removes it. Logs identify the selection without printing the URL or API key.
Before broadcasting, deployment scripts also check the live chain ID against the expected ID. Catalog selection and custom URLs go through the same live chain checks.
Proxy restrictions still apply: HTTPS on port 443, public IP addresses, no URL userinfo, and no custom authorization headers. Use a general-purpose execution RPC supporting reads, fee queries, gas estimation, signed-transaction submission and receipt lookup. Write-only sequencer endpoints and beacon APIs cannot serve the complete workflow. Later verification needs contract state at the deployment block, so check the provider's historical-state retention.
The catalog is not a deployment certification. Shared endpoints can restrict methods or traffic; plans and availability can change. Provider fees are separate from blockchain transaction fees. The local rehearsal keeps its own private Anvil endpoint and ignores external catalog settings.
Run a proxy for contract indexing
The indexing lane runs a persistent RPC proxy. Run your indexer, its contract configuration and its database separately. The proxy keeps the provider URL and any API key away from the indexer and allows exactly these JSON-RPC methods:
eth_chainId eth_blockNumber eth_getBlockByNumber eth_getLogs
These methods support event-log polling and block/reorg tracking. Calls, receipts, traces and transaction submission are unavailable through this lane. The Cast and release lanes retain their own method policies. The proxy limits methods and resource use; it does not filter contract addresses or prove that upstream responses are correct.
Start the proxy
Run Make as a non-root user with Docker and Compose. Prepare an existing file outside the checkout containing one complete public HTTPS RPC URL. The proxy permits port 443, public IP addresses and no URL userinfo or custom authorization headers. An API key may be part of the protected URL's path or query. Each proxy uses this one upstream; clients cannot choose another destination.
The URL file must have a normalized absolute path with no symlink components, be owned by LOCAL_UID (your UID by default), and have owner-only permissions, such as 0600. Keep it available throughout the proxy's lifetime. Do not put the URL or API key in Make arguments or indexer configuration.
export RPC_URL_FILE=/absolute/path/to/private/base-sepolia-rpc-url
export RPC_INDEXER_COMPOSE_PROJECT_NAME=contract-base-sepolia
make rpc/indexer/up
make rpc/indexer/logs
The proxy runs as the operator's non-root UID with a read-only root filesystem, no capabilities, a read-only URL-file mount, bounded memory/PIDs/CPU and no published host port. Only the proxy joins its egress network. The command prints the client network and internal RPC URL; the example produces:
Client network: contract-base-sepolia_rpc_internal
RPC URL: http://contract-base-sepolia-rpc:8080
Startup waits for /healthz, which checks local request handling. It does not contact the upstream, verify its chain ID or prove indexing readiness. Configure the expected chain ID in your indexer and check the upstream chain at startup. Use a different project name and protected URL file for each chain or provider policy. Project-specific DNS aliases keep endpoints distinct when an indexer joins several proxy networks.
Attach an indexer without granting internet access
In your indexer's Compose file, join the proxy's existing internal network and point the indexer's RPC configuration at http://contract-base-sepolia-rpc:8080. This network fragment must be combined with an explicitly configured, pinned indexer image and database; it is not a complete rindexer deployment:
services:
rindexer:
networks:
- base_sepolia_rpc
- indexer_database
postgres:
networks:
- indexer_database
networks:
base_sepolia_rpc:
external: true
name: contract-base-sepolia_rpc_internal
indexer_database:
internal: true
List only these internal networks on the indexer; a default or egress network would give it another route. Do not use network_mode: service:rpc-proxy, which would share the proxy's internet route. Give the indexer its own database role and database. Keep the RPC URL file and wallet/signing keys out of the indexer. The proxy needs no database access.
Configure storage, ABIs, contract addresses, start blocks and events in the indexer itself. Keep address filters in its RPC requests and choose block ranges the provider can serve within the limits below. External integrations need a separately designed network route. No live indexer or database deployment has been verified for this lane.
Capacity, deadlines and failures
The indexing profile sets these limits explicitly:
| Setting | Indexing profile | Meaning |
|---|---|---|
RPC_PROXY_MAX_CONCURRENT_REQUESTS | 4 | Active client connections, including slow clients and health probes |
RPC_PROXY_MAX_BATCH_ITEMS | 100 | JSON-RPC items per batch; every item must be allowed |
RPC_PROXY_MAX_REQUEST_BYTES | 1 MiB | Request body |
RPC_PROXY_MAX_RESPONSE_BYTES | 16 MiB | Upstream response body |
RPC_PROXY_CONNECT_TIMEOUT_SECONDS | 10 seconds | Socket inactivity/connect timeout |
RPC_PROXY_UPSTREAM_TIMEOUT_SECONDS | 60 seconds | Total upstream DNS/TLS/request/response budget |
RPC_PROXY_REQUEST_TIMEOUT_SECONDS | 90 seconds | Whole accepted connection, including client headers/body and response delivery |
The whole-connection deadline is the outer cap. Requests run in separate bounded worker processes, so a stalled request does not serialize the others. When all workers are occupied, the proxy rejects new connections, returning HTTP 503 with Retry-After when it can deliver the response. It keeps no unbounded application queue. Health probes share the same capacity and can also receive 503.
Start with low indexer concurrency, leaving room for block polling and health probes; event streams share the four-connection limit. These limits bound simultaneous work, sizes and time. They do not enforce requests per second or a provider's daily quota. For 503, reduce combined concurrency. For response-size or deadline failures, reduce the requested block range first. Provider rate limits, batch policies and historical coverage still apply.
Read-only clients may retry with bounded backoff. The proxy never retries, caches or switches upstreams. Review the limits alongside container memory and PID budgets before increasing them in this lane's configuration. WebSocket subscriptions and arbitrary HTTP proxying are unavailable; use HTTP log polling.
Logs omit request bodies and credential-bearing URLs. The service keeps at most three 10 MiB local log files. Stop indexer clients and disconnect their containers from this proxy's internal network before running:
make rpc/indexer/down RPC_INDEXER_COMPOSE_PROJECT_NAME=contract-base-sepolia
Logs and shutdown do not require the original URL file. To rotate it, stop the proxy, replace the protected file and run rpc/indexer/up again so the bind mount refers to the current file.
Sources and maintenance
Endpoint documentation was checked on 2026-10-20, not live-tested against these services. Update the catalog row when a published endpoint changes; a new network using the existing services needs no resolver code change.
Keep existing catalog keys and mainnet index values stable. Mainnet rows own their index; each testnet's mainnet field names its mainnet's catalog key. The table currently expects one application testnet per mainnet. Add or change network names, gas symbols, explorers, source URLs and source-check dates in the catalog. references cite network owners and endpoint providers; checkedOn records the documentation check date. A retired entry keeps its identity and an explanatory note, with an empty services object so release commands cannot resolve an endpoint for it.
The BSC testnet public endpoint uses HTTPS port 8545. It can be used by wallets, but does not meet the release proxy's port-443 restriction described above. Scroll Sepolia is retained as retired, following Scroll's shutdown notice; its former RPC is deliberately absent.
- PublicNode Ethereum and Base supply the catalog's public Ethereum/Base endpoints.
- Arbitrum network information, OP network information and Polygon RPC information supply their public endpoints and network IDs.
- Base network information supplies Base's network IDs.
- Alchemy's supported networks supplies the authenticated URL templates.
- Quicknode's network and retention guide covers account-specific endpoints usable through
RPC_URL_FILE.