Demo Implementer Guide
This guide describes the deployed 1.0.1 Testnet gateway and matching SDK. Use the SDK integration guide, release notes, and compatibility table.
The gateway uses escrow-v5/head-v2. Reference signers default to ALL; builders support the specified consensus sighash scopes. Historical RC2 state used escrow-v4/head-v1 and must be completed or recovered with its original runtime. See the template transition.
The npm latest tag serves 1.0.1. The public gateway and browser remain
Testnet-only integration tools, not hosted mainnet services. Batch settlement
uses binding kaspa-escrow-v3 and template kaspa-x402-escrow-v5.
Start With The Artifacts
Canonical site:
https://kaspa-x402.org
Useful entry points:
- schemas:
https://kaspa-x402.org/schemas/; - specs:
https://kaspa-x402.org/spec/; - vectors:
https://kaspa-x402.org/vectors/; - gateway docs:
https://kaspa-x402.org/docs/testnet-gateway/; - gateway base URL:
https://demo.kaspa-x402.org.
Install the current recommended Testnet release explicitly:
npm install @kaspa-x402/core@1.0.1 @kaspa-x402/client@1.0.1
Use exact version 1.0.1 for repeatable integration, or @latest for the stable
channel. Production deployments must meet the SDK operating requirements. The
hosted gateway package is private and is not published to npm.
Validate Schemas And Vectors
Before calling the hosted gateway, an implementation should be able to:
- Fetch JSON Schemas from
/schemas/. - Validate local copies against the published
$idroutes. - Load
/vectors/index.json. - Validate every listed positive vector, including KIP-20 batch genesis, voucher, claim, top-up, and refund artifacts.
- Confirm negative vectors fail for the expected reason.
Amounts are decimal strings in sompi. Batch arithmetic is additionally capped
at signed-int64 maximum (9223372036854775807) because covenant state and
SilverScript arithmetic use signed integers. KIP-9 storage mass depends on the
full transaction shape rather than defining a universal dust amount. The hosted
gateway's funding policy uses conservative values; smaller values require
transaction-specific mass and reserve analysis.
Discover Gateway Support
curl -fsS https://demo.kaspa-x402.org/supported
Before submitting a 1.0.1 payment, confirm the response advertises the expected release and capability. The current public gateway advertises:
network: "kaspa:testnet-10";asset: "KAS";scheme: "batch-settlement", bindingkaspa-escrow-v3, and templatekaspa-x402-escrow-v5;scheme: "exact"under the configured exact profile; and- accepted finality
accepted.
standard-native needs no merchant inventory. Optional additive needs an
available reusable KIP-10 head. No mainnet profile is advertised. If exact is
absent from /supported or /exact returns 503 exact_unavailable, exact
settlement is disabled or an additive deployment has no available head; use the
advertised batch profile instead.
Exact Flow
Request the protected resource:
curl -i https://demo.kaspa-x402.org/exact
Hosted result while exact settlement is disabled or an additive head is unavailable:
- HTTP
503; - JSON body with
error: "exact_unavailable".
Enabled expected result:
- HTTP
402; PAYMENT-REQUIREDresponse header;- a JSON body with
error: "payment_required".
Decode the PAYMENT-REQUIRED header and inspect extra.profile.
standard-native is the default: build an ordinary native KAS transaction whose
canonical payment output transfers exactly the advertised amount to payTo.
For optional additive, the offer contains a complete reusable head challenge:
head id/version, expected outpoint, amount, script public key, redeem script,
covenant threshold, challenge id, and canonical output index zero. Spend that
head and create the same-script successor at index zero with:
successor amount = head amount + advertised exact amount
That successor increase is the entire merchant payment; do not create a second
merchant payment output. Build the signed SDK-safe JSON transaction artifact and
retry with an exact-transaction payload. The hosted gateway submits that
artifact through TN10 PNN/WSS and waits for accepted payment evidence before
serving the response:
PAYMENT-SIGNATURE: <base64 x402 PaymentPayload>
Successful retry result:
- HTTP
200; PAYMENT-RESPONSEheader;- response JSON identifying the resource, fingerprint, transaction id, output index, and accepted finality.
Identical retries with the same request and payment evidence should return the
cached HTTP 200. Reusing the same exact transaction for a different resource
must be rejected. If an additive gateway has no available head, clients should
use batch-settlement or another server.
The hosted 1.0.1 gateway uses public Testnet-10 PNN/WSS nodes for funding, UTXOs, DAA, fees, transaction submission, acceptance, and selected-chain lineage. It does not require the public REST transaction index. Durable receipts and pre-broadcast checkpoints support retries and Worker restart recovery without treating uncertain transactions as new payments.
Hash-chain Browser Demo
The 1.0.1 hash-chain-additive flow is available from the browser demo
when the operator enables its gateway Durable Object issuer and registers a
funded head. Check /supported for
extra.profile: "hash-chain-additive" before expecting a live quote.
- Open
https://kaspa-x402.org/demo/, load the SDK, and generate or import a throwaway Testnet-10 key. Fund its address and connect to a Testnet-10 node. - Under Hash-chain exact, fetch a quote. The page shows the exact price, the fee budget (target 0.01 KAS, maximum 0.1 KAS), the current head, and expiry.
- Click Pay quoted Testnet KAS. The browser signs a grant claim, receives its one-use key, signs and broadcasts the payment, then retrieves the report.
- The result shows the accepted transaction ID, actual fee, and the head's value before and after payment. Retry same payment retrieves that same payment result. Fetch another quote after success to start a new logical payment using the same testnet key. While pending, retry that payment rather than starting another.
The merchant head increases by exactly the quote. Unlike the older additive
profile, this profile changes its hash guard and the payer broadcasts the
transaction. Wallet and grant keys stay in browser memory and are cleared on
reset; keep the page open while a payment is pending.
A busy/unavailable message is normal for this small demo. An abandoned claimed grant can require a manual operator rotation before the head is available again. Expiry alone does not revoke its signing key on-chain. See the profile and operator instructions.
Batch Flow
Request:
curl -i https://demo.kaspa-x402.org/batch
The 402 response must contain batch-settlement requirements with
extra.binding: "kaspa-escrow-v3" and
extra.templateId: "kaspa-x402-escrow-v5".
Open a lane by building and funding the advertised singleton KIP-20 genesis.
Before signing the first voucher, derive and retain its stable covenantId and
the genesis outpoint. Submit a deposit-voucher payload whose funding evidence
proves the transaction has exactly one output, the expected covenant genesis.
The gateway verifies the genesis transaction, script, value, initial state, and
covenant id before accepting protected work. A newly opened lane starts with
on-chain S = 0.
Later requests submit voucher payloads with a higher lifetime cumulative
ceiling T. The voucher signature binds Testnet-10, stable covenantId, and T; it
does not bind the rotating outpoint. Both client and server still persist the
current outpoint because standard RPC cannot find the current UTXO from a
covenant id.
The reference Testnet-10 policy requires 30 confirmations proven by an authoritative selected-chain traversal. Accepting-block and durable-checkpoint blue scores bind the evidence but do not determine selected-chain depth. Clients resume lineage from that checkpoint, process removed blocks before additions, and accept only one verified successor. Missing or pruned continuity keeps the lane unavailable; UTXO presence alone or peer channel metadata is not enough.
For one lane define A as lifetime committed fixed charges, S as lifetime gross
on-chain settlement including claim fees, V as current covenant value, and R as
the server-advertised minimum successor reserve claimReserveSompi. Voucher
acceptance requires:
0 <= S <= A <= T
(T - S) + R <= V
A - S is outstanding committed charge and T - S is authorization headroom. A
claim spends one same-ID input and creates one same-ID successor. If D is the
gross claim and F is the transaction fee, the provider receives D - F, the
successor value is V - D, and successor state becomes S + D. A top-up also
spends one same-ID input and creates one same-ID successor, increases V, and
preserves A, S, and T. A timeout refund spends one same-ID input and creates no
same-ID successor. The complete lane sequence is singleton genesis, repeated
partial claims, same-ID top-up, then refund; durable implementations must reload
the current head and any unresolved transition attempt after restart.
Successful paid retries return HTTP 200 with
PAYMENT-RESPONSE.success: true, a commitment id in the settlement transaction
field, and updated channel state in extensions.kaspa. Stale vouchers or stale
outpoints receive a corrective HTTP 402 with current lane state. If a claim,
top-up, or refund broadcast is uncertain, the lane remains unavailable until
trusted transaction evidence reconciles its current outpoint.
Unsupported Profiles
The hosted gateway must not accept foreign schemes, old alpha batch bindings, or future profiles as Kaspa payment evidence. A paid retry whose selected payment requirement is not currently advertised must fail before protected content is produced. A foreign scheme maps to:
Expected public error reason:
unsupported_scheme
A known Kaspa scheme with a mismatched binding or template maps to
invalid_payment_requirements at the public wire boundary.
Clients should parse mixed accepts envelopes selectively: validate the
envelope shape, keep compatible Kaspa entries, and skip foreign entries. A
foreign-only challenge should fail locally as unsupported.
Reporting Interop Issues
When reporting an interoperability issue, include:
- package versions or commit hash, gateway URL, and UTC timestamp;
- network, scheme, binding, and template;
- decoded
PAYMENT-REQUIREDandPAYMENT-SIGNATUREsummaries, with private keys removed; - HTTP status, public error reason, and exact transaction/output identity when relevant;
- batch channel id, stable
covenantId, current outpoint, and A/S/T/V/R values.
Do not post private keys, wallet seeds, or reusable unpaid payment headers.
Source: /docs/demo-implementer-guide.md