npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xrpljapan/x402-xrpl

v0.1.0

Published

x402 Payment Protocol XRPL (XRP Ledger) implementation

Readme

@xrpljapan/x402-xrpl

Public Beta License Node x402

Community XRPL mechanism for the x402 payment protocol.

⚠️ Public Beta. This package is 0.1.x and under active development. APIs, wire format details, and defaults may change without notice between releases. It has not been independently audited. Use at your own risk and pin an exact version in production. See the Disclaimer below.

Implements the exact payment scheme on the XRP Ledger (XRPL) for x402 v2. Its center of gravity is the resource server — the side that prices and accepts payments. ExactXrplServerScheme parses dollar and asset prices, enriches payment requirements (invoiceId, sourceTag, issuer), and resolves USD to a configured IOU, so an existing HTTP API can charge for XRP and IOU (RLUSD, USDC, etc.) payments with a few lines. The matching client and self-hostable facilitator roles complete the loop. Follows the t54 XRPL facilitator's wire format (XRP interop verified end-to-end on testnet).

Why the resource server is the main value. In an x402 deployment the client just signs a transaction and the facilitator just verifies and submits it — both are largely mechanical and interchangeable (you can even point at the hosted t54 facilitator and never run one yourself). The resource server is where the integration work and the business logic live: it decides what to charge, in which asset, binds each payment to an invoice for replay protection, and turns a plain HTTP endpoint into a paid one. That is the role this package is built to make easy.

This package is maintained by XRPL Japan. It is not yet part of the official x402 TypeScript monorepo (@x402/evm, @x402/svm, …). It follows the same register(network, scheme) integration model as those packages.

Features

  • Server-first integrationExactXrplServerScheme turns an HTTP endpoint into a paid one: parses "$0.10" and explicit asset prices, enriches requirements (invoiceId, sourceTag, issuer), and resolves USD to your configured IOU
  • Invoice binding — replay protection via InvoiceID (SHA-256) or MemoData, enforced end-to-end
  • Assets — native XRP (drops) and IOU tokens (RLUSD, USDC, custom issuers)
  • Three x402 rolesSchemeNetworkServer, SchemeNetworkClient, SchemeNetworkFacilitator
  • No-custody facilitator — verifies and submits presigned Payment transactions; never holds payer keys
  • t54 wire format — payload shape follows the t54 XRPL facilitator conventions (XRP interop verified E2E; IOU not yet supported by t54)
  • Dual build — ESM + CJS with subpath exports
  • Test coverage — unit tests + optional XRPL testnet integration tests

Requirements

  • Node.js ≥ 22
  • Peer dependency: @x402/core ≥ 2
  • Runtime dependency: xrpl ^5

Installation

npm install @x402/core @xrpljapan/x402-xrpl xrpl
# or
pnpm add @x402/core @xrpljapan/x402-xrpl xrpl

Quick start

Resource server

The primary integration point. Parse prices and enrich payment requirements (invoiceId, sourceTag, issuer):

import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server";
import { ExactXrplServerScheme } from "@xrpljapan/x402-xrpl";

const facilitator = new HTTPFacilitatorClient({
  url: process.env.XRPL_FACILITATOR_URL!, // e.g. t54 or your own
});

const server = new x402ResourceServer(facilitator)
  .register("xrpl:*", new ExactXrplServerScheme({
    defaultUsdIou: {
      asset: "524C555344000000000000000000000000000000", // RLUSD
      issuer: "rIssuer...",
    },
  }));

await server.initialize();

Dollar-string prices (e.g. "$0.10") resolve 1:1 to the configured USD IOU. Explicit { asset: "XRP", amount: "1000000" } amounts pass through unchanged. XRP-denominated dollar pricing is not supported — use a USD-pegged IOU instead.

The snippet above uses the core @x402/core/server API with a single facilitator. For an Express-integrated server that fans out across multiple facilitators (one per network) and mixes XRPL with EVM rails, see examples/multichain, which wires x402ResourceServer through @x402/express and an array of HTTPFacilitatorClients.

Client

Build and sign an XRPL Payment transaction from x402 payment requirements:

import { x402Client } from "@x402/core/client";
import { ExactXrplClientScheme, XrplWalletSigner } from "@xrpljapan/x402-xrpl";

const signer = new XrplWalletSigner(process.env.XRPL_SEED!);

const client = new x402Client();
client.register("xrpl:1", new ExactXrplClientScheme(signer));
// or register all XRPL networks:
// client.register("xrpl:*", new ExactXrplClientScheme(signer));

Self-hosted facilitator

Run your own facilitator for redundancy, privacy, or fallback:

import { x402Facilitator } from "@x402/core/facilitator";
import { ExactXrplFacilitator } from "@xrpljapan/x402-xrpl";

const facilitator = new x402Facilitator();
facilitator.register(["xrpl:0", "xrpl:1"], new ExactXrplFacilitator());

Override the rippled WebSocket endpoint if needed:

