@erudite-intelligence/x402-kaspa
v1.0.0
Published
x402 payment protocol implementation for Kaspa (KAS) blockDAG network
Maintainers
Readme
@erudite-intelligence/x402-kaspa
x402 payment protocol implementation for Kaspa (KAS) blockDAG network.
First x402 spec for Kaspa. Native KAS payments with ~10 second finality.
What This Does
Implements the x402 protocol for Kaspa, enabling HTTP-native micropayments using KAS. Three components:
- Facilitator — Verifies signed Kaspa transactions and broadcasts them to the network
- Client — Creates x402 payment payloads from signed Kaspa transactions
- Server — Builds
PaymentRequirementsfor resource servers accepting KAS
How Kaspa x402 Works
- Client requests a protected resource
- Server returns
402withPaymentRequirements(price in USD, merchant Kaspa address) - Client converts USD to sompi using KAS/USD price oracle
- Client selects UTXOs, constructs and signs a complete Kaspa transaction
- Client sends the signed transaction in the
PAYMENT-SIGNATUREheader - Facilitator verifies: address match, amount sufficient, valid structure
- Facilitator broadcasts the transaction to the Kaspa network
- Kaspa confirms in ~10 seconds (10 blocks at 10 BPS)
- Server returns the resource
Key difference from Bitcoin x402: No PSBTs. Kaspa transactions are fully signed by the client — the facilitator just validates and broadcasts. ~10 second finality vs ~10 minutes for BTC.
Install
npm install @erudite-intelligence/x402-kaspaPeer dependency: @x402/core >= 2.3.0
Usage
Facilitator (verify + settle)
import { ExactKaspaFacilitatorScheme } from "@erudite-intelligence/x402-kaspa/facilitator";
import { x402ResourceServer } from "@x402/express";
import { HTTPFacilitatorClient } from "@x402/core/server";
const facilitatorClient = new HTTPFacilitatorClient({ url: process.env.FACILITATOR_URL });
const resourceServer = new x402ResourceServer(facilitatorClient)
.register("kaspa:mainnet", new ExactKaspaFacilitatorScheme({
priceOracle: { source: "coingecko" },
minConfirmations: 10,
settlementTimeoutMs: 30_000,
}));Client (create payment payloads)
import { ExactKaspaClientScheme } from "@erudite-intelligence/x402-kaspa/client";
import { x402Client } from "@x402/core/client";
const client = new x402Client()
.register("kaspa:mainnet", new ExactKaspaClientScheme({
signer: {
address: "kaspa:qq...",
createSignedTransaction: async (payTo, amountSompi) => {
// Use kaspa WASM SDK or kaspa-rpc-client to build + sign tx
const tx = await yourKaspaWallet.send(payTo, amountSompi);
return {
signedTransaction: tx.toHex(),
txId: tx.id,
inputCount: tx.inputs.length,
outputCount: tx.outputs.length,
};
},
},
priceOracle: { source: "coingecko" },
}));Server (build payment requirements)
import { buildKaspaPaymentRequirements } from "@erudite-intelligence/x402-kaspa/server";
const routes = {
"GET /api/premium": {
accepts: buildKaspaPaymentRequirements({
price: "$1.00",
payTo: "kaspa:qqe3p64wpjf5y27kxppxrgks298ge6lhu6ws7ndx4tswzj7c84qkjk3rz5jyg",
}),
description: "Premium API access",
},
};Direct utility usage
import {
kasToSompi,
sompiToKas,
usdToSompi,
validateKaspaAddress,
getKasPrice,
KaspaApiClient,
} from "@erudite-intelligence/x402-kaspa";
// Denomination conversion
kasToSompi(5.5); // 550_000_000n
sompiToKas(100_000_000n); // 1.0
// Address validation
validateKaspaAddress("kaspa:qq..."); // { isValid: true }
// Price oracle
const price = await getKasPrice({ source: "coingecko" });
const sompi = usdToSompi("$5.00", price.kasUsd);
// REST API client
const api = new KaspaApiClient("kaspa:mainnet");
const balance = await api.getBalance("kaspa:qq...");
const utxos = await api.getUtxos("kaspa:qq...");CAIP-2 Network Identifiers
| Identifier | Network |
|---|---|
| kaspa:mainnet | Kaspa mainnet |
| kaspa:testnet-10 | Kaspa Testnet 10 |
| kaspa:testnet-11 | Kaspa Testnet 11 |
No official CAIP-2 namespace exists for Kaspa yet. This package defines the namespace for x402 usage. A ChainAgnostic namespace proposal is planned.
Denomination
| Unit | Sompi | |---|---| | 1 KAS | 100,000,000 sompi | | 0.01 KAS | 1,000,000 sompi | | 0.00000001 KAS | 1 sompi |
Configuration
Facilitator Config
interface KaspaFacilitatorConfig {
network?: KaspaNetwork; // Default: "kaspa:mainnet"
apiUrl?: string; // Custom REST API URL
priceOracle?: PriceOracleConfig; // Price source config
minConfirmations?: number; // Default: 10
settlementTimeoutMs?: number; // Default: 30000
priceSlippagePercent?: number; // Default: 0.02 (2%)
}Price Oracle
KAS has no stablecoins on L1 — a price oracle is required for USD→sompi conversion.
// CoinGecko (free tier, rate-limited)
{ source: "coingecko" }
// CoinGecko Pro
{ source: "coingecko", apiKey: "your-key" }
// CoinMarketCap
{ source: "coinmarketcap", apiKey: "your-key" }
// Custom
{ source: "custom", customFetcher: async () => 0.12 } // returns USD priceArchitecture
@erudite-intelligence/x402-kaspa
├── /facilitator — ExactKaspaFacilitatorScheme (verify + settle)
├── /client — ExactKaspaClientScheme (createPaymentPayload)
├── /server — buildKaspaPaymentRequirements()
├── utils/
│ ├── address — Kaspa address validation
│ ├── denomination — KAS ↔ sompi conversion
│ ├── priceOracle — KAS/USD price fetching with cache
│ └── apiClient — api.kaspa.org REST client
└── types/ — TypeScript type definitionsZero heavy dependencies. No WASM binaries required on the facilitator side. Uses api.kaspa.org REST API for all network interactions. The client side requires a signer (from kaspa WASM SDK or kaspa-rpc-client) — this is provided by the integrator, not bundled.
Verification Checks
The facilitator performs these checks during verify():
- Payload structure validation (all required fields present)
- Address format validation (prefix, length, charset, network match)
- Recipient matches
paymentRequirements.payTo - USD→sompi conversion with price oracle
- Payment amount ≥ required (with 2% slippage tolerance)
- Signed transaction is valid hex
- Transaction size within bounds (min 100 bytes, max 100KB)
- Input count ≤ 84 (Kaspa max UTXO inputs)
- Balance check via REST API (best-effort)
Security Notes
- Signature verification happens at broadcast. The Kaspa network validates Schnorr signatures when the transaction is submitted. Invalid signatures are rejected at
settle(), notverify(). This is the same pattern as our Bitcoin x402 implementation. - UTXO front-running risk: Between
verify()andsettle(), the customer could spend the same UTXOs elsewhere. The facilitator should callsettle()immediately afterverify()returns valid. - Price oracle trust: The facilitator trusts the configured price source. Use multiple sources or a trusted custom fetcher for high-value payments.
- No OP_RETURN: Kaspa does not support arbitrary data in transaction outputs. Payment metadata is carried in the x402 HTTP headers, not on-chain.
Kaspa Network Properties
| Property | Value |
|---|---|
| Consensus | GHOSTDAG (blockDAG) |
| Block rate | 10 BPS (post-Crescendo, May 2025) |
| Finality | ~10 seconds |
| Fees | < $0.001 |
| Signature | Schnorr |
| Address | Bech32-like (kaspa:qq...) |
| Supply | 28.7 billion KAS max |
| Smart contracts | None on L1 |
Facilitator Lineup
With this package, the EruditePay facilitator supports six chains:
.register("eip155:8453", new ExactEvmScheme()) // Base (Coinbase)
.register("solana:mainnet", new ExactSvmScheme()) // Solana (Coinbase)
.register("tron:mainnet", new ExactTronScheme()) // Tron (Erudite)
.register("bip122:bitcoin", new ExactBtcScheme()) // Bitcoin (Erudite)
.register("xrpl:0", new ExactXrpScheme()) // XRP (Erudite)
.register("kaspa:mainnet", new ExactKaspaFacilitatorScheme()) // Kaspa (Erudite)Roadmap
- [ ] Testnet integration tests (kaspa:testnet-10)
- [ ] Adversarial test suite (180+ tests target)
- [ ] Kasware browser wallet adapter for @x402/paywall
- [ ] wRPC WebSocket settlement (alternative to REST API)
- [ ] Submit CAIP-2 namespace proposal to ChainAgnostic
- [ ] Submit PR to coinbase/x402 repo
License
MIT — Erudite Intelligence LLC
