Custom RPC
Public RPC endpoints (https://eth.llamarpc.com, https://mainnet.base.org)
are fine for one-off reads. For anything sustained — UI dashboards
that poll, scripts that fan out reads, write workloads — use a paid
provider. The SDK doesn’t care which; it’s plain http(url) to viem.
const apyx = createApyxClient({
chain: mainnet,
transport: http('https://eth-mainnet.g.alchemy.com/v2/SECRET'),
});
Why bother
| Public RPC | Paid RPC |
|---|---|
| Free | $/req or monthly |
| Heavy ratelimits — 100s of req/min | 1k+ req/sec |
| Often missing archive history | Full archive |
| Variable latency, may drop calls | Consistent <100ms |
| No support / SLA | Support + uptime guarantee |
For a UI that polls apyx.apyUSD.exchangeRate() every block, you
will hit the public-RPC ratelimit fast. The error bubbles up as a viem
HttpRequestError with status: 429 — fix it by switching to a paid
endpoint.
SDK script
import { createApyxClient } from '@koed_jang/apyx-sdk';
import { http } from 'viem';
import { mainnet } from 'viem/chains';
const apyx = createApyxClient({
chain: mainnet,
transport: http(process.env.ETH_RPC_URL, {
timeout: 10_000, // fail-fast above 10s
retryCount: 3, // viem's built-in retry/backoff
}),
});
http() supports the full viem transport options object — timeout,
retry count, batch settings — without the SDK getting in the way.
CLI
Per-session via flag
The cleanest path. The config file stays clean; the secret URL never gets persisted:
apyx repl --rpc-url 'https://eth-mainnet.g.alchemy.com/v2/SECRET'
The banner reflects the override:
rpc: https://eth-mainnet.g.alchemy.com/v2/SECRET (overridden)
Persistent via config
Write the URL into your home config so every session uses it:
{
"profiles": {
"default": {
"chain": "ethereum",
"rpcUrl": "https://eth-mainnet.g.alchemy.com/v2/SECRET",
"signer": { "type": "key", "keyPath": "~/.apyx/keys/default" }
}
}
}
chmod 600 ~/.apyx/config.json
Lock down the config file — paid RPC URLs typically embed an API key. Anyone with the file can run requests on your bill.
Environment-variable indirection
A common mid-ground: keep the URL out of files, plumb it via env:
export ETH_RPC_URL='https://eth-mainnet.g.alchemy.com/v2/SECRET'
apyx repl --rpc-url "$ETH_RPC_URL"
In CI, set ETH_RPC_URL as a secret. Locally, direnv + a gitignored
.envrc works well:
# .envrc
export ETH_RPC_URL='https://eth-mainnet.g.alchemy.com/v2/SECRET'
Browser playground
The playground has a per-chain RPC bar — see
Playground Coverage. The override is
persisted in localStorage per chain so refreshing the page keeps your
URL in place. That URL never reaches the SDK package itself; it lives
in the playground’s own state.
Provider notes
The SDK has been smoke-tested with the major providers below:
| Provider | URL shape | Notes |
|---|---|---|
| Alchemy | https://eth-mainnet.g.alchemy.com/v2/<KEY> | Default for the maintainers’ dev workflow. |
| Infura | https://mainnet.infura.io/v3/<KEY> | |
| QuickNode | https://<endpoint>.quiknode.pro/<KEY>/ | Trailing slash is fine. |
| Ankr | https://rpc.ankr.com/eth | Free tier ratelimits aggressively; paid tier OK. |
| Self-hosted (anvil / reth / geth) | http://127.0.0.1:8545 | The e2e suite uses anvil mainnet forks at this URL — see E2E testing. |
The SDK does no provider-specific shimming; if viem’s http() accepts
your URL, the SDK does too.
Verifying the recipe
The session-flag override path is covered by
test/e2e/cli/session-flags.e2e.spec.ts, which asserts
that --rpc-url overrides the profile and shows up in the banner with
the (overridden) suffix.
Related
- Session-Start Flags —
--rpc-urlin the full flag table. - Configuration — persisting an RPC URL via the config file.
- Multi-chain — wiring two paid endpoints (one per chain).