Ic-query 0.17 : Query the Internet Computer from Your Terminal

Joined NNS topology reports

Topology joins the five registry inventories into operational views. Running any read report will populate missing component caches; topology refresh updates all five.

30. Topology summary

$ icq nns topology summary
topology: ic subnets 84 nodes 814 node_operators 135 node_providers 103 data_centers 100

METRIC           COUNT
--------------   -----
subnets             84
routing_ranges      51
nodes              814
node_operators     135
node_providers     103
data_centers       100

KIND           SUBNETS   NODES
-------------  -------   -----
application         47     587
cloud_engine        34     140
system               3      87
unknown              0       0

RELATION                           KNOWN   UNKNOWN   COVERAGE
nodes -> node providers              814         0     100.0%
...

31. Join coverage

This answers whether node → operator → provider → data-centre joins can be resolved.

$ icq nns topology coverage
FIELD            VALUE
--------------   -----
network             ic
nodes              814
node_operators     135
node_providers     103
data_centers       100

RELATION                           KNOWN   UNKNOWN   COVERAGE
--------------------------------   -----   -------   --------
nodes -> node providers              814         0     100.0%
nodes -> node operators              814         0     100.0%
nodes -> data centers                814         0     100.0%
node operators -> node providers     135         0     100.0%
node operators -> data centers       135         0     100.0%

32. Registry-version alignment

$ icq nns topology versions
SOURCE           VERSION   FETCHED_AT             STALE   ENDPOINT
--------------   -------   --------------------   -----   ------------------
subnet_catalog     62718   2026-07-30T18:03:39Z   no      -
nodes              62718   2026-07-30T18:03:39Z   -       https://icp-api.io
node_providers     62718   2026-07-30T18:03:39Z   -       https://icp-api.io
node_operators     62719   2026-07-30T18:03:39Z   -       https://icp-api.io
data_centers       62719   2026-07-30T18:03:39Z   -       https://icp-api.io

33. Topology health

$ icq nns topology health
CHECK               STATUS      DETAIL
------------------  ----------  ---------------------------------------------
registry_versions   attention   5 sources span registry versions 62718..62719
cache_freshness     ok          no stale topology sources
join_coverage       ok          2712 known, 0 unknown (100.0%)

34. Topology gaps

$ icq nns topology gaps
STATUS   DETAIL
------   ---------------------
ok       no topology join gaps

35. Operator capacity

This compares assigned nodes with operator allowances.

$ icq nns topology capacity
FIELD                              VALUE
----------------------------   ---------
network                               ic
status                         attention
node_operators                       135
total_node_allowance                 789
assigned_nodes                       814
available_node_slots                 454
over_assigned_operators               88
over_assigned_nodes                  479

36. Regional distribution

$ icq nns topology regions
REGION               DATA_CENTERS   OPERATORS   PROVIDERS   NODES
-------------------  ------------   ---------   ---------   -----
Europe, CH, Zurich              4          13           5      66
...

37. Provider footprint

$ icq nns topology providers
PROVIDER       STATUS   GOV_NODES   NODES   OPERATORS   DCS   REGIONS
-------------  -------  ---------   -----   ---------   ---   -------
bvcsg-3od6r... over           140     140          18     9         7
...

38. Refresh every topology component

$ icq nns topology refresh
topology_refresh: ic components 5 wrote 5 replaced 0 dry_run no

SOURCE           COUNT   VERSION   DRY_RUN   WROTE   REPLACED
--------------   -----   -------   -------   -----   --------
subnet_catalog      84     62718   no        yes     no
nodes              814     62718   no        yes     no
node_providers     103     62718   no        yes     no
node_operators     135     62719   no        yes     no
data_centers       100     62719   no        yes     no

SNS queries

Every SNS-specific command accepts either the positive numeric ID printed by sns list or the project’s Root canister principal. In the examples, 1 resolves to Dragginz.

Deployed projects and configuration

39. List deployed SNS projects

Use --sort id|name; --verbose prints full principals.

$ icq sns list --sort id
network: ic
sns_count: 53
metadata_error_count: 16

ID   NAME       ROOT          GOVERNANCE    LEDGER        SWAP          INDEX
--   ---------  ------------  ------------  ------------  ------------  ------------
 1   Dragginz   zxeu2-7aaaa   zqfso-syaaa   zfcdd-tqaaa   zcdfx-6iaaa   zlaol-iaaaa
 2   OpenChat   3e3x2-xyaaa   ...           ...           ...           ...
...

40. Inspect one SNS

$ icq sns info 1
network: ic
sns_id: 1
name: Dragginz
description: An SNS DAO for Dragginz
url: https://dragginz.io
root_canister_id: zxeu2-7aaaa-...
governance_canister_id: zqfso-syaaa-...
ledger_canister_id: zfcdd-tqaaa-...
swap_canister_id: zcdfx-6iaaa-...
index_canister_id: zlaol-iaaaa-...

41. Inspect the SNS token

$ icq sns token 1
network: ic
sns_id: 1
name: Dragginz
token_symbol: DKP
decimals: 8
total_supply: 7999840312.98
transfer_fee: 0.00
standards: ICRC-1, ICRC-2, ICRC-3, ICRC-10, ICRC-21, ICRC-103, ICRC-106
index_canister_id: zlaol-iaaaa-...

42. Inspect governance parameters

$ icq sns params 1
network: ic
sns_id: 1
name: Dragginz
minimum_stake: 1000.00 DKP
transaction_fee: 0.00 DKP
proposal_reject_cost: 50000.00 DKP
maximum_dissolve_delay: 2922.00d
initial_voting_period: 4.00d
...

43. List SNS canisters and operational health

This asks SNS Root for the declared canisters and their summaries without modifying the canister list.

$ icq sns canister list 1
network: ic
sns_id: 1
name: Dragginz
canister_count: 9
health_summary_count: 9
health_gap_count: 0
point_in_time_guaranteed: no
summary_call_type: ingress_update
update_canister_list: no

ROLE         CANISTER       STATUS    MEMORY       CYCLES
-----------  -------------  --------  -----------  ----------------
root         zxeu2-7aaaa...  running   ...          ...
governance   zqfso-syaaa...  running   ...          ...
ledger       zfcdd-tqaaa...  running   ...          ...
swap         zcdfx-6iaaa...  running   ...          ...
index        zlaol-iaaaa...  running   ...          ...
archive      ...             running   ...          ...
dapp         ...             running   ...          ...

SNS proposals

Lists default to 25 and cap at 100. Filters include:

  • --before ID

  • --status any|open|decided|rejected|adopted|executed|failed

  • --topic any|dao-community-settings|sns-framework-management|dapp-canister-management|application-business-logic|governance|treasury-asset-management|critical-dapp-operations

  • --eligible any|yes|no

  • --proposer NEURON_ID_PREFIX and --query TEXT

  • --sort api|id|status|topic|proposer|title|action|action-id|yes|no|total-votes|tally-time|ballots|eligible|reject-cost|reward-round|reward-end|created|decided|executed|failed

  • --asc, --desc, and --verbose

Non-API sorts and richer filters use a complete cache.

Compatibility note: the following blocks show the successful report shape implemented and tested by 0.17.1. During the live check for this post, proposal calls against Dragginz and Kinic failed because their list_proposals responses encoded status as nat64 while this release expected int32. The CLI reported the Candid mismatch rather than returning unsafe data. The other SNS query families worked.

44. List SNS proposals

$ icq sns proposal list 1 --status open --limit 3
network: ic
sns_id: 1
name: Dragginz
requested_limit: 3
status_filter: open
data_source: cache
proposal_count: 3

ID   ACTION   DECISION   CREATED_AT             TITLE
--   -------  ---------  ---------------------  ----------------
30   motion   open       2026-07-...            Example proposal
...

45. Inspect one SNS proposal

Add --ballots and/or --verbose for the ballot table and unabridged detail.

$ icq sns proposal info 1 30 --ballots
network: ic
sns_id: 1
name: Dragginz
proposal_id: 30
data_source: cache

proposal:
  decision_state: open
  topic: governance
  action: motion
  title: Example proposal
  ...

ballots:
NEURON_ID   VOTE   VOTING_POWER
...         yes    ...

46. Refresh a complete SNS proposal snapshot

$ icq sns proposal refresh 1 --page-size 100
network: ic
sns_id: 1
name: Dragginz
proposal_count: ...
page_size: 100
page_count: ...
complete: yes
replaced_existing_cache: no
wrote_cache: yes
attempt_finalized: yes
cache_path: .../sns/ic/zxeu2-7aaaa-.../proposals/full.json

47. List SNS proposal caches

This is local-only and lists caches for every SNS.

$ icq sns proposal cache list
network: ic
cache_root: /home/alice/.cache/ic-query
cache_count: 1

STATUS   ID   NAME       ROOT          ROWS   PAGES   FETCHED_AT
valid     1   Dragginz   zxeu2-7...     ...     ...    2026-07-30T...

48. Inspect one SNS proposal cache

$ icq sns proposal cache status 1
network: ic
cache_root: /home/alice/.cache/ic-query
input: 1
found: yes
sns_id: 1
name: Dragginz
cache_status: valid
complete: yes
row_count: ...
cache_path: .../sns/ic/zxeu2-7aaaa-.../proposals/full.json

SNS neurons

--sort api is a bounded live query. --sort id|stake|maturity|created needs a complete cache and can combine with --owner PRINCIPAL. Add --verbose for full neuron IDs.

49. List SNS neurons

$ icq sns neuron list 1 --limit 3 --sort api
network: ic
sns_id: 1
name: Dragginz
requested_limit: 3
data_source: live
sort: api
neuron_count: 3

NEURON_ID   STAKE        MATURITY   STAKED_MATURITY   CREATED_AT
----------  -----------  ---------  ----------------  ---------------------
0000aee8    ...          ...        ...               ...
000c034e    807984.80    ...        ...               ...
0014a852    ...          ...        ...               ...

50. Refresh a complete SNS neuron snapshot

$ icq sns neuron refresh 1 --page-size 100
network: ic
sns_id: 1
name: Dragginz
page_size: 100
page_count: ...
neuron_count: ...
complete: yes
wrote_cache: yes
replaced_existing_cache: no
attempt_finalized: yes
cache_path: .../sns/ic/zxeu2-7aaaa-.../neurons/full.json

51. List SNS neuron caches

$ icq sns neuron cache list
network: ic
cache_root: /home/alice/.cache/ic-query
cache_count: 1

STATUS   ID   NAME       ROOT       COMPLETE   ROWS   PAGES   FETCHED_AT
valid     1   Dragginz   zxeu2...   yes         ...     ...    2026-07-30T...

52. Inspect one SNS neuron cache

$ icq sns neuron cache status 1
network: ic
input: 1
cache_root: /home/alice/.cache/ic-query
found: yes
sns_id: 1
name: Dragginz
cache_status: valid
complete: yes
row_count: ...
cache_path: .../sns/ic/zxeu2-7aaaa-.../neurons/full.json

Generic ICRC queries

These commands are ledger-driven rather than network-driven. They work with compatible ICRC ledgers that are not part of an SNS, too.

Ledger discovery and history

53. Probe ledger capabilities

This checks declared standards plus live availability of ICRC-106 and ICRC-3 methods.

$ icq icrc ledger capabilities mxzaz-hqaaa-aaaar-qaada-cai
ledger_canister_id: mxzaz-hqaaa-aaaar-qaada-cai
standard_count: 7
capability_count: 6

CAPABILITY                     METHOD                        STATUS      DETAIL
-----------------------------  ----------------------------  ----------  -----------------------------
ICRC-1 supported standards     icrc1_supported_standards     available   7 standard(s)
ICRC-106 index discovery       icrc106_get_index_principal   available   n5wcd-faaaa-aaaar-qaaea-cai
ICRC-3 block history           icrc3_get_blocks              available   log_length 4_024_608
ICRC-3 supported block types   icrc3_supported_block_types   available   5 block type(s)
ICRC-3 archive discovery       icrc3_get_archives            available   1 archive range(s)
ICRC-3 tip certificate         icrc3_get_tip_certificate     available   verified certificate

54. Read token metadata

$ icq icrc ledger token ryjl3-tyaaa-aaaaa-aaaba-cai
ledger_canister_id: ryjl3-tyaaa-aaaaa-aaaba-cai
token_name: Internet Computer
token_symbol: ICP
decimals: 8
transfer_fee: 0.0001
total_supply: 555228727.51
minting_account_owner: rrkah-fqaaa-aaaaa-aaaaq-cai

STANDARD   URL
ICRC-1     https://github.com/dfinity/ICRC-1/...
ICRC-2     https://github.com/dfinity/ICRC-1/...
ICRC-21    ...

55. Discover the ledger’s index

$ icq icrc ledger index mxzaz-hqaaa-aaaar-qaada-cai
ledger_canister_id: mxzaz-hqaaa-aaaar-qaada-cai
index_canister_id: n5wcd-faaaa-aaaar-qaaea-cai
fetched_at: 2026-07-30T18:09:31Z
source_endpoint: https://icp-api.io

The ICP ledger does not export icrc106_get_index_principal, so discovery correctly fails there. Supply its index explicitly for account-history operations:

$ icq icrc ledger index ryjl3-tyaaa-aaaaa-aaaba-cai
icrc: ... Canister has no query method 'icrc106_get_index_principal'

56. Read ledger-wide ICRC-3 transactions

Use --start NAT, --limit 1..100, and --follow-archives. Without archive following, a range in an archive is returned as a callback descriptor; with it, icq follows the callback.

$ icq icrc ledger transactions mxzaz-hqaaa-aaaar-qaada-cai \
    --start 0 --limit 3 --follow-archives
ledger_canister_id: mxzaz-hqaaa-aaaar-qaada-cai
requested_start: 0
requested_limit: 3
follow_archives: true
log_length: 4_024_608
followed_archive_blocks: 3

ARCHIVE_CANISTER              INDEX   KIND   TIMESTAMP_NS             AMOUNT_BASE_UNITS
nbsys-saaaa-aaaar-qaaga-cai       0   mint   1675241149669614928                100000
nbsys-saaaa-aaaar-qaaga-cai       1   mint   1675416282438485110             150000000
nbsys-saaaa-aaaar-qaaga-cai       2   xfer   1675680654649369360                100000

57. List supported ICRC-3 block types

$ icq icrc ledger block-types mxzaz-hqaaa-aaaar-qaada-cai
ledger_canister_id: mxzaz-hqaaa-aaaar-qaada-cai
block_type_count: 5

BLOCK_TYPE   URL
----------   ------------------------------------------------------------
1burn        https://github.com/dfinity/ICRC-1/.../ICRC-1/README.md
1mint        https://github.com/dfinity/ICRC-1/.../ICRC-1/README.md
1xfer        https://github.com/dfinity/ICRC-1/.../ICRC-1/README.md
2approve     https://github.com/dfinity/ICRC-1/.../ICRC-2/README.md
2xfer        https://github.com/dfinity/ICRC-1/.../ICRC-2/README.md

58. Discover archive ranges

Optionally add --from CANISTER_ID to continue from an archive principal.

$ icq icrc ledger archives mxzaz-hqaaa-aaaar-qaada-cai
ledger_canister_id: mxzaz-hqaaa-aaaar-qaada-cai
from_canister_id: -
archive_count: 1

ARCHIVE_CANISTER              START        END
---------------------------   -----   --------
nbsys-saaaa-aaaar-qaaga-cai       0    4022999

59. Verify the certified ledger tip

This is more than a byte dump. icq authenticates the mainnet certificate and delegation, checks canister authority and freshness, proves the supplied hash tree against certified_data, and verifies the canonical last_block_index and last_block_hash leaves when present.

$ icq icrc ledger tip-certificate mxzaz-hqaaa-aaaar-qaada-cai
ledger_canister_id: mxzaz-hqaaa-aaaar-qaada-cai
certificate_present: true
certificate_bytes: 2028
hash_tree_bytes: 82
certificate_hex: d9d9f7a3647472656583018301...
hash_tree_hex: 830183024f6c6173745f626c6f...
fetched_at: 2026-07-30T18:09:02Z
source_endpoint: https://icp-api.io

