Skip to content

Ripple Custody

[Source]

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.

RippleCustody.create()

Construct with every value passed explicitly.

Signature

RippleCustody.create(options: RippleCustodyOptions): Promise<RippleCustody>

Options

FieldTypeRequiredDescription
gatewayUrlstringYesThe Custody gateway base URL.
authRippleCustodyAuthOptionsYesIntent-author credentials and token endpoint.
auth.signingKeystringYesIntent-author private key, as PEM contents.
auth.tokenUrlstringYesThe Custody token endpoint URL.
auth.clientIdstringNoThe OIDC client id to authenticate as. Defaults to customer_api.
domainIdstringYesThe Custody domain this custodian operates in.
primarystringYesThe primary account's r-address; validated against the discovered set.
allowRawSigningbooleanNoEnable the raw-signing fallback. Defaults to false.
defaultFeeFeeIntentNoHouse fee intent — a priority tier and/or a maxFeeDrops cap. Backends that can't honor the tier auto-price and warn. Defaults to low.
defaultDryRunbooleanNoPre-flight every write through Custody's dry-run. Defaults to false.
defaultTimeoutMsnumberNoHow long submitAndWait polls before throwing IntentPendingError.
httpCustodyHttpPortNoAdvanced: a custom HTTP transport, shape { send: (request) => Promise<response> }. Defaults to the production fetch port; most callers omit it.
Caution

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.

RippleCustody.fromEnv()

Reads the endpoints, credentials, and domain from environment variables.

The env requires these keys:

  • RIPPLE_CUSTODY_GATEWAY_URL
  • RIPPLE_CUSTODY_AUTH_SIGNING_KEY
  • RIPPLE_CUSTODY_AUTH_TOKEN_URL
  • RIPPLE_CUSTODY_AUTH_CLIENT_ID (optional)
  • RIPPLE_CUSTODY_DOMAIN_ID

Signature

RippleCustody.fromEnv(options: RippleCustodyFromEnvOptions): Promise<RippleCustody>

Options

FieldTypeRequiredDescription
primarystringYesThe primary account's r-address; validated against the discovered set.
allowRawSigningbooleanNoEnable the raw-signing fallback. Defaults to false.
defaultFeeFeeIntentNoHouse fee intent — a priority tier and/or a maxFeeDrops cap. Backends that can't honor the tier auto-price and warn. Defaults to low.
defaultDryRunbooleanNoPre-flight every write through Custody's dry-run. Defaults to false.
defaultTimeoutMsnumberNoHow long submitAndWait polls before throwing IntentPendingError.
envobjectNoThe source the RIPPLE_CUSTODY_* environment variables are read from, as a map of names to values. Defaults to process.env.
httpobjectNoA custom HTTP transport (implements CustodyHttpPort). Defaults to the production fetch port; most callers omit it.
Caution

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.

Resolving the signing key

fromEnv() accepts RIPPLE_CUSTODY_AUTH_SIGNING_KEY in three forms, chosen by what the value starts with:

Value starts withResolved as
-----BEGINLiteral PEM contents.
arn:aws:secretsmanager:An AWS Secrets Manager secret ARN — the secret is fetched and parsed.
anything elseA 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:

FieldRequiredDescription
private_keyYesThe intent-author private key, PEM contents.
user_aliasYesThe 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.

Example

const rippleCustody = await RippleCustody.fromEnv({
  primary: process.env.RIPPLE_CUSTODY_PRIMARY ?? '',
})