Skip to Content
SDKTxnodClient

TxnodClient

TxnodClient is the primary entry point of @txnod/sdk. Every method signs outbound requests with HMAC-SHA256 using the project’s apiSecret, retries automatically on 429 and 5xx, and throws a typed subclass of TxnodError on any non-2xx response.

AI coding agents: a full, version-matched copy of this page and every other SDK guide ships inside the @txnod/sdk tarball at node_modules/@txnod/sdk/docs/, with an entry point at node_modules/@txnod/sdk/AGENTS.md. Prefer those offline files after install — they need no network access.

Construction

import { TxnodClient } from '@txnod/sdk'; const client = new TxnodClient({ projectId: process.env.TXNOD_PROJECT_ID!, apiSecret: process.env.TXNOD_API_SECRET!, });

baseUrl defaults to https://txnod.com. Override only for staging or integration tests — production code should never hardcode a different origin.

createInvoice(body)

Create a new invoice. Idempotent on (project_id, external_id).

import { TxnodClient, TxnodError, AddressVerificationError } from '@txnod/sdk'; // Set TXNOD_BTC_XPUB=zpub6r... in env to enable address verification. const client = new TxnodClient({ projectId: process.env.TXNOD_PROJECT_ID!, apiSecret: process.env.TXNOD_API_SECRET!, }); try { const invoice = await client.createInvoice({ amount_usd: 10.0, coin: 'btc', external_id: 'order-123', callback_url: 'https://my-site.com/webhooks/txnod', }); console.log(invoice.id, invoice.address, invoice.payment_uri); } catch (err) { if (err instanceof AddressVerificationError) { console.error('address verify failed', err.expected_address, err.derived_address); } else if (err instanceof TxnodError) { console.error(err.error_code, err.status, err.request_id); } throw err; }

getInvoice(id)

Fetch an invoice by ULID.

import { TxnodClient, TxnodError } from '@txnod/sdk'; const client = new TxnodClient({ projectId: process.env.TXNOD_PROJECT_ID!, apiSecret: process.env.TXNOD_API_SECRET!, }); try { const invoice = await client.getInvoice('01HK8MAR2QEXAMPLE000000000'); console.log(invoice.status); } catch (err) { if (err instanceof TxnodError) console.error(err.error_code); throw err; }

searchInvoices(query)

Search invoices with snake_case query filters. Returns a cursor-paginated page.

import { TxnodClient, TxnodError } from '@txnod/sdk'; const client = new TxnodClient({ projectId: process.env.TXNOD_PROJECT_ID!, apiSecret: process.env.TXNOD_API_SECRET!, }); try { const page = await client.searchInvoices({ status: 'paid', limit: 20, }); for (const invoice of page.items) console.log(invoice.id); } catch (err) { if (err instanceof TxnodError) console.error(err.error_code); throw err; }

cancelInvoice(id)

Cancel a pending or detected invoice and release its pool address into cooldown.

import { TxnodClient, TxnodError } from '@txnod/sdk'; const client = new TxnodClient({ projectId: process.env.TXNOD_PROJECT_ID!, apiSecret: process.env.TXNOD_API_SECRET!, }); try { const cancelled = await client.cancelInvoice('01HK8MAR2QEXAMPLE000000000'); console.log(cancelled.status); } catch (err) { if (err instanceof TxnodError) console.error(err.error_code); throw err; }

listOrphanPayments(query)

List on-chain receipts that did not match any invoice address at detection time.

import { TxnodClient, TxnodError } from '@txnod/sdk'; const client = new TxnodClient({ projectId: process.env.TXNOD_PROJECT_ID!, apiSecret: process.env.TXNOD_API_SECRET!, }); try { const page = await client.listOrphanPayments({ chain: 'btc', limit: 50 }); for (const orphan of page.items) console.log(orphan.tx_hash); } catch (err) { if (err instanceof TxnodError) console.error(err.error_code); throw err; }

attributeOrphanPayment(txHash, body)

Attribute an orphan payment to an external invoice id. Creates a synthetic paid invoice and emits an invoice.paid webhook event.

import { TxnodClient, TxnodError } from '@txnod/sdk'; const client = new TxnodClient({ projectId: process.env.TXNOD_PROJECT_ID!, apiSecret: process.env.TXNOD_API_SECRET!, }); try { const invoice = await client.attributeOrphanPayment('0xabc123', { external_id: 'order-123', }); console.log(invoice.id); } catch (err) { if (err instanceof TxnodError) console.error(err.error_code); throw err; }

listWebhookEvents(query)

List outbound webhook events for the authenticated project.

import { TxnodClient, TxnodError } from '@txnod/sdk'; const client = new TxnodClient({ projectId: process.env.TXNOD_PROJECT_ID!, apiSecret: process.env.TXNOD_API_SECRET!, }); try { const page = await client.listWebhookEvents({ status: 'delivered', limit: 100, }); for (const event of page.items) console.log(event.id, event.status); } catch (err) { if (err instanceof TxnodError) console.error(err.error_code); throw err; }

resendWebhookEvent(eventId)

Resend a previously-dispatched webhook event with a fresh event_id.

import { TxnodClient, TxnodError } from '@txnod/sdk'; const client = new TxnodClient({ projectId: process.env.TXNOD_PROJECT_ID!, apiSecret: process.env.TXNOD_API_SECRET!, }); try { const resent = await client.resendWebhookEvent( '01HK8MAR2QEXAMPLE000000000', ); console.log(resent.event_id); } catch (err) { if (err instanceof TxnodError) console.error(err.error_code); throw err; }

getRates(query)

Indicative USD rates for enabled coins. The binding rate is captured by createInvoice in rate_snapshot.

import { TxnodClient, TxnodError } from '@txnod/sdk'; const client = new TxnodClient({ projectId: process.env.TXNOD_PROJECT_ID!, apiSecret: process.env.TXNOD_API_SECRET!, }); try { const rates = await client.getRates({ coins: 'btc,eth' }); console.log(rates.rates.btc); } catch (err) { if (err instanceof TxnodError) console.error(err.error_code); throw err; }

quoteAmount(query)

Convert a USD amount into per-coin crypto amounts. Indicative only.

import { TxnodClient, TxnodError } from '@txnod/sdk'; const client = new TxnodClient({ projectId: process.env.TXNOD_PROJECT_ID!, apiSecret: process.env.TXNOD_API_SECRET!, }); try { const quote = await client.quoteAmount({ amount_usd: 10.0, coins: 'btc', }); console.log(quote.quotes.btc); } catch (err) { if (err instanceof TxnodError) console.error(err.error_code); throw err; }