MARKET
Nirium← Home
Back to Nirium
Audit Trail

Verifiable Receipts for Stellar Payments

Nirium anchors payment and audit evidence as cryptographic receipts anyone can check independently. Non-custodial: we only verify and record - you and your counterparties sign every transaction yourselves.

01 · Overview

What Nirium Is

Nirium anchors evidence - a payment, an API response, a milestone decision - as a sha-256 hash pinned to IPFS, with an optional ed25519 signature attesting who produced it. The result is a receipt: a CID anyone can resolve, recompute, and compare against the original evidence, with or without Nirium being online.

Non-custodial by design. Nirium never holds funds and never sees a private key: POST /api/audit/log only ever receives a hash (or a small JSON record) and, optionally, a signature someone else already produced. Every payment, approval or release referenced anywhere in this document is signed by the party that owns the funds, not by Nirium.

A CID by itself proves a fact did not change after it was anchored - it does not prove who produced it. The optional agent signature closes that second gap. Both are explained in detail in §3 and §4 below.

02 · Quickstart

Quickstart (5 min)

Every command below ran against the live agent on 29-oct-2026. Swap the base URL to switch networks: https://nirium-agent.fly.dev for testnet, https://nirium-agent-mainnet.fly.dev for mainnet - both boxes expose the identical API.

1. Get a free API key (optional today).

Open /keys, connect a Stellar wallet (Freighter, Pollar or any wallet-kit supported signer), and generate a free key. POST /api/audit/log currently accepts requests with no key at all during the open beta - rate-limited to 20 requests/minute per IP on each box - so this step is optional right now and will matter once audit pricing goes live. Payouts does require one. The x402 and MPP routes don't: the payment itself is the access.

2. Anchor a receipt.

testnet
curl -X POST https://nirium-agent.fly.dev/api/audit/log \
  -H "Content-Type: application/json" \
  -d '{"record":{"doc_type":"invoice","amount_usd":42,"ref":"your-reference"},"tag":"demo"}'
response, verbatim
{
  "cid": "Qmb41zzbMGzP27Su1XQkhY2SQHSRjNy3ywYRbfundyWMQX",
  "gatewayUrl": "https://gateway.pinata.cloud/ipfs/Qmb41zzbMGzP27Su1XQkhY2SQHSRjNy3ywYRbfundyWMQX",
  "content_sha256": "68117b8d5b9cad107ac9df653bc5fb23451696f97268facc6e049c89831650ac",
  "anchoredAt": "2026-10-29T22:07:13.605Z",
  "verify": "fetch the gatewayUrl and recompute sha-256 over your original evidence"
}

3. Verify it in the browser.

Paste the CID at nirium.xyz/verify (or open /verify?cid=<CID> directly). It fetches the document from IPFS, recomputes the hash from the embedded record , and checks the agent signature if one is present.

4. Verify it independently, from the terminal.

install once
npm install -g nirium-cli
real output
$ npx nirium-cli verify Qmb41zzbMGzP27Su1XQkhY2SQHSRjNy3ywYRbfundyWMQX
🔍 Nirium Audit Verifier
CID:            Qmb41zzbMGzP27Su1XQkhY2SQHSRjNy3ywYRbfundyWMQX
--------------------------------------------------
✔ HASH:        MATCH (68117b8d5b9cad10...)
ℹ SIGNATURE:   ABSENT (No agent attestation embedded)
--------------------------------------------------
✅ VERIFICATION PASSED

That output came from nirium-cli@3.1.1 installed fresh via npx on 7 Nov 2026, not from a local build - it independently refetched the CID and recomputed the hash itself. With no flags it tries Filebase's dedicated gateway, then Pinata, ipfs.io and dweb.link, so one slow or rate-limited gateway doesn't fail the check. Pass --gateway (repeatable) to use your own list.

5. Same thing, on mainnet.

QmcJymJiegpsQ6peU7djM31hwcYbH5VvjYqnuUH1UcaKLP
sha256: fef2595c85078bc8471e30881a2cb8466aca4e27968a96661e6e5fc445dae6d9

Anchored to the mainnet box while building this page. The document itself reports network: "stellar:pubnet" - that field is set by the box that anchored it, never by the request body.

03 · Reference

Receipt Format

The JSON document pinned to IPFS carries these fields:

