@nanosession/faremeter
v0.2.0
Published
Faremeter adapter plugin for NanoSession
Readme
@nanosession/faremeter
Faremeter adapter for NanoSession x402 payments
This package provides adapters that bridge NanoSession's payment handlers to the Faremeter x402 middleware interface.
Installation
npm install @nanosession/faremeter
# or
pnpm add @nanosession/faremeterPeer dependencies: This package requires @nanosession/core, @nanosession/facilitator, @nanosession/client, and @nanosession/rpc to be installed.
Usage
Server-Side: FacilitatorHandler
The createFacilitatorHandler function creates a Faremeter-compatible FacilitatorHandler that verifies and settles NanoSession payments.
import { createFacilitatorHandler } from '@nanosession/faremeter';
import { NanoRpcClient } from '@nanosession/rpc';
const rpcClient = new NanoRpcClient({ endpoints: ['https://rpc.nano.to'] });
const facilitatorHandler = createFacilitatorHandler({
rpcClient,
payTo: 'nano_your_receiving_address',
defaultResourceAmountRaw: '1000000000000000000000000', // 0.001 XNO in raw
maxTimeoutSeconds: 300,
});
// Use with Faremeter middleware:
// app.use(faremeter({ facilitatorHandler }));FacilitatorHandler Methods
| Method | Description |
|--------|-------------|
| getSupported() | Returns supported payment schemes (nano-session on nano:mainnet) |
| getRequirements(accepts) | Enriches payment requirements with session ID and tag |
| handleVerify(req, payment) | Verifies a payment without marking as spent |
| handleSettle(req, payment) | Verifies and settles a payment (marks as spent) |
Client-Side: PaymentHandler
The createPaymentHandler function creates a Faremeter-compatible PaymentHandler that creates and broadcasts Nano payments.
import { createPaymentHandler } from '@nanosession/faremeter';
import { NanoRpcClient } from '@nanosession/rpc';
const rpcClient = new NanoRpcClient({ endpoints: ['https://rpc.nano.to'] });
const paymentHandler = createPaymentHandler({
rpcClient,
seed: process.env.NANO_WALLET_SEED!, // 64-char hex seed
maxSpend: '100000000000000000000000000', // Optional: max spend limit per request
});
// Use with Faremeter client:
// const client = createClient({ paymentHandler });Security Model
NanoSession uses session-bound payments to prevent receipt theft attacks:
- Each payment request includes a unique
sessionIdandtag - Requirements expose a normative send amount:
amount(exact raw to send) - Transparent fields in
extra.nanoSessionincluderesourceAmountRaw,tagAmountRaw, andtag - Server verifies the block against the issued session requirements before accepting payment
This prevents attackers from stealing payment proofs (block hashes) and reusing them for different sessions.
Critical: The server MUST maintain a spent set to prevent replay attacks. See PRODUCTION.md for production deployment requirements.
x402 Extensions
NanoSession supports x402 protocol extensions via the extensions field on PaymentRequired and PaymentPayload. The @nanosession/core package provides helpers for the upstream payment-identifier extension, which enables client-generated idempotency keys for request deduplication.
import {
PAYMENT_IDENTIFIER,
declarePaymentIdentifierExtension,
extractPaymentIdentifier,
validatePaymentIdentifierRequirement,
isPaymentIdentifierRequired,
} from '@nanosession/core';
// In your server: advertise support in the 402 response extensions
const extensions = {
[PAYMENT_IDENTIFIER]: declarePaymentIdentifierExtension() // required: false by default
};
// In your settle/verify handler: extract the client's idempotency key
const id = extractPaymentIdentifier(paymentPayload);
if (id) {
const cached = await idempotencyStore.get(id);
if (cached) return cached; // Return cached response on retry
}This extension is orthogonal to NanoSession's session binding and spent set — it provides HTTP-layer retry deduplication, not blockchain-layer anti-replay.
API Reference
createFacilitatorHandler(options: FacilitatorOptions)
| Option | Type | Required | Description |
|--------|------|----------|-------------|
| rpcClient | NanoRpcClient | Yes | Nano RPC client instance |
| payTo | string | Yes | Receiving Nano address |
| defaultResourceAmountRaw | string | No | Default resource amount in raw (before tag amount) |
| maxTimeoutSeconds | number | No | Session timeout (default: 300) |
| spentSet | SpentSetStorage | No | Custom spent set storage |
createPaymentHandler(options: PaymentHandlerOptions)
| Option | Type | Required | Description |
|--------|------|----------|-------------|
| rpcClient | NanoRpcClient | Yes | Nano RPC client instance |
| seed | string | Yes | 64-character hex wallet seed |
| maxSpend | string | No | Maximum spend per request in raw |
Example
See examples/faremeter-server/ for a complete working example with:
- Express server using Faremeter middleware
- NanoSession facilitator service
- 402 Payment Required flow
Documentation
Full protocol specification and guides: https://csi.ninzin.net/x402.NanoSession/
License
MIT