new ExactXrplFacilitator({ rpcConfig: { rpcUrl: "wss://your-node.example.com" } });

ExactXrplFacilitator keeps one pooled WebSocket connection per rippled URL and reconnects automatically if it drops. Long-running servers reuse the connection across requests. Call await close() on the ExactXrplFacilitator instance on shutdown — an open WebSocket otherwise keeps the Node.js process alive, which matters for short-lived scripts. Unexpected RPC/transport failures propagate as exceptions (they are not payment rejections); catch them at your HTTP boundary and decide between a protocol-shaped error response, a 503 + retry, or RPC failover.

If you supply a custom connect implementation (instead of the default xrpl.js-backed one), note that XrplAccountView.getTransferRate is a required method and XrplAccountState.sequence is a required field — custom implementations must supply them.

Examples

  • examples/multichain — one resource server, three payment rails: XRP and RLUSD on XRPL testnet (self-hosted facilitator from this package) plus USDC on Base Sepolia (official @x402/evm + x402.org facilitator). Includes an unattended XRP-rail smoke test.

Networks

| CAIP-2 ID | Network | Default rippled URL | |-----------|---------|---------------------| | xrpl:0 | XRPL mainnet | wss://xrplcluster.com | | xrpl:1 | XRPL testnet | wss://s.altnet.rippletest.net:51233 | | xrpl:* | CAIP family wildcard | — |

Assets

| Type | asset | amount | extra | |------|---------|----------|---------| | XRP | "XRP" | drops as integer string (1 XRP = 1,000,000 drops) | invoiceId, sourceTag | | IOU | 40-hex currency code | decimal string (e.g. "0.01") | issuer required |

RLUSD currency code: 524C555344000000000000000000000000000000

For IOUs whose issuer sets a TransferRate (transfer fee), the client automatically adds SendMax = amount × rate to the signed transaction; without it rippled rejects the payment with tecPATH_PARTIAL.

Facilitator options

Facilitator URLs are not hardcoded in this library. Configure them in your application.

Hosted (t54)

| Environment | Example URL | Network | |-------------|-------------|---------| | Mainnet | https://xrpl-facilitator-mainnet.t54.ai | xrpl:0 | | Testnet | https://xrpl-facilitator-testnet.t54.ai | xrpl:1 |

Pass the URL to HTTPFacilitatorClient on the resource server. Any facilitator implementing the standard x402 HTTP contract (/verify, /settle, /supported) works.

Self-hosted

Use ExactXrplFacilitator in-process (see Quick start). No HTTP URL required — only rippled connectivity.

Multi-network coexistence

x402 is designed for multiple chains side by side. Register XRPL alongside EVM, Solana, or other mechanisms:

import { x402Client } from "@x402/core/client";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { ExactXrplClientScheme, XrplWalletSigner } from "@xrpljapan/x402-xrpl";

const client = new x402Client()
  .register("eip155:*", new ExactEvmScheme(evmSigner))
  .register("xrpl:*", new ExactXrplClientScheme(new XrplWalletSigner(xrplSeed)));

Resource servers can expose multiple accepts options (one per network) and route to different facilitator URLs.

Wire format

The x402 payload for XRPL exact:

{
  "signedTxBlob": "1200002280000000...",
  "invoiceId": "INV-abc123"
}
  • signedTxBlob — hex-encoded, presigned XRPL Payment transaction
  • invoiceId — required; echoed for t54 wire compatibility

The cryptographic binding is inside the signed transaction (InvoiceID = SHA-256 of invoiceId, or MemoData). That on-chain binding is the source of truth for verification.

The facilitator verifies the single signature cryptographically and accepts it when the signing key is the account's master key (unless disabled via lsfDisableMaster) or its on-ledger RegularKey. Multi-signed transactions are rejected.

Note: For failures detected before signature verification (invalid_payload, amount_mismatch, destination_tag_mismatch, invoice_binding_missing, etc.), the payer field — when present — is read from the unverified blob's Account field and is unauthenticated: anyone can craft a blob naming any account. Do not use it for attribution, rate limiting, or blocklists. Once verification reaches the signature check, payer is cryptographically authenticated.

Additional checks enforced by verify:

  • LastLedgerSequence is required (reason missing_last_ledger_sequence) — reliable submission needs a deadline.
  • When extra.destinationTag is set, the signed tx must carry the same DestinationTag (reason destination_tag_mismatch).
  • The XRP balance check accounts for the ledger reserve (reserve_base + reserve_inc × OwnerCount) and the tx fee, not just the raw balance.
  • Non-existent payer accounts return account_not_found instead of an error.
  • The payload's invoiceId echo must equal extra.invoiceId.
  • A tx Sequence already consumed on-ledger is rejected up front (reason sequence_too_old) instead of surfacing as submit_error:tefPAST_SEQ at settle. Ticketed payments (Sequence: 0 + TicketSequence) are exempt.
  • For IOUs whose issuer sets a TransferRate, the signed tx must carry a SendMax in the same asset covering amount × rate (reasons missing_send_max / insufficient_send_max), and the trustline balance is checked against the fee-inclusive debit. This catches third-party clients that skip SendMax before they fail at settle with tecPATH_PARTIAL.

