You can perform the following fungible token management operations on the XRP ledger:
- Manage trust lines, including trust line creation, settings, and freezing
- Preauthorize deposits on an account
- Claw back tokens from an account
- Trade tokens in the decentralized exchange (DEX)
Each of these operations involves the creation of a transaction order.
You can also issue XRPL fungible tokens with a transfer order or transaction order. Transfer orders are the recommended method for sending all assets, including XRPL tokens.
For more information about:
- Issuing tokens with a transfer order, see Send assets
- Trading tokens on the DEX, see Trade in the Decentralized Exchange in the XRPL documentation
All new requests to change the system state follow the same process. To familiarize yourself with this process first, see Manage intents and approvals.
This page covers XRPL fungible tokens using trust lines. For Multi-Purpose Tokens (MPTs), see Multi-Purpose Tokens.
XRPL uses decimal values for fungible tokens, but Ripple Custody only supports integers. Based on the smallest possible token value in XRPL (1000000000000000e-96) Ripple Custody represents this as 1 and registers the token asset with 81 decimals.
This means that to send 1 unit of a token, you must be represent it as 1000000000000000000000000000000000000000000000000000000000000000000000000000000000.
For an example of an XRPL token payload, see Add tokens.
A trust line is an accounting relationship between two accounts: a token issuer account, which controls the tokens, and a token holder account, which receives the tokens. A trust line:
- Creates a trust relationship between accounts for trading fungible tokens
- Is identified by the account pair and currency symbol
- Provides a structure to hold the tokens
In a given trust line, the token issuer has a negative balance equal to the positive balance of the token holder. For example, if the token holder holds 10 tokens issued by the issuer:
- The issuer account has a balance of -10 tokens
- The holder account has a balance of 10 tokens
For more information about trust lines, see Trust Lines in the XRPL documentation.
In Ripple Custody, you can create a trust line in two ways:
- With an issuer account and currency
- With a validated fungible token asset
To create trust lines, you need the following:
| Prerequisite | Additional information |
|---|---|
| The account ID of the holder account. | View account details |
The address of the token issuer account, or tickerId of an allowlisted fungible token. | If you want to use:
|
| Enough funds in the accounts to cover the transaction and all reserves, including the network reserve of 10 XRP and the reserve of 2 XRP for each object held in the account, including the account itself. | Check account balances |
The following new IDs, in a standard UUID format:
|
You can use the TrustSet operation to create new trust lines.
For more information about the TrustSet operation, see TrustSet in the XRPL documentation.
Creation of a trust line adds a reserved amount of 2 XRP. For more information about reserved amounts, see Check account balances.
To create a trust line, follow the steps in Manage intents and approvals, with a transaction order payload similar to one of the following examples.
The following example creates a trust line between a holder account and an issuer account specified with a code and issuer address:
{
"payload": {
"id": "8fd2d859-77de-4bcc-976c-3f4ccdfdcc3d",
"accountId": "c8b9519a-be18-4db7-9aca-cce93834841b",
"parameters": {
"operation": {
"type": "TrustSet",
"flags": [],
"enableRippling": false,
"limitAmount": {
"currency": {
"code": "USD",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"type": "Currency"
},
"value": "100",
},
}
"sourceTag": 123456,
"memos": [],
"feeStrategy": {
"drops": "5",
"type": "SpecifiedAdditionalFee"
},
"maximumFee": "50",
"type": "XRPL",
},
"description": "string",
"customProperties": {},
"type": "v0_CreateTransactionOrder"
}
}The following example creates a trust line between a holder account and an issuer account specified with a ticker ID:
{
"payload": {
"id": "8fd2d859-77de-4bcc-976c-3f4ccdfdcc3d",
"accountId": "c8b9519a-be18-4db7-9aca-cce93834841b",
"parameters": {
"operation": {
"type": "TrustSet",
"flags": [],
"enableRippling": false,
"limitAmount": {
"currency": {
"tickerId": "3334a1d5-1176-401f-b534-ec13a6b5ee8e",
"type": "TickerId"
},
"value": "100",
},
}
"sourceTag": 123456,
"memos": [],
"feeStrategy": {
"drops": "5",
"type": "SpecifiedAdditionalFee"
},
"maximumFee": "50",
"type": "XRPL",
},
"description": "string",
"customProperties": {},
"type": "v0_CreateTransactionOrder"
}
}Fields of the payload block to note are as follows:
| Field | Description |
|---|---|
id | ID of the transaction order |
accountId | ID of the holder account |
parameters.operation | Details of the operation:
|
parameters.feeStrategy | The fee strategy to use for the transaction. For more information, see Fee strategy and maximum fee. |
parameters.maximumFee | The maximum fee, in drops. For more information, see Fee strategy and maximum fee. |
parameters.type | Ledger type, in this case XRPL. |
type | v0_CreateTransactionOrder |
You can use the TrustSet operation with flag tfSetAuth to authorize the counterparty to hold assets.
This setting is only relevant if asfRequireAuth is enabled for the holder account. For more information, see Update XRPL account settings.
To create an authorized trust line, follow the steps in Manage intents and approvals, with a transaction order payload similar to the examples in Create a trust line. The key fields to note are:
accountID: The holder account ID.flags: Set totfSetAuth.
You can use the TrustSet operation with flags tfSetFreeze or tfClearFreeze to freeze and unfreeze trust lines.
You cannot freeze the trust line if asfNoFreeze is enabled for the issuer account. For more information, see Update XRPL account settings.
To freeze or unfreeze a trust line, follow the steps in Manage intents and approvals, with a transaction order payload similar to the examples in Create a trust line. The key fields to note are:
accountID: The issuer account ID.flags: Set totfSetFreezeortfClearFreeze.
You can use the TrustSet operation with flag tfSetAuth to authorize a holder account to hold tokens in a trust line.
This setting is only relevant if asfRequireAuth is enabled for the holder account. For more information, see Update XRPL account settings.
To authorize an account, follow the steps in Manage intents and approvals, with a transaction order payload similar to the examples in Create a trust line. The key fields to note are:
accountID: The holder account ID.flags: Set totfSetAuth.
You can use the DepositPreAuth operation to authorize an account to send tokens and XRP to the holder account. You can also remove authorization from an authorized account.
For more information about the DepositPreAuth operation, see DepositPreAuth in the XRPL documentation.
This operation is only valid for accounts with the asfDepositAuth setting enabled.
For more information, see Update XRPL account settings.
To authorize or unauthorize an account, follow the steps in Manage intents and approvals with a transaction order payload similar to one of the following examples.
The following example shows an account authorization:
{
"payload": {
"id": "8fd2d859-77de-4bcc-976c-3f4ccdfdcc3d",
"accountId": "c8b9519a-be18-4db7-9aca-cce93834841b",
"parameters": {
"operation": {
"type": "DepositPreauth",
"authorize": {
"address": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"type": "Address"
},
},
}
"sourceTag": 123456,
"memos": [],
"feeStrategy": {
"drops": "5",
"type": "SpecifiedAdditionalFee"
},
"maximumFee": "50",
"type": "XRPL",
},
"description": "string",
"customProperties": {},
"type": "v0_CreateTransactionOrder"
}The following example shows the removal of an account authorization:
{
"payload": {
"id": "8fd2d859-77de-4bcc-976c-3f4ccdfdcc3d",
"accountId": "c8b9519a-be18-4db7-9aca-cce93834841b",
"parameters": {
"operation": {
"type": "DepositPreauth",
"unauthorize": {
"address": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"type": "Address"
},
},
}
"sourceTag": 123456,
"memos": [],
"feeStrategy": {
"drops": "5",
"type": "SpecifiedAdditionalFee"
},
"maximumFee": "50",
"type": "XRPL",
},
"description": "string",
"customProperties": {},
"type": "v0_CreateTransactionOrder"
}Fields of the payload block to note are as follows:
| Field | Description |
|---|---|
id | ID of the transaction order |
accountId | ID of the holder account |
parameters.operation | Details of the operation:
You cannot authorize and unauthorize in the same operation. |
parameters.feeStrategy | The fee strategy to use for the transaction. For more information, see Fee strategy and maximum fee. |
parameters.maximumFee | The maximum fee, in drops. For more information, see Fee strategy and maximum fee. |
parameters.type | Ledger type, in this case XRPL. |
type | v0_CreateTransactionOrder |
You can use the Clawback operation to claw back tokens issued from the issuer account. You can use this, for example, when the trust line for an account is frozen.
For more information about the Clawback operation, see Clawback in the XRPL documentation.
This operation is only valid for accounts with the asfAllowTrustLineClawback setting enabled.
For more information, see Update XRPL account settings.
| Prerequisite | Additional information |
|---|---|
| The account ID of the issuer account. | View account details |
The address and currency of the account or tickerId of an allowlisted fungible token. | If you want to use:
|
| The details of the account from which to claw back tokens. | If the account is:
|
| Enough funds in the accounts to cover the transaction and all reserves, including the network reserve of 10 XRP and the reserve of 2 XRP for each object held in the account, including the account itself. | Check account balances |
The following new IDs, in a standard UUID format:
|
To claw back tokens from an account, follow the steps in Manage intents and approvals with a transaction order payload similar to one of the following example.
The following example shows clawback of a specific asset ID from an account address:
{
"payload": {
"id": "8fd2d859-77de-4bcc-976c-3f4ccdfdcc3d",
"accountId": "c8b9519a-be18-4db7-9aca-cce93834841b",
"parameters": {
"operation": {
"type": "Clawback",
"currency": {
"tickerId": "3334a1d5-1176-401f-b534-ec13a6b5ee8e",
"type": "TickerId"
},
"holder": {
"address": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"type": "Address"
},
"value": "3141592650000000000000000000000000000000000000000000000000000000000000000000000000"
}
"sourceTag": 123456,
"memos": [],
"feeStrategy": {
"drops": "5",
"type": "SpecifiedAdditionalFee"
},
"maximumFee": "50",
"type": "XRPL",
},
"description": "string",
"customProperties": {},
"type": "v0_CreateTransactionOrder"
}
}Fields of the payload block to note are as follows:
| Field | Description |
|---|---|
id | ID of the transaction order |
accountId | ID of the issuer account |
parameters.operation | Details of the operation:
|
parameters.feeStrategy | The fee strategy to use for the transaction. For more information, see Fee strategy and maximum fee. |
parameters.maximumFee | The maximum fee, in drops. For more information, see Fee strategy and maximum fee. |
parameters.type | Ledger type, in this case XRPL. |
type | v0_CreateTransactionOrder |
You can use the OfferCreate operation to create an offer on the DEX to trade XRP for tokens, or tokens for other tokens. Only offers that have a corresponding offer on the DEX are executed.
For example:
- A seller account offers tokens for XRP.
- A taker account offers XRP for tokens.
As long as the offer amounts match, the trade is automatically executed on the ledger.
For more information about:
- The
OfferCreateoperation, see OfferCreate in the XRPL documentation. - Trading tokens on the DEX, see Trade in the Decentralized Exchange in the XRPL documentation.
Since Ripple Custody only supports the creation of offers with a corresponding offer on the DEX, it is mandatory to set one of the following settings:
tfImmediateOrCancel: The offer is either executed immediately or cancelled. It can be partially fulfilled.tfFillOrKill: The offer is either fully filled immediately or cancelled. It can't be partially fulfilled.
You can also set the following optional setting:
tfSell: Used to agree to receive more than the amount specified in Taker Pays if an offer is available for more than the amount asked for.
To create an offer to trade on the DEX, follow the steps in Manage intents and approvals, with a transaction order payload similar to the following example.
The following example shows an immediate-or-cancel offer for a token:
{
"payload": {
"id": "8fd2d859-77de-4bcc-976c-3f4ccdfdcc3d",
"accountId": "c8b9519a-be18-4db7-9aca-cce93834841b",
"parameters": {
"operation": {
"type": "OfferCreate",
"flags": ["tfImmediateOrCancel"],
"takerGets": {
"currency": {
"tickerId": "3334a1d5-1176-401f-b534-ec13a6b5ee8e",
"type": "TickerId"
},
"amount": "3141592650000000000000000000000000000000000000000000000000000000000000000000000000"
},
"takerPays": {
"currency": {
"code": "USD",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"type": "Currency"
},
"amount": "3141592650000000000000000000000000000000000000000000000000000000000000000000000000"
},
}
"sourceTag": 123456,
"memos": [],
"feeStrategy": {
"drops": "5",
"type": "SpecifiedAdditionalFee"
},
"maximumFee": "50",
"type": "XRPL",
},
"description": "string",
"customProperties": {},
"type": "v0_CreateTransactionOrder"
}
}Fields of the payload block to note are as follows:
| Field | Description |
|---|---|
id | ID of the transaction order |
accountId | ID of the account creating the offer |
parameters.operation | Details of the operation:
|
parameters.feeStrategy | The fee strategy to use for the transaction. For more information, see Fee strategy and maximum fee. |
parameters.maximumFee | The maximum fee, in drops. For more information, see Fee strategy and maximum fee. |
parameters.type | Ledger type, in this case XRPL. |
type | v0_CreateTransactionOrder |