Ripple Custody authenticates with an intent-author key exchanged for a token. A Custody deployment is per-tenant, so its gateway and token URLs point at the instance provisioned for you. See: Generate a key pair and register a public key for instructions on creating API credentials to fill in this constructor.
Construct with every value passed explicitly.
RippleCustody.create(options: RippleCustodyOptions): Promise<RippleCustody>| Field | Type | Required | Description |
|---|---|---|---|
gatewayUrl | string | Yes | The Custody gateway base URL. |
auth | RippleCustodyAuthOptions | Yes | Intent-author credentials and token endpoint. |
auth.signingKey | string | Yes | Intent-author private key, as PEM contents. |
auth.tokenUrl | string | Yes | The Custody token endpoint URL. |
auth.clientId | string | No | The OIDC client id to authenticate as. Defaults to customer_api. |
domainId | string | Yes | The Custody domain this custodian operates in. |
primary | string | Yes | The primary account's r-address; validated against the discovered set. |
allowRawSigning | boolean | No | Enable the raw-signing fallback. Defaults to false. |
defaultFee | FeeIntent | No | House fee intent — a priority tier and/or a maxFeeDrops cap. Backends that can't honor the tier auto-price and warn. Defaults to low. |
defaultDryRun | boolean | No | Pre-flight every write through Custody's dry-run. Defaults to false. |
defaultTimeoutMs | number | No | How long submitAndWait polls before throwing IntentPendingError. |
http | CustodyHttpPort | No | Advanced: a custom HTTP transport, shape { send: (request) => Promise<response> }. Defaults to the production fetch port; most callers omit it. |
Enabling allowRawSigning weakens the custodian's controls. On the raw path the custodian signs an opaque payload rather than a structured operation, so its transaction-level controls (transfer policies, allow-lists, and approval rules keyed to operation semantics) cannot inspect what is being signed. Ripple Custody types this payload Unsafe. xrpl.js protocol validation still runs on every path, so malformed transactions are still rejected; what is lost is the custodian's ability to reason about the transaction's intent.
Leave it off unless a specific transactor requires it, and prefer routing those operations through a signer that models them natively.
Reads the endpoints, credentials, and domain from environment variables.
The env requires these keys:
RIPPLE_CUSTODY_GATEWAY_URLRIPPLE_CUSTODY_AUTH_SIGNING_KEYRIPPLE_CUSTODY_AUTH_TOKEN_URLRIPPLE_CUSTODY_AUTH_CLIENT_ID(optional)RIPPLE_CUSTODY_DOMAIN_ID
RippleCustody.fromEnv(options: RippleCustodyFromEnvOptions): Promise<RippleCustody>| Field | Type | Required | Description |
|---|---|---|---|
primary | string | Yes | The primary account's r-address; validated against the discovered set. |
allowRawSigning | boolean | No | Enable the raw-signing fallback. Defaults to false. |
defaultFee | FeeIntent | No | House fee intent — a priority tier and/or a maxFeeDrops cap. Backends that can't honor the tier auto-price and warn. Defaults to low. |
defaultDryRun | boolean | No | Pre-flight every write through Custody's dry-run. Defaults to false. |
defaultTimeoutMs | number | No | How long submitAndWait polls before throwing IntentPendingError. |
env | object | No | The source the RIPPLE_CUSTODY_* environment variables are read from, as a map of names to values. Defaults to process.env. |
http | object | No | A custom HTTP transport (implements CustodyHttpPort). Defaults to the production fetch port; most callers omit it. |
Enabling allowRawSigning weakens the custodian's controls. On the raw path the custodian signs an opaque payload rather than a structured operation, so its transaction-level controls (transfer policies, allow-lists, and approval rules keyed to operation semantics) cannot inspect what is being signed. Ripple Custody types this payload Unsafe. xrpl.js protocol validation still runs on every path, so malformed transactions are still rejected; what is lost is the custodian's ability to reason about the transaction's intent.
Leave it off unless a specific transactor requires it, and prefer routing those operations through a signer that models them natively.
fromEnv() accepts RIPPLE_CUSTODY_AUTH_SIGNING_KEY in three forms, chosen by what the value starts with:
| Value starts with | Resolved as |
|---|---|
-----BEGIN | Literal PEM contents. |
arn:aws:secretsmanager: | An AWS Secrets Manager secret ARN — the secret is fetched and parsed. |
| anything else | A path to a .pem file on disk, read at startup. |
For the Secrets Manager path, the secret's value must be a JSON object (not a raw PEM string) with these fields:
| Field | Required | Description |
|---|---|---|
private_key | Yes | The intent-author private key, PEM contents. |
user_alias | Yes | The Custody user this keypair belongs to. Validated as present so an incomplete secret fails fast. |
The AWS client is constructed with no explicit credentials, so it uses the default AWS SDK credential provider chain: environment variables, a shared profile, or the runtime's IAM role. Resolution throws SimpleXRPLError if the secret is empty, isn't valid JSON, or is missing private_key or user_alias.
const rippleCustody = await RippleCustody.fromEnv({
primary: process.env.RIPPLE_CUSTODY_PRIMARY ?? '',
})