@spx-network/sdk
v0.1.0
Published
SPX Protocol SDK — streaming payments for the Solana agent economy
Readme
@spx/sdk
Streaming payments for the Solana agent economy. Collapse millions of micropayments into single on-chain settlements.
Install
npm install @spx/sdkQuick Start — Provider (get paid)
Add SPX payment verification to any Express API:
import express from "express";
import { spxMiddleware } from "@spx/sdk/server";
const app = express();
// Verify vouchers on every request — Ed25519 check, no RPC, microseconds
app.use("/api", spxMiddleware({
agentPublicKeys: {
// escrow pubkey → agent's Ed25519 public key
"EscrowPubkeyHere...": new Uint8Array([/* 32 bytes */]),
},
onVoucher: (voucher, amount) => {
console.log(`Earned ${amount} tokens`);
},
}));
app.get("/api/data", (req, res) => {
res.json({ result: "paid content" });
});
app.listen(3000);Requests without a valid X-SPX-Voucher header get a 402 Payment Required response.
Quick Start — Agent (pay for services)
import { SpxClient } from "@spx/sdk/client";
import { PublicKey } from "@solana/web3.js";
const client = new SpxClient({
agentSecretKey: myAgentKeypair.secretKey, // Ed25519 keypair
escrowKey: new PublicKey("MyEscrowPDA..."),
escrowCreatedAt: 1700000000n, // from on-chain escrow account
});
// Sign a voucher (off-chain, instant, no tx)
const { header } = client.pay(
new PublicKey("ServicePubkey..."),
1000n // amount in token units
);
// Attach to any HTTP request
const response = await fetch("https://api.example.com/data", {
headers: { "X-SPX-Voucher": header },
});How It Works
- Owner creates an escrow on Solana and deposits USDC
- Agent signs cumulative vouchers off-chain (Ed25519, instant)
- Service verifies vouchers locally (no RPC call — microseconds)
- Service batch-settles on-chain when ready (N vouchers → 1 transaction)
Only the latest voucher per escrow matters. 1 million API calls = 1 settlement transaction.
Settlement
Services collect vouchers and settle periodically:
import { buildSettleInstructions } from "@spx/sdk";
import { Connection, Transaction } from "@solana/web3.js";
const verifier = new SpxVerifier({ agentPublicKeys: { ... } });
// After accumulating vouchers...
const vouchers = verifier.getSettleableVouchers();
for (const voucher of vouchers) {
const [ed25519Ix, settleIx] = buildSettleInstructions({
voucher,
agentPublicKey, // 32 bytes
service: serviceKeypair.publicKey,
serviceTokenAccount,
escrow: voucher.escrowKey,
vault: escrowVault,
treasuryTokenAccount,
mint: usdcMint,
});
const tx = new Transaction().add(ed25519Ix, settleIx);
// sign and send...
}API Reference
Vouchers
signVoucher(params)→SpxVoucher— sign a voucher with agent keypairverifyVoucher(voucher, agentPublicKey)→boolean— local Ed25519 checkserializeVoucher(voucher)→string— base64 for HTTP headersdeserializeVoucher(encoded)→SpxVoucher— parse from HTTP headerbuildVoucherMessage(...)→Buffer— raw 110-byte message
Client
new SpxClient({ agentSecretKey, escrowKey, escrowCreatedAt })— create clientSpxClient.fromChain({ connection, agentSecretKey, owner, label })— create from on-chain stateclient.pay(serviceKey, amount)→{ voucher, header }— sign and serialize
Server
new SpxVerifier({ agentPublicKeys })— create verifierverifier.verify(headerValue)→VerifyResult— verify a voucherverifier.getSettleableVouchers()→SpxVoucher[]— latest per escrowspxMiddleware({ agentPublicKeys, onVoucher })— Express middleware
PDAs
findEscrowPda(owner, label)→[PublicKey, bump]findSettlementPda(escrow, service)→[PublicKey, bump]findConfigPda()→[PublicKey, bump]
Settlement
buildEd25519Instruction(agentPublicKey, message, signature)→TransactionInstructionbuildSettleInstruction(params)→TransactionInstructionbuildSettleInstructions(params)→[TransactionInstruction, TransactionInstruction]
Protocol
SPX Program ID: 56xJw72Lc1yDC6QwV8xNhiU6dDgUT1E9Ybh1nSxD4QZW
Voucher format (110 bytes):
SPX_VOUCHER_V1 (14) | escrow (32) | created_at (8 i64 BE)
| service (32) | amount (8 u64 BE) | cumulative (8 u64 BE) | nonce (8 u64 BE)License
MIT