anchored document
{
  "version": "1.1.0",
  "node": "audit-external",
  "content_sha256": "<64-char lowercase hex>",
  "agent": { "id": "optional", "key": "G...", "alg": "ed25519", "statement": "...", "signature": "..." },
  "record": { "...": "your JSON object, if you sent one (up to 8KB)" },
  "txHash": "optional, if you're pointing the receipt at an existing on-chain tx",
  "network": "stellar:testnet | stellar:pubnet",
  "tag": "optional label",
  "anchoredAt": "ISO 8601 timestamp"
}

How content_sha256 is computed:

  • Hash-only mode. You send hash: a 64-char sha-256 hex string, optionally prefixed sha-256:. The server stores it exactly (lowercased, prefix stripped) and never sees your original evidence.
  • Record mode. You send record (a plain JSON object, up to 8KB). The server computes content_sha256 = sha256(JSON.stringify(record)) - standard JSON.stringify, compact (no whitespace), in whatever key insertion order your object had. To recompute it yourself, stringify your object in the same key order and hash the UTF-8 bytes.

Agent attestation (optional):

Sign the string nirium-audit-v1:<content_sha256> (lowercase hex, domain-prefixed so a signature made for something else - a wallet login, for example - can't be replayed here) with an ed25519 key. Any Stellar G... address works as the public key, since a Stellar address is already an ed25519 public key - no separate registration. Two signature encodings are accepted: raw bytes of the statement, or the SEP-53 digest (sha256("Stellar Signed Message:\n" + statement)), so a plain Keypair.sign() and a wallet's signMessage both work.

04 · Reference

Verifying a Receipt

Three equally valid ways to check a receipt - none of them require trusting Nirium:

  • Browser - nirium.xyz/verify.
  • CLI - npx nirium-cli verify <CID>.
  • By hand - fetch the CID from any IPFS gateway, recompute sha-256 over JSON.stringify(record) (or your original file, for hash-only anchors), and compare to content_sha256. For a signature: verify ed25519(signature) over the UTF-8 bytes of nirium-audit-v1:<content_sha256> against agent.key.

A known, deliberate behavior: hash-only anchors with no signature verify nothing.

If a receipt was anchored with hash (not record) and carries no agent signature, there is nothing embedded for the tool to recompute against - so the CLI refuses to call that a pass:

hash-only, no evidence supplied
$ npx nirium-cli verify QmaofB6naeySxZsgA4R4p8YWzz3fujTitAa1ndJ1PQjbme
🔍 Nirium Audit Verifier
CID:            QmaofB6naeySxZsgA4R4p8YWzz3fujTitAa1ndJ1PQjbme
--------------------------------------------------
ℹ HASH:        NOT CHECKED (hash-only anchor: 0b2e5f91485badeb...)
   Pass --hash <hex> or --evidence <file> to compare it with your original evidence.
ℹ SIGNATURE:   ABSENT (No agent attestation embedded)
--------------------------------------------------
❌ NOTHING VERIFIED (pass --hash, --evidence, or anchor with an agent signature)

That refusal is the fix for issue #149: earlier versions of the CLI printed VERIFICATION PASSED in exactly this situation - a hash-only anchor with nothing to compare it against and no signature attached. Supplying your original evidence turns it into a real check:

same CID, with --evidence
$ npx nirium-cli verify QmaofB6naeySxZsgA4R4p8YWzz3fujTitAa1ndJ1PQjbme --evidence ./my-evidence.txt
...
✔ HASH:        MATCH (0b2e5f91485badeb...) [hash-only]
ℹ SIGNATURE:   ABSENT (No agent attestation embedded)
--------------------------------------------------
✅ VERIFICATION PASSED

An attested, record-mode receipt verifies both the hash and the signature automatically, with no extra flags:

Qmbhgu8U2Fz5eJdHakveorj4FUTx7hjVFFzUXgv6fzQNha
sha256: dd8624889f541323551ba1167f5619ab87a8d418d5a342316b838671d761d6a3

Signed with a throwaway testnet key generated for this page (GBJYCLT2AEWUTDKRETUTYHNNEH45QL4B6TFY6GKLKT4KQ57SHMSE7LFL). Run npx nirium-cli verify on this CID - no flags needed.

Anchor from the terminal (nirium-cli 3.1.0+).

nirium anchor takes a hash (--hash), a file (--file, only its sha-256 is sent, never the file) or a small JSON record (--record, up to 8KB). Point it at a node with --url; there is no --network flag because the node decides its own network. Real run against testnet, 7 Nov 2026:

real output
$ npx nirium-cli anchor --record '{"doc":"nirium-docs-example","date":"2026-11-07"}' \
    --tag docs-example-7nov --url https://nirium-agent.fly.dev
✅ Anchored to IPFS
   CID:            QmNNKGCx8i8zQZuCBsuRh9fbAiF7v2smQVszxkqdxpXx5J
   Content sha256: 938c3fbff4c3cb484fc8e3944e8e3d5334bee6abcec1e726d16b6d5adfead23d
   Gateway URL:    https://gateway.pinata.cloud/ipfs/QmNNKGCx8i8zQZuCBsuRh9fbAiF7v2smQVszxkqdxpXx5J
   Anchored at:    2026-11-07T19:31:43.837Z

   Verify independently: nirium verify QmNNKGCx8i8zQZuCBsuRh9fbAiF7v2smQVszxkqdxpXx5J

Add --sign to attach an ed25519 attestation. The secret key comes from an environment variable you name with --key-env (or the CLI config store); it signs locally and is never sent or printed. Same day, with a throwaway testnet key:

real output
$ npx nirium-cli anchor --hash 8d81e311646b8b84dab222401576f2211df704e53ebac732e3fcd4219cd2a883 \
    --sign --key-env MY_STELLAR_SECRET --tag docs-example-7nov --url https://nirium-agent.fly.dev
✅ Anchored to IPFS
   CID:            QmS1dJaMat4yWfMJ2HwYGkNMUxQD2fF7unUgFTnuLmRPfh
   Content sha256: 8d81e311646b8b84dab222401576f2211df704e53ebac732e3fcd4219cd2a883
   Attested by:    GBZSUF6WJ2M7HQ7B6ABBVHD7RJRK6FOMVKJMMSGO4C2F3RIKY2SVKN5A
   Anchored at:    2026-11-07T19:31:48.425Z

$ npx nirium-cli verify QmS1dJaMat4yWfMJ2HwYGkNMUxQD2fF7unUgFTnuLmRPfh \
    --hash 8d81e311646b8b84dab222401576f2211df704e53ebac732e3fcd4219cd2a883
✔ HASH:        MATCH (8d81e311646b8b84...) [hash-only]
✔ SIGNATURE:   VALID (Signed by GBZSUF6WJ2M7HQ7B6ABBVHD7RJRK6FOMVKJMMSGO4C2F3RIKY2SVKN5A)
   Statement:  nirium-audit-v1:8d81e311646b8b84dab222401576f2211df704e53ebac732e3fcd4219cd2a883
--------------------------------------------------
✅ VERIFICATION PASSED

To pull many CIDs at once and verify them in bulk, use the Reporting node - see §5.

05 · Reference

Reporting

The Reporting node is a read-only summary of what the Nirium agent already records: Audit Trail anchors, payment receipts from Nirium's own x402 endpoint, and payroll runs. It holds no funds and no keys, and it needs no API key. Requests are rate-limited.

What it is not. It reports on the whole node, not on one account. Its counts include Nirium's own test anchors, so they are not a count of users - who anchored what is listed in Evidence (§9). It is not certified regulatory reporting: anything filed with an authority stays the client's responsibility, and every response says so in its disclaimer field.

A real report, right now

Live report · testnetAPI JSON
Loading…

Testnet, no real value: mostly our own tests and workshops. Switch to MAIN in the menu to see mainnet.

Endpoints

  • GET /api/reporting/summary - totals for a period: payroll runs, payment receipts, anchors and when the last anchor happened.
  • GET /api/reporting/export?type=anchors|payments|payroll&format=csv|json - the rows behind those totals, as CSV or JSON. No CIDs and no payroll run ids: those belong to whoever anchored or paid.
  • GET /api/reporting/info - node metadata and the list of endpoints.

from and to take ISO dates and default to the last 30 days. network is mainnet or testnet; leave it out to get both. limit defaults to 500, maximum 1000.

From the CLI

nirium report points at a local agent by default, so pass --url. One week on mainnet (counts as of 8 Nov 2026). The last-anchor date and the CID-free export need nirium-cli 3.2.0 or newer; older versions print the latest CID instead:

example output
$ npx nirium-cli report summary --from 2026-11-01 --to 2026-11-07 \
    --network mainnet --url https://nirium-agent-mainnet.fly.dev
📊 Nirium Reporting Summary
   Network:  mainnet
   Period:   2026-11-01 -> 2026-11-07
   Payroll:  0 settled run(s), 0 recipient(s) paid
   Payments: 0 receipt(s), 0.00 USDC total
   Anchors:  9 (last: 2026-11-06)

Payments is 0 for that week because the last mainnet payment receipt from Nirium's x402 endpoint is from 29 Sep 2026. export anchors lists when and on which network each anchor happened, without CIDs: an anchor's CID stays with whoever made it, and they check it with nirium verify <cid> or on /verify.

usage
nirium report export anchors --network mainnet --url https://nirium-agent-mainnet.fly.dev --csv anchors.csv

Without the CLI

curl
curl "https://nirium-agent-mainnet.fly.dev/api/reporting/summary?network=mainnet&from=2026-11-01&to=2026-11-07"
curl "https://nirium-agent-mainnet.fly.dev/api/reporting/export?type=anchors&format=csv&network=mainnet" -o anchors.csv

06 · Guide

x402 Sellers

x402Serve(), part of the nirium SDK, turns any Express route into a paid endpoint: nothing downstream runs until a payment settles on-chain. It works with any x402 facilitator - Nirium does not run one. The default is OpenZeppelin Channels; free, per-network keys are at channels.openzeppelin.com/testnet/gen (testnet) and channels.openzeppelin.com/gen (mainnet) - a mainnet key returns 401 against testnet and vice versa.

x402Serve() itself does not emit a receipt - it only collects payment. To anchor one per paid call, call agent.anchorAuditRecord() (or POST /api/audit/log directly) inside your own route handler, which only runs after the middleware has already settled the charge:

server.ts
import express from 'express';
import { Agent, x402Serve } from 'nirium';

const app = express();
const agent = new Agent({ apiKey: process.env.NIRIUM_API_KEY });

app.use('/premium', x402Serve({
  payTo: process.env.STELLAR_PAY_TO!,
  facilitatorApiKey: process.env.X402_FACILITATOR_API_KEY!,
  routes: { 'GET /signals': '$0.02' },
}));

app.get('/premium/signals', async (_req, res) => {
  const signals = [{ pair: 'USDC/CETES', edge: '0.42%' }];
  const receipt = await agent.anchorAuditRecord({
    record: { route: '/premium/signals', signals },
    tag: 'x402-sale',
  });
  res.json({ signals, receipt: receipt.cid });
});

A starting point for the server above, scaffolded by the published CLI (ran live while writing this page - exit code 0):

real terminal output
$ npx nirium-cli create x402 -n my-api

💸 [Scaffold] Creating x402 paid API: my-api...

✅ Project initialized in ./my-api

🚀 Get started:
   cd my-api
   npm install
   npm run dev

Getting listed in an x402 Bazaar (optional, nirium@0.18.0+).

Add input, inputSchema and/or output to a route and x402Serve() declares the Bazaar discovery extension for it. A facilitator that reads that extension catalogs the route the first time a payment for it settles, so agents can find it by searching instead of needing the URL hardcoded. Checked live against Rail402's facilitator on Stellar testnet before this shipped (#262). Routes without these fields behave exactly as before.

server.ts
app.use('/premium', x402Serve({
  payTo: process.env.STELLAR_PAY_TO!,
  facilitatorApiKey: process.env.X402_FACILITATOR_API_KEY!,
  routes: {
    'GET /signals': {
      price: '$0.02',
      description: 'Arbitrage signals',
      input: { count: 20 },
      inputSchema: { properties: { count: { type: 'integer', maximum: 100 } } },
      output: { example: { signals: [{ pair: 'XLM/USDC', confidence: 0.85 }] } },
    },
  },
}));

Try it as a buyer: Nirium's own test endpoint.

To test an x402 client against a real seller, point it at GET /api/v1/premium/market. It answers 402 for 0.05 USDC and, once paid, returns Stellar network state: the base fee, the Blend rate when the node can read it, and the fixed CETES reference (read 12 Nov 2026). It is a test target, not a data product: much of what it returns is fixed or public. On testnet it costs test USDC; on mainnet it charges real USDC. Who has paid it so far is in Evidence (§9). The other two premium routes answer 501 on mainnet without charging, because that box runs no signal loop and holds no signing key.

real output, testnet, 8 Nov 2026
$ curl -i https://nirium-agent.fly.dev/api/v1/premium/market
HTTP/1.1 402 Payment Required
payment-required: eyJ4NDAyVmVyc2lvbiI6MiwiZXJyb3IiOiJQYXltZW50IHJlcXVpcmVkIi...

# accepts[0], decoded from the base64 header:
{
  "scheme": "exact",
  "network": "stellar:testnet",
  "amount": "500000",
  "asset": "CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA",
  "payTo": "GC4Q5TWWXI7IHN6DYCBEKCOWJWCKY4JE2NLKLU5SE3YL44IUUFPKUOPC",
  "maxTimeoutSeconds": 300,
  "extra": { "areFeesSponsored": true }
}

amount is in the token's 7-decimal units: 500000 = 0.05 USDC. The same route on https://nirium-agent-mainnet.fly.dev uses stellar:pubnet and the mainnet USDC contract.

07 · Advanced

Pre-Sign Policy Hook

A pre-sign policy hook (#96, shipped in nirium@0.16.0) lets your own code approve or refuse an x402 payment before it is signed. It runs client-side, wraps your signer, and only lets a signature through when your policy function returns an ALLOW bound to the exact authorization about to be signed - same contract, destination, amount, and a short-lived expiry you control. A DENY, a WAIT, a timeout, a malformed answer, or no answer at all: nothing gets signed. It fails closed by construction, not by convention.

This is not a spending limit. It is a single yes/no gate your own policy function controls, evaluated once per payment, against that one specific authorization - not a running budget or cap Nirium tracks on your behalf.

Status: exercised on testnet only so far. Verified against a throwaway testnet key: an ALLOW decision settled on-chain, while DENY and an expired decision left the balance untouched. It has not yet been run against mainnet traffic.

08 · Pilot

Escrow Evidence with Trustless Work

A testnet pilot with Trustless Work closes the gap between "evidence was anchored" and "the escrow actually paid because of it." A decision gate (POST /api/payroll/escrow/decision-gate/execute) fetches a receipt by CID, recomputes its hash, and requires that the attestation on it be signed by the same key as the escrow's serviceProvider role - not just any valid signature - before it calls the existing scoped signer that approves and releases a milestone.

Honest limits, stated plainly:

  • This is a testnet-only pilot. Escrow contract: CADMJSOMBSHUW2LMETBUOVH2CSVY3EDISY4V7UMH7TDU2LE5XRCEULAG.
  • The on-chain release that was actually executed ran under the first version of this rule - before the serviceProvider-key requirement above was added. It has not been re-run end-to-end under the current rule yet; the stricter check has only been exercised with real DENY cases against the live gate since then.

The approve and release transactions from that pilot, both confirmed successful on Horizon testnet:

09 · Evidence

Evidence

Public transaction hashes and CIDs, organized by network. Every row was independently re-verified against Horizon, the IPFS gateway, or GitHub directly before being listed here - not copied from prior reports.

Mainnet

The x402 payment account GCLBBPON256CV7ATEHM5B54BOKNC7GX53MBINJ42MHVXGDMMZ3ZWKBHP shows 36 settled x402 payments between 9 Jul and 29 Sep 2026 (confirmed against Horizon: 37 successful invoke_host_function operations total, but one of those is the Trustless Work escrow release listed separately below, not an x402 payment; plus the account's own funding tx). Stated honestly: these are our own tests and integration tests, not independent paying customers yet. The most recent batch, below, exercised the payment path through an external policy engine.

What it provesHash / CIDDateLink
x402 payment, first of the 29 Sep integration-test batch18f7dcab48087800cefb319a04c17291376df053805763fe3e952d472e32fb912026-09-29View
x402 payment, last of the same batch - also the most recent of all 36 x402 paymentsb34630f6637d6773ad4f7378dac8690ae6d1809173ff9c9541d22165aeef57882026-09-29View
External integrator receipt: TIA anchors a signed exchange-rate quote (used with TIA's permission)QmVWZM1i9qusiTfNAT9QdSFYJNEwQUXtnWuSkrCqRAnGEu2026-10-18View
Same integration, second anchored quoteQmWnt7mQNYB6RgFW9AUPxHsw1B5GerR6bJPHiCZXQLKdCH2026-10-23View
Same integration, third anchored receiptQmXT33ZyUvwxzamEMeGYyUxpAWt86bsPpRkFFu4D1fPkso2026-11-06View
Same integration, fourth anchored receiptQmZ9bQxXLqoCvAQ6AtRChd18MS9YkjBF6MbT9k5e84PTTv2026-11-12View
Trustless Work escrow, full lifecycle, own-funds test (0.50 USDC)0c533088ab6326a78b9f79c197b7636ca4662a0d72562968ddea37f370a8192b2026-09-03View

All four TIA receipts are signed by GATT3MOLOCTDOUGS3FDNZUYV3UKDLIQE4PN7JJ4JYZBYJOOXBVJV4KXI - verified with npx nirium-cli verify against each CID above. Both wallets in the underlying payments belong to TIA (integration tests, not customer payments).

Testnet

What it provesHash / CIDDateLink
TIA's first anchored quote, testnetQmQ71ruWPtEkDPmsPy1b3JNqJzwMJ1oGaZ3sdaXHWdUoDq2026-10-15View
Pre-sign policy hook (§7): ALLOW decision, payment settled (0.02 USDC)eefd57995733c29fd1ba8244b783419015af642073e9c918a0d732a6bb81a6b32026-10-01View
Trustless Work escrow pilot (§8): deploya0ed118a0a02ad87e09f0a743cc90d32199c931baf01b052cf49393e857198502026-10-10View
Same pilot: fund8769aba1b652b01ee2aafc9083fd1a775722690757e560fb43bd49f98e4856cf2026-10-11View
Same pilot: tampered evidence, decision gate refuses before touching the networkQmbwr5eYNex7pzvCSWVu8Q7h4bvfLzkukDu7XXtR7fnkYs2026-10-11View
Same pilot: valid evidence, decision gate authorizes - the approve+release in §8QmSpgUkiJnCfdALUtHXocKQ8GtGaG4LsxUWEoUDFDruWXN2026-10-11View
MPP Charge: settled payment4d20d8648ce001c4e8e894725ad08a8dbcd3904e0024ca440728bc91e6c102362026-10-15View
MPP Charge: settled paymente70cfcb884c17d946210a000a627b7a9c316737a61a66ad2e42d905df679f1672026-10-15View
MPP Charge: settled paymentbe7865f19b4daf9b60993eb4df900098663a55861a357fd7b67a059cc228ff032026-10-15View

Recap of the honest limit from §8: the valid-evidence release above ran under the first version of the decision-gate rule - hash and milestone match only, before the serviceProvider-key requirement existed.

External builders (Niriumtober)

Six external builders anchored their own signed receipts with their own keys during Niriumtober (22 Oct - 3 Nov 2026) or right after it: four on testnet and two on mainnet, six different signing keys. Each receipt was re-checked on IPFS on 9 Nov 2026 (hash and signature). Their CIDs are theirs, so they are not listed here; we share them on request with each builder's permission. TIA, listed above, is counted as an integration, not again here.

Upstream contributions

Merged in repositories Nirium does not control - each confirmed via the GitHub API (re-checked 9 Nov 2026). All were merged by the repository's maintainers except stellar-dev-skill #150, which Stellar's triage bot reviewed and merged:

Separately, shared work in the x402 core protocol itself - team-wide, not exclusive to Nirium: #3138, #3215, #3338, #3339 in x402-foundation/x402.

10 · Reference

Security and Limits

What Nirium can and cannot do with your keys:

  • POST /api/audit/log never receives a private key - only a hash, an optional small JSON record, and an optional signature someone else already produced.
  • A free key from /keys is self-service and wallet-signed, scoped to the free tier by default.
  • Free keys cannot trigger mainnet Payouts or autonomous Treasury rebalancing - those stay invite-only (institutional/enterprise tier, assigned manually) regardless of key tier.

Known limits, stated plainly:

  • MPP Charge is wired on both networks, but has only been exercised with a settled payment on testnet so far - treat MPP on mainnet as unverified until a mainnet settlement hash exists.
  • The pre-sign policy hook (§7, #96) has likewise only been exercised on testnet.
  • /api/audit/log is free during the open beta, rate-limited to 20 requests/minute per IP on each box.

Treasury and Payouts are separate, invite-only modules, not covered here.

11 · Roadmap

Roadmap

Planned, not live: batching anchored receipts into a Soroban registry contract, so a receipt's existence can be checked on-chain directly instead of only via an IPFS CID. No date set yet.

A minimal ReceiptRegistry prototype was measured on testnet on 29 Oct 2026 - a cost check, not a launch: contract CBK7GBTO32ZFARQP4D2LVPLR3AOFZZJZXQSMZJWRUPPU7OYIDFPIWQBG, each anchor_root call costing 17,472 stroops (0.0017472 XLM), confirmed against Horizon.