Skip to content

iou.issue()

[Source]

Generate a new trust line-based IOU in one call: the issuer enables rippling, the hot wallet extends trust to the maximum limit, and if amount is given, the issuer distributes that amount to the hot wallet.

Omit amount to set the trust line up only and distribute later with iou.transfer.

Sourcing the issuer and hot wallet

There are two ways to name the two accounts an issuance needs:

  • Pass holder — a client-owned account, on any connector. The issuer comes from options.from (default: the primary signer). Both resolve through the client's signers, so either can be custody-held on Ripple Custody or Palisade.
  • Omit holder — both accounts are bootstrapped from the XRPL_ISSUER_SEED and XRPL_HOT_WALLET_SEED environment seeds. This is the local dev flow.

Signature

iou.issue(
  params: IOUIssueParams,
  options?: IOUWriteOptions,
): Promise<SubmissionResult<IOUIssueIntent>>

Parameters

ParameterTypeRequiredDescription
tickerstringYesThe currency code: a 3-character ISO-4217-style code or a 40-character hex code. Any other code (e.g., a 5-character ticker) is auto-encoded to the 40-character hex form.
holderstringNoThe hot-wallet (holder) r-address that extends trust to the issuer — a client-owned account on any connector. Omit to bootstrap both accounts from the environment seeds.
amountstringNoHow much of the new IOU the issuer distributes to the hot wallet as a final step, as a decimal string. Must be strictly positive ('0' is rejected) with at most 15 significant digits. Omit to set the trust line up only.

Options

options is an optional second argument that sets the source account and overrides the fee.

OptionTypeRequiredDescription
fromAccountSelectorNoThe account to act as — an r-address string, or an object { address } or { signer, account? }. Defaults to the primary signer's primary account. (For IOU operations, this is the issuer.)
feeFeeIntentNoFee override — a priority tier and/or a maxFeeDrops cap.
idempotencyKeystringNoA prior submission's idempotencyKey, to retry to the same intent instead of creating a duplicate. Auto-generated when omitted.

Returns

Resolves to a SubmissionResult<IOUIssueIntent> (from the final step).

Every simpleXRPL write resolves to a SubmissionResult<T> — a union tagged by source, with the backend's raw response preserved verbatim. Its common fields are:

FieldTypeDescription
intentTThe operation-specific output — see the operation's own return fields.
source'xrpld' | 'custody' | 'palisade'Which backend produced the result; discriminates response.
responseTxResponse | custody record | Palisade recordThe backend's raw response, preserved verbatim.
txHashstring (optional)The XRPL transaction hash, once the transaction is on-ledger.
intentIdstring (optional)The custodian intent id, when the path produced one. Hold onto this to resume via client.intent.
idempotencyKeystring (optional)The UUIDv7 this submission carried. Pass it back as a later call's idempotencyKey to retry to the same intent rather than creating a duplicate.

Return fields

For IOU.issue, the intent (IOUIssueIntent) carries:

FieldTypeDescription
iouIDstringThe currency code and issuer of the new IOU, e.g. USD.rIssuer....
amountstring (optional)The amount distributed to the hot wallet, or undefined when the issuance only set the trust line up.

Underlying XRPL transactors

Runs as an ordered, multi-step sequence (no rollback on partial failure):

  1. AccountSet — the issuer enables rippling (defaultRipple).
  2. TrustSet — the hot wallet extends trust to the issuer, up to the maximum limit.
  3. Paymentonly when amount is given. The issuer distributes that amount to the hot wallet. The distribution must follow the TrustSet: without the limit in place, the Payment fails with tecPATH_DRY.

Throws an IntentValidationError if the environment-seed flow is used and the required seeds aren't set, or if amount is not a positive finite number. Throws a MultiStepFailureError if any step fails, carrying the steps that already committed — a distribution failure leaves the trust line in place, so it can be retried with iou.transfer.

Example

// Issue USD and put 1,000 into circulation on a custody-held hot wallet.
const { intent } = await client.iou.issue(
  {
    ticker: 'USD',
    holder: 'rHotWallet...',
    amount: '1000',
  },
  { from: 'rIssuer...' },
)

console.log(intent.iouID, intent.amount)