Demo Gateway Operations
Status: alpha operations runbook for the hosted kaspa:testnet-10 gateway. This runbook describes the public demo service at:
https://demo.kaspa-x402.org
Current deployment: alpha.8 Worker version d9bac848-bc14-4326-9945-7a5a5722d63a, built from commit 37a4704. The funded standard-native exact canary passed with accepted finality, identical replay, and cross-resource replay rejection. The default exact profile needs no merchant inventory; optional additive uses durable KIP-10 head chains.
The gateway is an integration target, not a wallet, custodian, faucet, facilitator, mainnet service, or availability commitment.
Operator Controls
The Worker configuration lives in packages/demo-gateway/wrangler.jsonc.
Important non-secret variables:
| Variable | Purpose |
|---|---|
KASPA_X402_GATEWAY_ENABLED | Set to false to stop protected exact and batch endpoints with HTTP 503. /health, /canary, /metrics, and /supported remain visible. |
KASPA_X402_CHAIN_API_BASE | REST chain evidence source. Current value: https://api-tn10.kaspa.org. |
KASPA_X402_PAY_TO | Testnet address receiving exact payments. |
KASPA_X402_SERVER_PUBLIC_KEY | Testnet server public key advertised in batch escrow terms. |
KASPA_X402_EXACT_AMOUNT | Exact-payment price in sompi. Must be at least 10000000. |
KASPA_X402_EXACT_PROFILE | Alpha.8 exact profile: standard-native (default) or optional additive. |
KASPA_X402_MIN_DEPOSIT_SOMPI | Batch escrow deposit floor. Must be at least 10000000. |
KASPA_X402_REFUND_TIMEOUT_DAA_DELTA | Maximum DAA horizon for the persisted absolute batch timeout. The Worker rolls the timeout only at the minimum-lead boundary. |
KASPA_X402_MINIMUM_REFUND_LEAD_DAA | Minimum remaining DAA lead required before accepting a batch payment. |
KASPA_X402_SITE_BASE_URL | Standards site base URL used by canary checks. |
KASPA_X402_GATEWAY_BASE_URL | Gateway base URL used by canary checks. |
KASPA_X402_HOSTED_EXACT_SETTLEMENT_ENABLED | Set to true only when the hosted exact verifier, PNN broadcast path, and finality observation are deployed. Additive also requires a durable available head. |
KASPA_X402_CHAIN_BROADCAST_MODE | pnn for hosted KIP-10 exact settlement. REST is read-side evidence only for hosted exact. |
KASPA_X402_PNN_ENDPOINTS | Comma-separated public TN10 WSS endpoints used by the Worker to submit exact transaction artifacts. |
The Worker must not receive a mainnet key, a spending key, or a faucet key. Claim broadcasting is disabled in the hosted gateway package.
Secret variables:
| Variable | Purpose |
|---|---|
KASPA_X402_ADMIN_TOKEN | Bearer token for additive exact-head registration, reconciliation, and stats endpoints. Set with wrangler secret put; do not commit it. |
Deploy
From the repository root:
npm --workspace @kaspa-x402/demo-gateway run build
npm --workspace @kaspa-x402/demo-gateway exec -- wrangler deploy --config wrangler.jsonc
After deployment, verify:
curl -fsS https://demo.kaspa-x402.org/health
curl -fsS https://demo.kaspa-x402.org/canary
npm run check:demo-gateway
check:demo-gateway starts a local Worker, verifies the unpaid exact and batch availability gate, verifies the unpaid batch offer, rejects a foreign payment scheme, and checks the health and canary routes. A deployed paid check still requires an isolated funded testnet wallet.
Exact Profiles And Additive Heads
Hosted exact is enabled only when KASPA_X402_HOSTED_EXACT_SETTLEMENT_ENABLED=true. The default standard-native profile requires no merchant inventory. Optional additive also requires at least one durable merchant-owned KIP-10 head. The Worker does not hold the merchant wallet key and does not create heads from public requests.
1. Create one or more independent merchant-owned KIP-10 additive heads from an isolated TN10 wallet. 2. Record each head id/version, current outpoint and amount, serialized script public key, redeem script, additive threshold, status, and timestamps. 3. Register the head records with the Worker:
KASPA_X402_DEMO_ADMIN_TOKEN=<token> \
npm run demo:exact-heads -- register --file heads.json
4. Confirm head availability:
KASPA_X402_DEMO_ADMIN_TOKEN=<token> npm run demo:exact-heads -- stats
curl -fsS https://demo.kaspa-x402.org/supported
standard-native advertises exact without a head. additive advertises exact only while a matching head is available. Issuing an unpaid 402 does not reserve, retire, or consume a head. Settlement atomically claims the advertised current outpoint, verifies a same-script successor whose delta equals the exact price, and advances that same durable lineage. Stale competing clients receive a fresh 402 against the current head.
Before each additive offer, the Worker confirms only the selected durable current outpoint against the accepted address UTXO set. It makes at most two bounded candidate attempts, independent of total head inventory. A missing or conflicting selected head becomes unavailable. Full-pool checks are operator work, not anonymous request work. If a known external transaction advanced a head, provide the complete ordered accepted lineage to recover it:
KASPA_X402_DEMO_ADMIN_TOKEN=<token> \
npm run demo:exact-heads -- reconcile \
--head-id <head-id> \
--transactions <first-txid>,<next-txid>
The gateway accepts only a chain in which every transaction spends the prior outpoint, preserves the same script and output index, satisfies the KIP-10 threshold, and ends at the current unspent head. Never use an arbitrary output to the same P2SH address as lineage evidence.
Rollback
Use the Cloudflare Workers deployment list for the project named kaspa-x402-demo-gateway.
Rollback procedure:
1. Identify the last deployment that served valid /health and /canary. 2. Roll back to that Worker version in Cloudflare. 3. Confirm https://demo.kaspa-x402.org/health returns ok: true. 4. Run an unpaid batch request and confirm HTTP 402; confirm /exact returns 503 exact_unavailable unless a working hosted exact settlement path is deliberately enabled and tested. 5. Record the version, reason, and verification result in the operator notes.
If the bad deployment changed durable state shape, disable the gateway first with KASPA_X402_GATEWAY_ENABLED=false, then inspect state compatibility before rolling forward again.
Emergency Disable
Set:
KASPA_X402_GATEWAY_ENABLED=false
Deploy the Worker. Protected endpoints must return:
{ "ok": false, "error": "gateway_disabled" }
Health and canary endpoints stay readable so operators can distinguish an intentional disable from a platform or chain outage.
Re-enable by restoring:
KASPA_X402_GATEWAY_ENABLED=true
Chain Evidence Or PNN Outage
The Worker uses REST evidence for accepted UTXOs and DAA health. Hosted exact also uses public TN10 PNN/WSS for transaction submission. If /health, the scheduled canary, or the hosted exact proof reports chain failure:
1. Confirm whether https://api-tn10.kaspa.org/info/blockdag is reachable. 2. If the REST endpoint is down or stale, disable the gateway. 3. Do not point the public gateway at mainnet or an unreviewed private node. 4. If moving to a different kaspa:testnet-10 REST endpoint, deploy only after unpaid offers and a manual paid exact check pass. 5. If PNN submission is failing, disable hosted exact or the full gateway until a paid exact proof passes again. 6. Re-enable only after /health, /canary, batch deposit, replay rejection, and exact payment checks pass when hosted exact settlement is enabled.
The static browser demo uses PNN/WASM for client-side checks, and hosted exact uses lightweight PNN/WSS JSON inside the Worker for KIP-10 submission. A PNN outage can break hosted exact while /batch remains usable.
Scheduled Canary
The Worker runs a non-spending scheduled canary every 15 minutes.
The canary checks:
kaspa:testnet-10REST health and virtual DAA evidence;- the public
payment-requiredschema URL; - the immutable
v0.1.0-alpha.1release snapshot with a cache-busted request; - the public docs index and expected page marker;
- exact support advertisement only when hosted exact settlement is enabled and, for
additive, a head is available, without claiming that head; - unpaid batch offer shape and deposit floor;
- unsupported foreign payment scheme rejection.
The scheduled canary skips paid exact and replay checks because the Worker does not hold spending keys. Those checks must be run manually from an isolated funded testnet wallet so canary failures cannot spend unbounded funds.
Read the enabled state and latest canary report:
curl -fsS https://demo.kaspa-x402.org/canary
An operator should check /canary after each gateway or site deployment and at least once per day while the demo is advertised. If ok is false, disable broad public guidance until the failed check is understood and fixed.
Manual Paid Canary
Use an isolated testnet key. Do not import a key that controls mainnet funds.
Minimum manual paid checks:
1. If exact is not deployed with a working KIP-10 settlement path, request GET /exact and confirm HTTP 503 exact_unavailable. 2. If exact is deployed, request GET /exact and confirm HTTP 402. For standard-native, build an ordinary exact native transfer. For additive, spend the advertised head and increase its same-script successor by exactly the advertised amount, with no separate merchant payment output. Retry with PAYMENT-SIGNATURE, and confirm the Worker broadcasts the artifact through PNN, observes accepted finality, and returns HTTP 200. 3. Retry the identical paid exact request and confirm idempotent HTTP 200. 4. Present the same exact transaction to a different resource and confirm conflict rejection. 5. Open a batch channel with a deposit-voucher payment and confirm HTTP 200. 6. Reuse the channel with a voucher-only payment and confirm HTTP 200. 7. Replay an earlier stale batch voucher after the later voucher and confirm corrective HTTP 402.
Record transaction ids, output indexes, Worker version, response status, and PAYMENT-RESPONSE summaries in the operator notes.
The committed hosted exact proof pays /exact with a signed exact transaction artifact, confirms the Worker-broadcast transaction is accepted, retries the same payment for idempotency, and rejects the same transaction on a different resource. In default standard-native mode it needs no admin state. In additive mode it funds and registers a reusable head first:
KASPA_X402_RPC_URL=<tn10-rpc-url> \
KASPA_X402_FUNDING_WALLET=wallet-key:/path/to/testnet-key \
KASPA_X402_KASPA_WASM_MODULE=/path/to/kaspa.js \
KASPA_X402_EXPECTED_GATEWAY_ORIGIN=https://demo.kaspa-x402.org \
KASPA_X402_EXPECTED_EXACT_PROFILE=standard-native \
KASPA_X402_EXPECTED_EXACT_AMOUNT=20000000 \
KASPA_X402_EXPECTED_EXACT_PAY_TO=<expected-merchant-address> \
KASPA_X402_LIVE_CONFIRM=I_UNDERSTAND_THIS_USES_TESTNET_FUNDS \
npm run proof:hosted-exact
Set KASPA_X402_EXACT_PROFILE=additive and KASPA_X402_EXPECTED_EXACT_PROFILE=additive, then provide KASPA_X402_DEMO_ADMIN_TOKEN=<token> to exercise the optional head profile. The additive proof derives and pins the locally created head address when an explicit expected payTo is absent. The proof refuses to sign if the gateway origin, resource, profile, amount, recipient, or network differs from the operator pins.
Also confirm that legacy observe-only exact-transfer evidence is rejected and does not return protected content. Alpha.6/alpha.7 reservation and borrow instructions are historical only; alpha.8 uses standard-native by default and reusable additive heads when explicitly enabled.
Durable State Policy
The hosted gateway uses one SQLite-backed Durable Object. It stores exact replay records, payment identifiers, batch channels, settlement commitments, locks, rate counters, metrics, and the latest canary report.
Policy for the public alpha:
- durable state is operational evidence, not a user account database;
- no private keys or wallet seeds are stored;
- no unauthenticated backup, export, or admin read route is exposed;
- additive exact-head admin routes require
KASPA_X402_ADMIN_TOKEN; - state may be reset during alpha incidents after the gateway is disabled and the reset is disclosed in operator notes;
- production operators should design their own backup and state-partitioning policy before using this code outside the hosted demo.
When a release changes wire format or durable state, document a release-specific migration before deployment. Disable the gateway before any destructive state change, preserve replay evidence where formats remain compatible, and require fresh paid exact and batch canaries before re-enabling public guidance. The immutable release snapshots retain the earlier alpha cutover records.
Rotate Addresses And Keys
Use this when a testnet address is too noisy, a test key is suspected exposed, or a clean public demo history is needed.
1. Disable the gateway. 2. Generate a new kaspatest: pay-to address using an isolated testnet wallet. 3. Generate a new server public key for batch terms. Keep any private signing material outside the Worker. 4. Update KASPA_X402_PAY_TO and KASPA_X402_SERVER_PUBLIC_KEY. 5. Decide whether to preserve or reset the Durable Object namespace. Preserve state for replay continuity; reset state for a clean demo history. 6. Deploy and verify /health, /canary, unpaid offers, paid exact only when hosted exact settlement is enabled, batch deposit-voucher, voucher-only reuse, and replay rejection. 7. Re-enable the gateway.
Incident Note Template
Date:
Operator:
Worker version:
Incident:
User-visible impact:
Gateway enabled state:
Chain evidence:
Canary result:
Actions taken:
Paid evidence affected:
Follow-up:
Keep incident notes factual and testnet-scoped.
Source: /docs/demo-operations.md