From 03dadfc7dc6df2298630a0e442cd433297f667c0 Mon Sep 17 00:00:00 2001 From: Sergen Uysal <0xsergen@gmail.com> Date: Fri, 4 Sep 2026 18:08:26 +0300 Subject: [PATCH 1/4] [CON-906] Correct CLI and SDK reference against the live product Audited cli-reference.md and sdk-reference.md against qn 0.6.0 and @quicknode/sdk 3.8.2. 14 confirmed defects. Every claim was executed, not read. Wrong values and enums: - Chain vocabularies were conflated. `qn chain list` returns 76 short slugs (`eth`), not long names (`ethereum`). Added a vocabulary table for short slugs, long names, and network keys. - `generatePaymentWallet` accepts "evm" | "svm" | "tempo". "tempo" was missing. Examples that could never run: - `eth_getBalance` used the placeholder `0xabc...`, which fails -32602. Replaced with a real EOA. - The `eth_call` stdin literal was not valid JSON. Replaced with a real USDC totalSupply() call. - The webhook example pointed `--template evm-wallet` at the USDC contract, not a wallet. Replaced with an EOA. Silent failures (a 2xx or an exit 0 that returns nothing usable): - `stream test-filter` returns `result` as a JSON string. The SDK example read fields off it directly, which yields undefined. Added JSON.parse and documented the shape. - `logs` from test-filter can never be observed. The API sends objects, both clients decode string[], so any console.log in a filter fails the whole call. Documented, and warned against console.log. - The SQL example read `result.rows`, which is a count. The rows are in `result.data`. The example ran a billed query and discarded it. - "Lists store ordered values" is false. Lists sort lexicographically. Added a warning against using a list as a queue or cursor log. Omissions: - `supported-payments` can omit `asset` and can return a raw CAIP-2 id. - `endpoint logs` and `log-details` are Enterprise-only, and report the gate as "unauthorized. Check your API key". Documented the -v diagnosis. - Added the default output format (json when piped, table on a TTY) and the scope of --wide. - Added an exit-code table. Every code was verified live. - Added the nine typed SDK errors. Only the payment errors were listed. Command coverage was already complete: a recursive --help walk found 126 leaf commands and 0 were missing. Verification: 22/22 SDK assertions pass, and every corrected CLI example was re-executed. Findings in the audit workspace. Version bumps for the three plugin manifests land in the CON-905 PR, the last of this set to merge. --- .../references/quicknode/cli-reference.md | 49 ++++++++++++++++--- .../references/quicknode/sdk-reference.md | 48 +++++++++++++++--- 2 files changed, 84 insertions(+), 13 deletions(-) diff --git a/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md b/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md index 363db2e..fbccb1e 100644 --- a/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md +++ b/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md @@ -62,7 +62,7 @@ Set output with `--format` or `-o`. | `md` | Markdown tables for issues and docs | | `toon` | Compact LLM-oriented structured output | -Examples: +With `--format` unset the CLI reads `[output] format` from the config file, then defaults to `table` on a TTY and `json` when stdout is piped. `--wide`/`-w` affects only `table` and `md`. ```bash qn endpoint list --format json @@ -70,6 +70,18 @@ qn usage summary --from 7d -o yaml qn endpoint list --wide ``` +## Exit Codes + +| Code | Meaning | +|------|---------| +| `0` | Success | +| `1` | Usage error — bad flag, missing argument, unparseable value | +| `2` | API or request error — the server rejected the call (also plan-gated features, and drawdown credit exhaustion) | +| `3` | Indeterminate outcome on a paid call — the request was sent but the response was lost; the wallet may already be charged | +| `4` | No credentials — no `--api-key`, no `--config-file`, no `~/.config/qn/config.toml` | +| `5` | Gated command refused — a destructive command ran in a non-TTY without `--yes`, before any request was sent | +| `130` | Interrupted (SIGINT) | + ## Command Groups ### Auth @@ -110,10 +122,10 @@ Params: positional (JSON array), by name (JSON object), from a file, or from std ```bash qn rpc call eth_blockNumber -qn rpc call eth_getBalance '["0xabc...", "latest"]' +qn rpc call eth_getBalance '["0xBE0eB53F46cd790Cd13851d5EFf43D12404d33E8", "latest"]' qn rpc call getSlot --network solana-mainnet qn rpc call eth_call --params-file params.json -echo '[...]' | qn rpc call eth_call - +echo '[{"to": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "data": "0x18160ddd"}, "latest"]' | qn rpc call eth_call - cat params.json | qn rpc call eth_call -f - ``` @@ -174,7 +186,9 @@ qn rpc mpp supported-networks qn rpc mpp supported-payments ``` -Use a slug from `supported-networks` as `--network`. Use a row from `supported-payments` — it returns the payment network, asset symbol, and token address — as `--payment-network` and `--payment-asset`. Query these instead of hardcoding a network or asset list. +Use a slug from `supported-networks` as `--network`. Use a row from `supported-payments` as `--payment-network` and `--payment-asset`. Query these instead of hardcoding a network or asset list. + +Rows carry `network` and `address`; `asset` is optional. `network` is a slug (`base-sepolia`) or a raw CAIP-2 id (`eip155:1952`). `--payment-asset` accepts a symbol or a contract address/mint. The query network and the payment network are independent. `--network ethereum-mainnet` with `--payment-network base-sepolia` pays on Base Sepolia for an Ethereum Mainnet read. @@ -327,6 +341,8 @@ qn endpoint log-details qn endpoint metrics --metric method_calls_over_time --period day ``` +On plans that do not support logging, they exit `2` reporting `unauthorized. Check your API key`; `-v` shows the details. + Commands that create, update, pause, resume, archive, enable or disable multichain, or change endpoint security/rate limits mutate endpoint state. ```bash @@ -439,6 +455,12 @@ qn stream test-filter \ --filter-file filter.js ``` +`test-filter` prints `{ "result": ..., "logs": [] }`, where `result` is the filter's return value as a JSON-encoded string, not an object. + +A filter that calls `console.log` makes the command fail with `Error: unexpected response shape from API.` and exit `1`. The request itself succeeds — the API returns HTTP `201` with each log entry as a `{ "level", "message" }` object, which the client decodes as a string and rejects, so `logs` only ever renders as `[]`. Filters run through the CLI or the SDK must not call `console.log`. + +The filter file exports `main(stream)`. For the `block` dataset `stream.data` is an array of blocks, one per batch entry. + Create and lifecycle commands change Stream state and may prompt: ```bash @@ -469,9 +491,11 @@ qn webhook create \ --url https://example.com/webhook \ --compression none \ --template evm-wallet \ - --wallet 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 + --wallet 0xBE0eB53F46cd790Cd13851d5EFf43D12404d33E8 ``` +Pass `--wallet` once per address. `--wallets-list-name ` is the alternative: it reads the addresses from a saved Key-Value Store list instead. + Webhook lifecycle and update commands: ```bash @@ -496,7 +520,7 @@ qn kv set delete mykey qn kv set bulk --add threshold=750000 --delete old_threshold ``` -Lists store ordered values under one key: +Lists store multiple values under one key. `qn kv list get` returns items sorted lexicographically, not in insertion order: ```bash qn kv list list @@ -519,6 +543,8 @@ qn sql query --file query.sql --cluster-id hyperliquid-core-mainnet qn sql query --file - --cluster-id hyperliquid-core-mainnet ``` +`qn sql query` costs API credits on every call; `qn sql schema` is free. + ### Account Operations ```bash @@ -536,7 +562,16 @@ qn billing payments qn completions zsh ``` -`qn chain credits ` returns the per-method API credit costs for that chain, using the same chain slugs returned by `qn chain list`. Use it when an agent needs account-aware credit costs instead of hardcoding method multipliers. +`qn chain credits ` returns the per-method API credit costs for that chain. Use it when an agent needs account-aware credit costs. + +The CLI uses three chain vocabularies: + +| Where | Vocabulary | Examples | +|-------|-----------|----------| +| `qn chain list` | short slugs | `eth`, `matic`, `sol`, `btc` | +| `qn chain credits ` | accepts either the short slug or the long name | `eth` or `ethereum`, `sol` or `solana` | +| `qn endpoint create --chain` | long names | `ethereum`, `solana` | +| `qn rpc call --network` / `qn rpc list-networks` | network keys | `ethereum-mainnet`, `base-mainnet`, `solana-mainnet`, `polygon`, `btc` | ## Confirmation Behavior diff --git a/plugins/build-web3/skills/build-web3/references/quicknode/sdk-reference.md b/plugins/build-web3/skills/build-web3/references/quicknode/sdk-reference.md index c984ded..ab13c34 100644 --- a/plugins/build-web3/skills/build-web3/references/quicknode/sdk-reference.md +++ b/plugins/build-web3/skills/build-web3/references/quicknode/sdk-reference.md @@ -87,7 +87,10 @@ if (!status.enabled) { // params defaults to []; pass an array (positional) or object (by name). const blockNumber = await qn.rpc.call("eth_blockNumber"); -const balance = await qn.rpc.call("eth_getBalance", ["0xabc...", "latest"]); +const balance = await qn.rpc.call("eth_getBalance", [ + "0xBE0eB53F46cd790Cd13851d5EFf43D12404d33E8", + "latest", +]); // Multichain: seed the network map from admin.getEndpointUrls, then select // a network by its multichain_urls key as the 3rd argument. @@ -140,7 +143,9 @@ for (const row of credits.data.slice(0, 5)) { } ``` -`accountInfo()` calls the Admin API account-info endpoint and returns details such as account id, name, creation timestamp, billing version, and current subscription. `getApiCredits(chain)` calls the per-chain API credits endpoint and returns `{ method, credits }` rows for the supplied chain slug. Use `listChains()` to discover valid chain slugs. +`accountInfo()` calls the Admin API account-info endpoint and returns details such as account id, name, creation timestamp, billing version, and current subscription. `getApiCredits(chain)` calls the per-chain API credits endpoint and returns `{ method, credits }` rows for the supplied chain. + +`listChains()` returns short slugs (`eth`, `matic`, `sol`). `getApiCredits` accepts either the slug or the long name. The `rpc` client uses a third vocabulary, network keys such as `ethereum-mainnet`. ### Streams @@ -165,9 +170,19 @@ const test = await qn.streams.testFilter({ filterFunction, }); -console.log({ streams: streams.pageInfo.total, enabled: enabled.total, result: test.result }); +// test.result is a JSON-encoded string. +const filtered = JSON.parse(test.result); + +console.log({ + streams: streams.pageInfo.total, + enabled: enabled.total, + filtered, + logs: test.logs, +}); ``` +`testFilter` returns `{ result: string, logs: string[] }`, where `result` is the filter's output serialized as JSON. A filter that calls `console.log` makes `testFilter` throw `DecodeError`: the API returns each log entry as an object and the client decodes `logs` as strings, so `logs` only ever resolves to `[]`. + ### Webhooks ```typescript @@ -199,6 +214,8 @@ if (sets.data.length > 0) { console.log({ sets: sets.data.length, lists: lists.data.keys.length }); ``` +`getSets()` returns `{ data: [{ key, value }], cursor }` with `data` as an array; `getLists()` returns `{ data: { keys: [...] }, cursor }` with `data` as an object wrapping `keys`. `getSet(key)` returns `{ value }` as a string. List items come back sorted lexicographically, not in insertion order. + ### SQL Explorer ```typescript @@ -214,9 +231,12 @@ const result = await qn.sql.query( const schema = await qn.sql.getSchema("hyperliquid-core-mainnet"); console.log(`${result.rows} rows, ${result.credits} credits`); -console.log(schema); +console.log(result.data); // the rows themselves +console.log(schema.tables.map((t) => t.name)); ``` +`query` returns `{ meta, data, rows, rowsBeforeLimitAtLeast, statistics, credits }`. `rows` is a count; the row objects are in `data`, keyed by the selected columns. `rowsBeforeLimitAtLeast` is the match count before `LIMIT`. `query` costs API credits on every call; `getSchema` is free. + ## RPC Micropayments Node 3.8.0+, other languages 0.8.0+. The `rpc` client can pay for calls with stablecoins through the x402 or MPP gateway instead of an API key. Set a payment wallet and the SDK handles the HTTP `402 Payment Required` challenge, signs the payment, and resends the request. This lane needs no Quicknode account, API key, or provisioned endpoint — construct the SDK without an API key. @@ -287,12 +307,12 @@ quicknode-sdk = { version = "0.8", features = ["payments", "payments-svm", "paym ```typescript import { generatePaymentWallet } from "@quicknode/sdk"; -const wallet = generatePaymentWallet("evm"); // "evm" or "svm" +const wallet = generatePaymentWallet("evm"); // "evm" | "svm" | "tempo" console.log("Fund this address:", wallet.address); // Persist wallet.key now. It cannot be recovered later. ``` -Use `evm` for x402 on EVM and for MPP on Tempo; use `svm` for x402 on Solana. Other bindings expose it as `generate_payment_wallet`. +`chain` is typed `"evm" | "svm" | "tempo"`. Use `evm` for x402 on EVM, `svm` for x402 on Solana, and `evm` or `tempo` for MPP on Tempo — both return a secp256k1 hex key. Other bindings expose it as `generate_payment_wallet`. ### x402 Credit Drawdown @@ -349,6 +369,22 @@ The gateway has no read-only channel endpoint, so it cannot reconstruct a lost l | `PaymentRejectedError` | The gateway refused the payment; nothing settled | | `PaymentIndeterminateError` | Outcome unknown — the payment may have settled. Check the wallet before retrying; never blind-retry a paid call | +## Errors + +Every SDK call throws from one typed hierarchy rooted at `QuicknodeError`. All of these are named exports. + +| Error | Extra fields | Raised when | +|-------|--------------|-------------| +| `QuicknodeError` | — | Base class for every SDK error | +| `ConfigError` | — | Bad or missing configuration — an unknown network key before `setNetworks`, an unknown payment chain | +| `HttpError` | — | Transport failure | +| `TimeoutError` | — | Extends `HttpError`. Request exceeded `QN_SDK__HTTP__TIMEOUT_SECS` | +| `ConnectionError` | — | Extends `HttpError`. Could not reach the host | +| `ApiError` | `status`, `body` | The API returned a non-2xx response | +| `DecodeError` | `body` | The response could not be decoded into the expected shape | +| `RpcError` | `code` | The JSON-RPC response carried an `error` member | +| `PaymentError` | — | Base class for the payment lane (see the table above) | + ## Other Languages Python, Rust, and Ruby expose the same product-client model through language-native method names: From fa51da275ad8092edf44806bce4a8fe19512839f Mon Sep 17 00:00:00 2001 From: Sergen Uysal <0xsergen@gmail.com> Date: Fri, 4 Sep 2026 18:24:24 +0300 Subject: [PATCH 2/4] [CON-906] Add Test: lines for the re-verified CLI and SDK examples CON-901 asks for a Test: line on every example. Added them for the five examples re-verified live in this session, in PR #8's format. CLI: - RPC params block. eth_getBalance returns a hex quantity, and the piped eth_call returns USDC totalSupply() as one 32-byte hex word. - stream test-filter on block 17811625. `result` is a JSON string and `logs` is []. SDK, against a freshly installed 3.8.2. 12 of 12 assertions pass: - RPC block. eth_getBalance returns a hex quantity; the truncated placeholder throws RpcError with code -32602. - testFilter. typeof test.result is "string", test.logs is [], and a filter calling console.log throws DecodeError. - generatePaymentWallet. evm and tempo give a 42-character 0x address, svm a base58 address, and any other value throws ConfigError naming all three. The remaining examples in these two files carry no Test: line yet. Two reasons, both recorded in the report: - Account-scoped examples (`endpoint list`, `kv set list`, `stream list`) can only assert this account's counts. A reader on another account cannot compare against them, so the line would mislead. - Mutating and paid paths were never executed, so there is no measured value to assert. Also confirmed and unchanged: the published package's `types` entry is sdk.d.ts, the documented class is QuicknodeSdk, the documented env var is QN_SDK__API_KEY, and `dataset` takes the StreamDataset enum rather than a raw string. Three drafts of the verification script got those wrong; the reference had all four right. Version bumps for the three plugin manifests land in the CON-905 PR, the last of this set to merge. --- .../skills/build-web3/references/quicknode/cli-reference.md | 4 ++++ .../skills/build-web3/references/quicknode/sdk-reference.md | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md b/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md index fbccb1e..d6ef1d6 100644 --- a/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md +++ b/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md @@ -129,6 +129,8 @@ echo '[{"to": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "data": "0x18160ddd" cat params.json | qn rpc call eth_call -f - ``` +**Test:** `ethereum-mainnet` · block `latest` — `eth_getBalance` returns a hex quantity, and the piped `eth_call` returns USDC `totalSupply()` as one 32-byte hex word + `--network ` selects a network on the multichain endpoint (e.g. `base-mainnet`, `solana-mainnet`, `polygon`, `btc`). Omit it for the default network. `qn rpc list-networks` (alias `ls`) lists available keys — no RPC call made. ```bash @@ -455,6 +457,8 @@ qn stream test-filter \ --filter-file filter.js ``` +**Test:** `ethereum-mainnet` · block `17811625` — `result` is a JSON string holding the filter's return value, and `logs` is `[]` + `test-filter` prints `{ "result": ..., "logs": [] }`, where `result` is the filter's return value as a JSON-encoded string, not an object. A filter that calls `console.log` makes the command fail with `Error: unexpected response shape from API.` and exit `1`. The request itself succeeds — the API returns HTTP `201` with each log entry as a `{ "level", "message" }` object, which the client decodes as a string and rejects, so `logs` only ever renders as `[]`. Filters run through the CLI or the SDK must not call `console.log`. diff --git a/plugins/build-web3/skills/build-web3/references/quicknode/sdk-reference.md b/plugins/build-web3/skills/build-web3/references/quicknode/sdk-reference.md index ab13c34..752655c 100644 --- a/plugins/build-web3/skills/build-web3/references/quicknode/sdk-reference.md +++ b/plugins/build-web3/skills/build-web3/references/quicknode/sdk-reference.md @@ -127,6 +127,8 @@ try { // await qn.admin.disableToolingAccess(); ``` +**Test:** `ethereum-mainnet` · block `latest` — `eth_getBalance` on that address returns a hex quantity; passing the truncated placeholder `0xabc...` instead throws `RpcError` with `code === -32602` + ### Account Info and API Credits ```typescript @@ -181,6 +183,8 @@ console.log({ }); ``` +**Test:** `ethereum-mainnet` · block `17811625` — `typeof test.result === "string"` and `test.logs` is `[]`; a filter calling `console.log` throws `DecodeError` instead + `testFilter` returns `{ result: string, logs: string[] }`, where `result` is the filter's output serialized as JSON. A filter that calls `console.log` makes `testFilter` throw `DecodeError`: the API returns each log entry as an object and the client decodes `logs` as strings, so `logs` only ever resolves to `[]`. ### Webhooks @@ -312,6 +316,8 @@ console.log("Fund this address:", wallet.address); // Persist wallet.key now. It cannot be recovered later. ``` +**Test:** offline, no network — `evm` and `tempo` return a 42-character `0x` address, `svm` a base58 address; any other value throws `ConfigError` naming all three + `chain` is typed `"evm" | "svm" | "tempo"`. Use `evm` for x402 on EVM, `svm` for x402 on Solana, and `evm` or `tempo` for MPP on Tempo — both return a secp256k1 hex key. Other bindings expose it as `generate_payment_wallet`. ### x402 Credit Drawdown From b4640c06bc052d57f8944924eecd515ebeda991a Mon Sep 17 00:00:00 2001 From: Sergen Uysal <0xsergen@gmail.com> Date: Fri, 4 Sep 2026 18:49:16 +0300 Subject: [PATCH 3/4] [CON-906] Add three more CLI Test: lines and the --yes requirement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CON-901 asks for a Test: line on every runnable example. These three were assertable with a value any reader can reproduce, and all three are free reads that create nothing. - `qn agent context` returns 370 lines of Markdown titled "# qn — usage guide for agents", with 9 `##` sections. Verified with QN_API_KEY empty, which is how the "needs no authentication" claim in that section is actually proved rather than asserted. - `qn endpoint list | head -c 1` prints `{`. Piped output defaults to json, not table, so a script never needs `-o json`. This is the claim the Output Formats defect was about. - `qn kv set list` returns `data` as an array of {key, value}; `qn kv list list` returns `data` as an object wrapping `keys`. The two commands do not share a response shape. Also documented: every delete command needs `--yes` when no terminal is attached. Without it the command exits non-zero and deletes nothing. Hit while scripting this audit's own resource cleanup. Checked and found correct, so not changed: `qn kv list list` is the canonical subcommand, with `ls` as its alias. It is not a typo for `ls`. --- .../build-web3/references/quicknode/cli-reference.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md b/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md index d6ef1d6..10e1d6e 100644 --- a/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md +++ b/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md @@ -50,6 +50,8 @@ qn agent context qn agent context -o json ``` +**Test:** `qn agent context` with `QN_API_KEY` empty — 370 lines of Markdown titled `# qn — usage guide for agents`, with 9 `##` sections. It succeeds with no key, which is how you confirm it needs no authentication + ## Output Formats Set output with `--format` or `-o`. @@ -70,6 +72,8 @@ qn usage summary --from 7d -o yaml qn endpoint list --wide ``` +**Test:** `qn endpoint list | head -c 1` — prints `{`. Piped output defaults to `json`, not `table`, so a script never has to pass `-o json` + ## Exit Codes | Code | Meaning | @@ -537,6 +541,11 @@ qn kv list update allowlist --add 0x456 --remove 0xabc qn kv list delete allowlist ``` +Every `delete` needs `--yes` when no terminal is attached. Without it the command +exits non-zero and deletes nothing. + +**Test:** `qn kv set list` — `data` is an **array** of `{key, value}`; `qn kv list list` — `data` is an **object** with a `keys` array. The two commands do not share a response shape + ### SQL Explorer ```bash From 5cdecbf9efcde6175ebf315bbeaf981b35d61cf3 Mon Sep 17 00:00:00 2001 From: Sergen Uysal <0xsergen@gmail.com> Date: Fri, 4 Sep 2026 19:02:05 +0300 Subject: [PATCH 4/4] [CON-906] Close the three free RPC Test: gaps, and one wrong claim These were the three remaining assertable and free examples in cli-reference.md. All three now carry a Test: line. Coverage goes from 5 of 33 runnable blocks to 8. Two live findings, both response-shape defects that fail silently. `qn rpc call -o json` prints the JSON-RPC result unwrapped. There is no jsonrpc, id, or result field. Code that reads `.result` on it gets undefined. `qn rpc list-networks -o json` returns `{"networks": [...]}`. That is a sixth distinct CLI response shape and it is not the `data` envelope the other list commands use, so `.data` is undefined. Also corrects a claim this branch added in b4640c0. The piped-output default is not universal. `qn rpc list-networks` prints a bare newline-separated list even when piped, with no JSON, so a script that pipes it and parses JSON fails. Verified: endpoint list, chain list and kv set list all print `{` when piped; rpc list-networks prints `0`. The Test: line now names all four commands and the exception. The asserted network count is dated in the line and marked as growing, because it drifts. The block-object assertion names the key range and the missing envelope rather than a field count, for the same reason. Verified live against account 464482. All calls read-only and free. No resource created. --- .../references/quicknode/cli-reference.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md b/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md index 10e1d6e..8a09833 100644 --- a/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md +++ b/plugins/build-web3/skills/build-web3/references/quicknode/cli-reference.md @@ -66,13 +66,17 @@ Set output with `--format` or `-o`. With `--format` unset the CLI reads `[output] format` from the config file, then defaults to `table` on a TTY and `json` when stdout is piped. `--wide`/`-w` affects only `table` and `md`. +**The piped default is not universal.** `qn rpc list-networks` prints a bare +newline-separated list of slugs even when piped, with no JSON. A script that +pipes it and parses JSON fails. Pass `-o json` explicitly for that command. + ```bash qn endpoint list --format json qn usage summary --from 7d -o yaml qn endpoint list --wide ``` -**Test:** `qn endpoint list | head -c 1` — prints `{`. Piped output defaults to `json`, not `table`, so a script never has to pass `-o json` +**Test:** `qn endpoint list | head -c 1`, `qn chain list | head -c 1`, and `qn kv set list | head -c 1` all print `{`; `qn rpc list-networks | head -c 1` prints `0`, the first character of `0g-galileo`. The piped default holds for three of these four commands and not for the fourth ## Exit Codes @@ -122,6 +126,11 @@ qn auth login qn rpc call eth_getBlockByNumber '["latest", false]' --network base-mainnet ``` +With `-o json` the CLI prints the JSON-RPC `result` **unwrapped**. There is no +`jsonrpc`, `id`, or `result` field to read past. + +**Test:** `base-mainnet` · block `latest` — `-o json` prints the block object itself at the top level, keyed `baseFeePerGas` through `withdrawalsRoot`, with no `jsonrpc`, `id`, or `result` wrapper; `transactions` holds hashes, not objects, because the second parameter is `false` + Params: positional (JSON array), by name (JSON object), from a file, or from stdin. ```bash @@ -142,6 +151,8 @@ qn rpc list-networks qn rpc list-networks -o json ``` +**Test:** `qn rpc list-networks` — one network key per line, sorted, `0g-galileo` first and `zora-mainnet` last (132 keys on 2026-09-04; the count grows, so do not gate on it). With `-o json` the payload is `{"networks": [...]}`. It is **not** the `data` envelope the other list commands use, so `.data` is `undefined` + `--endpoint-url ` sends the call to a self-authenticating URL instead of the Tooling Access endpoint, overriding `[rpc] endpoint_url` in `~/.config/qn/config.toml`. Mutually exclusive with `--network`. First-run `qn rpc call` prompts `[y/N]` to enable Tooling Access if it isn't provisioned yet. Pass `-y`/`--yes` to auto-confirm non-interactively. @@ -150,6 +161,8 @@ First-run `qn rpc call` prompts `[y/N]` to enable Tooling Access if it isn't pro qn rpc call eth_blockNumber --network base-mainnet -y ``` +**Test:** `base-mainnet` · block `latest` — returns a bare JSON string such as `"0x308471d"`, not an object. `-y` exits `0` and prompts nothing when Tooling Access is already enabled, so it is safe to pass unconditionally in a script + ### Paid RPC (x402 and MPP) Requires CLI v0.6.0+. `qn rpc call` can pay for a call with stablecoins through the x402 or MPP gateway instead of using the account's API key. This lane requires no Quicknode account, API key, login, Tooling Access, or provisioned endpoint — only a funded local wallet.