Endpoint overrides must still serve mainnet-certified responses; alternate root keys are not configured.

Accounts

Accounts are an owner principal plus an optional 32-byte subaccount expressed as exactly 64 hexadecimal characters.

60. Read a balance

$ icq icrc account balance mxzaz-hqaaa-aaaar-qaada-cai aaaaa-aa
ledger_canister_id: mxzaz-hqaaa-aaaar-qaada-cai
account_owner: aaaaa-aa
subaccount_hex: -
token_symbol: ckBTC
decimals: 8
balance: 0.00 ckBTC
balance_base_units: 1
source_endpoint: https://icp-api.io

With a subaccount:

$ icq icrc account balance LEDGER OWNER \
    --subaccount 0000000000000000000000000000000000000000000000000000000000000000
balance: ...

61. Read an ICRC-2 allowance

The first principal is the account owner; the second is the spender. Optional flags are --owner-subaccount and --spender-subaccount.

$ icq icrc account allowance mxzaz-hqaaa-aaaar-qaada-cai aaaaa-aa aaaaa-aa
ledger_canister_id: mxzaz-hqaaa-aaaar-qaada-cai
account_owner: aaaaa-aa
spender_owner: aaaaa-aa
token_symbol: ckBTC
allowance: 0.00 ckBTC
allowance_base_units: 0
expires_at_unix_nanos: -
source_endpoint: https://icp-api.io

Indexed account history

An account page is a bounded live read. A refresh walks the verified index and attempts to publish one complete local snapshot. List and status are then strictly local.

The index is discovered through ICRC-106 unless --index-canister-id is supplied. The selected index is verified against the requested ledger. Cursors are arbitrary-size unsigned decimal Candid Nat values: pass the returned next_start back as --start.

62. Fetch one live account-history page

$ icq icrc account transaction page mxzaz-hqaaa-aaaar-qaada-cai aaaaa-aa --limit 3
ledger_canister_id: mxzaz-hqaaa-aaaar-qaada-cai
index_canister_id: n5wcd-faaaa-aaaar-qaaea-cai
account_owner: aaaaa-aa
requested_start: -
requested_limit: 3
next_start: 779513
oldest_transaction_id: 779513
balance: 0.00 ckBTC
returned_transactions: 1

    ID   KIND       TIMESTAMP_NS          AMOUNT      FEE         FROM      TO
------   --------   -------------------   ---------   ---------   -------   --------
779513   transfer   1702571763745130378   0.00 ckBTC  0.00 ckBTC  kjz3i...  aaaaa-aa

For ICP, provide the official index:

$ icq icrc account transaction page ryjl3-tyaaa-aaaaa-aaaba-cai aaaaa-aa \
    --index-canister-id qhbym-qaaaa-aaaaa-aaafq-cai
ledger_canister_id: ryjl3-tyaaa-aaaaa-aaaba-cai
index_canister_id: qhbym-qaaaa-aaaaa-aaafq-cai
...

63. Refresh the complete account history

Use --page-size 1..100 and optionally --max-pages. A capped or failed attempt records progress and leaves the last valid complete cache untouched.

$ icq icrc account transaction refresh mxzaz-hqaaa-aaaar-qaada-cai aaaaa-aa \
    --page-size 100
ledger_canister_id: mxzaz-hqaaa-aaaar-qaada-cai
index_canister_id: n5wcd-faaaa-aaaar-qaaea-cai
account_owner: aaaaa-aa
transaction_count: ...
newest_transaction_id: ...
oldest_transaction_id: ...
page_size: 100
page_count: ...
point_in_time_guaranteed: false
replaced_existing_cache: false
attempt_finalization_error: -
cache_path: .../icrc/ic/account-<identity-hash>/transactions/full.json

Exhausting the API proves that all pages were collected, but the index API exposes no immutable snapshot version; that is why point_in_time_guaranteed remains false.

64. List cached account transactions

The cache must already exist. Choose --sort newest|oldest and any positive --limit.

