diff --git a/docs/concepts/decentralized-storage/credentials.md b/docs/concepts/decentralized-storage/credentials.md new file mode 100644 index 00000000000..d6855afd5a6 --- /dev/null +++ b/docs/concepts/decentralized-storage/credentials.md @@ -0,0 +1,47 @@ +# Credentials + +The Credentials feature is a set of tools for managing authorization and compliance requirements using the XRP Ledger blockchain, while respecting privacy and decentralization. This feature extends and interconnects with other features of the XRP Ledger including [Deposit Authorization](https://xrpl.org/docs/concepts/accounts/depositauth). The goal of this feature is to streamline the process of compliance checks such as [KYC (Know Your Customer)](https://en.wikipedia.org/wiki/Know_your_customer) and to enable further trust-based applications within the XRP Ledger ecosystem. + +The design of the Credentials standard draws from the [W3C Verifiable Credentials standard](https://www.w3.org/TR/vc-data-model-2.0/). It is intended to be compatible to an extent that makes sense in the context of the XRP Ledger. There are some differences in data structures and formatting: for example, the subject of a credential is identified by an XRP Ledger address rather than a URL. + +## Overview + +_Credentials_ are signed statements that can be stored in the ledger and can attest to a user's identity, legal status, or other status. This feature includes issuance, storage, and verification of credentials directly on the XRP Ledger, while still supporting the privacy needs of users. + +This feature set is designed for an ecosystem of parties with the following roles: + +- _Authorizers_ who want to limit specific actions or interactions to users who possess the correct credentials. +- _Issuers_ who provide credentials to users who meet their criteria. +- _Users_ who obtain credentials from issuers and use those credentials to interact with authorizers. + +Each credential applies to a specific user's XRP Ledger account, and is attested by a specific credential issuer. The exact qualifications that a credential entails are open-ended, and defined by their issuers. They can range from trivial to serious, or broad to narrow. Some examples of things a credential could state: + +- That a user is not a subject of sanctions by a particular nation or set of nations. +- That a user has accredited investor status in the US. +- That a user has reached a specific level in a particular video game. + +### Uses + +Within the XRP Ledger, you can use Deposit Authorization to automatically allow senders with the correct set of credentials, instead of approving sending accounts individually. Future amendments could further extend credentials to gate access to other features such as holding tokens, participating in lending pools, or contributing to an AMM. + +Credentials stored in the XRP Ledger can also be used to authorize off-ledger activities, especially in association with a decentralized identifier. + +## Usage Flow + +A typical flow to use Credentials involves three parties with different roles, as described in the following example: + +* Verity is a regulated business that wants to interact only with properly KYC'd accounts, to ensure legal compliance. This makes Verity an _authorizer_ because they configure which accounts are allowed (authorized) to interact with them. +* Isabel is a credential issuer who vets accounts and issues credentials attesting that the accounts are who they say they are. +* Alice is a user who wants to interact with Verity. + +All three parties need XRP Ledger accounts. The flow works as follows: + +1. Verity sets up their account so that only authorized accounts can interact with them. Since they trust Isabel to properly vet accounts and issue relevant credentials, they configure their account to accept credentials issued by Isabel. +2. Alice submits whatever documents are necessary to Isabel privately, off-chain. +3. Isabel examines Alice's documents and creates a credential attesting to Alice's trustworthiness. +4. Alice accepts the credential, making it valid. +5. Alice can now interact with/send funds to Verity. + +Importantly, the documents that Alice sends to Isabel can include personally identifiable or private information that's needed to verify Alice's identity, but this information is never published or stored on the blockchain and Verity does not need to see it. Also, other businesses that trust Isabel can accept the same credentials so Alice does not need to repeatedly re-verify for every party she wants to interact with. + +To revoke a credential, Isabel can delete it from the ledger. Alice can also delete her own credentials. diff --git a/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry.md b/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry.md index acd60ac26b0..c8380034578 100644 --- a/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry.md +++ b/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry.md @@ -34,19 +34,20 @@ In addition to the general fields above, you must specify *exactly 1* of the fol - [ledger\_entry](#ledger_entry) - [Request Format](#request-format) - [General Fields](#general-fields) - - [Get Ledger Object by ID](#get-ledger-object-by-id) - - [Get AccountRoot Object](#get-accountroot-object) - - [Get AMM Object](#get-amm-object) - - [Get Bridge Object](#get-bridge-object) - - [Get DirectoryNode Object](#get-directorynode-object) - - [Get Offer Object](#get-offer-object) - - [Get Oracle Object](#get-oracle-object) - - [Get RippleState Object](#get-ripplestate-object) - - [Get Check Object](#get-check-object) - - [Get Escrow Object](#get-escrow-object) - - [Get PayChannel Object](#get-paychannel-object) - - [Get DepositPreauth Object](#get-depositpreauth-object) - - [Get Ticket Object](#get-ticket-object) + - [Get Ledger Entry by ID](#get-ledger-entry-by-id) + - [Get AccountRoot Entry](#get-accountroot-entry) + - [Get AMM Entry](#get-amm-entry) + - [Get Bridge Entry](#get-bridge-entry) + - [Get Credential Entry](#get-credential-object) + - [Get DirectoryNode Entry](#get-directorynode-object) + - [Get Offer Entry](#get-offer-object) + - [Get Oracle Entry](#get-oracle-object) + - [Get RippleState Entry](#get-ripplestate-object) + - [Get Check Entry](#get-check-object) + - [Get Escrow Entry](#get-escrow-object) + - [Get PayChannel Entry](#get-paychannel-object) + - [Get DepositPreauth Entry](#get-depositpreauth-object) + - [Get Ticket Entry](#get-ticket-object) - [Get NFT Page](#get-nft-page) - [Response Format](#response-format) - [Possible Errors](#possible-errors) @@ -54,9 +55,10 @@ In addition to the general fields above, you must specify *exactly 1* of the fol {% admonition type="warning" name="Caution" %}If you specify more than 1 of these type-specific fields in a request, the server retrieves results for only 1 of them. It is not defined which one the server chooses, so you should avoid doing this.{% /admonition %} -### Get Ledger Object by ID +### Get Ledger Entry by ID + -Retrieve any type of ledger object by its unique ID. +Retrieve any type of ledger entry by its unique ID. | Field | Type | Description | |:--------|:-------|:----------------------------------------------------------| @@ -109,7 +111,8 @@ You can use this type of request to get any singleton ledger entry, if it exists -### Get AccountRoot Object +### Get AccountRoot Entry + Retrieve an [AccountRoot entry](../../../protocol/ledger-data/ledger-entry-types/accountroot.md) by its address. This is roughly equivalent to the [account_info method][]. @@ -156,7 +159,8 @@ rippled json ledger_entry '{ "account_root": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59 -### Get AMM Object +### Get AMM Entry + _(Added by the [AMM amendment][])_ @@ -222,7 +226,8 @@ rippled json ledger_entry '{ "amm": { "asset": { "currency": "XRP" }, "asset2": [Try it! >](/resources/dev-tools/websocket-api-tool?server=wss%3A%2F%2Fs.devnet.rippletest.net%3A51233%2F#ledger_entry-amm) -### Get Bridge Object +### Get Bridge Entry + _(Requires the [XChainBridge amendment][] {% not-enabled /%})_ @@ -292,7 +297,61 @@ rippled json ledger_entry '{ "bridge_account": "rnQAXXWoFNN6PEqwqsdTngCtFPCrmfuq [Try it! >](/resources/dev-tools/websocket-api-tool?server=wss%3A%2F%2Fs.devnet.rippletest.net%3A51233%2F#ledger_entry-bridge) -### Get DirectoryNode Object +### Get Credential Entry + +Retrieve a [Credential entry][], which represents an attestation by one account about another account. + +| Field | Type | Required? | Description | +|:-----------------------------|:---------------------|:----------|-------------| +| `credential` | Object or String | Yes | Specify the Credential to retrieve. If a string, must be the [ledger entry ID][] of the entry, as hexadecimal. If an object, requires `subject`, `issuer`, and `credential_type` sub-fields. | +| `credential.subject` | String - [Address][] | Yes | The account that is the subject of the credential. | +| `credential.issuer` | String - [Address][] | Yes | The account that issued the credential. | +| `credential.credential_type` | String - Hexadecimal | Yes | The type of the credential, as issued. | + +WebSocket: + +```json +{ + "id": "example_get_credential", + "command": "ledger_entry", + "credential": { + "subject": "rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8", + "issuer": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX", + "credential_type": "6D795F63726564656E7469616C" + }, + "ledger_index": "validated" +} +``` + +JSON-RPC: + +```json +{ + "method": "ledger_entry", + "params": [{ + "credential": { + "subject": "rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8", + "issuer": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX", + "credential_type": "6D795F63726564656E7469616C" + }, + "ledger_index": "validated" + }] +} +``` + +Commandline: + +```bash +rippled json ledger_entry '{ "credential": {"subject": "rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8", "issuer": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX","credential_type": "6D795F63726564656E7469616C"}, "ledger_index": "validated" }' +``` + + + + +### Get DirectoryNode Entry + Retrieve a [DirectoryNode](../../../protocol/ledger-data/ledger-entry-types/directorynode.md), which contains a list of other ledger objects. Can be provided as string (object ID of the Directory) or as an object. @@ -348,7 +407,8 @@ rippled json ledger_entry '{ "directory": { "owner": "rf1BiGeXwwQoi8Z2ueFYTEXSwu -### Get Offer Object +### Get Offer Entry + Retrieve an [Offer entry](../../../protocol/ledger-data/ledger-entry-types/offer.md), which defines an offer to exchange currency. Can be provided as string (unique index of the Offer) or as an object. @@ -402,7 +462,8 @@ rippled json ledger_entry '{ "offer": { "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJY [Try it! >](/resources/dev-tools/websocket-api-tool#ledger_entry-offer) -### Get Oracle Object +### Get Oracle Entry + _(Requires the [PriceOracle amendment][])_ @@ -458,7 +519,8 @@ rippled json ledger_entry '{ "oracle": { "account": "rNZ9m6AP9K7z3EVg6GhPMx36V4Q [Try it! >](/resources/dev-tools/websocket-api-tool?server=wss%3A%2F%2Fs.devnet.rippletest.net%3A51233%2F#ledger_entry-oracle) -### Get RippleState Object +### Get RippleState Entry + Retrieve a [RippleState entry][], which tracks a (non-XRP) currency balance between two accounts. @@ -517,7 +579,8 @@ rippled json ledger_entry '{ "ripple_state": { "accounts": ["rf1BiGeXwwQoi8Z2ueF -### Get Check Object +### Get Check Entry + Retrieve a [Check entry](../../../protocol/ledger-data/ledger-entry-types/check.md), which is a potential payment that can be cashed by its recipient. @@ -562,7 +625,8 @@ rippled json ledger_entry '{ "check": "C4A46CCD8F096E994C4B0DEAB6CE98E722FC17D79 -### Get Escrow Object +### Get Escrow Entry + Retrieve an [Escrow entry](../../../protocol/ledger-data/ledger-entry-types/escrow.md), which holds XRP until a specific time or condition is met. Can be provided as string (object ID of the Escrow) or as an object. @@ -615,7 +679,8 @@ rippled json ledger_entry '{ "escrow": { "owner": "rL4fPHi2FWGwRGRQSH7gBcxkuo2b9 -### Get PayChannel Object +### Get PayChannel Entry + Retrieve a [PayChannel entry](../../../protocol/ledger-data/ledger-entry-types/paychannel.md), which holds XRP for asynchronous payments. @@ -659,15 +724,24 @@ rippled json ledger_entry '{ "payment_channel": "C7F634794B79DB40E87179A9D1BF05D [Try it! >](/resources/dev-tools/websocket-api-tool#ledger_entry-paychannel) -### Get DepositPreauth Object +### Get DepositPreauth Entry + Retrieve a [DepositPreauth entry](../../../protocol/ledger-data/ledger-entry-types/depositpreauth.md), which tracks preauthorization for payments to accounts requiring [Deposit Authorization](../../../../concepts/accounts/depositauth.md). -| Field | Type | Description | -|:-----------------------------|:---------------------|:-----------------------| -| `deposit_preauth` | Object or String | Specify the DepositPreauth to retrieve. If a string, must be the [ledger entry ID](../../../protocol/ledger-data/common-fields.md) of the DepositPreauth entry, as hexadecimal. If an object, requires `owner` and `authorized` sub-fields. | -| `deposit_preauth.owner` | String - [Address][] | _(Required if `deposit_preauth` is specified as an object)_ The account that provided the preauthorization. | -| `deposit_preauth.authorized` | String - [Address][] | _(Required if `deposit_preauth` is specified as an object)_ The account that received the preauthorization. | +| Field | Type | Required? | Description | +|:-----------------------------|:---------------------|:----------|-------------| +| `deposit_preauth` | Object or String | Yes | Specify the DepositPreauth to retrieve. If a string, must be the [ledger entry ID][] of the DepositPreauth entry, as hexadecimal. If an object, requires `owner` sub-field and either `authorized` or `authorize_credentials` sub-field. | +| `deposit_preauth.owner` | String - [Address][] | Yes | The account that provided the preauthorization. | +| `deposit_preauth.authorized` | String - [Address][] | No | The account that received the preauthorization. | +| `deposit_preauth.authorized_credentials` | Array | No | A set of credentials that received the preauthorization. | + +Each member of the `deposit_preauth.authorized_credentials` array, if provided, must include the following nested fields: + +| Field | Type | Required? | Description | +|:------------------|:---------------------|:----------|:------------| +| `issuer` | String - [Address][] | Yes | The address of the account that issued the credential. | +| `credential_type` | String - Hexadecimal | Yes | The type of the credential, as issued. | {% tabs %} @@ -711,7 +785,8 @@ rippled json ledger_entry '{ "deposit_preauth": { "owner": "rf1BiGeXwwQoi8Z2ueFY [Try it! >](/resources/dev-tools/websocket-api-tool#ledger_entry-depositpreauth) -### Get Ticket Object +### Get Ticket Entry + Retrieve a [Ticket entry](../../../protocol/ledger-data/ledger-entry-types/ticket.md), which represents a [sequence number][] set aside for future use. _(Added by the [TicketBatch amendment][])_ diff --git a/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/deposit_authorized.md b/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/deposit_authorized.md index e8949a617a6..10b3cee95f3 100644 --- a/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/deposit_authorized.md +++ b/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/deposit_authorized.md @@ -1,6 +1,4 @@ --- -html: deposit_authorized.html -parent: path-and-order-book-methods.html seo: description: Check whether an account is authorized to send money directly to another. labels: @@ -10,7 +8,7 @@ labels: # deposit_authorized [[Source]](https://github.com/XRPLF/rippled/blob/817d2339b8632cb2f97d3edd6f7af33aa7631744/src/ripple/rpc/handlers/DepositAuthorized.cpp "Source") -The `deposit_authorized` command indicates whether one account is authorized to send payments directly to another. See [Deposit Authorization](../../../../concepts/accounts/depositauth.md) for information on how to require authorization to deliver money to your account. +The `deposit_authorized` command indicates whether one account is authorized to send payments directly to another. See [Deposit Authorization](https://xrpl.org/docs/concepts/accounts/depositauth/) for information on how to require authorization to deliver money to your account. ## Request Format An example of the request format: @@ -24,6 +22,10 @@ An example of the request format: "command": "deposit_authorized", "source_account": "rEhxGqkqPPSxQ3P25J66ft5TwpzV14k2de", "destination_account": "rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8", + "credentials": [ + "A182EFBD154C9E80195082F86C1C8952FC0760A654B886F61BB0A59803B4387B", + "383D269D6C7417D0A8716B09F5DB329FB17B45A5EFDBAFB82FF04BC420DCF7D5" + ], "ledger_index": "validated" } ``` @@ -37,6 +39,10 @@ An example of the request format: { "source_account": "rEhxGqkqPPSxQ3P25J66ft5TwpzV14k2de", "destination_account": "rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8", + "credentials": [ + "A182EFBD154C9E80195082F86C1C8952FC0760A654B886F61BB0A59803B4387B", + "383D269D6C7417D0A8716B09F5DB329FB17B45A5EFDBAFB82FF04BC420DCF7D5" + ], "ledger_index": "validated" } ] @@ -45,23 +51,27 @@ An example of the request format: {% /tab %} {% tab label="Commandline" %} + ```bash #Syntax: deposit_authorized [] rippled deposit_authorized rEhxGqkqPPSxQ3P25J66ft5TwpzV14k2de rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8 validated ``` {% /tab %} - {% /tabs %} The request includes the following parameters: -| `Field` | Type | Description | -|:----------------------|:---------------------------|:------------------------| -| `source_account` | String - [Address][] | The sender of a possible payment. | -| `destination_account` | String - [Address][] | The recipient of a possible payment. | -| `ledger_hash` | String | _(Optional)_ A 32-byte hex string for the ledger version to use. (See [Specifying Ledgers][]) | -| `ledger_index` | String or Unsigned Integer | _(Optional)_ The [ledger index][] of the ledger to use, or a shortcut string to choose a ledger automatically. (See [Specifying Ledgers][]) | +| Field | Type | Required? | Description | +|:----------------------|:---------------------|:----------|-------------| +| `source_account` | String - [Address][] | Yes | The sender of a possible payment. | +| `destination_account` | String - [Address][] | Yes | The recipient of a possible payment. | +| `ledger_hash` | [Hash][] | No | A 20-byte hex string for the ledger version to use. (See [Specifying Ledgers][]) | +| `ledger_index` | [Ledger Index][] | No | The [ledger index][] of the ledger to use, or a shortcut string to choose a ledger automatically. (See [Specifying Ledgers][]) | +| `credentials` | Array | No | A set of credentials to take into account when checking if the sender can send funds to the destination. Each member of the array must be the unique ID of a [Credential entry][] in the ledger. Cannot be an empty array. | +{% admonition type="info" name="Note" %} +If you provide a set of credentials that does not exactly match a set of credentials preauthorized by the destination, the payment is not authorized, even if the destination has preauthorized a subset of those credentials. This matches the behavior of transaction processing. +{% /admonition %} ## Response Format @@ -74,6 +84,10 @@ An example of a successful response: { "id": 1, "result": { + "credentials": [ + "A182EFBD154C9E80195082F86C1C8952FC0760A654B886F61BB0A59803B4387B", + "383D269D6C7417D0A8716B09F5DB329FB17B45A5EFDBAFB82FF04BC420DCF7D5" + ], "deposit_authorized": true, "destination_account": "rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8", "ledger_hash": "BD03A10653ED9D77DCA859B7A735BF0580088A8F287FA2C5403E0A19C58EF322", @@ -91,6 +105,10 @@ An example of a successful response: ```json { "result": { + "credentials": [ + "A182EFBD154C9E80195082F86C1C8952FC0760A654B886F61BB0A59803B4387B", + "383D269D6C7417D0A8716B09F5DB329FB17B45A5EFDBAFB82FF04BC420DCF7D5" + ], "deposit_authorized": true, "destination_account": "rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8", "ledger_hash": "BD03A10653ED9D77DCA859B7A735BF0580088A8F287FA2C5403E0A19C58EF322", @@ -110,6 +128,10 @@ Loading: "/etc/rippled.cfg" { "result" : { + "credentials": [ + "A182EFBD154C9E80195082F86C1C8952FC0760A654B886F61BB0A59803B4387B", + "383D269D6C7417D0A8716B09F5DB329FB17B45A5EFDBAFB82FF04BC420DCF7D5" + ], "deposit_authorized" : true, "destination_account" : "rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8", "ledger_hash" : "BD03A10653ED9D77DCA859B7A735BF0580088A8F287FA2C5403E0A19C58EF322", @@ -121,30 +143,34 @@ Loading: "/etc/rippled.cfg" } ``` {% /tab %} - {% /tabs %} The response follows the [standard format][], with a successful result containing the following fields: -| `Field` | Type | Description | -|:-----------------------|:--------------------------|:------------------------| -| `deposit_authorized` | Boolean | Whether the specified source account is authorized to send payments directly to the destination account. If `true`, either the destination account does not require [Deposit Authorization](../../../../concepts/accounts/depositauth.md) or the source account is preauthorized. | -| `destination_account` | String - [Address][] | The destination account specified in the request. | -| `ledger_hash` | String | _(May be omitted)_ The identifying hash of the ledger that was used to generate this response. | -| `ledger_index` | Number - [Ledger Index][] | _(May be omitted)_ The ledger index of the ledger version that was used to generate this response. | -| `ledger_current_index` | Number - [Ledger Index][] | _(May be omitted)_ The ledger index of the current in-progress ledger version, which was used to generate this response. | -| `source_account` | String - [Address][] | The source account specified in the request. | -| `validated` | Boolean | _(May be omitted)_ If `true`, the information comes from a validated ledger version. | - -{% admonition type="info" name="Note" %}A `deposit_authorized` status of `true` does not guarantee that a payment can be sent from the specified source to the specified destination. For example, the destination account may not have a [trust line](../../../../concepts/tokens/fungible-tokens/index.md) for the specified currency, or there may not be enough liquidity to deliver a payment.{% /admonition %} +| Field | Type | Required? | Description | +|:-----------------------|:--------------------------|:----------|:--------------| +| `credentials` | Array of [Hash][] | No | The credentials specified in the request, if any. | +| `deposit_authorized` | Boolean | Yes | Whether the specified source account is authorized to send payments directly to the destination account. If `true`, either the destination account does not require [deposit authorization](https://xrpl.org/docs/concepts/accounts/depositauth) or the source account is preauthorized. | +| `destination_account` | String - [Address][] | Yes | The destination account specified in the request. | +| `ledger_hash` | String | No | The identifying hash of the ledger that was used to generate this response. | +| `ledger_index` | Number - [Ledger Index][] | No | The ledger index of the ledger version that was used to generate this response. | +| `ledger_current_index` | Number - [Ledger Index][] | No | The ledger index of the current in-progress ledger version, which was used to generate this response. | +| `source_account` | String - [Address][] | Yes | The source account specified in the request. | +| `validated` | Boolean | No | If `true`, the information comes from a validated ledger version. | + +{% admonition type="info" name="Note" %} +A `deposit_authorized` status of `true` does not guarantee that a payment can be sent from the specified source to the specified destination. For example, the destination account may not have a [trust line](https://xrpl.org/docs/concepts/tokens/fungible-tokens) for the specified currency, or there may not be enough liquidity to deliver a payment. +{% /admonition %} ## Possible Errors * Any of the [universal error types][]. * `invalidParams` - One or more fields are specified incorrectly, or one or more required fields are missing. * `actMalformed` - An [Address][] specified in the `source_account` or `destination_account` field of the request was not properly formatted. (It may contain a typo or be the wrong length, causing a failed checksum.) +* `badCredentials` - At least one of the supplied credentials does not exist, is expired, or has not been accepted. * `dstActNotFound` - The `destination_account` field of the request does not correspond to an account in the ledger. * `lgrNotFound` - The ledger specified by the `ledger_hash` or `ledger_index` does not exist, or it does exist but the server does not have it. * `srcActNotFound` - The `source_account` field of the request does not correspond to an account in the ledger. + {% raw-partial file="/docs/_snippets/common-links.md" /%} diff --git a/docs/references/protocol/ledger-data/ledger-entry-types/credential.md b/docs/references/protocol/ledger-data/ledger-entry-types/credential.md new file mode 100644 index 00000000000..d400d7941d9 --- /dev/null +++ b/docs/references/protocol/ledger-data/ledger-entry-types/credential.md @@ -0,0 +1,65 @@ +--- +seo: + description: An attestation about a subject account from a credential issuer account, which can be used to preauthorize payments. +--- +# Credential + +A `Credential` entry represents a [credential](../index.md), which contains an attestation about a _subject_ account from a _credential issuer_ account. The meaning of the attestation is defined by the issuer. + +## Example Credential JSON + +```json +{ + "LedgerEntryType": "Credential", + "Flags": 65536, + "Subject": "rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8", + "Issuer": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX", + "IssuerNode": "0000000000000000", + "CredentialType": "6D795F63726564656E7469616C", + "PreviousTxnID": "8089451B193AAD110ACED3D62BE79BB523658545E6EE8B7BB0BE573FED9BCBFB", + "PreviousTxnLgrSeq": 234644, + "SubjectNode": "0000000000000000", + "index": "A738A1E6E8505E1FC77BBB9FEF84FF9A9C609F2739E0F9573CDD6367100A0AA9" +} +``` + + + +## Credential Fields + +In addition to the [common fields](../common-fields.md), {% code-page-name /%} entries have the following fields: + +| Field | JSON Type | [Internal Type][] | Required? | Description | +|:--------------------|:---------------------|:------------------|:----------|:----------------| +| `CredentialType` | String - Hexadecimal | Blob | Yes | Arbitrary data defining the type of credential this entry represents. The minimum length is 1 byte and the maximum length is 64 bytes. | +| `Expiration` | Number | UInt32 | No | Time after which the credential is expired, in [seconds since the Ripple Epoch][]. +| `Issuer` | String - [Address][] | AccountID | Yes | The account that issued this credential. | +| `IssuerNode` | String | UInt64 | Yes | A hint indicating which page of the issuer's directory links to this entry, in case the directory consists of multiple pages. | +| `PreviousTxnID` | String - [Hash][] | Hash256 | Yes | The identifying hash of the transaction that most recently modified this entry. | +| `PreviousTxnLgrSeq` | Number | UInt32 | Yes | The [index of the ledger][Ledger Index] that contains the transaction that most recently modified this object. | +| `Subject` | String - [Address][] | AccountID | Yes | The account that this credential is for. | +| `SubjectNode` | String | UInt64 | Yes | A hint indicating which page of the subject's owner directory links to this entry, in case the directory consists of multiple pages. | +| `URI` | String - Hexadecimal | Blob | No | Arbitrary additional data about the credential, for example a URL where a W3C-formatted Verifiable Credential can be retrieved. | + +## Credential Flags + +Credential entries can have the following flags combined in the `Flags` field: + +| Flag Name | Hex Value | Decimal Value | Description | +|---------------|--------------|---------------|-------------| +| `lsfAccepted` | `0x00010000` | 65536 | If enabled, the subject of the credential has accepted the credential. Otherwise, the issuer created the credential but the subject has not yet accepted it, meaning it is not yet valid. | + +## Credential Reserve + +A credential entry counts as one item towards the owner reserve of the subject account, if the subject has accepted the credential. Otherwise, a credential entry counts as one item toward the reserve of the issuer account. + +## Credential ID Format + +The unique ID of a Credential entry is the SHA-512Half hash of the following values concatenated in order: + +* The `Credential` space key (`0x0044`); +* The `Subject` field's value; +* The `Issuer` field's value; and +* The `CredentialType` field's value. + +{% raw-partial file="/docs/_snippets/common-links.md" /%} diff --git a/docs/references/protocol/ledger-data/ledger-entry-types/depositpreauth.md b/docs/references/protocol/ledger-data/ledger-entry-types/depositpreauth.md index 64377cc73cc..0f6a98191fb 100644 --- a/docs/references/protocol/ledger-data/ledger-entry-types/depositpreauth.md +++ b/docs/references/protocol/ledger-data/ledger-entry-types/depositpreauth.md @@ -9,12 +9,17 @@ labels: # DepositPreauth [[Source]](https://github.com/XRPLF/rippled/blob/master/src/ripple/protocol/impl/LedgerFormats.cpp#L172-L178 "Source") -A `DepositPreauth` entry tracks a preauthorization from one account to another. [DepositPreauth transactions][] create these entries. +A `DepositPreauth` entry tracks a preauthorization from one account. You can always create a preauthorization by sending a [DepositPreauth transaction][], but it has no effect unless you are using [Deposit Authorization](https://xrpl.org/docs/concepts/accounts/depositauth). -This has no effect on processing of transactions unless the account that provided the preauthorization requires [Deposit Authorization](../../../../concepts/accounts/depositauth.md). In that case, the account that was preauthorized can send payments and other transactions directly to the account that provided the preauthorization. Preauthorizations are one-directional, and have no effect on payments going the opposite direction. +A preauthorization allows specific others to send money directly to you even if you have Deposit Authorization enabled. Preauthorizations are one-directional, and have no effect on payments going the opposite direction. + +You can preauthorize a specific _account_ or a _set of credentials_. In the case of a set of credentials, any account that has a matching set of credentials on-ledger can send you money. _(Credential preauthorization requires the [Credentials amendment][]. {% not-enabled /%})_ ## Example {% $frontmatter.seo.title %} JSON +{% tabs %} + +{% tab label="Single account preauthorization" %} ```json { "LedgerEntryType": "DepositPreauth", @@ -27,20 +32,55 @@ This has no effect on processing of transactions unless the account that provide "index": "4A255038CC3ADCC1A9C91509279B59908251728D0DAADB248FFE297D0F7E068C" } ``` +{% /tab %} + +{% tab label="Credential preauthorization" %} +```json +{ + "LedgerEntryType": "DepositPreauth", + "Account": "rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8", + "AuthorizeCredentials": [{ + "Credential": { + "Issuer": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX", + "CredentialType": "6D795F63726564656E7469616C" + } + }], + "Flags": 0, + "OwnerNode": "0000000000000000", + "PreviousTxnID": "FD2A4E9E317C7FEF112D22ADEB9E2C6DC3C2AB6E2AD96A50B76EBB9DEB39EA77", + "PreviousTxnLgrSeq": 7, + "index": "F2B8550ADF60FD268157262C1C54E1D1014BDEA361CE848B6F48556348327E5F" +} +``` +{% /tab %} +{% /tabs %} ## {% $frontmatter.seo.title %} Fields In addition to the [common fields](../common-fields.md), {% code-page-name /%} entries have the following fields: -| Field | JSON Type | [Internal Type][] | Required? | Description | -|:--------------------|:-----------------|:------------------|:----------|:----------------| -| `Account` | String | Account | Yes | The account that granted the preauthorization. (The destination of the preauthorized payments.) | -| `Authorize` | String | Account | Yes | The account that received the preauthorization. (The sender of the preauthorized payments.) | -| `LedgerEntryType` | String | UInt16 | Yes | The value `0x0070`, mapped to the string `DepositPreauth`, indicates that this is a DepositPreauth object. | -| `OwnerNode` | String | UInt64 | Yes | A hint indicating which page of the sender's owner directory links to this object, in case the directory consists of multiple pages. **Note:** The object does not contain a direct link to the owner directory containing it, since that value can be derived from the `Account`. | -| `PreviousTxnID` | String | Hash256 | Yes | The identifying hash of the transaction that most recently modified this object. | -| `PreviousTxnLgrSeq` | Number | UInt32 | Yes | The [index of the ledger][Ledger Index] that contains the transaction that most recently modified this object. | +| Field | JSON Type | [Internal Type][] | Required? | Description | +|:--------------------|:------------------|:------------------|:----------|:------------| +| `Account` | String | Account | Yes | The account that granted the preauthorization. (The destination of the preauthorized payments.) | +| `Authorize` | String | Account | No | The account that received the preauthorization. (The sender of the preauthorized payments.) | +| `AuthorizeCredentials` | Array | Array | No | The set of credentials that received preauthorization. (Any account with these credentials is preauthorized.) This array has a minimum length of 1 and a maximum length of 8 credentials. | +| `LedgerEntryType` | String | UInt16 | Yes | The value `0x0070`, mapped to the string `DepositPreauth`, indicates that this is a DepositPreauth object. | +| `OwnerNode` | String | UInt64 | Yes | A hint indicating which page of the sender's owner directory links to this object, in case the directory consists of multiple pages. **Note:** The object does not contain a direct link to the owner directory containing it, since that value can be derived from the `Account`. | +| `PreviousTxnID` | String - [Hash][] | Hash256 | Yes | The identifying hash of the transaction that most recently modified this object. | +| `PreviousTxnLgrSeq` | Number | UInt32 | Yes | The [index of the ledger][Ledger Index] that contains the transaction that most recently modified this object. | + +Each entry must have _either_ the `Authorize` field or the `AuthorizeCredentials` field, but not both. + +### Authorized Credential Objects +If the entry has an `AuthorizeCredentials` field, each member of that array is an inner object, identifying one credential to require, with the following format: + +| Field | JSON Type | [Internal Type][] | Required? | Description | +|:-----------------|:---------------------|:------------------|:----------|:----------------| +| `Issuer` | String - [Address][] | AccountID | Yes | The issuer of the credential. | +| `CredentialType` | String - Hexadecimal | Blob | Yes | The credential type of the credential. | + +To be preauthorized, an account must hold all the specified credentials. ## {% $frontmatter.seo.title %} Flags @@ -52,10 +92,23 @@ There are no flags defined for {% code-page-name /%} entries. ## DepositPreauth ID Format -The ID of a `DepositPreauth` object is the [SHA-512Half][] of the following values, concatenated in order: +There are two formats for the ID of a `DepositPreauth` entry, depending on whether it authorizes an individual account or a set of credentials. + +### Individual Account Preauthorization + +In this case, the ID is the [SHA-512Half][] of the following values, concatenated in order: * The DepositPreauth space key (`0x0070`) * The AccountID of the owner of this object (the sender of the [DepositPreauth transaction][] that created this object; in other words, the one that granted the preauthorization) -* The AccountID of the preauthorized account (the `Authorized` field of the [DepositPreauth transaction][] that created this object; in other words, the one that received the preauthorization) +* The AccountID in the `Authorize` field + +### Credential Preauthorization +_(Requires the [Credentials amendment][]. {% not-enabled /%})_ + +In this case, the ID is the [SHA-512Half][] of the following values, concatenated in order: + +* The Credential Preauth space key (`0x0050`) +* The AccountID of the owner of this object (the sender of the [DepositPreauth transaction][] that created this object; in other words, the one that granted the preauthorization) +* The contents of the `AuthorizeCredentials` field. {% raw-partial file="/docs/_snippets/common-links.md" /%} diff --git a/docs/references/protocol/transactions/types/accountdelete.md b/docs/references/protocol/transactions/types/accountdelete.md index d5d16f4c50c..792a88adff6 100644 --- a/docs/references/protocol/transactions/types/accountdelete.md +++ b/docs/references/protocol/transactions/types/accountdelete.md @@ -31,12 +31,12 @@ An AccountDelete transaction deletes an [account](../../ledger-data/ledger-entry [Query example transaction. >](/resources/dev-tools/websocket-api-tool?server=wss%3A%2F%2Fxrplcluster.com%2F&req=%7B%22id%22%3A%22example_AccountDelete%22%2C%22command%22%3A%22tx%22%2C%22transaction%22%3A%221AF19BF9717DA0B05A3BFC5007873E7743BA54C0311CCCCC60776AAEAC5C4635%22%2C%22binary%22%3Afalse%7D) {% raw-partial file="/docs/_snippets/tx-fields-intro.md" /%} - -| Field | JSON Type | [Internal Type][] | Description | -|:-----------------|:-----------------|:------------------|:-------------------| -| `Destination` | String - [Address][] | AccountID | The address of an account to receive any leftover XRP after deleting the sending account. Must be a funded account in the ledger, and must not be the sending account. | -| `DestinationTag` | Number | UInt32 | _(Optional)_ Arbitrary [destination tag](../../../../concepts/transactions/source-and-destination-tags.md) that identifies a hosted recipient or other information for the recipient of the deleted account's leftover XRP. | +| Field | JSON Type | [Internal Type][] | Required? | Description | +|:-----------------|:-----------------|:------------------|:----------|:------------| +| `CredentialIDs` | Array of Strings | Vector256 | No | Set of Credentials to authorize a deposit made by this transaction. Each member of the array must be the ledger entry ID of a Credential entry in the ledger. For details, see [Credential IDs](./payment.md#credential-ids). | +| `Destination` | String - [Address][] | AccountID | Yes | The address of an account to receive any leftover XRP after deleting the sending account. Must be a funded account in the ledger, and must not be the sending account. | +| `DestinationTag` | Number | UInt32 | No | Arbitrary [destination tag](../../../../concepts/transactions/source-and-destination-tags.md) that identifies a hosted recipient or other information for the recipient of the deleted account's leftover XRP. | ## Special Transaction Cost diff --git a/docs/references/protocol/transactions/types/credentialaccept.md b/docs/references/protocol/transactions/types/credentialaccept.md new file mode 100644 index 00000000000..7ca9435cdbf --- /dev/null +++ b/docs/references/protocol/transactions/types/credentialaccept.md @@ -0,0 +1,48 @@ +--- +seo: + description: Accept a credential provisionally issued to your account. +--- +# CredentialAccept Transaction + +A CredentialAccept transaction accepts a credential, which makes the credential valid. Only the subject of the credential can do this. + +## Example CredentialAccept JSON + +```json +{ + "TransactionType" : "CredentialAccept", + "Account": "rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8", + "Issuer": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX", + "CredentialType": "6D795F63726564656E7469616C", + "Fee": "10", + "Flags": 0, + "Sequence": 234203 +} +``` + + +## CredentialAccept Fields + +In addition to the [common fields][], CredentialAccept transactions use the following fields: + +| Field | JSON Type | [Internal Type][] | Required? | Description | +|:-----------------|:-----------------|:------------------|:----------|:------------| +| `Issuer` | String - [Address][] | AccountID | Yes | The address of the issuer that created the credential. | +| `CredentialType` | String | Blob | Yes | Arbitrary data defining the type of credential. The minimum size is 1 byte and the maximum is 64 bytes. | + +The `Account` field (the sender of this transaction) must be the subject of the credential. + +The combination of `Account`, `Issuer`, and `CredentialType` must match a `Credential` ledger entry that exists in the ledger and has not already been accepted; otherwise, the transaction fails. + +## Error Cases + +| Error Code | Description | +|:-----------|:------------| +| `tecDUPLICATE` | The specified credential has already been accepted. | +| `tecEXPIRED` | The specified credential has an expiration time in the past. (In this case, the transaction also deletes the expired credentials from the ledger.) | +| `tecNO_ENTRY` | The credential uniquely identified by the `Account`, `Issuer`, and `CredentialType` fields of the transaction does not exist in the ledger. | +| `temDISABLED` | The related amendment is not enabled. | +| `temINVALID_ACCOUNT_ID` | The provided `Issuer` field is invalid. For example, it contains [ACCOUNT_ZERO][]. | + + +{% raw-partial file="/docs/_snippets/common-links.md" /%} diff --git a/docs/references/protocol/transactions/types/credentialcreate.md b/docs/references/protocol/transactions/types/credentialcreate.md new file mode 100644 index 00000000000..90f5b6216bf --- /dev/null +++ b/docs/references/protocol/transactions/types/credentialcreate.md @@ -0,0 +1,51 @@ +--- +seo: + description: Provisionally issue a credential to a subject account. +--- + +# CredentialCreate Transaction + +A CredentialCreate transaction creates a credential in the ledger. The issuer of the credential uses this transaction to provisionally issue a credential. The credential is not valid until the subject of the credential accepts it with a [CredentialAccept transaction][]. + +## Example CredentialCreate JSON + +```json +{ + "TransactionType" : "CredentialCreate", + "Account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX", + "Subject": "rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8", + "CredentialType": "6D795F63726564656E7469616C", + "Fee": "10", + "Flags": 0, + "Sequence": 234200 +} +``` + + +## CredentialCreate Fields + +In addition to the [common fields][], CredentialCreate transactions use the following fields: + +| Field | JSON Type | [Internal Type][] | Required? | Description | +|:-----------------|:-----------------|:------------------|:----------|:------------| +| `Subject` | String - [Address][] | AccountID | Yes | The subject of the credential. | +| `CredentialType` | String - Hexadecimal | Blob | Yes | Arbitrary data defining the type of credential this entry represents. The minimum length is 1 byte and the maximum length is 64 bytes. | +| `Expiration` | Number | UInt32 | No | Time after which this credential should be considered expired, in [seconds since the Ripple Epoch][]. | +| `URI` | String | Blob | No | Arbitrary additional data about the credential, such as the URL where users can look up an associated Verifiable Credential document. If present, the minimum length is 1 byte and the maximum is 256 bytes. | + +The `Account` field (the sender) of the transaction is the issuer of the credential. It is possible for the issuer and the subject to be the same account. + +## Error Cases + +Besides errors that can occur for all transactions, CredentialCreate transactions can result in the following [transaction result codes][]: + +| Error Code | Description | +|:-----------|:------------| +| `tecDUPLICATE` | A credential with the same subject, issuer, and credential type already exists in the ledger. | +| `tecEXPIRED` | The credential's expiration time is in the past. | +| `tecNO_TARGET` | The account specified in the `Subject` field is not a funded account in the ledger. | +| `temDISABLED` | The related amendment is not enabled. | +| `temINVALID_ACCOUNT_ID` | The provided `Subject` field is invalid. For example, it contains [ACCOUNT_ZERO][]. | + + +{% raw-partial file="/docs/_snippets/common-links.md" /%} diff --git a/docs/references/protocol/transactions/types/credentialdelete.md b/docs/references/protocol/transactions/types/credentialdelete.md new file mode 100644 index 00000000000..923516bd608 --- /dev/null +++ b/docs/references/protocol/transactions/types/credentialdelete.md @@ -0,0 +1,49 @@ +--- +seo: + description: Remove a credential from the ledger, effectively revoking it. +--- +# CredentialDelete Transaction + +A CredentialDelete transaction removes a credential from the ledger, effectively revoking it. Users may also want to delete an unwanted credential to reduce their [reserve requirement][]. + +## Example CredentialDelete JSON + +```json +{ + "TransactionType" : "CredentialDelete", + "Account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX", + "Subject": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", + "CredentialType": "6D795F63726564656E7469616C", + "Fee": "10", + "Flags": 0, + "Sequence": 234203 +} +``` + + +## CredentialDelete Fields + +In addition to the [common fields][], CredentialDelete transactions use the following fields: + +| Field | JSON Type | [Internal Type][] | Required? | Description | +|:-----------------|:-----------------|:------------------|:----------|:------------| +| `CredentialType` | String - Hexadecimal | Blob | Yes | Arbitrary data defining the type of credential to delete. The minimum length is 1 byte and the maximum length is 256 bytes. | +| `Subject` | String - [Address][] | AccountID | No | The subject of the credential to delete. If omitted, use the `Account` (sender of the transaction) as the subject of the credential. | +| `Issuer` | String - [Address][] | AccountID | No | The issuer of the credential to delete. If omitted, use the `Account` (sender of the transaction) as the issuer of the credential. | + +You must provide the `Subject` field, `Issuer` field, or both. + +This transaction looks for a [Credential ledger entry](../../ledger-data/ledger-entry-types/credential.md) with the specified subject, issuer, and credential type, and deletes that entry if the sender of the transaction has permission to. The holder or issuer of a credential can delete it at any time. If the credential is expired, anyone can delete it. + + +## Error Cases + +| Error Code | Description | +|:-----------|:------------| +| `temDISABLED` | The related amendment is not enabled. | +| `temINVALID_ACCOUNT_ID` | A provided `Subject` or `Issuer` field is invalid. For example, it contains [ACCOUNT_ZERO][]. | +| `tecNO_PERMISSION` | The sender is neither the issuer nor subject of the credential, and the credential is not expired. | +| `tecNO_ENTRY` | The specified credential does not exist in the ledger. | + + +{% raw-partial file="/docs/_snippets/common-links.md" /%} diff --git a/docs/references/protocol/transactions/types/depositpreauth.md b/docs/references/protocol/transactions/types/depositpreauth.md index ec231aa8ca9..da0f71b1768 100644 --- a/docs/references/protocol/transactions/types/depositpreauth.md +++ b/docs/references/protocol/transactions/types/depositpreauth.md @@ -11,12 +11,15 @@ labels: _Added by the [DepositPreauth amendment][]._ -A DepositPreauth transaction gives another account pre-approval to deliver payments to the sender of this transaction. This is only useful if the sender of this transaction is using (or plans to use) [Deposit Authorization](../../../../concepts/accounts/depositauth.md). +A DepositPreauth transaction grants preauthorization to deliver payments to your account. This is only useful if you are using (or plan to use) [Deposit Authorization](../../../../concepts/accounts/depositauth.md). -{% admonition type="success" name="Tip" %}You can use this transaction to preauthorize certain counterparties before you enable Deposit Authorization. This may be useful to ensure a smooth transition from not requiring deposit authorization to requiring it.{% /admonition %} +{% admonition type="success" name="Tip" %}You can use this transaction before you enable Deposit Authorization. This may be useful to ensure a smooth transition from not requiring deposit authorization to requiring it.{% /admonition %} ## Example {% $frontmatter.seo.title %} JSON +{% tabs %} + +{% tab label="Single account preauthorization" %} ```json { "TransactionType" : "DepositPreauth", @@ -27,26 +30,65 @@ A DepositPreauth transaction gives another account pre-approval to deliver payme "Sequence" : 2 } ``` +{% /tab %} + +{% tab label="Credential preauthorization" %} +```json +{ + "TransactionType" : "DepositPreauth", + "Account" : "rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8", + "AuthorizeCredentials": [{ + "Credential": { + "Issuer": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX", + "CredentialType": "6D795F63726564656E7469616C" + } + }], + "Fee" : "10", + "Flags": 0, + "Sequence": 230984 +} +``` +{% /tab %} +{% /tabs %} [Query example transaction. >](/resources/dev-tools/websocket-api-tool?server=wss%3A%2F%2Fxrplcluster.com%2F&req=%7B%22id%22%3A%22example_DepositPreauth%22%2C%22command%22%3A%22tx%22%2C%22transaction%22%3A%22CB1BF910C93D050254C049E9003DA1A265C107E0C8DE4A7CFF55FADFD39D5656%22%2C%22binary%22%3Afalse%7D) {% raw-partial file="/docs/_snippets/tx-fields-intro.md" /%} - +| Field | JSON Type | [Internal Type][] | Required? | Description | +|:-------------------------|:---------------------|:------------------|:----------|:------------| +| `Authorize` | String - [Address][] | AccountID | No | An account to preauthorize. | +| `AuthorizeCredentials` | Array | STArray | No | A set of credentials to authorize. _(Requires the [Credentials amendment][]. {% not-enabled /%})_ | +| `Unauthorize` | String | AccountID | No | An account whose preauthorization should be revoked. | +| `UnauthorizeCredentials` | Array | STArray | No | A set of credentials whose preauthorization should be revoked. _(Requires the [Credentials amendment][]. {% not-enabled /%})_ | + +You must provide **exactly one** of `Authorize`, `AuthorizeCredentials`, `Unauthorize`, or `UnauthorizeCredentials`. + +If this transaction is successful, it creates or removes a [DepositPreauth entry](../../ledger-data/ledger-entry-types/depositpreauth.md) in the ledger, based on the field provided. + + +### AuthorizeCredentials Objects + +If provided, each member of the `AuthorizeCredentials` field or `UnauthorizeCredentials` field must be an inner object with the following fields: + +| Field | JSON Type | [Internal Type][] | Required? | Description | +|:-----------------|:---------------------|:------------------|:----------|:------------| +| `Issuer` | String - [Address][] | AccountID | Yes | The issuer of the credential. | +| `CredentialType` | String - Hexadecimal | Blob | Yes | The credential type of the credential. | -| Field | JSON Type | [Internal Type][] | Description | -|:--------------|:----------|:------------------|:-----| -| `Authorize` | String | AccountID | _(Optional)_ The XRP Ledger address of the sender to preauthorize. | -| `Unauthorize` | String | AccountID | _(Optional)_ The XRP Ledger address of a sender whose preauthorization should be revoked. | +## Error Cases -You must provide _either_ `Authorize` or `Unauthorize`, but not both. +In addition to error types that can occur for all transactions, DepositPreauth transactions can result in the following error codes: -This transaction has the following limitations: +| Error Code | Description | +|:--------------------------|:------------| +| `tecDUPLICATE` | The transaction would create a preauthorization that already exists. | +| `tecINSUFFICIENT_RESERVE` | The sender would not meet the [reserve requirement][] after adding another entry to the ledger. (A DepositPreauth entry counts as one item towards the authorizer's owner reserve.) | +| `tecNO_ENTRY` | The transaction tried to revoke a preauthorization that does not exist in the ledger. | +| `tecNO_ISSUER` | One or more specified credential issuers does not exist in the ledger. | +| `tecNO_TARGET` | The transaction tried to authorize an account that is not a funded account in the ledger. | +| `temCANNOT_PREAUTH_SELF` | The address in the `Authorize` field is the sender of the transaction. You cannot preauthorize yourself. | +| `temDISABLED` | A required amendment is not enabled. | -- An account cannot preauthorize (or unauthorize) its own address. Attempting to do so fails with the result [`temCANNOT_PREAUTH_SELF`](../transaction-results/tem-codes.md). -- Attempting to preauthorize an account which is already preauthorized fails with the result [`tecDUPLICATE`](../transaction-results/tec-codes.md). -- Attempting to unauthorize an account which is not preauthorized fails with the result [`tecNO_ENTRY`](../transaction-results/tec-codes.md). -- Attempting to preauthorize an address that is not funded in the ledger fails with the result [`tecNO_TARGET`](../transaction-results/tec-codes.md). -- Adding authorization adds a [DepositPreauth object](../../ledger-data/ledger-entry-types/depositpreauth.md) to the ledger, which counts toward the [owner reserve requirement](../../../../concepts/accounts/reserves.md#owner-reserves). If the sender of the transaction does not have enough XRP to pay for the increased reserve, the transaction fails with the result [`tecINSUFFICIENT_RESERVE`](../transaction-results/tec-codes.md). If the sender of the account is already at the maximum number of owned objects, the transaction fails with the result [`tecDIR_FULL`](../transaction-results/tec-codes.md). {% raw-partial file="/docs/_snippets/common-links.md" /%} diff --git a/docs/references/protocol/transactions/types/escrowfinish.md b/docs/references/protocol/transactions/types/escrowfinish.md index d57a99286ba..7a38de7cc7a 100644 --- a/docs/references/protocol/transactions/types/escrowfinish.md +++ b/docs/references/protocol/transactions/types/escrowfinish.md @@ -10,9 +10,10 @@ labels: [[Source]](https://github.com/XRPLF/rippled/blob/master/src/ripple/app/tx/impl/Escrow.cpp "Source") +Deliver XRP from an escrow (held payment) to the recipient. + _Added by the [Escrow amendment][]._ -Deliver XRP from a held payment to the recipient. ## Example {% $frontmatter.seo.title %} JSON @@ -30,21 +31,20 @@ Deliver XRP from a held payment to the recipient. [Query example transaction. >](/resources/dev-tools/websocket-api-tool?server=wss%3A%2F%2Fxrplcluster.com%2F&req=%7B%22id%22%3A%22example_EscrowFinish%22%2C%22command%22%3A%22tx%22%2C%22transaction%22%3A%22317081AF188CDD4DBE55C418F41A90EC3B959CDB3B76105E0CBE6B7A0F56C5F7%22%2C%22binary%22%3Afalse%7D) {% raw-partial file="/docs/_snippets/tx-fields-intro.md" /%} - - -| Field | JSON Type | [Internal Type][] | Description | -|:----------------|:-----------------|:------------------|:--------------------| -| `Owner` | String | AccountID | Address of the source account that funded the held payment. | -| `OfferSequence` | Unsigned Integer | UInt32 | Transaction sequence of [EscrowCreate transaction][] that created the held payment to finish. | -| `Condition` | String | Blob | _(Optional)_ Hex value matching the previously-supplied [PREIMAGE-SHA-256 crypto-condition](https://tools.ietf.org/html/draft-thomas-crypto-conditions-02#section-8.1) of the held payment. | -| `Fulfillment` | String | Blob | _(Optional)_ Hex value of the [PREIMAGE-SHA-256 crypto-condition fulfillment](https://tools.ietf.org/html/draft-thomas-crypto-conditions-02#section-8.1.4) matching the held payment's `Condition`. | +| Field | JSON Type | [Internal Type][] | Required? | Description | +|:----------------|:----------|:------------------|:----------|:------------| +| `Owner` | String | AccountID | Yes | Address of the source account that funded the escrow. | +| `OfferSequence` | Number | UInt32 | Yes | Transaction sequence of [EscrowCreate transaction][] that created the escrow to finish. | +| `Condition` | String | Blob | No | Hex value matching the previously-supplied [PREIMAGE-SHA-256 crypto-condition](https://tools.ietf.org/html/draft-thomas-crypto-conditions-02#section-8.1) of the escrow. | +| `CredentialIDs` | Array of Strings | Vector256 | No | Set of Credentials to authorize a deposit made by this transaction. Each member of the array must be the ledger entry ID of a Credential entry in the ledger. For details, see [Credential IDs](./payment.md#credential-ids). | +| `Fulfillment` | String | Blob | No | Hex value of the [PREIMAGE-SHA-256 crypto-condition fulfillment](https://tools.ietf.org/html/draft-thomas-crypto-conditions-02#section-8.1.4) matching the escrow's `Condition`. | Any account may submit an EscrowFinish transaction. -- If the held payment has a `FinishAfter` time, you cannot execute it before this time. Specifically, if the corresponding [EscrowCreate transaction][] specified a `FinishAfter` time that is after the close time of the most recently-closed ledger, the EscrowFinish transaction fails. -- If the held payment has a `Condition`, you cannot execute it unless you provide a matching `Fulfillment` for the condition. -- You cannot execute a held payment after it has expired. Specifically, if the corresponding [EscrowCreate transaction][] specified a `CancelAfter` time that is before the close time of the most recently-closed ledger, the EscrowFinish transaction fails. +- If the escrow has a `FinishAfter` time, you cannot execute it before this time. Specifically, if the corresponding [EscrowCreate transaction][] specified a `FinishAfter` time that is after the close time of the most recently-closed ledger, the EscrowFinish transaction fails. +- If the escrow has a `Condition`, you cannot execute it unless you provide a matching `Fulfillment` for the condition. +- You cannot execute an escrow after it has expired. Specifically, if the corresponding [EscrowCreate transaction][] specified a `CancelAfter` time that is before the close time of the most recently-closed ledger, the EscrowFinish transaction fails. {% admonition type="info" name="Note" %}The minimum [transaction cost](../../../../concepts/transactions/transaction-cost.md) to submit an EscrowFinish transaction increases if it contains a fulfillment. If the transaction has no fulfillment, the transaction cost is the standard 10 drops. If the transaction contains a fulfillment, the transaction cost is 330 [drops of XRP][] plus another 10 drops for every 16 bytes in size of the preimage.{% /admonition %} diff --git a/docs/references/protocol/transactions/types/payment.md b/docs/references/protocol/transactions/types/payment.md index 28f5811244a..990de8f8f71 100644 --- a/docs/references/protocol/transactions/types/payment.md +++ b/docs/references/protocol/transactions/types/payment.md @@ -37,19 +37,21 @@ Payments are also the only way to [create accounts](#creating-accounts). [Query example transaction. >](/resources/dev-tools/websocket-api-tool?server=wss%3A%2F%2Fxrplcluster.com%2F&req=%7B%22id%22%3A%22example_Payment%22%2C%22command%22%3A%22tx%22%2C%22transaction%22%3A%227BF105CFE4EFE78ADB63FE4E03A851440551FE189FD4B51CAAD9279C9F534F0E%22%2C%22binary%22%3Afalse%7D) {% raw-partial file="/docs/_snippets/tx-fields-intro.md" /%} - -| Field | JSON Type | [Internal Type][] | Description | -|:-----------------|:---------------------|:------------------|:---------------| -| `Amount` | [Currency Amount][] | Amount | Alias to `DeliverMax`. | -| `DeliverMax` | [Currency Amount][] | Amount | [API v2][]: The maximum amount of currency to deliver. For non-XRP amounts, the nested field names MUST be lower-case. If the [`tfPartialPayment` flag](#payment-flags) is set, deliver _up to_ this amount instead. {% badge href="https://github.com/XRPLF/rippled/releases/tag/2.0.0" %}New in: rippled 2.0.0{% /badge %} | -| `DeliverMin` | [Currency Amount][] | Amount | _(Optional)_ Minimum amount of destination currency this transaction should deliver. Only valid if this is a [partial payment](../../../../concepts/payment-types/partial-payments.md). For non-XRP amounts, the nested field names are lower-case. | -| `Destination` | String | AccountID | The unique address of the account receiving the payment. | -| `DestinationTag` | Number | UInt32 | _(Optional)_ Arbitrary tag that identifies the reason for the payment to the destination, or a hosted recipient to pay. | -| `InvoiceID` | String | Hash256 | _(Optional)_ Arbitrary 256-bit hash representing a specific reason or identifier for this payment. | -| `Paths` | Array of path arrays | PathSet | (Optional, auto-fillable) Array of [payment paths](../../../../concepts/tokens/fungible-tokens/paths.md) to be used for this transaction. Must be omitted for XRP-to-XRP transactions. | -| `SendMax` | [Currency Amount][] | Amount | _(Optional)_ Highest amount of source currency this transaction is allowed to cost, including [transfer fees](../../../../concepts/tokens/transfer-fees.md), exchange rates, and [slippage](http://en.wikipedia.org/wiki/Slippage_%28finance%29). Does not include the [XRP destroyed as a cost for submitting the transaction](../../../../concepts/transactions/transaction-cost.md). For non-XRP amounts, the nested field names MUST be lower-case. Must be supplied for cross-currency/cross-issue payments. Must be omitted for XRP-to-XRP payments. | +| Field | JSON Type | [Internal Type][] | Required? | Description | +|:-----------------|:---------------------|:------------------|:----------|:------------| +| `Amount` | [Currency Amount][] | Amount | API v1: Yes | Alias to `DeliverMax`. | +| `CredentialIDs` | Array of Strings | Vector256 | No | Set of Credentials to authorize a deposit made by this transaction. Each member of the array must be the ledger entry ID of a Credential entry in the ledger. _(Requires the [Credentials amendment][]._ {% not-enabled /%})_ | +| `DeliverMax` | [Currency Amount][] | Amount | Yes | [API v2][]: The maximum amount of currency to deliver. [Partial payments](#partial-payments) can deliver less than this amount and still succeed; other payments fail unless they deliver the exact amount. {% badge href="https://github.com/XRPLF/rippled/releases/tag/2.0.0" %}New in: rippled 2.0.0{% /badge %} | +| `DeliverMin` | [Currency Amount][] | Amount | No | Minimum amount of destination currency this transaction should deliver. Only valid if this is a [partial payment](../../../../concepts/payment-types/partial-payments.md). For non-XRP amounts, the nested field names are lower-case. | +| `Destination` | String | AccountID | Yes | The unique address of the account receiving the payment. | +| `DestinationTag` | Number | UInt32 | No | Arbitrary tag that identifies the reason for the payment to the destination, or a hosted recipient to pay. | +| `InvoiceID` | String | Hash256 | No | Arbitrary 256-bit hash representing a specific reason or identifier for this payment. | +| `Paths` | Array of path arrays | PathSet | No | _(Auto-fillable)_ Array of [payment paths](../../../../concepts/tokens/fungible-tokens/paths.md) to be used for this transaction. Must be omitted for XRP-to-XRP transactions. | +| `SendMax` | [Currency Amount][] | Amount | No | Highest amount of source currency this transaction is allowed to cost, including [transfer fees](../../../../concepts/tokens/transfer-fees.md), exchange rates, and [slippage](http://en.wikipedia.org/wiki/Slippage_%28finance%29). Does not include the [XRP destroyed as a cost for submitting the transaction](../../../../concepts/transactions/transaction-cost.md). Must be supplied for cross-currency/cross-issue payments. Must be omitted for XRP-to-XRP payments. | + +When specifying a transaction, you must specify either `Amount` or `DeliverMax`, but not both. When displaying transactions in JSON, API v1 always uses `Amount` and API v2 (or later) always uses `DeliverMax`. ## Types of Payments @@ -84,7 +86,7 @@ Most of the time, the `issuer` field of a non-XRP [Currency Amount][] indicates The Payment transaction type can create new accounts in the XRP Ledger by sending enough XRP to an unfunded address. Other transactions to unfunded addresses always fail. -For more information, see [Accounts](../../../../concepts/accounts/index.md#creating-accounts). +For more information, see [Creating Accounts](../../../../concepts/accounts/index.md#creating-accounts). ## Paths @@ -113,7 +115,7 @@ Transactions of the Payment type support additional values in the [`Flags` field ## Partial Payments -A partial payment allows a payment to succeed by reducing the amount received. Partial payments are useful for [returning payments](../../../../concepts/payment-types/bouncing-payments.md) without incurring additional costs to oneself. However, partial payments can also be used to exploit integrations that naively assume the `Amount` field of a successful transaction always describes the exact amount delivered. +A partial payment allows a payment to succeed by reducing the amount received. Partial payments are useful for [returning payments](../../../../concepts/payment-types/bouncing-payments.md) without incurring additional costs to oneself. However, partial payments can also be used to exploit integrations that naively assume the `Amount` field of a successful transaction always describes the exact amount delivered. To reduce confusion, `Amount` has been renamed to `DeliverMax` in API v2 and later. A partial payment is any [Payment transaction][] with the `tfPartialPayment` flag enabled. A partial payment can be successful if it delivers any positive amount greater than or equal to its `DeliverMin` field (or any positive amount at all if `DeliverMin` is not specified) without sending more than the `SendMax` value. @@ -138,4 +140,21 @@ The `tfLimitQuality` flag is most useful when combined with [partial payments](. In the above example with a ¥95/$15 offer and a ¥5/$2 offer, the situation is different if my transaction has both `tfPartialPayment` and `tfLimitQuality` enabled. If we keep my `SendMax` of 20 USD and a destination `Amount` of 100 CNY, then the limit quality is still `5`. However, because I am doing a partial payment, the transaction sends as much as it can instead of failing if the full destination amount cannot be sent. This means that my transaction consumes the ¥95/$15 offer, whose quality is about `6.3`, but it rejects the ¥5/$2 offer because that offer's quality of `2.5` is worse than the quality limit of `5`. In the end, my transaction only delivers ¥95 instead of the full ¥100, but it avoids wasting money on poor exchange rates. +## Credential IDs + +You can send money to an account that uses [Deposit Authorization](../../../../concepts/accounts/depositauth.md) by providing the `CredentialIDs` field with an exact set of credentials that are preauthorized by the recipient. The set of credentials must match a [DepositPreauth entry](../../ledger-data/ledger-entry-types/depositpreauth.md) in the ledger. + +The credentials provided in the `CredentialIDs` field must all be valid, meaning: + +- The provided credentials must exist. +- The provided credentials must have been accepted by the subject. +- None of the provided credentials may be expired. +- The sender of this transaction must be the subject of each of the credentials. + +If you provide credentials even though the destination account does not use Deposit Authorization, the credentials are not needed but they are still checked for validity. + +### Special Case for Destination Accounts Below the Reserve + +If an account has Deposit Authorization enabled, but its current XRP balance is less than the [reserve requirement](../../../../concepts/accounts/reserves.md), there is a special exception to Deposit Authorization where anyone can send a Payment transaction, without preauthorization, for up to the base account reserve; this exists as an emergency measure to prevent an account from getting "stuck" without enough XRP to transact. To qualify for this special case, the payment MUST NOT use the `CredentialIDs` field. + {% raw-partial file="/docs/_snippets/common-links.md" /%} diff --git a/docs/references/protocol/transactions/types/paymentchannelclaim.md b/docs/references/protocol/transactions/types/paymentchannelclaim.md index b3926b9b55a..39cbc819ab4 100644 --- a/docs/references/protocol/transactions/types/paymentchannelclaim.md +++ b/docs/references/protocol/transactions/types/paymentchannelclaim.md @@ -46,18 +46,18 @@ The **destination address** of a channel can: {% raw-partial file="/docs/_snippets/tx-fields-intro.md" /%} - -| Field | JSON Type | [Internal Type][] | Description | -|:------------|:----------|:------------------|:-------------------------------| -| `Channel` | String | Hash256 | The unique ID of the channel, as a 64-character hexadecimal string. | -| `Balance` | String | Amount | _(Optional)_ Total amount of [XRP, in drops][Currency Amount], delivered by this channel after processing this claim. Required to deliver XRP. Must be more than the total amount delivered by the channel so far, but not greater than the `Amount` of the signed claim. Must be provided except when closing the channel. | -| `Amount` | String | Amount | _(Optional)_ The amount of [XRP, in drops][Currency Amount], authorized by the `Signature`. This must match the amount in the signed message. This is the cumulative amount of XRP that can be dispensed by the channel, including XRP previously redeemed. | -| `Signature` | String | Blob | _(Optional)_ The signature of this claim, as hexadecimal. The signed message contains the channel ID and the amount of the claim. Required unless the sender of the transaction is the source address of the channel. | -| `PublicKey` | String | Blob | _(Optional)_ The public key used for the signature, as hexadecimal. This must match the `PublicKey` stored in the ledger for the channel. Required unless the sender of the transaction is the source address of the channel and the `Signature` field is omitted. (The transaction includes the public key so that `rippled` can check the validity of the signature before trying to apply the transaction to the ledger.) | +| Field | JSON Type | [Internal Type][] | Required? | Description | +|:------------|:----------|:------------------|:----------|:------------| +| `Amount` | String | Amount | No | The amount of [XRP, in drops][Currency Amount], authorized by the `Signature`. This must match the amount in the signed message. This is the cumulative amount of XRP that can be dispensed by the channel, including XRP previously redeemed. | +| `Balance` | String | Amount | No | Total amount of [XRP, in drops][Currency Amount], delivered by this channel after processing this claim. Required to deliver XRP. Must be more than the total amount delivered by the channel so far, but not greater than the `Amount` of the signed claim. Must be provided except when closing the channel. | +| `Channel` | String | Hash256 | Yes | The unique ID of the channel, as a 64-character hexadecimal string. | +| `CredentialIDs` | Array of Strings | Vector256 | No | Set of Credentials to authorize a deposit made by this transaction. Each member of the array must be the ledger entry ID of a Credential entry in the ledger. For details, see [Credential IDs](./payment.md#credential-ids). | +| `PublicKey` | String | Blob | No | The public key used for the signature, as hexadecimal. This must match the `PublicKey` stored in the ledger for the channel. Required unless the sender of the transaction is the source address of the channel and the `Signature` field is omitted. (The transaction includes the public key so that `rippled` can check the validity of the signature before trying to apply the transaction to the ledger.) | +| `Signature` | String | Blob | No | The signature of this claim, as hexadecimal. The signed message contains the channel ID and the amount of the claim. Required unless the sender of the transaction is the source address of the channel. | -If the payment channel was created before the [fixPayChanRecipientOwnerDir amendment](/resources/known-amendments.md#fixpaychanrecipientownerdir) became enabled (on 2020-05-01), it is possible that the destination of the payment channel has been [deleted](../../../../concepts/accounts/deleting-accounts.md) and does not currently exist in the ledger. If the destination has been deleted, the source account cannot send XRP from the channel to the destination; instead, the transaction fails with `tecNO_DST`. (And, of course, the deleted account cannot send any transactions at all.) Other uses of this transaction type are unaffected when the destination account has been deleted, including adjusting the channel expiration, closing a channel with no XRP, or removing a channel that has passed its expiration time. +If the payment channel was created before the [fixPayChanRecipientOwnerDir amendment](/resources/known-amendments.md#fixpaychanrecipientownerdir) became enabled (on 2020-05-01), it is possible that the destination account has been [deleted](../../../../concepts/accounts/deleting-accounts.md) and does not currently exist in the ledger. If the destination has been deleted, the source account cannot send XRP from the channel to the destination; instead, the transaction fails with `tecNO_DST`. Other uses of this transaction type are unaffected when the destination account has been deleted, including adjusting the channel expiration, closing a channel with no XRP, or removing a channel that has passed its expiration time. ## PaymentChannelClaim Flags diff --git a/sidebars.yaml b/sidebars.yaml index 3fcc68c6554..7017d7073bc 100644 --- a/sidebars.yaml +++ b/sidebars.yaml @@ -160,6 +160,7 @@ - page: docs/concepts/decentralized-storage/index.md expanded: false items: + - page: docs/concepts/decentralized-storage/credentials.md - page: docs/concepts/decentralized-storage/decentralized-identifiers.md - page: docs/concepts/decentralized-storage/price-oracles.md - page: docs/tutorials/index.md @@ -326,6 +327,7 @@ - page: docs/references/protocol/ledger-data/ledger-entry-types/amm.md - page: docs/references/protocol/ledger-data/ledger-entry-types/bridge.md - page: docs/references/protocol/ledger-data/ledger-entry-types/check.md + - page: docs/references/protocol/ledger-data/ledger-entry-types/credential.md - page: docs/references/protocol/ledger-data/ledger-entry-types/depositpreauth.md - page: docs/references/protocol/ledger-data/ledger-entry-types/did.md - page: docs/references/protocol/ledger-data/ledger-entry-types/directorynode.md @@ -358,6 +360,9 @@ - page: docs/references/protocol/transactions/types/ammdeposit.md - page: docs/references/protocol/transactions/types/ammvote.md - page: docs/references/protocol/transactions/types/ammwithdraw.md + - page: docs/references/protocol/transactions/types/credentialaccept.md + - page: docs/references/protocol/transactions/types/credentialcreate.md + - page: docs/references/protocol/transactions/types/credentialdelete.md - page: docs/references/protocol/transactions/types/checkcancel.md - page: docs/references/protocol/transactions/types/checkcash.md - page: docs/references/protocol/transactions/types/checkcreate.md