Step 3: Check Transaction Outputs
Now we use the registry to check transaction outputs. Replace check.ts with:
import { findRegistryCell, fetchRegistryPayload, preflightCheck } from "@ckb-firewall/sdk";
const RPC_URL = "https://testnet.ckb.dev";
const REGISTRY_SPEC = { codeHash: "0x493f1700508125b0e281b8fb1d168b03bd5ef71480399dd59221224901a9cd09", hashType: "type" as const, typeIdValue: "0x9be0ad6e4e5039a64d9725ff037057c16ef59f126e3bdd9841b802f0e0a112fe", required: true,};
const { txHash, index } = await findRegistryCell(RPC_URL, REGISTRY_SPEC);const registry = await fetchRegistryPayload(RPC_URL, txHash, index);console.log(`Registry loaded: ${registry.entries.length} active entries`);
// A clean recipient — not on the blacklistconst cleanOutput = { lockArgs: "0x331cdd72ff9f7f22c53f9710d6639ca46de3ac06" };
// A blacklisted recipient — on the testnet blacklistconst blockedOutput = { lockArgs: "0xababababababababababababababababababababab" };
function check(label: string, lockArgs: string) { const result = preflightCheck([{ lockArgs }], [registry]); if (result.ok) { console.log(`✓ ${label} → clean`); } else { console.log(`✗ ${label} → ${result.reason} (code ${result.code})`); }}
check(cleanOutput.lockArgs, cleanOutput.lockArgs);check(blockedOutput.lockArgs, blockedOutput.lockArgs);Run it:
npx tsx check.tsExpected output:
Registry loaded: 2 active entries✓ 0x331cdd72... → clean✗ 0xababababab... → BlacklistedLockArgs (code 11)preflightCheck is synchronous and makes no network calls — it checks the output against the already-fetched registry. You call it once per transaction, passing all outputs at once. It returns on the first blocked output it finds.
Notice the structure of the blocked result: { ok: false, code: 11, reason: "BlacklistedLockArgs" }. The code and reason fields are narrowed by the discriminated union, so you can switch on result.code with full type safety — no casting required.
Continue to Step 4.