Settlement finality

settle waits for a validated ledger. A not_validated result means the transaction was submitted but not confirmed in a validated ledger before timeout. It is reported as success: false but includes the transaction hash — the payment may still settle on-chain later. Reconcile by transaction hash rather than treating not_validated as "no funds moved".

If submission itself throws (e.g. the transaction expired before validation, or a tem/tef rejection), settle reports success: false with errorReason: "submit_error:<message>" rather than raising.

Package exports

import { ... } from "@xrpljapan/x402-xrpl";                 // all public APIs
import { ... } from "@xrpljapan/x402-xrpl/exact/client";
import { ... } from "@xrpljapan/x402-xrpl/exact/server";
import { ... } from "@xrpljapan/x402-xrpl/exact/facilitator";

Public API

| Export | Role | |--------|------| | ExactXrplServerScheme | Server — parse prices, enrich requirements | | ExactXrplClientScheme | Client — build and sign payment payloads | | ExactXrplFacilitator | Facilitator — verify and settle on-chain | | XrplWalletSigner | Default XrplSigner (family seed or Wallet) | | XrplSigner | Signer interface for custom wallet integrations | | encodeCurrencyCode, invoiceIdHash, … | Shared helpers |

Development

pnpm install
pnpm build          # ESM + CJS to dist/
pnpm test           # unit tests
pnpm test:coverage  # unit tests + V8 coverage (thresholds enforced)
pnpm lint
pnpm format
pnpm build && pnpm check:package  # publint + arethetypeswrong + pack/import smoke

# XRPL testnet e2e (requires network + faucet)
RUN_XRPL_INTEGRATION=1 pnpm test:integration

# Local deterministic e2e (no faucet, no public testnet):
docker compose up -d
RUN_XRPL_STANDALONE=1 pnpm test:integration

t54 facilitator smoke test

node scripts/t54-facilitator-check.mjs
FACILITATOR_URL=https://xrpl-facilitator-testnet.t54.ai NETWORK=xrpl:1 node scripts/t54-facilitator-check.mjs

CI

GitHub Actions run lint, typecheck, unit tests with coverage thresholds, build, and package checks on every push/PR (.github/workflows/ci.yml). Testnet e2e runs weekly or on manual dispatch (.github/workflows/integration.yml) since the public testnet/faucet are rate-limited. Workflows activate once the repo is pushed to GitHub.

Interoperability status

| Scenario | Status | |----------|--------| | Self-hosted facilitator — XRP on testnet | Verified E2E | | Self-hosted facilitator — IOU on testnet | Verified E2E | | t54 testnet facilitator — XRP (/verify, /settle) | Verified E2E 2026-07-04 with a faucet-funded wallet: /verify returned isValid:true, /settle returned success:true — network-gated test in test/integration/xrp-e2e.test.ts | | t54 testnet facilitator — IOU (/verify, /settle) | Rejected 2026-07-04: /verify returns HTTP 200 with {"isValid":false,"invalidReason":"unsupported_payment_features"} for a well-formed IOU payload (XRP against the same facilitator passes) — t54 testnet does not yet support IOU assets; test skipped in test/integration/iou-e2e.test.ts pending t54 support |

Documentation

Relationship to official x402

This package follows the official x402 protocol and @x402/core interfaces.

Contributing

Contributions are welcome. Please open an issue or pull request on this repository.

  1. Fork the repository
  2. Create a feature branch
  3. Run pnpm test and pnpm lint
  4. Submit a pull request with a clear description

For larger changes, open an issue first to discuss the approach.

Public beta

@xrpljapan/x402-xrpl is currently in public beta (0.1.x). This means:

  • APIs may change. Public interfaces, option shapes, and defaults can change between minor releases without a deprecation cycle. Pin an exact version (@xrpljapan/[email protected]) if you depend on current behavior.
  • Wire format may evolve. The XRPL exact payload tracks the t54 de-facto format and any future upstream x402 spec; it is not frozen.
  • Not independently audited. The cryptographic and settlement logic has not undergone a third-party security audit.
  • Interop is partial. See Interoperability status for what is verified end-to-end today (XRP is; t54 IOU is not yet supported upstream).

Bug reports and feedback are welcome — please open an issue.

Disclaimer

THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT, as set out in the Apache License 2.0.

This package handles the construction, signing, and submission of on-chain payment transactions. You are solely responsible for reviewing and testing it before handling real value. The maintainers (XRPL Japan) and contributors accept no liability for any loss of funds, failed or duplicated settlements, or other damages arising from its use. Nothing here is financial, legal, or tax advice. Test thoroughly on XRPL testnet before touching mainnet funds, and pin an exact version in production.

License

Apache License 2.0