Accept exact-USD stablecoin payments on-chain, with your own wallet, no gateway.
MIT · @blockindex/crypto-payments · TypeScript / ESM · Node · Deno · browser · Running in production
Accept DigiByte (DGB) and DigiDollar (DD) payments with your own DigiByte Core wallet — non-custodially, with no hosted payment gateway. Extracted from BlockIndex.AI's production checkout; the first published DigiDollar acceptance integration anywhere.
DigiDollar is exact USD on-chain. 1 DD = $1.00 by definition — no oracle, no
rate-lock, no volatility window. A $35.00 product costs exactly 3,500 DigiDollar
cents today, tomorrow, always. Combined with DigiByte's 15-second blocks, that
makes DD the ideal instrument for fixed-price checkout: the customer sends the
exact amount, and you credit in ~90 seconds. No Coinbase Commerce, no BitPay, no
NOWPayments — funds land in wallets you control, and no third party ever holds
a cent.
New to all of this? Read top to bottom. Building? Skip to Architecture and the operator guide.
| Doc | What it covers |
|---|---|
| WHAT_IS_DIGIDOLLAR.md | DigiDollar from zero — what it is and why exact-USD on-chain matters. |
| ARCHITECTURE.md | How the toolkit works: the mental model, the two integration models, the address pool, the acceptance sequence, the module map. |
| guides/ACCEPTING_DIGIDOLLAR_AND_DGB.md | The node-operator + integrator playbook: node config, wallets, the RPC surface, hardening. |
| HOW_BLOCKINDEX_INTEGRATED.md | Real-world case study — how BlockIndex.AI took this to production. |
| SECURITY.md | Threat model, hot-wallet hardening, the security checklist. |
| FAQ.md | Common questions, answered plainly. |
| RESOURCES.md | Links: white paper, tech specs, use cases, dev chat, activation status. |
| DOCUMENTATION.md | The full documentation index. |
The demo merchant is a runnable ~300-line reference checkout — Node built-ins plus this library only. It boots with no node required (mock mode), so you can click through the whole flow in a minute:
npm install # installs workspaces + builds the library
node examples/demo-merchant/server.js # demo checkout
# open http://localhost:8787Then follow the demo's testnet walkthrough to
point it at a real DigiByte Core testnet node and pay a live TD… invoice.
This isn't a proof of concept. BlockIndex.AI accepts DigiDollar for its $350 lifetime membership, live on DigiByte mainnet, using this exact toolkit: https://blockindex.ai/founder → Pay with Crypto → DigiDollar.
Full write-up: HOW_BLOCKINDEX_INTEGRATED.md.
- Merchants & indie builders who want to take crypto for a fixed-price product without handing funds (and fees) to a third-party gateway.
- DigiByte node operators who want to turn a node they already run into a payment rail.
- Developers integrating DigiDollar who want a correct, tested reference for
the tricky parts — the
OP_RETURNvalue model, the address pool, cents-not-floats, confirmation policy — instead of discovering them the hard way. - Anyone curious what a real, non-custodial, exact-USD on-chain checkout looks like end to end.
import {
DigiByteCoreRpc, DigiDollarWatcher, DigiDollarAddressSource,
IdentityPriceSource, buildInvoiceTerms, reconcileInvoice,
} from '@blockindex/crypto-payments';
const core = new DigiByteCoreRpc({ url: 'http://127.0.0.1:14022', user, password, walletName: 'dd_hot' });
const { address } = await new DigiDollarAddressSource(core, 'mainnet').nextAddress(); // fresh DD…
const terms = buildInvoiceTerms({
asset: 'DIGIDOLLAR', priceUsdCents: 3500, // $35.00 → 3500n cents
priceQuote: await new IdentityPriceSource().usdPerUnit('DIGIDOLLAR'), now: new Date(),
});
const payments = await new DigiDollarWatcher(core).getPayments(address); // amounts in cents
reconcileInvoice(terms, payments); // 'credit' | 'wait' | 'underpaid' | 'double_spend_risk' | 'none'See the module map in ARCHITECTURE.md for what each import does.
These are protocol realities, not implementation choices — every design decision in this toolkit follows from them:
-
1 DD = $1.00, and the base unit is the US cent. All amounts are integer cents (
BigInt), quoting is the identity function, and there is no price feed to fetch or lock. Never floats — silent rounding is a money bug. -
The DD value lives in an
OP_RETURN, not in the output value. A DigiDollar payment is a 0-satoshi Taproot output plus anOP_RETURNcarrying the cent amount.gettransaction/listunspentsee 0 sats — a DGB-style parser will report amount 0 and wrongly mark the invoice underpaid. Detect withlistdigidollarunspent/listdigidollartxs(requiresdigidollar=1andtxindex=1indigibyte.conf). Also:walletnotifyis not guaranteed to fire on a DD receive — a blocknotify-driven poll oflistdigidollarunspentis the authoritative detection path. -
DigiByte Core v1 has NO DigiDollar watch-only. The node that detects DD payments must hold the keys — a hot (encrypted, localhost-RPC-only) descriptor wallet. Mitigate, don't fight it: keep the hot balance low and sweep to cold storage on a schedule. (DGB coin does support watch-only — receive DGB against a cold xpub.)
-
Receive addresses come from the node, via a pool.
getdigidollaraddressmints a fresh HD-derived address per call (DD…mainnet /TD…testnet /RD…regtest — Base58Check, not bech32). Your web backend usually can't reach the private node, so the node pre-mints addresses and pushes them (public strings only, never keys) to your backend's address pool; invoice creation pops one. Guard the refill endpoint with its own secret — pool poisoning redirects customer funds. -
Buyers pay the miner fee in DGB, not DD. A wallet holding only DigiDollar cannot send it — say so in your checkout UI ("you'll need ~0.1 DGB for the network fee"). Confirmation policy is USD-tiered in the library (<$100 → 6 confs ≈ 90 s; $100–$10k → 20; >$10k → 60) and env-overridable.
- Push (recommended) —
guides/walletnotify-reference/: your node runswalletnotify/blocknotifyscripts that POST verified payments{asset, network, address, txid, vout, amount, confirmations}to your backend's secret-gated ingest endpoint. No wallet, watcher, or RPC client ever runs on the backend. The demo merchant implements the receiving side of this exact contract. - Pull —
guides/watcher-reference/: a co-located worker polls the node/explorers and posts to the same ingest endpoint.
Either way the invariants hold: one fresh address per invoice, integer base units
only, N confirmations before credit, idempotency by (asset, network, txid, vout),
and every amount re-verified server-side — never trust a client-reported payment.
digidollar-toolkit/
├── packages/
│ └── crypto-payments/ @blockindex/crypto-payments — the MIT TypeScript library:
│ quoting, address derivation (xpub + DD pool), chain
│ watchers, pricing, invoice state machine, Core RPC client.
│ Pure JS (@scure/@noble), ESM — runs in Node, Deno, browser.
├── guides/
│ ├── ACCEPTING_DIGIDOLLAR_AND_DGB.md the node-operator + integrator playbook
│ ├── walletnotify-reference/ PUSH model (recommended): walletnotify/blocknotify
│ │ scripts + DD pool refill cron, with .env.example
│ └── watcher-reference/ PULL model: a co-located polling watcher worker
└── examples/
└── demo-merchant/ runnable reference: Node-builtins HTTP backend
(POST /invoice, GET /invoice/:id, POST /ingest)
+ a one-page polling checkout. Boots with no node
(mock mode); full testnet walkthrough in its README.
MIT © BlockIndex.AI — use it, fork it, sell things with it.