$ icq icrc account transaction list mxzaz-hqaaa-aaaar-qaada-cai aaaaa-aa \
    --sort newest --limit 3
ledger_canister_id: mxzaz-hqaaa-aaaar-qaada-cai
index_canister_id: n5wcd-faaaa-aaaar-qaaea-cai
account_owner: aaaaa-aa
requested_limit: 3
sort: newest
returned_transactions: 1
total_transactions: 1
complete: true
point_in_time_guaranteed: false
cache_path: .../transactions/full.json

    ID   KIND       TIMESTAMP_NS          AMOUNT      FEE
------   --------   -------------------   ---------   ---------
779513   transfer   1702571763745130378   0.00 ckBTC  0.00 ckBTC

65. Inspect account-history cache status

$ icq icrc account transaction cache status mxzaz-hqaaa-aaaar-qaada-cai aaaaa-aa
ledger_canister_id: mxzaz-hqaaa-aaaar-qaada-cai
account_owner: aaaaa-aa
source_endpoint: https://icp-api.io
found: true
cache_status: valid
index_canister_id: n5wcd-faaaa-aaaar-qaaea-cai
transaction_count: 1
complete: true
point_in_time_guaranteed: false
expected_cache_path: .../transactions/full.json

If the cache is absent, found: false is returned with the exact expected cache, attempt, and lock paths. No live call is made.


Automation recipes

The stable JSON reports make icq useful in shell scripts as well as interactive sessions.

Find all system subnets:

$ icq nns subnet list --kind system --format json \
    | jq -r '.subnets[].subnet_id'
tdb26-jop6k-aogll-7ltgs-...
uzr34-akd3s-...
...

Check that every topology join is known:

$ icq nns topology coverage --format json \
    | jq '[.nodes_with_unknown_data_center_count,
           .nodes_with_unknown_node_operator_count,
           .nodes_with_unknown_node_provider_count,
           .node_operators_with_unknown_data_center_count,
           .node_operators_with_unknown_node_provider_count] | add == 0'
true

Resolve an SNS ledger and query it generically:

$ LEDGER=$(icq sns info 1 --format json | jq -r '.ledger_canister_id')
$ icq icrc ledger capabilities "$LEDGER" --format json \
    | jq -r '.capabilities[] | [.name, .status] | @tsv'
ICRC-1 supported standards	available
ICRC-106 index discovery	available
ICRC-3 block history	available
...

Keep cache files somewhere explicit:

$ export ICQ_CACHE_ROOT=/var/cache/ic-query
$ icq nns topology refresh --format json > topology-refresh.json
$ icq nns topology health --format json | jq '.overall_status'
"ok"

Using the Rust library

The CLI is only one wrapper. For typed reports and renderers without process shell-outs:

$ cargo add ic-query@0.17 --no-default-features

For native live calls, filesystem-backed caches, refresh builders, or custom source adapters, enable host:

$ cargo add ic-query@0.17 --no-default-features --features host

The public families are ic_query::nns, ic_query::sns, ic_query::icrc, and ic_query::subnet_catalog. The host feature exposes narrow source traits, so another native tool can provide fixture, mirror, proxy, or pre-collected data while reusing the same request, report, validation, and rendering code.

Cache and failure semantics worth knowing

  • Complete snapshot files, locks, and refresh-attempt sidecars are strictly validated against their schema, network, entity, collection, and scope.

  • Refresh publishes atomically only after collection and validation succeed.

  • A failed or capped refresh preserves the previous complete cache.

  • Malformed or stale locks are reported but never silently deleted. Remove one manually only after confirming no refresh is running.

  • Cache identity includes the relevant endpoint and entity identity. ICRC account caches also include the ledger, owner, and subaccount; pagination and sort are view options rather than cache identity.

  • Local cache list, cache status, and ICRC transaction list commands never make network calls.

  • Use command-specific help for the authoritative limits and defaults, for example icq nns proposal list --help or icq icrc account transaction refresh --help.

Links

That is the entire 0.17.1 query surface: 38 NNS queries, 14 SNS queries, and 13 generic ICRC queries.