Skip to content

SDK

After this page your app reports every send and simulation attempt to WireTap, which unlocks the two failure classes on-chain watching cannot see: drops and preflight failures.

Watching the chain answers “why did this landed transaction fail?” — but a transaction that never landed left no record anywhere. The SDK fixes that by capturing a small envelope at send time (signature, blockhash validity window, RPC endpoint hash, wallet adapter, simulation logs on failure). WireTap’s correlation job then matches envelopes against observed chain data and classifies everything that never landed. This also powers the per-provider drop rates behind provider_report.

Privacy: the SDK never sees keys or signing material. Payer addresses can be reported as-is or as a salted hash (privacy: "hash").

Terminal window
pnpm add @wiretap-labs/sdk

The SDK is published on npm as @wiretap-labs/sdk.

import { Connection } from "@solana/web3.js";
import { createWireTap } from "@wiretap-labs/sdk";
const wiretap = createWireTap({
ingestUrl: process.env.WIRETAP_API_URL!, // your API base (hosted or self-hosted)
apiKey: process.env.WIRETAP_API_KEY!, // ingest-scoped key (dashboard / wiretap init)
program: "DemoAMM…", // program(s) you're tracking
});
// wrap the connection you already use — send/simulate calls are observed
const connection = wiretap.wrapConnection(
new Connection("https://api.devnet.solana.com"),
);
// use `connection` exactly as before

wrapConnection wraps sendRawTransaction, sendTransaction, and simulateTransaction. (createWireTap also returns wrapKitSender, anchorProvider, and capturePreflightFailure for Kit/Anchor code paths.) Envelopes are batched, sent asynchronously, and never block or fail your sends — if the ingest endpoint is unreachable, batches are dropped after a bounded retry.

Any send through the wrapped connection is captured. If a transaction never lands — e.g. it went out on an already-stale blockhash — there’s no on-chain record, so the correlation job is what classifies it as a drop:

// `connection` is the wrapped connection from above
const sig = await connection.sendRawTransaction(staleTx.serialize());
console.log(sig); // feed this to `/why` once it's classified

Within about a minute (one blockhash validity window plus the correlation interval), the drop is classified. Ask in Telegram or MCP:

/why <printed-signature>
→ ✗ never landed — expired_blockhash
sent 14:02:11 via rpc "public" · lastValidBlockHeight passed at 14:03:04
53 slots of lag between send and expiry — see /status for provider split
Option Default Notes
ingestUrl Required. Your WireTap API base (hosted or self-hosted)
apiKey Required. Ingest-scoped key
program Required. Program ID to attribute envelopes to
payerPrivacy "plain" "hash" reports a salted hash of the payer
flushIntervalMs 3000 Envelope batch interval (ms)
maxBatch 50 Flush immediately once this many envelopes queue

The RPC endpoint is reported as a hash + coarse label (helius, quicknode, public…) — never the full URL, which may embed API keys.