Guides · Part 3 of 5
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 exit code carries that verdict, so it drops straight into CI:
| Exit code | Meaning |
|---|---|
0 | valid |
1 | integrity failure — a check did not pass |
2 | network error — couldn't reach an explorer |
3 | pending — not enough confirmations yet |
4+ | verifier couldn't run — a host-side failure |
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.
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' | 'failed'
if (report.verdict !== 'valid') {
console.error(report.validation.issues, report.record_signatures);
}verifyTx returns a full VerifyReport: the verdict and exit code, the resolved
block time and slot, the structural validation summary, record_signatures and
merkle_checks, and an http_calls 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, pass your secret key for the relevant item:
const report = await verifyTx({
txHash: '3b9f…c1a2',
decryption: [{ itemIndex: 0, 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" | "failed"
if report.verdict != Verdict::Valid {
eprintln!("{:?}", report.validation.issues);
eprintln!("{:?}", report.record_signatures);
}To verify a record sealed to you, attach your secret key for the relevant item.
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 {
item_index: 0,
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.