Skip to content

Releases: SlowBearDigger/xmr-pay

v1.3.0 - digest hardening (RFC 7616)

Choose a tag to compare

@SlowBearDigger SlowBearDigger released this 15 Jul 21:22
  • SHA-256 and SHA-256-sess digest challenges now authenticate; unknown algorithms still fail closed.
  • A 401 with stale=true gets exactly one retry with the fresh nonce; a server that always claims stale gets that retry and then a hard node-auth, never a loop.
  • A -sess response always carries the cnonce it folded into HA1, which was unverifiable without qop before.
  • Each behaviour pinned by a mock-node test (35 checks in the node-auth suite).

v1.2.0 - authenticated daemon nodes

Choose a tag to compare

@SlowBearDigger SlowBearDigger released this 15 Jul 21:22
ee86a3a
  • Structured node config: per-node auth (basic / digest) with credentials, XMR_NODES_JSON for the agent, and an explicit allow_insecure_http opt-in before credentials ride plain HTTP.
  • Native Basic/Digest transport that refuses redirects, caps response size, and never re-sends credentials to a host it was not given.
  • Localhost bridge that allowlists daemon RPC routes so monero-ts can sync through an authenticated node; passwords stay in the agent process.
  • xmr-pay init wizard prompts for authenticated nodes; docs/AGENT.md covers the config.
  • Node URL validation rejects input the WHATWG parser silently repairs (empty userinfo/query/fragment, backslashes, missing authority slashes), keeping parity with the PHP engine.

v1.1.0 — Tier-0 spine, hardening, stress suite

Choose a tag to compare

@SlowBearDigger SlowBearDigger released this 21 Jun 21:34

Added

  • ./state, ./refund, ./report — pure, zero-dep protocol contracts, mirrored 1:1 in the WooCommerce PHP engine and pinned by conformance vectors.
  • hosted/ — a fully static, zero-server checkout page hosting the <xmr-pay> widget.
  • docs/EVENTS.md — state / event / webhook / refund-record contract.
  • Widget: visibility-triggered poll + adaptive backoff + 3-step progress + a11y.
  • Stress/property suites: agent.load (N=8000), chaos-reorg, invariant-stress (2.87M checks).

Fixed

  • createOrder stores the canonical amount (a float like 0.1 + 0.2 can no longer brick settlement).
  • settled latches on check() — a reorg-driven re-check can never un-settle a paid order.

Full suite green (~2.9M checks).

xmr-pay 1.0.2

Choose a tag to compare

@SlowBearDigger SlowBearDigger released this 20 Jun 22:40

Security: burning-bug defence. summarizeTransfers now deduplicates by the one-time output key (not txid alone), so two outputs sharing a key (a 2018-style burn, even across txids) can never credit one real payment twice. Bundled wallet2 transports already collapse burns; this hardens the public export for any transport. See CHANGELOG.

xmr-pay 1.0.1

Choose a tag to compare

@SlowBearDigger SlowBearDigger released this 20 Jun 20:20

First stable release of the xmr-pay toolkit.

Sovereign, non-custodial Monero payments: payment links + QR, a zero-dependency checkout widget, and trustless on-chain detection (proof mode + a watch-mode agent that sums payments). No accounts, no API keys, no third party in the payment path.

Settlement is order-independent and covered by an adversarial test suite (property, fuzz, mutation, soak, stress, quorum), verified live on stagenet.

Install: npm i xmr-pay monero-ts

Note: 1.0.0 shipped with an order-dependence bug in settlement dedup and is deprecated on npm; use 1.0.1.

v0.4.0-beta.1 — money-path correctness fixes

Choose a tag to compare

@SlowBearDigger SlowBearDigger released this 16 Jun 23:46

Patch beta over 0.4.0-beta.0 — three money-path correctness fixes from a deep adversarial review, each with new tests. Install: npm i xmr-pay@beta.

Fixes

  • HIGH — wallet-rpc unlock_time could strand real payments. verifyPaymentViaRpc rejected any non-zero unlock_time as locked, so a legit, already-spendable payment was stuck forever on the wallet-rpc transport. It now checks whether the lock has elapsed (block-height vs unix-timestamp form), matching the monero-ts path.
  • MEDIUM — double-spend gate was dead on the wallet-rpc watcher. createWatcher.incoming() didn't carry double_spend_seen, so a daemon-flagged contested tx could be credited. The flag is now surfaced and the gate holds the funds until it clears.
  • MEDIUM — a late payment could be orphaned at expiry. The agent now checks every unpaid order on fresh state before the expiry sweep, so funds that land in an order's final pre-expiry window are recorded and the order is never expired-then-dropped. The production batch path stays O(1) in network calls.
  • LOW — receipts no longer derive piconero from a float when an exact receivedPico is absent (falls back to the exact order amount).

Also

  • Docs accuracy pass: agent/serverless env-var tables, order status vocabulary, signing fingerprint example, and a new xmr-pay/widget package export.

Full suite green (23 files + 92k-case math fuzz).

Verify

minisign -Vm SHA256SUMS -P RWSA/E4ogu5/1mQf2r66pkWK9fYBEeFdf2cvrjkhiALoXCWT3woSSRtH
sha256sum -c SHA256SUMS

v0.4.0-beta.0 — payment-correctness, reliability, scale

Choose a tag to compare

@SlowBearDigger SlowBearDigger released this 16 Jun 21:28

Beta. Install: npm i xmr-pay@beta · Run the agent: npx xmr-pay

This release is a payment-correctness and reliability pass — informed by a side-by-side study of MoneroPay and BTCPay's Monero plugin, plus an adversarial "make everything go wrong" audit. We hold nothing custodial, so the surface is small; we spent it on getting the money path exactly right.

Money-path correctness (all fuzz-tested)

  • No false-paid on zero/invalid amounts; exact-piconero arithmetic everywhere (no float in money decisions)
  • No double-credit from subaddress reuse, plus a concurrent-reservation (TOCTOU) guard
  • Exact overpaid / atomicToPico / negative picoToXmrString

Monero-grade verification (beyond the references)

  • double_spend_seen gate — a flagged tx is held, not credited, until it clears
  • unlock_time elapsed-awareness (both block-height and unix-timestamp forms) in watch and tx-proof paths

Reliability & scale

  • Durable fulfillment webhook — signed (HMAC), replay-defended, idempotent, with redelivery + reconcile cron
  • Node failover + sync timeout
  • O(1) getTransfers per tick (was O(N) per order) — the scale bottleneck

UX / fewer support tickets

  • Overpayment detection + configurable underpayment tolerance (dust/fee/rounding)
  • Partial payment never orphaned on expiry — funds-bearing orders are never dropped
  • Sync-status surfaced ("node catching up…") instead of a silent "unpaid"

Verify this release

minisign -Vm SHA256SUMS -P RWSA/E4ogu5/1mQf2r66pkWK9fYBEeFdf2cvrjkhiALoXCWT3woSSRtH
sha256sum -c SHA256SUMS

Non-custodial: the agent holds only your view key — it can see payments, never spend them.

v0.3.1 — one-command agent (npx xmr-pay)

Choose a tag to compare

@SlowBearDigger SlowBearDigger released this 15 Jun 17:11

npx xmr-pay — run the non-custodial agent in one command

npx xmr-pay

An interactive setup wizard (network, primary address, private view key, node), then it runs. Designed to remove the setup friction:

  • Truly one command — the bin name matches the package, so npx xmr-pay resolves with no prior install; the Monero engine (monero-ts, WASM) auto-installs into the data dir on first run.
  • No footguns — restore height is set to the current block automatically (no historical rescan / birthday-1 stall), the wallet + order ledger persist, SIGTERM is handled, and the agent token + webhook secret are generated for you.
  • Closes the loop with your store — prints the exact Agent URL / token / webhook secret to paste into the WooCommerce settings.
  • Config + view key stay on your machine (./xmr-pay-data/config.json, mode 600). npx xmr-pay start runs it again later.

No change to the signed money-path modules since 0.3.0 (same SHA256SUMS) — this release adds the bin/ launcher + a CLI test.

Verify the signed manifest:
minisign -Vm SHA256SUMS -P RWSA/E4ogu5/1mQf2r66pkWK9fYBEeFdf2cvrjkhiALoXCWT3woSSRtH

v0.3.0 — verifiable receipts + widget watch-mode

Choose a tag to compare

@SlowBearDigger SlowBearDigger released this 15 Jun 16:33

Verifiable payment receipts (dual-root)

A new xmr-pay/receipt module: a self-contained, verifiable record of a paid order with two independent roots of trust:

  • Merchant signature (Ed25519, offline) — verifies in a millisecond against the merchant's published fingerprint.
  • On-chain tx_proof (trustless) — a recipient-side Monero InProof anyone can check against the chain with check_tx_proof, no trust in the merchant at all. The same transaction that paid the order proves the order.

signReceipt / verifyReceipt / verifyReceiptOnChain / receiptFromOrder, domain-tagged, exact piconero math. Plus examples/verify-receipt.html — a standalone, zero-dependency, client-side (WebCrypto Ed25519) verifier you can host anywhere.

Verified live end-to-end on a real stagenet payment: receipt minted with InProof → signature valid + InProof confirmed on-chain.

Agent (examples/scanner-agent.js)

  • Mints + signs a receipt on payment (best-effort InProof from the view-only wallet), serves GET /receipt/:id, includes the receipt in the order.paid webhook.
  • Fix: handle SIGTERM (systemd restart) + save the wallet on shutdown — a restart no longer re-creates subaddress indices (which could reuse a pending order's address).
  • Fix: persist the receipt on the live order so GET /receipt/:id works after the paid event.

Widget

  • Watch-mode: status-url + an "I've paid — detect it" button with auto-polling (no txid/proof paste needed).
  • On paid: download the signed receipt + a one-click link to the offline verifier. redirect-url supported. Retries the receipt fetch while the agent finishes minting.

Verify

  • verifyPayment now also returns exact receivedPico.

Artifacts signed with minisign (minisign.pub in the repo):
minisign -Vm SHA256SUMS -P RWSA/E4ogu5/1mQf2r66pkWK9fYBEeFdf2cvrjkhiALoXCWT3woSSRtH

v0.2.5 — order persistence + create-order race fix

Choose a tag to compare

@SlowBearDigger SlowBearDigger released this 15 Jun 12:40

Added — agent order persistence

examples/scanner-agent.js persists its order ledger to XMR_ORDERS_FILE (default orders.json) — saved on create/update/paid/SIGINT/30s, reloaded on boot. On restart it re-checks every pending order against the persisted wallet, so a payment that landed during downtime still auto-completes. Pair with XMR_WALLET_PATH. Funds are never lost regardless (they're on-chain); this auto-completes the matching order across an agent restart.

Fixed — create-order race

Two concurrent createOrder calls with the same id both passed the has() check (before the await) and both allocated a subaddress. A reserving set now rejects the duplicate.

Docs

New docs/STORAGE.md — the storage-agnostic model (any Map-like store; JSON default; Redis/SQL; the WooCommerce two-layer model). New test/stress.test.js (concurrency, pool, adversarial summing, pico exactness). 12 offline suites green.


Verify: `minisign -Vm SHA256SUMS -P $(cat minisign.pub)` then `shasum -c SHA256SUMS`.