Guides · Part 3 of 8
Verify a record
Verification is the half of Label 309 that asks nobody's permission. Given a Cardano transaction reference, you can confirm a record yourself — against the public chain, through an explorer you choose. There is no login, and nothing about the result depends on whoever published it.
With the CLI
Install the cardanowall binary, then point it at a transaction:
cardanowall verify 3b9f…c1a2It resolves the transaction through a public Cardano explorer, structurally validates the record, checks any authorship signatures, confirms the record is settled, and prints a verdict. The verdict is one of four states, and the exit code carries it through verbatim — so it drops straight into CI:
| Exit code | Verdict | Meaning |
|---|---|---|
0 | valid | every required check passed |
1 | failed | a record-attributable check failed (integrity, structure, or signature) |
2 | unverifiable | no record fault, but a required check could not run (network or policy) |
3 | pending | not enough confirmations yet — no result from a pending record is final |
4 | — | CLI input error (bad arguments or missing required input) |
The split between failed and unverifiable is deliberate: a failed verdict
is always attributable to the record itself, so no misbehaving explorer can
manufacture one; unverifiable means the verifier could not complete a check
for reasons outside the record — a gateway it couldn't reach, a deny-listed
host, or a fetch ceiling.
Add --json for a machine-readable report, and keep every network hop under
your control by pointing at your own infrastructure:
cardanowall verify 3b9f…c1a2 \
--cardano-gateway https://your-koios-instance/api/v1 \
--threshold 20 \
--jsonIf the record is sealed to you, hand the verifier your key and it will decrypt the payload and recompute the plaintext hash:
cardanowall verify 3b9f…c1a2 --secret-key-stdinPrefer --secret-key-stdin, --secret-key-file, or the
CARDANOWALL_RECIPIENT_KEY environment variable over a bare --secret-key
flag, so the key never lands in your shell history.
Verify without the network
You can also check a record you hold as a file, with no transaction and no
explorer, by pointing --record at its bytes (raw CBOR or its hex encoding):
cardanowall verify --record ./record.cborThis runs the same structural, signature, and content checks over the supplied
bytes: a producer's pre-submission check ("is the record I am about to publish
well-formed and correctly signed?") or an archival re-validation. With no
transaction there is nothing to say about the chain, so the report omits block
time and confirmations unless you assert them yourself with --block-time,
--slot, and --confirmations.
For a record anchored on the preprod test network rather than mainnet, add
--network preprod to any of the on-chain commands above.
With the TypeScript SDK
The verifier the CLI uses ships in the SDK. It needs no client, no base URL, and no key — verification is gateway-agnostic:
import { verifyTx } from '@cardanowall/sdk-ts/verifier';
const report = await verifyTx({ txHash: '3b9f…c1a2' });
console.log(report.verdict); // 'valid' | 'pending' | 'unverifiable' | 'failed'
if (report.verdict !== 'valid') {
console.error(report.issues, report.signatures);
}verifyTx returns a full VerifyReport: the verdict and exitCode, the resolved
block_time and confirmationDepth, the structural-and-verifier issues list,
the per-item items and merkle check results, the optional signatures, and an
auditTrail log of every outbound request it made — so you can prove to yourself
it never contacted the publisher.
To verify a record sealed to you, hand the verifier your secret key. The keyring is global to the run — every key you pass is tried against every sealed item, so there is no per-item index:
const report = await verifyTx({
txHash: '3b9f…c1a2',
decryption: [{ recipientSecretKey: mySecretKey }],
});With the Python SDK
cardanowall-sdk is a byte-for-byte twin of the TypeScript verifier — the same
checks, the same verdict:
import asyncio
import cardanowall
report = asyncio.run(cardanowall.verify_tx(cardanowall.VerifyTxInput(tx_hash="3b9f…c1a2")))
print(report.verdict)With the Rust SDK
The cardanowall crate carries the same verifier. verify_tx is synchronous —
it owns a blocking transport — and returns the same VerifyReport:
use cardanowall::verifier::{verify_tx, Verdict, VerifyTxInput};
let report = verify_tx(&VerifyTxInput::new("3b9f…c1a2"));
println!("{}", report.verdict.as_str()); // "valid" | "pending" | "unverifiable" | "failed"
if report.verdict != Verdict::Valid {
eprintln!("{:?}", report.issues);
eprintln!("{:?}", report.record_signatures);
}To verify a record sealed to you, attach your secret key. The keyring is global
to the run — every key is tried against every sealed item, so a credential
carries no item index. The input fields are public, so build on top of
VerifyTxInput::new:
use cardanowall::verifier::{verify_tx, Decryption, VerifyTxInput};
let mut input = VerifyTxInput::new("3b9f…c1a2");
input.decryption = Some(vec![Decryption::Recipient {
recipient_secret_key: my_secret_key, // Vec<u8>
}]);
let report = verify_tx(&input);Why this needs no trust
Every check runs from public data and an explorer you choose. The people who published the record cannot influence the outcome — and if they disappeared tomorrow, your verification would still work exactly the same.