Verify yourself

How to verify a Kaspa transaction yourself.

The goal is not to make every reader a node operator on day one. The goal is to show the route away from one hosted explorer, one wallet UI, or one dashboard when you need stronger assurance.

Mainnet commands move around with releases. Check the source links before touching real funds.

Start here

Pick the job.

Verify chain state

Run or query a node, compare explorers, and check accepted transactions without trusting one hosted screen.

Start with node commands

Use a wallet from terminal

Open the Rusty Kaspa CLI route, inspect help, confirm network, and avoid signing until key storage is clear.

Start with kaspa-cli

Practice safely

Use testnet or TN12 before mainnet. Testnet coins are for learning, not value storage.

Start with testnet

Build app checks

Use wRPC and accepted-transaction replay when an app needs to prove that a txid, payload, or output really landed.

Start with wRPC

Use a hosted API

Use a documented API for address history, acceptance checks, block ranges, and KRC token data when a prototype cannot run its own indexer yet.

Start with KDP

Mental model

Verification ladder.

1. Explorer

Use an explorer to see whether a transaction appears accepted. This is convenient, not the final trust model.

2. Second source

Compare another explorer, API, wallet, or indexer view. If two hosted views disagree, slow down.

3. Your wallet

Check network, address, balance, transaction history, fee, and signing intent inside wallet software you control.

4. Your node

Run or query a node when you need to verify chain state without depending on a hosted interface.

Independent verification means climbing this ladder when the situation matters. It does not mean every normal payment requires every step.

Hosted API

KDP commands and boundaries.

The Kaspa Developer Platform is a hosted API for chain data, transaction checks, block queries, KRC20 token data, and a node RPC proxy. It is useful for prototypes, dashboards, exchange/wallet integrations, and second-source checks.

POST

Transaction acceptance

Batch-check txids for acceptance, accepting block hash, and confirmation count.

curl --request POST \
  --url https://api.kas.fyi/v1/transactions/acceptance \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{"transactionIds":["<txid>"]}'
GET

DAA-score blocks

Read a bounded DAA-score range. KDP limits these ranges to 100 scores per request.

curl --request GET \
  --url https://api.kas.fyi/v1/blocks/daa-score/{daa_score_start}/{daa_score_end} \
  --header 'x-api-key: <api-key>'

For paginated jobs, advance the range deliberately and record the last checked score.

GET

Blue-score blocks

Read blocks by blue score when that is the progress marker your app stores.

curl --request GET \
  --url https://api.kas.fyi/v1/blocks/blue-score/{blue_score_start}/{blue_score_end} \
  --header 'x-api-key: <api-key>'
GET

Address history

Use cursor pagination for large address histories. Cache carefully and handle rate limits.

curl --request GET \
  --url 'https://api.kas.fyi/v1/addresses/<address>/transactions?limit=100' \
  --header 'x-api-key: <api-key>'
DATA

API data rules

Amounts are sompi strings, not floats. Hashes are 64-character hex strings. Addresses use the kaspa: prefix. API timestamps are Unix milliseconds.

1 KAS = 100000000 SOMPI
amount: "31112708372"
blockTime: 1749531022210
LIMITS

Rate limits and keys

Send the API key in x-api-key. Watch rate-limit headers, request-unit cost, 401 errors for key issues, and 429 errors for backoff.

ratelimit-limit: 500;w=1
ratelimit-remaining: 490
x-request-cost-ru: 10
BOUNDARY

Production boundary

API keys, rate limits, pricing, and provider uptime are product dependencies. Production apps should plan their own node, indexer, or redundant provider path when reliability, privacy, or scale matters.

KDP is a useful hosted read path. Protocol status still comes from source, releases, KIPs, nodes, and network evidence.

Mainnet

Run a Rusty Kaspa node.

Prerequisites: Docker for the container route, or Rust/Cargo for the source route. A node can verify chain state; it does not create or protect wallet keys by itself.

Docker route with persistent storage:

docker pull kaspanet/rusty-kaspad:latest
mkdir -p ~/kaspa-data
docker run -d --name kaspa-node --restart unless-stopped \
  -v ~/kaspa-data:/app/data \
  -p 16110:16110 -p 16111:16111 -p 17110:17110 -p 18110:18110 \
  kaspanet/rusty-kaspad:latest

Basic container checks:

docker ps
docker logs --tail=80 kaspa-node

Source-build route from the Rusty Kaspa README:

git clone https://github.com/kaspanet/rusty-kaspa
cd rusty-kaspa
cargo run --release --bin kaspad

Mainnet node with UTXO indexing:

cargo run --release --bin kaspad -- --utxoindex

Use --utxoindex when wallet or UTXO queries need indexed UTXO state. Let the node sync before treating its answers as current.

Wallet and RPC

Open the terminal wallet/RPC path.

From a Rusty Kaspa checkout:

cd cli
cargo run --release

Use this as the current source-backed entry into the Rusty Kaspa terminal RPC and wallet runtime. Before creating wallets or signing anything:

Check network

Confirm whether the CLI is connected to mainnet or testnet before creating or importing wallet material.

Check files

Find where wallet files, keys, and local state are stored. Do not guess.

Check intent

For every transaction, inspect address, amount, fee, network, and whether it is a send, sweep, or self-transfer.

Test small

Use tiny amounts first, then verify the accepted txid through independent sources.

wRPC

Enable a JSON WebSocket RPC endpoint.

Rusty Kaspa documents wRPC as optional and disabled by default. For JSON wRPC:

cargo run --release --bin kaspad -- --utxoindex --rpclisten-json=default

This lets SDKs and scripts query node state over WebSocket. Bind carefully on public machines. A public RPC endpoint is infrastructure, not a wallet safety boundary.

Use wRPC when an app needs to read accepted transactions, inspect payload-capable routes, or compare indexer state against node-observed chain state.

Testnet

Practice before mainnet.

Generic Rusty Kaspa testnet route:

cargo run --release --bin kaspad -- --testnet

Older hard-fork testnet guides used explicit suffixes, for example:

kaspad --testnet --netsuffix=10 --utxoindex
cargo run --bin kaspad --release -- --testnet --netsuffix=10 --utxoindex

For TN12/Toccata work, verify the current netsuffix, release, endpoint, and flags from active public docs before running. TN10 examples are historical context, not TN12 instructions.

Builder Evidence links the public site to the TN12 proof lab when you want accepted testnet examples.

TN12 practice

Use the proof lab for covenant-shaped testnet work.

TN12 is where covenant, payload, and replay experiments can be practiced before mainnet behavior changes. In the TN12 repo, the basic route is:

git clone https://github.com/parker2017code/tn12-covenant-vault-demo
cd tn12-covenant-vault-demo
npm ci
npm run check:all
npm run check:tn12
npm run playground:wallets

Then fund only the printed kaspatest: addresses with faucet tKAS, inspect txids in the TN12 explorer, and replay before believing app state. Anything with --submit is a real TN12 broadcast.

Status: testnet practice. Mainnet wallet, custody, and Toccata activation claims need mainnet evidence.

Toccata reminder

Update this when mainnet behavior changes.

Toccata/TN12 command examples stay in the testnet or targeted lane until public activation evidence, Rusty Kaspa releases, official docs, and working tool commands show that the behavior is live on mainnet.

Sources

Check these before running commands.

Kaspa Build

kaspa.org/build

Node, SDK, query, explorer, and testnet entry points.

Kaspa Docs

docs.kaspa.org

Integration docs for RPC, payloads, accepted transactions, and node infrastructure.