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_PREFIXand--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_proposalsresponses encodedstatusasnat64while this release expectedint32. 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 transactionlistcommands never make network calls. -
Use command-specific help for the authoritative limits and defaults, for example
icq nns proposal list --helporicq 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.