Skip to content

About

High-level, custodian-aware TypeScript SDK for the XRP Ledger.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Latest commit

 

History

154 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

simpleXRPL

A high-level TypeScript SDK for the XRP Ledger, scoped to the institutional / Web2 audience. simpleXRPL collapses the distance between a business intent ("transfer this token", "freeze that holder", "issue this credential") and the XRPL transactions that realize it — without forcing the caller to learn transactor-specific details, flag combinations, or signing-backend differences.

Writes dispatch to one of four signing backends behind a single Custodian abstraction: local (xrpl wallets), Ripple Custody, Palisade, and external signers — keys held in a KMS or HSM that never leave the secure boundary (a built-in AWS KMS adapter ships at simplexrpl/aws-kms; other devices implement the same ExternalSigner seam). Reads go straight through xrpl.

The SDK ships six business-intent verticals — xrp, iou, token, credential, domain, and account — behind a single SimpleXRPL.init(...) entry point.

Status: pre-1.0 and under active development. The public API may still change between releases.

Requirements

  • Node.js >= 20.19 (.nvmrc pins the dev version to 22)

simpleXRPL is Node-targeted and not intended to run in the browser. For browser-based reads or local signing, use the xrpl package directly.

Installation

npm install simplexrpl

Quick start

import { SimpleXRPL, LocalSigner } from 'simplexrpl'

// Bind one or more signing backends and connect to a network.
const client = await SimpleXRPL.init({
  xrpldUrl: 'wss://s.altnet.rippletest.net:51233',
  signers: [LocalSigner.fromEnv()],
})

// Each vertical exposes business-intent operations; the SDK builds, signs, and
// submits the underlying XRPL transaction for you.
await client.xrp.transfer({ to: 'rDestination...', amount: '10' })

See the API reference for every vertical, method, and type, and examples/ for runnable, type-checked samples. Writes dispatch to whichever signing backend owns the account — local, Ripple Custody, Palisade, or an external signer — with no change to the call.

Native operations and the raw-signing fallback

Each custodian models a subset of XRPL transactors as native operations: the SDK hands the backend a structured, typed operation, and the backend's own controls — transfer policies, allow-lists, and M-of-N approval rules — can inspect what they are approving.

For anything outside that subset, the SDK can fall back to raw signing: it builds and validates the transaction locally, then asks the backend to sign an opaque payload. This is off by default and must be enabled per custodian with allowRawSigning: true.

Warning

On the raw path the custodian cannot inspect what it is signing. Its transaction-level policies and approval rules operate on operation semantics, and a raw payload has none to read — Ripple Custody types it Unsafe for exactly this reason, and additionally requires the operator to enable that manifest capability server-side. Protocol validation still runs (xrpl's validate() executes on every path, so malformed transactions are still rejected); what you lose is the custodian's ability to reason about intent.

Treat allowRawSigning as a deliberate, audited exception rather than a default. Where a transactor matters to your controls, prefer a signing backend that models it natively.

Which transactors are native differs per backend — see docs/connector-routing.md for the current matrix, and note that a transactor can be native while a specific field on it is not, in which case that call also takes the raw path.

Ripple Custody versions

Each Custody instance runs its own version, so not every instance serves every endpoint or operation the SDK knows about. RippleCustody.create() reads the instance's version from the OpenAPI document it serves, and blocks a call the instance can't handle — an api.call endpoint, an api.propose intent type, or a vertical's native XRPL operation — with an UnsupportedInVersionError naming what is missing, before anything is sent.

const custody = await RippleCustody.fromEnv({ primary: 'r...' })
custody.backendVersion // e.g. '1.43.4'

To skip the detection request, pin the version instead; calls are then checked against data bundled with the SDK (one entry per minor version):

await RippleCustody.fromEnv({ primary: 'r...', apiVersion: '1.43' })

The error also says where the missing piece is available — e.g. official 1.37–1.43, or devbox (cmpt) for a pre-release feature. The full table is in docs/custody-endpoints.md.

The instance's internal API (/internal/v1/…) is reachable too, through its own typed entry point, and is checked the same way when the instance serves its internal document:

await custody.api.internal.call('getCurrentVault')

If the version can't be detected, the SDK emits a single Node warning (SIMPLEXRPL_CUSTODY_VERSION_UNDETECTED) and lets every call through to the server. autoDetectVersion: false turns detection off without the warning, and openApiUrl points it at a different document URL.

Development

Install dependencies with npm install.

The package ships a dual ESM + CJS build and is type-checked with tsc; tests run on Jest via ts-jest.

Script What it does
npm run typegen Regenerate committed custodian types from the vendored specs (openapi/)
npm run typecheck tsc --noEmit over the public surface
npm run build Clean, then emit dist/esm + dist/cjs and stamp type markers
npm test Unit tier (offline)
npm run test:integration Live tier (testnet, --runInBand)
npm run lint ESLint (type-aware)
npm run format Prettier write
npm run docgen TypeDoc reference (HTML) into docs/api
npm run docgen:md TypeDoc reference (Markdown) into docs/api-md
npm run docgen:routing Generate the connector routing table into docs/connector-routing.md

Custodian types are generated, not hand-authored

openapi-typescript turns the pinned specs in openapi/ into src/generated/{custody,palisade}.ts. The compiler then checks each adapter's mapping against the real contract, so an upstream API change surfaces as a type error instead of a silent drift. The generated files are committed (CI fails if they drift from the specs); regenerate with npm run typegen when bumping a vendored spec.

License

ISC

About

High-level, custodian-aware TypeScript SDK for the XRP Ledger.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages