diff --git a/docs/concepts/tokens/decentralized-exchange/permissioned-dex-roles.svg b/docs/concepts/tokens/decentralized-exchange/permissioned-dex-roles.svg new file mode 100644 index 00000000000..4fbbdbd77ea --- /dev/null +++ b/docs/concepts/tokens/decentralized-exchange/permissioned-dex-roles.svg @@ -0,0 +1,160 @@ + + +Tracy(Trader inpermissioned DEX)Order BookUSD.Acme:FOO.WayGateDomainID: Domain A10 FOO : 10 USD – Marko9 FOO : 15 USD – Tracy...Domain AOwner: OwenAccepted Credentials:- "Accredited" issued by Isabel- "Accredited" issued by OwenOwen(credential issuer and domain owner)CredentialType: "Accredited"Issuer: OwenSubject: Tracyholdsgrants accessissues diff --git a/docs/concepts/tokens/decentralized-exchange/permissioned-dex-structure.svg b/docs/concepts/tokens/decentralized-exchange/permissioned-dex-structure.svg new file mode 100644 index 00000000000..1d3305a7c51 --- /dev/null +++ b/docs/concepts/tokens/decentralized-exchange/permissioned-dex-structure.svg @@ -0,0 +1,164 @@ + + +Order BookEUR:JPYDomainID: BOrder BookJPY:EURDomainID: BPermissioned DEX AOrder BookUSD:FOOOrder BookBAR:BAZOrder BookFOO:USDOrder BookFOO:XRPOrder BookXRP:FOOOpen DEXOrder BookEUR:JPYDomainID: AOrder BookUSD:FOODomainID: AOrder BookFOO:XRPDomainID: APermissioned DEX B diff --git a/docs/concepts/tokens/decentralized-exchange/permissioned-dexes.md b/docs/concepts/tokens/decentralized-exchange/permissioned-dexes.md new file mode 100644 index 00000000000..9ebbff4d4a7 --- /dev/null +++ b/docs/concepts/tokens/decentralized-exchange/permissioned-dexes.md @@ -0,0 +1,84 @@ +--- +seo: + description: The definition and details of a Permissioned Domain instance. +labels: + - Compliance + - Decentralized Exchange +--- +# Permissioned DEXes + +Permissioned DEXes are controlled environments for trading within the XRP Ledger's [decentralized exchange (DEX)](./index.md). Trading in a permissioned DEX works like trading in the open DEX, except that a [_permissioned domain_](./permissioned-domains.md) controls who can place and accept offers. By relying on permissioned DEXes, regulated businesses can participate in trading on the XRP Ledger while ensuring that all the counterparties they deal with have been properly vetted. + +There can be multiple permissioned DEXes within the XRP Ledger blockchain. Each one is uniquely associated with a permissioned domain, which acts as an allow-list for accessing that DEX. Trades placed within a permissioned DEX can only execute against other trades in the same permissioned DEX. Each permissioned DEX can have order books for any number of currency pairs, as needed. + + +## Background + +The XRP Ledger has had a single, _open DEX_ since it launched. Anyone with an XRPL account can trade in this DEX, and the system automatically executes matching orders, also called offers, with no regard for who placed them. Orders also provide liquidity to cross-currency payments, which can potentially execute several trades as part of one atomic transaction. Since the system inherently knows nothing about the people and organizations behind the accounts, there is no certainty who the counterparties are for any given trade. However, economic sanctions and financial regulations often place strict rules against transacting with criminals, terrorists, or specific countries. Given these limitations, regulated financial institutions may not be willing to take the risk of trading in the open DEX. + +More background reading: + +- [Decentralized Exchange](./index.md) +- [Offers](./offers.md) +- [Permissioned Domains](./permissioned-domains.md) + + +## Roles + +To use a permissioned DEX, parties with the following roles and responsibilities need to exist: + +- At least two traders to place matching offers. For example, one selling USD for XRP and one selling XRP for USD. +- A permissioned domain owner, who controls which credentials give access to the domain. +- A credential issuer, who issues credentials to accounts they approve. + +It is possible for a single account to play more than one of these roles. For example, you could be the permissioned domain owner, credential issuer, _and_ a trader all at once. The only restriction is that the traders must be different accounts. + +{% inline-svg file="./permissioned-dex-roles.svg" /%} + +_Figure: A permissioned order book, linked to a permissioned domain. Owen is both the domain owner and the issuer of one of the domain's accepted credentials. Tracy is able to trade in the permissioned order book because she holds an appropriate credential issued by Owen._ + + +## Structure + +With the permissioned DEXes feature, a trade offer can be _open_, _permissioned_, or _hybrid_. An open offer uses the open DEX and can be matched by anyone else's open offer, hybrid offer, an [Automated Market Maker (AMM)](./automated-market-makers.md), or a combination of offers and an AMM. _Open offers_ are unchanged from how the XRPL's DEX works without permissioned DEXes. + +A permissioned offer specifies a domain ID, and is only valid if a permissioned domain with the matching ID exists and the account placing the offer has access to that domain because they hold the correct credentials. Permissioned offers are placed into an order book for the given domain and currency pair, separate from the open DEX's order book for that currency pair. Permissioned offers can only execute by matching other permissioned offers that specify the same domain ID. [Cross-currency payments](../../payment-types/cross-currency-payments.md) can also specify a domain ID, in which case they are restricted to only consuming offers from the corresponding permissioned DEX. Trades in a permissioned DEX can still use [auto-bridging](./autobridging.md) as long as the necessary orders all exist in the same permissioned DEX. + +A hybrid offer specifies a domain ID and a flag marking it as hybrid. Like a permissioned offer, it is only valid if the specified permissioned domain exists and the account placing the offer has access to that domain. However, a hybrid offer can match offers in both the specified DEX and the open DEX. Hybrid offers are tracked in both the open DEX order book and the domain-specific order book for their currency pair, and can be consumed by matching offers from either. When placed, they preferentially match offers from the permissioned DEX. + +In summary, see the following table summarizing what offers can match: + +| Offer/Payment Type | Open Offer | Hybrid Offer | Permissioned Offer | AMM | +|--------------------|------------|--------------|--------------------|-----| +| Open | ✅ | ✅ | ❌ | ✅ | +| Hybrid | ✅ | ✅ | ✅ (same domain) | ✅ | +| Permissioned | ❌ | ❌ | ✅ (same domain) | ❌ | + +There is no single ledger entry to represent a given permissioned DEX: it implicitly exists as all the order books with the same domain ID. Order books with a given domain ID are implicitly created when valid offers are placed using that domain ID, and those order books are automatically deleted when they are empty. A single transaction can use multiple order books with the same domain ID—in other words, different currency pairs in the same permissioned DEX—either as part of a longer cross-currency payment or through auto-bridging. A hybrid offer can match a mix of permissioned and open offers, but a transaction cannot use multiple different domains. + +The amount of liquidity and the best exchange rate available in any given DEX may vary depending on the offers placed in that DEX. Some traders may choose to trade in multiple permissioned DEXes and the open DEX to arbitrage price differences, while other traders may trade strictly in one domain, depending on their compliance requirements. + +{% inline-svg file="./permissioned-dex-structure.svg" /%} + +_Figure: The open DEX, and two different permissioned DEXes, each containing order books for a subset of possible currency pairs._ + + +### Invalid Permissioned Offers + +In addition to the ways offers can be unfunded in the open DEX, offers in a permissioned DEX can become _invalid_. Invalid offers are treated the same way as unfunded offers, and are automatically removed whenever a transaction modifies the order book containing them. They can remain in the ledger data indefinitely until a transaction removes them, but they cannot be executed if they are invalid. Reasons that a permissioned offer can become invalid include: + +- A credential, held by the account placing the offer, has expired or has been deleted. +- The permissioned domain has been updated to change the set of credentials that grant access, and the account placing the offer does not hold any of the new credentials. +- The permissioned domain has been deleted. + +Like with unfunded offers, it is possible for an offer to become temporarily invalid, then become valid again. For example, if a trader's credential that grants access to a permissioned domain expires, their offers in the corresponding permissioned DEX would be invalid; but if they get the credential renewed, any offers that hadn't already been removed automatically become valid again. + +### Limitations + +The permissioned DEXes feature is enabled by the **PermissionedDEX** amendment, and relies on the [Credentials](../../decentralized-storage/credentials.md) and [Permissioned Domains](./permissioned-domains.md) amendments, so it cannot be used until _all_ of those amendments have been enabled. + +Permissioned DEXes are incompatible with Automated Market Makers (AMMs). Permissioned offers and permissioned payments cannot be filled by AMMs, and access to AMMs cannot be restricted by a permissioned domain. Trades that use the open DEX can sometimes consume a hybrid offer and use an AMM in the same transaction, but transactions that specify a domain cannot use any AMMs. + +Each permissioned DEX is separate, with its own order books and offers. A single transaction cannot trade in multiple permissioned DEXes or aggregate liquidity from multiple permissioned DEXes. Hybrid offers can use a mix of one permissioned DEX and the open DEX, but they cannot use multiple different permissioned DEXes. + +The security and fairness of a permissioned DEX depend on the owner of the permissioned domain and the issuers of credentials that grant access to it. At a baseline, the definition of each credential and the requirements for getting that credential are defined and enforced by the credential issuer, so the existence of a permissioned domain does not inherently mean anything about who is able to use it in practice. A credential issuer can issue or revoke credentials at their discretion. If they are unreliable or compromised, so is any permissioned domain that accepts their credentials. Similarly, the domain owner can modify the domain's list of accepted credentials to grant or deny access to the domain arbitrarily, so if they are untrustworthy or compromised, the domain is as well. diff --git a/docs/img/_sources/permissioned-dex-roles.uxf b/docs/img/_sources/permissioned-dex-roles.uxf new file mode 100644 index 00000000000..87cf4f0ebb4 --- /dev/null +++ b/docs/img/_sources/permissioned-dex-roles.uxf @@ -0,0 +1,131 @@ + + + 10 + + UMLPackage + + 300 + 290 + 140 + 80 + + Credential +-- +Type: "Accredited" +Issuer: Owen +Subject: Tracy +halign=left + + + + Relation + + 210 + 310 + 110 + 40 + + lt=<<. +issues + 90.0;20.0;10.0;20.0 + + + UMLActor + + 120 + 300 + 160 + 140 + + Owen +(credential issuer +and domain owner) + + + + Relation + + 170 + 150 + 270 + 180 + + lt=<<. +r1=grants access + 10.0;10.0;10.0;40.0;230.0;40.0;230.0;150.0;250.0;160.0 + + + UMLClass + + 290 + 60 + 190 + 140 + + Domain A +-- +Owner: Owen +Accepted Credentials: +- "Accredited" issued + by Isabel +*- "Accredited" issued* +* by Owen* + + + + UMLClass + + 20 + 20 + 200 + 140 + + Order Book +USD.Acme:FOO.WayGate +-- +*DomainID: Domain A* +-- +10 FOO : 10 USD – Marko +- +9 FOO : 15 USD – Tracy +-- +... + + + + Relation + + 190 + 60 + 120 + 30 + + lt=<<. + 100.0;10.0;10.0;10.0 + + + UMLActor + + 450 + 300 + 160 + 140 + + Tracy +(Trader in +permissioned DEX) + + + + Relation + + 430 + 310 + 110 + 40 + + lt=.>> +holds + 90.0;20.0;10.0;20.0 + + diff --git a/docs/img/_sources/permissioned-dex-structure.uxf b/docs/img/_sources/permissioned-dex-structure.uxf new file mode 100644 index 00000000000..6b37f3ed219 --- /dev/null +++ b/docs/img/_sources/permissioned-dex-structure.uxf @@ -0,0 +1,175 @@ + + + 10 + + UMLClass + + 540 + 30 + 250 + 290 + + lt=. +Permissioned DEX B + + + + UMLPackage + + 410 + 80 + 110 + 70 + + Order Book +-- +FOO:XRP +DomainID: A + + + + UMLPackage + + 290 + 160 + 110 + 70 + + Order Book +-- +USD:FOO +DomainID: A + + + + UMLPackage + + 410 + 240 + 110 + 70 + + Order Book +-- +EUR:JPY +DomainID: A + + + + UMLClass + + 20 + 30 + 250 + 290 + + lt=. +Open DEX + + + + UMLPackage + + 30 + 80 + 110 + 70 + + Order Book +-- +XRP:FOO + + + + UMLPackage + + 150 + 80 + 110 + 70 + + Order Book +-- +FOO:XRP + + + + UMLPackage + + 150 + 160 + 110 + 70 + + Order Book +-- +FOO:USD + + + + UMLPackage + + 30 + 240 + 110 + 70 + + Order Book +-- +BAR:BAZ + + + + UMLPackage + + 30 + 160 + 110 + 70 + + Order Book +-- +USD:FOO + + + + UMLClass + + 280 + 30 + 250 + 290 + + lt=. +Permissioned DEX A + + + + UMLPackage + + 550 + 240 + 110 + 70 + + Order Book +-- +JPY:EUR +DomainID: B + + + + UMLPackage + + 670 + 240 + 110 + 70 + + Order Book +-- +EUR:JPY +DomainID: B + + + diff --git a/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/book_offers.md b/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/book_offers.md index d2ce353a0cc..1c60cdae1e2 100644 --- a/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/book_offers.md +++ b/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/book_offers.md @@ -1,6 +1,4 @@ --- -html: book_offers.html -parent: path-and-order-book-methods.html seo: description: Get info about offers to exchange two currencies. labels: @@ -10,7 +8,7 @@ labels: # book_offers [[Source]](https://github.com/XRPLF/rippled/blob/master/src/ripple/rpc/handlers/BookOffers.cpp "Source") -The `book_offers` method retrieves a list of [Offers](../../../../concepts/tokens/decentralized-exchange/offers.md) between two currencies, also known as an _order book_. The response omits [unfunded Offers](../../../../concepts/tokens/decentralized-exchange/offers.md#lifecycle-of-an-offer) and reports how much of each remaining Offer's total is currently funded. +The `book_offers` method retrieves a list of [offers](../../../../concepts/tokens/decentralized-exchange/offers.md) between two currencies, also known as an _order book_. The response omits [unfunded offers](../../../../concepts/tokens/decentralized-exchange/offers.md#lifecycle-of-an-offer) and reports how much of each remaining offer's total is currently funded. ## Request Format An example of the request format: @@ -71,11 +69,12 @@ The request includes the following parameters: | `Field` | Type | Required? | Description | |:---------------|:-----------------|:----------|-------------| -| `taker_gets` | Object | Yes | The asset the account taking the Offer would receive, as a [currency without an amount](../../../protocol/data-types/currency-formats.md#specifying-without-amounts). | -| `taker_pays` | Object | Yes | The asset the account taking the Offer would pay, as a [currency without an amount](../../../protocol/data-types/currency-formats.md#specifying-without-amounts). | +| `taker_gets` | Object | Yes | The asset the account taking the offer would receive, as a [currency without an amount](../../../protocol/data-types/currency-formats.md#specifying-without-amounts). | +| `taker_pays` | Object | Yes | The asset the account taking the offer would pay, as a [currency without an amount](../../../protocol/data-types/currency-formats.md#specifying-without-amounts). | +| `domain` | [Hash][] | No | The ledger entry ID of a permissioned domain. If provided, return offers from the corresponding [permissioned DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md) instead of using the open DEX. _(Requires the [PermissionedDEX amendment][] {% not-enabled /%})_ | | `ledger_hash` | [Hash][] | No | The unique hash of 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][]) | -| `limit` | Number | No | The maximum number of Offers to return. The response may include fewer results. | +| `limit` | Number | No | The maximum number of offers to return. The response may include fewer results. | | `taker` | String | No | The [Address][] of an account to use as a perspective. The response includes this account's Offers even if they are unfunded. (You can use this to see what Offers are above or below yours in the order book.) | @@ -242,9 +241,9 @@ The response follows the [standard format][], with a successful result containin | `ledger_current_index` | [Ledger Index][] | _(Omitted if `ledger_current_index` is provided)_ The [ledger index][] of the current in-progress ledger version, which was used to retrieve this information. | | `ledger_index` | [Ledger Index][] | _(Omitted if `ledger_current_index` provided)_ The ledger index of the ledger version that was used when retrieving this data, as requested. | | `ledger_hash` | [Hash][] | _(May be omitted)_ The identifying hash of the ledger version that was used when retrieving this data, as requested. | -| `offers` | Array | Array of offer objects, each of which has the fields of an [Offer object](../../../protocol/ledger-data/ledger-entry-types/offer.md) | +| `offers` | Array | Array of offer objects, as described below: | -In addition to the standard Offer fields, the following fields may be included in members of the `offers` array: +Each member of the `offers` array contains canonical fields of an [Offer entry][] and can also contain the following additional fields: | `Field` | Type | Description | |:--------------------|:--------------------|:--------------------| diff --git a/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/path_find.md b/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/path_find.md index 8c8c23f3465..bd8ecce7648 100644 --- a/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/path_find.md +++ b/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/path_find.md @@ -55,14 +55,16 @@ An example of the request format: The request includes the following parameters: -| `Field` | Type | Description | -|:----------------------|:-----------------|:----------------------------------| -| `subcommand` | String | Use `"create"` to send the create sub-command | -| `source_account` | String | Unique address of the account to find a path from. (In other words, the account that would be sending a payment.) | -| `destination_account` | String | Unique address of the account to find a path to. (In other words, the account that would receive a payment.) | -| `destination_amount` | String or Object | [Currency Amount][] that the destination account would receive in a transaction. **Special case:** You can specify `"-1"` (for XRP) or provide -1 as the contents of the `value` field (for non-XRP currencies). This requests a path to deliver as much as possible, while spending no more than the amount specified in `send_max` (if provided). | -| `send_max` | String or Object | _(Optional)_ [Currency Amount][] that would be spent in the transaction. Not compatible with `source_currencies`. | -| `paths` | Array | _(Optional)_ Array of arrays of objects, representing [payment paths](../../../../concepts/tokens/fungible-tokens/paths.md) to check. You can use this to keep updated on changes to particular paths you already know about, or to check the overall cost to make a payment along a certain path. | +| Field | Type | Required? | Description | +|:----------------------|:---------------------|:----------|:------------| +| `subcommand` | String | Yes | Use `"create"` to send the create sub-command | +| `source_account` | String - [Address][] | Yes | The account to find a path from. (In other words, the account that would be sending a payment.) | +| `destination_account` | String - [Address][] | Yes | The account to find a path to. (In other words, the account that would receive a payment.) | +| `destination_amount` | [Currency Amount][] | Yes | How much the destination account would receive. **Special case:** You can specify `"-1"` (for XRP) or provide -1 as the contents of the `value` field (for tokens). This requests a path to deliver as much as possible, while spending no more than the amount specified in `send_max` (if provided). | +| `domain` | String - [Hash][] | No | The ledger entry ID of a permissioned domain. If provided, only return paths that use the corresponding [permissioned DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md). _(Requires the [PermissionedDEX amendment][] {% not-enabled /%})_ | +| `paths` | Array | No | Array of arrays of objects, representing [payment paths](../../../../concepts/tokens/fungible-tokens/paths.md) to check. +| `send_max` | [Currency Amount][] | No | Maximum amount that would be spent. Not compatible with `source_currencies`. | +You can use this to keep updated on changes to particular paths you already know about, or to check the overall cost to make a payment along a certain path. | The server also recognizes the following fields, but the results of using them are not guaranteed: `source_currencies`, `bridges`. These fields should be considered reserved for future use. diff --git a/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/ripple_path_find.md b/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/ripple_path_find.md index dadc1988a82..1dc0bf439c5 100644 --- a/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/ripple_path_find.md +++ b/docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/ripple_path_find.md @@ -85,15 +85,16 @@ rippled ripple_path_find '{"source_account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59 The request includes the following parameters: -| `Field` | Type | Description | -|:----------------------|:---------------------------|:------------------------| -| `source_account` | String | Unique address of the account that would send funds in a transaction | -| `destination_account` | String | Unique address of the account that would receive funds in a transaction | -| `destination_amount` | String or Object | [Currency Amount][] that the destination account would receive in a transaction. **Special case:** You can specify `"-1"` (for XRP) or provide -1 as the contents of the `value` field (for non-XRP currencies). This requests a path to deliver as much as possible, while spending no more than the amount specified in `send_max` (if provided). | -| `send_max` | String or Object | _(Optional)_ [Currency Amount][] that would be spent in the transaction. Cannot be used with `source_currencies`. | -| `source_currencies` | Array | _(Optional)_ Array of currencies that the source account might want to spend. Each entry in the array should be a JSON object with a mandatory `currency` field and optional `issuer` field, like how [currency amounts][Currency Amount] are specified. Cannot contain more than **18** source currencies. By default, uses all source currencies available up to a maximum of **88** different currency/issuer pairs. | -| `ledger_hash` | String | _(Optional)_ The unique hash of 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 account that would send funds | +| `destination_account` | String - [Address][] | Yes | The account that would receive funds | +| `destination_amount` | [Currency Amount][] | Yes | How much the destination account would receive. **Special case:** You can specify `"-1"` (for XRP) or provide -1 as the contents of the `value` field (for tokens). This requests a path to deliver as much as possible, while spending no more than the amount specified in `send_max` (if provided). | +| `domain` | String - [Hash][] | No | The ledger entry ID of a permissioned domain. If provided, only return paths that use the corresponding [permissioned DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md). _(Requires the [PermissionedDEX amendment][] {% not-enabled /%})_ | +| `ledger_hash` | String - [Hash][] | No | The unique hash of 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][]) | +| `send_max` | [Currency Amount][] | No | Maximum amount that would be spent. Cannot be used with `source_currencies`. | +| `source_currencies` | Array | No | Array of currencies that the source account might want to spend. Each entry in the array should be a JSON object with a mandatory `currency` field and optional `issuer` field, like how [currency amounts][Currency Amount] are specified. Cannot contain more than **18** source currencies. By default, uses all source currencies available up to a maximum of **88** different currency/issuer pairs. | ## Response Format diff --git a/docs/references/http-websocket-apis/public-api-methods/subscription-methods/subscribe.md b/docs/references/http-websocket-apis/public-api-methods/subscription-methods/subscribe.md index c4548185de3..b592f11ca23 100644 --- a/docs/references/http-websocket-apis/public-api-methods/subscription-methods/subscribe.md +++ b/docs/references/http-websocket-apis/public-api-methods/subscription-methods/subscribe.md @@ -10,7 +10,7 @@ labels: - Smart Contracts --- # subscribe -[[Source]](https://github.com/XRPLF/rippled/blob/master/src/ripple/rpc/handlers/Subscribe.cpp "Source") +[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/rpc/handlers/Subscribe.cpp "Source") The `subscribe` method requests periodic notifications from the server when certain events happen. @@ -66,42 +66,47 @@ An example of the request format: The request includes the following parameters: -| `Field` | Type | Description | -|:--------------------|:-------|:----------------------------------------------| -| `streams` | Array | _(Optional)_ Array of string names of generic streams to subscribe to, as explained below | -| `accounts` | Array | _(Optional)_ Array with the unique addresses of accounts to monitor for validated transactions. The addresses must be in the XRP Ledger's [base58][] format. The server sends a notification for any transaction that affects at least one of these accounts. | -| `accounts_proposed` | Array | _(Optional)_ Like `accounts`, but include transactions that are not yet finalized. | -| `books` | Array | _(Optional)_ Array of objects defining [order books](http://www.investopedia.com/terms/o/order-book.asp) to monitor for updates, as detailed below. | -| `url` | String | (Optional for Websocket; Required otherwise) URL where the server sends a JSON-RPC callbacks for each event. *Admin-only.* | -| `url_username` | String | _(Optional)_ Username to provide for basic authentication at the callback URL. | -| `url_password` | String | _(Optional)_ Password to provide for basic authentication at the callback URL. | +| Field | Type | Required? | Description | +|:--------------------|:-------|:----------|:------------| +| `streams` | Array | No | Streams to subscribe to, as explained below. Each member of the array must be the string name of a stream. | +| `accounts` | Array | No | Array with the unique [addresses][Address] of accounts to monitor for validated transactions. The server sends a `transaction` type message whenever a transaction affects at least one of these accounts. | +| `accounts_proposed` | Array | No | Like `accounts`, but include transactions that are not yet finalized. | +| `books` | Array | No | Order books to monitor for updates. Each member of the array must be a [book object](#book-objects), as defined below. The server sends a `transaction` type message whenever a transaction affects this account. | +| `url` | String | Optional for Websocket; Required for JSON-RPC | **(Admin only)** URL where the server sends JSON-RPC callbacks for each event. | +| `url_username` | String | No | Username to provide for basic authentication at the callback URL. | +| `url_password` | String | No | Password to provide for basic authentication at the callback URL. | The following parameters are deprecated and may be removed without further notice: `user`, `password`, `rt_accounts`. The `streams` parameter provides access to the following default streams of information: -- `book_changes` - Sends a message with order book changes whenever the consensus process declares a new validated ledger. -- `consensus` - Sends a message whenever the server changes phase in the consensus cycle. -- `ledger` - Sends a message whenever the consensus process declares a new validated ledger. -- `manifests` - Sends a message whenever the server receives an update to a validator's ephemeral signing key. -- `peer_status` - **(Admin only)** Information about connected peer `rippled` servers, especially with regards to the consensus process. -- `transactions` - Sends a message whenever a transaction is included in a closed ledger. -- `transactions_proposed` - Sends a message whenever a transaction is included in a closed ledger, as well as some transactions that have not yet been included in a validated ledger and may never be. Not all proposed transactions appear before validation. - {% admonition type="info" name="Note" %}[Even some transactions that don't succeed are included](../../../protocol/transactions/transaction-results/index.md) in validated ledgers, because they take the anti-spam transaction fee.{% /admonition %} -- `server` - Sends a message whenever the status of the `rippled` server (for example, network connectivity) changes. -- `validations` - Sends a message whenever the server receives a validation message, regardless of if the server trusts the validator. (An individual `rippled` declares a ledger validated when the server receives validation messages from at least a quorum of trusted validators.) +| Stream Name | Message Type | Description | +|:------------------------|:---------------------|:------------| +| `book_changes` | `bookChanges` | Sends order book changes whenever the consensus process declares a new validated ledger. | +| `consensus` | `consensusPhase` | Sends a message whenever the server changes phase in the consensus cycle. | +| `ledger` | `ledgerClosed` | Sends a message whenever the consensus process declares a new validated ledger. | +| `manifests` | `manifestReceived` | Sends a message whenever the server receives an update to a validator's ephemeral signing key. | +| `peer_status` | `peerStatusChange` | **(Admin only)** Information about connected peer `rippled` servers, especially with regards to the consensus process. | +| `transactions` | `transaction` | Sends a message whenever a transaction is included in a closed ledger. | +| `transactions_proposed` | `transaction` | Sends a message whenever a transaction is included in a closed ledger, as well as some transactions that have not yet been included in a validated ledger and may never be. Not all proposed transactions appear before validation. {% admonition type="info" name="Note" %}[Even some transactions that don't succeed are included](../../../protocol/transactions/transaction-results/index.md) in validated ledgers, because they take the anti-spam transaction fee.{% /admonition %} | +| `server` | `serverStatus` | Sends a message whenever the status of the `rippled` server (for example, network connectivity) changes. | +| `validations` | `validationReceived` | Sends a message whenever the server receives a validation message, regardless of if the server trusts the validator. (An individual `rippled` declares a ledger validated when the server receives validation messages from at least a quorum of trusted validators.) | -{% admonition type="info" name="Note" %}The following streams are not available from Clio and `rippled` servers in [Reporting Mode][]: `server`, `peer_status`, `consensus`. Both will return the `reportingUnsupported` error if you request one of these streams. {% badge href="https://github.com/XRPLF/rippled/releases/tag/1.8.1" %}Updated in: rippled 1.8.1{% /badge %} {% badge href="https://github.com/XRPLF/clio/releases/tag/2.0.0" %}New in: Clio v2.0{% /badge %}{% /admonition %} +{% admonition type="info" name="Note" %}The following streams are not available from Clio servers: `server`, `peer_status`, `consensus`. If you request one of these streams, Clio returns the error `reportingUnsupported`. {% badge href="https://github.com/XRPLF/clio/releases/tag/2.0.0" %}New in: Clio v2.0{% /badge %}{% /admonition %} + +### Book Objects Each member of the `books` array, if provided, is an object with the following fields: -| `Field` | Type | Description | -|:-------------|:--------|:----------------------------------------------------| -| `taker_gets` | Object | Specification of which currency the account taking the Offer would receive, as a [currency object with no amount](../../../protocol/data-types/currency-formats.md#specifying-without-amounts). | -| `taker_pays` | Object | Specification of which currency the account taking the Offer would pay, as a [currency object with no amount](../../../protocol/data-types/currency-formats.md#specifying-without-amounts). | -| `taker` | String | Unique [account address](../../../../concepts/accounts/index.md) to use as a perspective for viewing offers, in the XRP Ledger's [base58][] format. (This affects the funding status and fees of [Offers](../../../../concepts/tokens/decentralized-exchange/offers.md).) | -| `snapshot` | Boolean | _(Optional)_ If `true`, return the current state of the order book once when you subscribe before sending updates. The default is `false`. | -| `both` | Boolean | _(Optional)_ If `true`, return both sides of the order book. The default is `false`. | +| Field | Type | Required? | Description | +|:-------------|:---------------------|:----------|:------------| +| `taker_gets` | Object - Currency | Yes | Specification of which currency the account taking the offer would receive, as a [currency object with no amount](../../../protocol/data-types/currency-formats.md#specifying-without-amounts). | +| `taker_pays` | Object - Currency | Yes | Specification of which currency the account taking the offer would pay, as a [currency object with no amount](../../../protocol/data-types/currency-formats.md#specifying-without-amounts). | +| `both` | Boolean | No | If `true`, return both sides of the order book. The default is `false`. | +| `domain` | String - [Hash][] | No | The ledger entry ID of a permissioned domain. If provided, subscribe to the order books for the corresponding [permissioned DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md) instead of the open DEX. _(Requires the [PermissionedDEX amendment][] {% not-enabled /%})_ | +| `snapshot` | Boolean | No | If `true`, return the current state of the order book once when you subscribe before sending updates. The default is `false`. | +| `taker` | String - [Address][] | No | The acount to use as a perspective for viewing offers. This affects the funding status and fees of [offers](../../../../concepts/tokens/decentralized-exchange/offers.md). | + ## Response Format @@ -167,7 +172,7 @@ The `ledger` stream only sends `ledgerClosed` messages when [the consensus proce The fields from a ledger stream message are as follows: -| `Field` | Type | Description | +| Field | Type | Description | |:--------------------|:--------------------------|:---------------------------| | `type` | String | `ledgerClosed` indicates this is from the ledger stream | | `fee_base` | Number | The [reference transaction cost](../../../../concepts/transactions/transaction-cost.md#reference-transaction-cost) as of this ledger version, in [drops of XRP][]. If this ledger version includes a [SetFee pseudo-transaction](../../../protocol/transactions/pseudo-transaction-types/setfee.md) the new transaction cost applies starting with the following ledger version. | @@ -212,7 +217,7 @@ The validations stream sends messages whenever it receives validation messages, The fields from a validations stream message are as follows: -| `Field` | Type | Description | +| Field | Type | Description | |:------------------------|:-----------------|:--------------------------------| | `type` | String | The value `validationReceived` indicates this is from the validations stream. | | `amendments` | Array of Strings | _(May be omitted)_ The [amendments](../../../../concepts/networks-and-servers/amendments.md) this server wants to be added to the protocol. | @@ -333,7 +338,7 @@ Transaction stream messages have the following fields: {% tab label="API v2" %} -| `Field` | Type | Description | +| Field | Type | Description | |:------------------------|:--------------------------|:-----------------------| | `close_time_iso` | String | The ledger close time represented in ISO 8601 time format. | | `type` | String | `transaction` indicates this is the notification of a transaction, which could come from several possible streams. | @@ -352,7 +357,7 @@ Transaction stream messages have the following fields: {% tab label="API v1" %} -| `Field` | Type | Description | +| Field | Type | Description | |:------------------------|:--------------------------|:-----------------------| | `type` | String | `transaction` indicates this is the notification of a transaction, which could come from several possible streams. | | `engine_result` | String | String [Transaction result code](../../../protocol/transactions/transaction-results/index.md) | @@ -389,7 +394,7 @@ Example of a Peer Status stream message: Peer Status stream messages represent some event where the status of the peer `rippled` server changed. These messages are JSON objects with the following fields: -| `Field` | Value | Description | +| Field | Value | Description | |:-------------------|:-------|:-----------------------------------------------| | `type` | String | `peerStatusChange` indicates this comes from the Peer Status stream. | | `action` | String | The type of event that prompted this message. See [Peer Status Events](#peer-status-events) for possible values. | diff --git a/docs/references/protocol/ledger-data/ledger-entry-types/directorynode.md b/docs/references/protocol/ledger-data/ledger-entry-types/directorynode.md index 58bf047239f..284638129ed 100644 --- a/docs/references/protocol/ledger-data/ledger-entry-types/directorynode.md +++ b/docs/references/protocol/ledger-data/ledger-entry-types/directorynode.md @@ -6,14 +6,14 @@ labels: - Decentralized Exchange --- # DirectoryNode -[[Source]](https://github.com/XRPLF/rippled/blob/f64cf9187affd69650907d0d92e097eb29693945/include/xrpl/protocol/detail/ledger_entries.macro#L165-L179 "Source") +[[Source]](https://github.com/XRPLF/rippled/blob/7e24adbdd0b61fb50967c4c6d4b27cc6d81b33f3/include/xrpl/protocol/detail/ledger_entries.macro#L177-L192 "Source") The `DirectoryNode` ledger entry type provides a list of links to other entries in the ledger's state data. A single conceptual _Directory_ takes the form of a doubly linked list, with one or more DirectoryNode entries each containing up to 32 [IDs of other entries](../common-fields.md). The first DirectoryNode entry is called the root of the directory, and all entries other than the root can be added or deleted as necessary. There are three kinds of directory: * _Owner directories_ list other entries owned by an account, such as [`RippleState` (trust line)](ripplestate.md) or [`Offer`](offer.md) entries. -* _Offer directories_ list the offers available in the [decentralized exchange](../../../../concepts/tokens/decentralized-exchange/index.md). A single Offer directory contains all the offers that have the same exchange rate for the same token (currency code and issuer). +* _Offer directories_ list the offers available in the [decentralized exchange](../../../../concepts/tokens/decentralized-exchange/index.md). A single offer directory contains all the offers that have the same exchange rate for the same token (currency code and issuer). * _NFT Offer directories_ list buy and sell offers for NFTs. Each NFT has up to two directories, one for buy offers, the other for sell offers. All types of directories are automatically updated by the protocol as necessary. @@ -97,6 +97,7 @@ All types of directories are automatically updated by the protocol as necessary. | Name | JSON Type | [Internal Type][] | Required? | Description | |:--------------------|:----------|:------------------|:----------|:------------| +| `DomainID` | String | Hash256 | No | (Offer directories only) The ledger entry ID of a permissioned domain. If present, this order book belongs to the corresponding [Permissioned DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md). Otherwise, this order book is part of the open DEX. _(Requires the [PermissionedDEX amendment][] {% not-enabled /%})_ | | `ExchangeRate` | String | UInt64 | No | (Offer directories only) **DEPRECATED**. Do not use. | | `Flags` | Number | UInt32 | Yes | A bit-map of boolean flags enabled for this object. Currently, the protocol defines no flags for `DirectoryNode` objects. The value is always `0`. | | `Indexes` | Array | Vector256 | Yes | The contents of this directory: an array of IDs of other objects. | @@ -136,8 +137,8 @@ Owner directories and offer directories for fungible tokens do not use flags; th There are three different formulas for creating the ID of a DirectoryNode, depending on which of the following the DirectoryNode represents: * The first page (also called the root) of an Owner or NFT Offer directory -* The first page of an Offer directory -* Later pages of either type +* The first page of an Offer directory, with variants for the open DEX and permissioned DEX _(Requires the [PermissionedDEX amendment][] {% not-enabled /%})_ +* Later pages of any type The first page of an Owner directory or NFT Offer directory has an ID that is the [SHA-512Half][] of the following values, concatenated in order: @@ -151,6 +152,7 @@ The first page of an Offer directory has a special ID: the higher 192 bits defin * The 160-bit currency code from the `TakerGetsCurrency` * The AccountID from the `TakerPaysIssuer` * The AccountID from the `TakerGetsIssuer` +* The `DomainID` of the permissioned domain this order book belongs to, if part of a permissioned DEX. Omitted for order books in the open DEX. The lower 64 bits of an Offer directory's ID represent the `TakerPays` amount divided by `TakerGets` amount from the offer(s) in that directory as a 64-bit number in the XRP Ledger's internal amount format. diff --git a/docs/references/protocol/ledger-data/ledger-entry-types/offer.md b/docs/references/protocol/ledger-data/ledger-entry-types/offer.md index af0a6fa9521..947090c90bf 100644 --- a/docs/references/protocol/ledger-data/ledger-entry-types/offer.md +++ b/docs/references/protocol/ledger-data/ledger-entry-types/offer.md @@ -5,11 +5,11 @@ labels: - Decentralized Exchange --- # Offer -[[Source]](https://github.com/XRPLF/rippled/blob/f64cf9187affd69650907d0d92e097eb29693945/include/xrpl/protocol/detail/ledger_entries.macro#L229-L240 "Source") +[[Source]](https://github.com/XRPLF/rippled/blob/7e24adbdd0b61fb50967c4c6d4b27cc6d81b33f3/include/xrpl/protocol/detail/ledger_entries.macro#L242-L255 "Source") -An `Offer` ledger entry describes an [Offer](../../../../concepts/tokens/decentralized-exchange/offers.md) to exchange currencies in the XRP Ledger's [decentralized exchange](../../../../concepts/tokens/decentralized-exchange/index.md). (In finance, this is more traditionally known as an _order_.) You an create a new Offer entry by sending an [OfferCreate transaction][] that is not fully executed immediately. +An `Offer` ledger entry describes an [offer](../../../../concepts/tokens/decentralized-exchange/offers.md) to exchange currencies in the XRP Ledger's [decentralized exchange](../../../../concepts/tokens/decentralized-exchange/index.md). (In finance, this is more traditionally known as an _order_.) You an create a new offer entry by sending an [OfferCreate transaction][] that is not fully executed immediately. -An Offer can become unfunded through other activities in the network, while remaining in the ledger. When processing transactions, the network automatically removes any unfunded Offers that those transactions come across. (Otherwise, unfunded Offers remain, because _only_ transactions can change the ledger state.) +An offer can become unfunded through other activities in the network, while remaining in the ledger. When processing transactions, the network automatically removes any unfunded Offers that those transactions come across. (Otherwise, unfunded Offers remain, because _only_ transactions can change the ledger state.) ## Example {% $frontmatter.seo.title %} JSON @@ -39,19 +39,21 @@ An Offer can become unfunded through other activities in the network, while rema In addition to the [common fields](../common-fields.md), {% code-page-name /%} entries have the following fields: -| Name | JSON Type | [Internal Type][] | Required? | Description | -|:--------------------|:-----------------|:------------------|:----------|:------------| -| `Account` | String | AccountID | Yes | The address of the account that owns this Offer. | -| `BookDirectory` | String | Hash256 | Yes | The ID of the [Offer Directory](directorynode.md) that links to this Offer. | -| `BookNode` | String | UInt64 | Yes | A hint indicating which page of the offer directory links to this entry, in case the directory consists of multiple pages. | -| `Expiration` | Number | UInt32 | No | Indicates the time after which this Offer is considered unfunded. See [Specifying Time][] for details. | -| `LedgerEntryType` | String | UInt16 | Yes | The value `0x006F`, mapped to the string `Offer`, indicates that this is an Offer entry. | -| `OwnerNode` | String | UInt64 | Yes | A hint indicating which page of the owner directory links to this entry, in case the directory consists of multiple pages. | -| `PreviousTxnID` | String | 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. | -| `Sequence` | Number | UInt32 | Yes | The `Sequence` value of the [OfferCreate][] transaction that created this offer. Used in combination with the `Account` to identify this offer. | -| `TakerPays` | [Currency Amount][] | Amount | Yes | The remaining amount and type of currency requested by the Offer creator. | -| `TakerGets` | [Currency Amount][] | Amount | Yes | The remaining amount and type of currency being provided by the Offer creator. | +| Name | JSON Type | [Internal Type][] | Required? | Description | +|:--------------------|:---------------------|:------------------|:----------|:------------| +| `Account` | String - [Address][] | AccountID | Yes | The account that owns this offer. | +| `AdditionalBooks` | Array | Array | No | A list of additional offer directories that link to this offer. This field is only present if this is a hybrid offer in a [permissioned DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md). The array always contains exactly 1 entry. _(Requires the [PermissionedDEX amendment][] {% not-enabled /%})_ | +| `BookDirectory` | String - [Hash][] | Hash256 | Yes | The ID of the [offer directory](directorynode.md) that links to this offer. | +| `BookNode` | String | UInt64 | Yes | A hint indicating which page of the offer directory links to this entry, in case the directory consists of multiple pages. | +| `DomainID` | String - [Hash][] | Hash256 | No | The ledger entry ID of a permissioned domain. If present, this offer belongs to the corresponding [Permissioned DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md). _(Requires the [PermissionedDEX amendment][] {% not-enabled /%})_ | +| `Expiration` | Number | UInt32 | No | Indicates the time after which this offer is considered unfunded. See [Specifying Time][] for details. | +| `LedgerEntryType` | String | UInt16 | Yes | The value `0x006F`, mapped to the string `Offer`, indicates that this is an offer entry. | +| `OwnerNode` | String | UInt64 | Yes | A hint indicating which page of the owner 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. | +| `Sequence` | Number | UInt32 | Yes | The `Sequence` value of the [OfferCreate][] transaction that created this offer. Used in combination with the `Account` to identify this offer. | +| `TakerPays` | [Currency Amount][] | Amount | Yes | The remaining amount and type of currency requested by the offer creator. | +| `TakerGets` | [Currency Amount][] | Amount | Yes | The remaining amount and type of currency being provided by the offer creator. | ## Offer Flags @@ -59,9 +61,9 @@ In addition to the [common fields](../common-fields.md), {% code-page-name /%} e | Flag Name | Hex Value | Decimal Value | Corresponding [OfferCreate Flag](../../transactions/types/offercreate.md#offercreate-flags) | Description | |--------------|--------------|---------------|-------------|------------------------| -| `lsfPassive` | `0x00010000` | 65536 | `tfPassive` | The offer was placed as "passive". This has no effect after the offer is placed into the ledger. | -| `lsfSell` | `0x00020000` | 131072 | `tfSell` | The offer was placed as a "Sell" offer. This has no effect after the offer is placed in the ledger, because `tfSell` only matters if you get a better rate than you asked for, which can only happen when the offer is initially placed. | - +| `lsfPassive` | `0x00010000` | 65536 | `tfPassive` | The offer was placed as passive. This has no effect after the offer is placed into the ledger. | +| `lsfSell` | `0x00020000` | 131072 | `tfSell` | The offer was placed as a sell offer. This has no effect after the offer is placed in the ledger, because `tfSell` only matters if you get a better rate than you asked for, which can only happen when the offer is initially placed. | +| `lsfHybrid` | `0x00040000` | 262144 | `tfHybrid` | The offer was placed as a hybrid offer, which means it is listed in a [permissioned DEX](/docs/concepts/tokens/decentralized-exchange/permissioned-dexes.md) and the open DEX. _(Requires the [PermissionedDEX amendment][] {% not-enabled /%})_ | ## {% $frontmatter.seo.title %} Reserve @@ -73,9 +75,9 @@ In addition to the [common fields](../common-fields.md), {% code-page-name /%} e The ID of an `Offer` entry is the [SHA-512Half][] of the following values, concatenated in order: * The Offer space key (`0x006F`) -* The AccountID of the account placing the Offer -* The Sequence number of the [OfferCreate transaction][] that created the Offer. +* The AccountID of the account placing the offer +* The Sequence number of the [OfferCreate transaction][] that created the offer. - If the OfferCreate transaction used a [Ticket](../../../../concepts/accounts/tickets.md), use the `TicketSequence` value instead. + If the OfferCreate transaction used a [ticket](../../../../concepts/accounts/tickets.md), use the `TicketSequence` value instead. {% raw-partial file="/docs/_snippets/common-links.md" /%} diff --git a/docs/references/protocol/transactions/types/offercreate.md b/docs/references/protocol/transactions/types/offercreate.md index b44a638311f..b518923ae62 100644 --- a/docs/references/protocol/transactions/types/offercreate.md +++ b/docs/references/protocol/transactions/types/offercreate.md @@ -1,6 +1,4 @@ --- -html: offercreate.html -parent: transaction-types.html seo: description: Submit an order to exchange currency. labels: @@ -34,15 +32,15 @@ An OfferCreate transaction places an [Offer](../../../../concepts/tokens/decentr {% tx-example txid="0CD69FD1F0A890CC57CDA430213FD294F7D65FF4A0F379A0D09D07A222D324E6" /%} {% raw-partial file="/docs/_snippets/tx-fields-intro.md" /%} - -| Field | JSON Type | [Internal Type][] | Description | -|:---------------|:--------------------|:------------------|:------------------| -| [`Expiration`](../../../../concepts/tokens/decentralized-exchange/offers.md#offer-expiration) | Number | UInt32 | _(Optional)_ Time after which the Offer is no longer active, in [seconds since the Ripple Epoch][]. | -| `OfferSequence` | Number | UInt32 | _(Optional)_ An Offer to delete first, specified in the same way as [OfferCancel][]. | -| `TakerGets` | [Currency Amount][] | Amount | The amount and type of currency being sold. | -| `TakerPays` | [Currency Amount][] | Amount | The amount and type of currency being bought. | +| Field | JSON Type | [Internal Type][] | Required? | Description | +|:-----------------|:--------------------|:------------------|:----------|-------------| +| `DomainID` | String - [Hash][] | Hash256 | No | The ledger entry ID of a permissioned domain. If provided, restrict this offer to the [permissioned DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md) of that domain. _(Requires the [PermissionedDEX amendment][] {% not-enabled /%})_ | +| [`Expiration`](../../../../concepts/tokens/decentralized-exchange/offers.md#offer-expiration) | Number | UInt32 | No | Time after which the Offer is no longer active, in [seconds since the Ripple Epoch][]. | +| `OfferSequence` | Number | UInt32 | No | An Offer to delete first, specified in the same way as [OfferCancel][]. | +| `TakerGets` | [Currency Amount][] | Amount | Yes | The amount and type of currency being sold. | +| `TakerPays` | [Currency Amount][] | Amount | Yes | The amount and type of currency being bought. | ## OfferCreate Flags @@ -50,31 +48,33 @@ Transactions of the OfferCreate type support additional values in the [`Flags` f | Flag Name | Hex Value | Decimal Value | Description | |:----------------------|:-------------|:--------------|:----------------------| -| `tfPassive` | `0x00010000` | 65536 | If enabled, the Offer does not consume Offers that exactly match it, and instead becomes an Offer object in the ledger. It still consumes Offers that cross it. | -| `tfImmediateOrCancel` | `0x00020000` | 131072 | Treat the Offer as an [Immediate or Cancel order](http://en.wikipedia.org/wiki/Immediate_or_cancel). The Offer never creates an [Offer object][] in the ledger: it only trades as much as it can by consuming existing Offers at the time the transaction is processed. If no Offers match, it executes "successfully" without trading anything. In this case, the transaction still uses the [result code](../transaction-results/index.md) `tesSUCCESS`. | -| `tfFillOrKill` | `0x00040000` | 262144 | Treat the offer as a [Fill or Kill order](http://en.wikipedia.org/wiki/Fill_or_kill). The Offer never creates an [Offer object][] in the ledger, and is canceled if it cannot be fully filled at the time of execution. By default, this means that the owner must receive the full `TakerPays` amount; if the `tfSell` flag is enabled, the owner must be able to spend the entire `TakerGets` amount instead. | +| `tfPassive` | `0x00010000` | 65536 | Do not consume offers that exactly match this one, only offers that cross it. This makes it possible to set up offers in the ledger that peg the exchange rate at a specific value. | +| `tfImmediateOrCancel` | `0x00020000` | 131072 | Treat the offer as an [Immediate or Cancel order](http://en.wikipedia.org/wiki/Immediate_or_cancel) and do not place an [Offer entry][] into the order books. The transaction trades as much as it can by consuming existing offers when it's processed. | +| `tfFillOrKill` | `0x00040000` | 262144 | Treat the offer as a [Fill or Kill order](http://en.wikipedia.org/wiki/Fill_or_kill), do not place an [Offer entry][] into the order books, and cancel the offer if it cannot be fully filled at the time of execution. By default, this means that the owner must receive the full `TakerPays` amount; if the `tfSell` flag is enabled, the owner must be able to spend the entire `TakerGets` amount instead. | | `tfSell` | `0x00080000` | 524288 | Exchange the entire `TakerGets` amount, even if it means obtaining more than the `TakerPays` amount in exchange. | +| `tfHybrid` | `0x00100000` | 1048576 | Make this a hybrid offer that can use both a permissioned DEX and the open DEX. The `DomainID` field must be provided when using this flag. | ## Error Cases | Error Code | Description | |:-------------------------|:--------------------------------------------------| -| `temINVALID_FLAG` | Occurs if the transaction specifies both `tfImmediateOrCancel` and `tfFillOrKill`. | -| `tecEXPIRED` | Occurs if the transaction specifies an `Expiration` time that has already passed. | -| `tecKILLED` | Occurs if the transaction specifies `tfFillOrKill`, and the full amount cannot be filled. If the _[ImmediateOfferKilled amendment][]_ is enabled, this result code also occurs when the transaction specifies `tfImmediateOrCancel` and executes without moving funds (previously, this would return `tesSUCCESS`). | -| `temBAD_EXPIRATION` | Occurs if the transaction contains an `Expiration` field that is not validly formatted. | -| `temBAD_SEQUENCE` | Occurs if the transaction contains an `OfferSequence` that is not validly formatted, or is higher than the transaction's own `Sequence` number. | -| `temBAD_OFFER` | Occurs if the Offer tries to trade XRP for XRP, or tries to trade an invalid or negative amount of a token. | -| `temREDUNDANT` | Occurs if the transaction specifies a token for the same token (same issuer and currency code). | -| `temBAD_CURRENCY` | Occurs if the transaction specifies a token with the currency code "XRP". | -| `temBAD_ISSUER` | Occurs if the transaction specifies a token with an invalid `issuer` value. | -| `tecNO_ISSUER` | Occurs if the transaction specifies a token whose `issuer` value is not a funded account in the ledger. | -| `tecFROZEN` | Occurs if the transaction involves a token on a [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md) trust line (including local and global freezes). Occurs if the `TakerPays` (buy amount) token has been deep-frozen by the issuer. | -| `tecUNFUNDED_OFFER` | Occurs if the owner does not hold a positive amount of the `TakerGets` currency. (Exception: if `TakerGets` specifies a token that the owner issues, the transaction can succeed.) | -| `tecNO_LINE` | Occurs if the transaction involves a token whose issuer uses [Authorized Trust Lines](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md) and the necessary trust line does not exist. | -| `tecNO_AUTH` | Occurs if the transaction involves a token whose issuer uses [Authorized Trust Lines](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md) and the the trust line that would receive the tokens exists but has not been authorized. | -| `tecINSUF_RESERVE_OFFER` | Occurs if the owner does not have enough XRP to meet the reserve requirement of adding a new Offer object to the ledger, and the transaction did not convert any currency. (If the transaction successfully traded any amount, the transaction succeeds with the result code `tesSUCCESS`, but does not create an Offer object in the ledger for the rest.) | -| `tecDIR_FULL` | Occurs if the owner owns too many items in the ledger, or the order book contains too many Offers at the same exchange rate already. | +| `tecDIR_FULL` | The owner owns too many items in the ledger, or the order book contains too many Offers at the same exchange rate already. | +| `tecEXPIRED` | The transaction specifies an `Expiration` time that has already passed. | +| `tecFROZEN` | The transaction involves a token on a [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md) trust line (including local and global freezes). The `TakerPays` (buy amount) token has been deep-frozen by the issuer. | +| `tecINSUF_RESERVE_OFFER` | The owner does not have enough XRP to meet the reserve requirement of adding a new offer ledger entry, and the transaction did not convert any currency. (If the transaction successfully traded any amount, the transaction succeeds with the result code `tesSUCCESS`, but does not create an offer ledger entry for the remainder.) | +| `tecKILLED` | The transaction specifies `tfFillOrKill`, and the full amount cannot be filled. If the _[ImmediateOfferKilled amendment][]_ is enabled, this result code also occurs when the transaction specifies `tfImmediateOrCancel` and executes without moving funds (previously, an Immediate or Cancel offer would return `tesSUCCESS` even if no funds were moved). | +| `tecNO_AUTH` | The transaction involves a token whose issuer uses [Authorized Trust Lines](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md) and the the trust line that would receive the tokens exists but has not been authorized. | +| `tecNO_ISSUER` | The transaction specifies a token whose `issuer` value is not a funded account in the ledger. | +| `tecNO_LINE` | The transaction involves a token whose issuer uses [Authorized Trust Lines](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md) and the necessary trust line does not exist. | +| `tecNO_PERMISSION` | The transaction uses a `DomainID` but the sender is not a member of that domain. _(Requires the [PermissionedDEX amendment][] {% not-enabled /%})_ | +| `tecUNFUNDED_OFFER` | The owner does not hold a positive amount of the `TakerGets` currency. (Exception: if `TakerGets` specifies a token that the owner issues, the transaction can succeed.) | +| `temBAD_CURRENCY` | The transaction specifies a fungible token incorrectly, such as a fungible token with the currency code "XRP". | +| `temBAD_EXPIRATION` | The transaction contains an `Expiration` field that is not validly formatted. | +| `temBAD_ISSUER` | The transaction specifies a token with an invalid `issuer` value. | +| `temBAD_OFFER` | The offer tries to trade XRP for XRP, or tries to trade an invalid or negative amount of a token. | +| `temBAD_SEQUENCE` | The transaction contains an `OfferSequence` that is not validly formatted, or is higher than the transaction's own `Sequence` number. | +| `temINVALID_FLAG` | The transaction specifies an invalid flag combination, such as both `tfImmediateOrCancel` and `tfFillOrKill`, or the transaction uses `tfHybrid` but omits the `DomainID` field. | +| `temREDUNDANT` | The transaction would trade a token for the same token (same issuer and currency code). | {% raw-partial file="/docs/_snippets/common-links.md" /%} diff --git a/docs/references/protocol/transactions/types/payment.md b/docs/references/protocol/transactions/types/payment.md index 98231775e23..571e0828e4f 100644 --- a/docs/references/protocol/transactions/types/payment.md +++ b/docs/references/protocol/transactions/types/payment.md @@ -1,6 +1,4 @@ --- -html: payment.html -parent: transaction-types.html seo: description: Send funds from one account to another. labels: @@ -10,7 +8,7 @@ labels: - Tokens --- # Payment -[[Source]](https://github.com/XRPLF/rippled/blob/5425a90f160711e46b2c1f1c93d68e5941e4bfb6/src/ripple/app/transactors/Payment.cpp "Source") +[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/Payment.cpp "Source") A Payment transaction represents a transfer of value from one account to another. (Depending on the path taken, this can involve additional exchanges of value, which occur atomically.) This transaction type can be used for several [types of payments](#types-of-payments). @@ -44,10 +42,11 @@ Payments are also the only way to [create accounts](#creating-accounts). | `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. | +| `DeliverMin` | [Currency Amount][] | Amount | No | Minimum amount of destination currency this transaction should deliver. Only valid if this is a [partial payment](#partial-payments). | +| `Destination` | String - [Address][] | AccountID | Yes | 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. | +| `DomainID` | String - [Hash][] | Hash256 | No | The ledger entry ID of a permissioned domain. If this is a cross-currency payment, only use the corresponding [permissioned DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md) to convert currency. Both the sender and the recipient must have valid credentials that grant access to the specified domain. This field has no effect if the payment is not cross-currency. _(Requires the [PermissionedDEX amendment][] {% not-enabled /%})_ | +| `InvoiceID` | String - Hexadecimal | Hash256 | No | Arbitrary 256-bit value 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. | @@ -65,7 +64,7 @@ The `Payment` transaction type functions differently depending on how you fill i | [Cross-currency Payment][] | Object (non-XRP) / String (XRP) | Object (non-XRP) / String (XRP) | Usually required | No | Send tokens from one holder to another. The `Amount` or `SendMax` can be XRP or tokens, but can't both be XRP. These payments [ripple through](../../../../concepts/tokens/fungible-tokens/rippling.md) the issuer and can take longer [paths](../../../../concepts/tokens/fungible-tokens/paths.md) through several intermediaries if the transaction specifies a path set. [Transfer fees](../../../../concepts/tokens/transfer-fees.md) set by the issuer(s) apply to this type of transaction. These transactions consume offers in the [decentralized exchange](../../../../concepts/tokens/decentralized-exchange/index.md) to connect different currencies, or currencies with the same currency code and different issuers. | | [Partial payment][] | Object (non-XRP) / String (XRP) | Object (non-XRP) / String (XRP) | Usually required | No | Sends _up to_ a specific amount of any currency. Uses the [`tfPartialPayment` flag](#payment-flags). May include a `DeliverMin` amount specifying the minimum that the transaction must deliver to be successful; if the transaction does not specify `DeliverMin`, it can succeed by delivering _any positive amount_. | | Currency conversion | Object (non-XRP) / String (XRP) | Object (non-XRP) / String (XRP) | Required | Yes | Consumes offers in the [decentralized exchange](../../../../concepts/tokens/decentralized-exchange/index.md) to convert one currency to another, possibly taking [arbitrage](https://en.wikipedia.org/wiki/Arbitrage) opportunities. The `Amount` and `SendMax` cannot both be XRP. Also called a _circular payment_ because it delivers money to the sender. This type of transaction may be classified as an "exchange" and not a "payment". | -| MPT Payment | Object | Omitted | Omitted | Yes | Send MPTs to a holder. See [MPT Payments](#mpt-payments). | +| MPT Payment | Object | Omitted | Omitted | No | Send MPTs to a holder. See [MPT Payments](#mpt-payments). | [Direct XRP Payment]: ../../../../concepts/payment-types/direct-xrp-payments.md [Creating or redeeming tokens]: ../../../../concepts/tokens/index.md @@ -77,11 +76,14 @@ The `Payment` transaction type functions differently depending on how you fill i -Most of the time, the `issuer` field of a non-XRP [Currency Amount][] indicates the issuer of a token. However, when describing payments, there are special rules for the `issuer` field in the `Amount` and `SendMax` fields of a payment. +Most of the time, the `issuer` field of a non-XRP [Currency Amount][] indicates the issuer of a token. However, when describing payments, there are special rules for the `issuer` field in the `DeliverMax` (or `Amount`) and `SendMax` fields of a payment. * There is only ever one balance between two addresses for the same currency code. This means that, sometimes, the `issuer` field of an amount actually refers to a counterparty, instead of the address that issued the token. -* When the `issuer` field of the destination `Amount` field matches the `Destination` address, it is treated as a special case meaning "any issuer that the destination accepts." This includes all addresses to which the destination has trust lines with a positive limit, as well as tokens with the same currency code issued by the destination. -* When the `issuer` field of the `SendMax` field matches the source account's address, it is treated as a special case meaning "any issuer that the source can use." This includes creating new tokens on trust lines that other accounts have extended to the source account, and sending tokens the source account holds from other issuers. +* When the `issuer` field of the destination `DeliverMax` field matches the `Destination` address, it is treated as a special case meaning "any issuer that the destination accepts." This includes all addresses to which the destination has trust lines with a positive limit, as well as tokens issued by the destination itself. +* When the `issuer` field of the `SendMax` field matches the source account's address, it is treated as a special case meaning "any issuer that the source can use." The payment can send tokens the source account already holds, or issue new tokens to others who have trust lines with the source account. + +In all of these cases, the currency code must still match exactly. + ## Creating Accounts @@ -111,7 +113,7 @@ Transactions of the Payment type support additional values in the [`Flags` field | Flag Name | Hex Value | Decimal Value | Description | |:-------------------|:-------------|:--------------|:-----------------------------| | `tfNoRippleDirect` | `0x00010000` | 65536 | Do not use the default path; only use paths included in the `Paths` field. This is intended to force the transaction to take arbitrage opportunities. Most clients do not need this. | -| `tfPartialPayment` | `0x00020000` | 131072 | If the specified `Amount` cannot be sent without spending more than `SendMax`, reduce the received amount instead of failing outright. See [Partial Payments](../../../../concepts/payment-types/partial-payments.md) for more details. | +| `tfPartialPayment` | `0x00020000` | 131072 | If the specified `Amount` cannot be sent without spending more than `SendMax`, reduce the received amount instead of failing outright. See [Partial Payments](#partial-payments) for more details. | | `tfLimitQuality` | `0x00040000` | 262144 | Only take paths where all the conversions have an input:output ratio that is equal or better than the ratio of `Amount`:`SendMax`. See [Limit Quality](#limit-quality) for details. | ## Partial Payments @@ -186,6 +188,10 @@ The credentials provided in the `CredentialIDs` field must all be valid, meaning 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. +{% admonition type="info" name="Note" %} +The `CredentialIDs` field is only used for deposit authorization, not for trading in a [permissioned DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md), even though Permissioned DEXes also use credentials to grant access. To trade in a permissioned DEX, you use the `DomainID` field to specify a domain for which you hold valid credentials. +{% /admonition %} + ## 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. diff --git a/sidebars.yaml b/sidebars.yaml index cfee7096734..d6acf43f656 100644 --- a/sidebars.yaml +++ b/sidebars.yaml @@ -150,6 +150,7 @@ - page: docs/concepts/tokens/decentralized-exchange/ticksize.md - page: docs/concepts/tokens/decentralized-exchange/automated-market-makers.md - page: docs/concepts/tokens/decentralized-exchange/permissioned-domains.md + - page: docs/concepts/tokens/decentralized-exchange/permissioned-dexes.md - page: docs/concepts/accounts/index.md expanded: false items: