From c50e0992659c2bcafac823fb36b46f66dc1f21a3 Mon Sep 17 00:00:00 2001 From: mDuo13 Date: Thu, 12 Jun 2025 13:56:06 -0700 Subject: [PATCH 1/7] Start binary format updates --- docs/references/protocol/binary-format.md | 133 ++++++++++++++-------- 1 file changed, 84 insertions(+), 49 deletions(-) diff --git a/docs/references/protocol/binary-format.md b/docs/references/protocol/binary-format.md index 051b3eb15f..5a2c935009 100644 --- a/docs/references/protocol/binary-format.md +++ b/docs/references/protocol/binary-format.md @@ -15,7 +15,7 @@ curated_anchors: anchor: "#type-list" --- # Binary Format -[[Source]](https://github.com/XRPLF/rippled/blob/develop/src/ripple/protocol/impl/STObject.cpp#L696-L718 "Source") +[[Source]](https://github.com/XRPLF/rippled/blob/develop/include/xrpl/protocol/SField.h "Source") This page describes the XRP Ledger's canonical binary format for transactions and other data. This binary format is necessary to create and verify digital signatures of those transactions' contents, and is also used in other places including in the [peer-to-peer communications between servers](../../concepts/networks-and-servers/peer-protocol.md). The [`rippled` APIs](../http-websocket-apis/index.md) typically use JSON to communicate with client applications. However, JSON is unsuitable as a format for serializing transactions for being digitally signed, because JSON can represent the same data in many different but equivalent ways. @@ -65,9 +65,9 @@ Additionally, many [client libraries](../client-libraries.md) provide serializat ## Internal Format -Each field has an "internal" binary format used in the `rippled` source code to represent that field when signing (and in most other cases). The internal formats for all fields are defined in the source code of [`SField.cpp`](https://github.com/XRPLF/rippled/blob/master/src/ripple/protocol/impl/SField.cpp). (This file also includes fields other than transaction fields.) The [Transaction Format Reference](transactions/index.md) also lists the internal formats for all transaction fields. +Each field has an canonical binary format, or _internal format_ used in the XRP Ledger protocol to represent that field in transactions and ledger data. The binary format is needed for signing, but it is also used in peer-to-peer communications, in ledger storage, and in other places. The binary formats for all fields are defined in the source code of [`SField.h`](https://github.com/XRPLF/rippled/blob/develop/include/xrpl/protocol/SField.h). The JSON format for transactions and ledger data is standardized for convenience, but JSON is only used in APIs and client libraries: strictly speaking, only the binary format exists at the level of the XRP Ledger protocol. -For example, the `Flags` [common transaction field](transactions/common-fields.md) becomes a UInt32 (32-bit unsigned integer). +The [Transaction Format Reference](transactions/index.md) and [Ledger Data Reference](ledger-data/index.md) list both the JSON and the internal (binary) formats for all fields. For example, the `Flags` [common transaction field](transactions/common-fields.md) is a Number in JSON and a UInt32 in binary. Even though the JSON representation uses a data type that can contain decimal places or very large values, the field is limited to values that can be represented as a 32-bit unsigned integer. ### Definitions File @@ -75,6 +75,8 @@ The following JSON file defines the important constants you need for serializing **** +You can also use the [server_definitions API method](http-websocket-apis/public-api-methods/server-info-methods/server_definitions.md) to get the same data from a server. This can be useful when working with dev networks, in-development features, and sidechains with new fields or data types. + The following table defines the top-level fields from the definitions file: | Field | Contents | @@ -99,8 +101,8 @@ The field definition objects in the `FIELDS` array have the following fields: ### Field IDs -[[Source - Encoding]](https://github.com/seelabs/rippled/blob/cecc0ad75849a1d50cc573188ad301ca65519a5b/src/ripple/protocol/impl/Serializer.cpp#L117-L148 "Source") -[[Source - Decoding]](https://github.com/seelabs/rippled/blob/cecc0ad75849a1d50cc573188ad301ca65519a5b/src/ripple/protocol/impl/Serializer.cpp#L484-L509 "Source") +[[Source - Encoding]](https://github.com/XRPLF/rippled/blob/edb4f0342c65bd739fee60b74566f3e771134c6c/src/libxrpl/protocol/Serializer.cpp#L120-L153 "Source") +[[Source - Decoding]](https://github.com/XRPLF/rippled/blob/edb4f0342c65bd739fee60b74566f3e771134c6c/src/libxrpl/protocol/Serializer.cpp#L429-L452 "Source") When you combine a field's type code and field code, you get the field's unique identifier, which is prefixed before the field in the final serialized blob. The size of the Field ID is one to three bytes depending on the type code and field codes it combines. See the following table: @@ -173,38 +175,42 @@ Field codes are reused for fields of different field types, but fields of the sa ## Type List -Transaction instructions may contain fields of any of the following types: +Transactions and ledger entries may contain fields of any of the following types: -| Type Name | Type Code | Bit Length | [Length-prefixed][]? | Description | -|:--------------|:----------|:-----------|:---------------------|----------------| -| [AccountID][] | 8 | 160 | Yes | The unique identifier for an [account](../../concepts/accounts/index.md). | -| [Amount][] | 6 | 64 or 384 | No | An amount of XRP or tokens. The length of the field is 64 bits for XRP or 384 bits (64+160+160) for tokens. | -| [Blob][] | 7 | Variable | Yes | Arbitrary binary data. One important such field is `TxnSignature`, the signature that authorizes a transaction. | -| [Hash128][] | 4 | 128 | No | A 128-bit arbitrary binary value. The only such field is `EmailHash`, which is intended to store the MD-5 hash of an account owner's email for purposes of fetching a [Gravatar](https://www.gravatar.com/). | -| [Hash160][] | 17 | 160 | No | A 160-bit arbitrary binary value. This may define a currency code or issuer. | -| [Hash256][] | 5 | 256 | No | A 256-bit arbitrary binary value. This usually represents the "SHA-512Half" hash of a transaction, ledger version, or ledger data object. | -| [PathSet][] | 18 | Variable | No | A set of possible [payment paths](../../concepts/tokens/fungible-tokens/paths.md) for a [cross-currency payment](../../concepts/payment-types/cross-currency-payments.md). | -| [STArray][] | 15 | Variable | No | An array containing a variable number of members, which can be different types depending on the field. Two cases of this include [memos](transactions/common-fields.md#memos-field) and lists of signers used in [multi-signing](../../concepts/accounts/multi-signing.md). | -| [STIssue][] | 24 | 160 or 320 | No | An asset definition, XRP or a token, with no quantity. | -| [STObject][] | 14 | Variable | No | An object containing one or more nested fields. | -| [UInt8][] | 16 | 8 | No | An 8-bit unsigned integer. | -| [UInt16][] | 1 | 16 | No | A 16-bit unsigned integer. The `TransactionType` is a special case of this type, with specific strings mapping to integer values. | -| [UInt32][] | 2 | 32 | No | A 32-bit unsigned integer. The `Flags` and `Sequence` fields on all transactions are examples of this type. | -| [XChainBridge][] | 25 | Variable | No | A bridge between two blockchains, identified by the door accounts and issued assets on both chains. | +| Type Name | Type Code | Bit Length | [Length-prefixed][]? | Description | +|:-----------------|:----------|:-----------|:---------------------|----------------| +| [AccountID][] | 8 | 160 | Yes | The unique identifier for an [account](../../concepts/accounts/index.md). | +| [Amount][] | 6 | Variable | No | An amount of XRP or tokens. The length of the field is 64 bits for XRP, 384 bits (64+160+160) for fungible tokens, or 264 bits for MPTs. | +| [Array][] | 15 | Variable | No | An array containing a variable number of members, which can be different types depending on the field. Two cases of this include [memos](transactions/common-fields.md#memos-field) and lists of signers used in [multi-signing](../../concepts/accounts/multi-signing.md). | +| [Blob][] | 7 | Variable | Yes | Arbitrary binary data. One important such field is `TxnSignature`, the signature that authorizes a transaction. | +| [Currency][] | 26 | 160 | No | A currency code, such as one used in [price oracles](../../concepts/decentralized-storage/price-oracles.md). | +| [Issue][] | 24 | 160 or 320 | No | An asset definition, XRP or a token, with no quantity. | +| [Object][] | 14 | Variable | No | An object containing one or more nested fields. These "inner" objects may have additional formatting restrictions. | +| [PathSet][] | 18 | Variable | No | A set of possible [payment paths](../../concepts/tokens/fungible-tokens/paths.md) for a [cross-currency payment](../../concepts/payment-types/cross-currency-payments.md). | +| [UInt8][] | 16 | 8 | No | An 8-bit unsigned integer. | +| [UInt16][] | 1 | 16 | No | A 16-bit unsigned integer. The `TransactionType` is a special case of this type, with specific strings mapping to integer values. | +| [UInt32][] | 2 | 32 | No | A 32-bit unsigned integer. The `Flags` and `Sequence` fields on all transactions are examples of this type. | +| [UInt64][] | 3 | 64 | No | A 64-bit unsigned integer. This type does not appear in transaction instructions, but several ledger entries use fields of this type. | +| [UInt96][] | 20 | 96 | No | **UNUSED.** A 96-bit unsigned integer. | +| [UInt128][] | 4 | 128 | No | A 128-bit binary value. The only such field is `EmailHash`, which is intended to store the MD-5 hash of an account owner's email for purposes of fetching a [Gravatar](https://www.gravatar.com/). | +| [UInt160][] | 17 | 160 | No | A 160-bit binary value. This may define a currency code or issuer. | +| [UInt192][] | 21 | 192 | No | A 192-bit binary value. This usually represents an MPT issuance. | +| [UInt256][] | 5 | 256 | No | A 256-bit binary value. This usually represents the hash of a transaction, ledger version, or ledger entry. | +| [Vector256][] | 19 | Variable | Yes | A list of 256-bit binary values. This may be a list of ledger entries or other hash values. | +| [XChainBridge][] | 25 | Variable | No | A bridge between two blockchains, identified by the door accounts and issued assets on both chains. | [Length-prefixed]: #length-prefixing +In the `rippled` source code, some types have an "ST" prefix, which stands for "serialized type". This separates the type definition in the XRP Ledger protocol from data types that may be defined at the programming language level such as arrays or objects. In addition to all of the above field types, the following types may appear in other contexts, such as [ledger objects](ledger-data/ledger-entry-types/index.md) and [transaction metadata](transactions/metadata.md): | Type Name | Type Code | [Length-prefixed]? | Description | |:------------|:----------|:-------------------|:------------------------------| | Transaction | 10001 | No | A "high-level" type containing an entire [transaction](transactions/index.md). | -| LedgerEntry | 10002 | No | A "high-level" type containing an entire [ledger object](ledger-data/ledger-entry-types/index.md). | +| LedgerEntry | 10002 | No | A "high-level" type containing an entire [ledger entry](ledger-data/ledger-entry-types/index.md). | | Validation | 10003 | No | A "high-level" type used in peer-to-peer communications to represent a validation vote in the [consensus process](../../concepts/consensus-protocol/index.md). | | Metadata | 10004 | No | A "high-level" type containing [metadata for one transaction](transactions/metadata.md). | -| [UInt64][] | 3 | No | A 64-bit unsigned integer. This type does not appear in transaction instructions, but several ledger objects use fields of this type. | -| Vector256 | 19 | Yes | This type does not appear in transaction instructions, but the [Amendments ledger object](ledger-data/ledger-entry-types/amendments.md)'s `Amendments` field uses this to represent which [amendments](../../concepts/networks-and-servers/amendments.md) are currently enabled. | ### AccountID Fields @@ -218,23 +224,40 @@ AccountIDs that appear as stand-alone fields (such as `Account` and `Destination ### Amount Fields [Amount]: #amount-fields -The "Amount" type is a special field type that represents an amount of currency, either XRP or a token. This type consists of two sub-types: +The _Amount_ type (also called "STAmount") is a special field type that represents an amount of currency or asset. This type consists of three sub-types, which are XRP, fungible tokens, and multi-purpose tokens (MPTs): - **XRP** - XRP is serialized as a 64-bit unsigned integer (big-endian order), except that the most significant bit is always 0 to indicate that it's XRP, and the second-most-significant bit is `1` to indicate that it is positive. Since the maximum amount of XRP (1017 drops) only requires 57 bits, you can calculate XRP serialized format by taking standard 64-bit unsigned integer and performing a bitwise-OR with `0x4000000000000000`. + XRP is serialized as a 64-bit unsigned integer (big-endian order), except that the most significant bit is always `0`, the second-most-significant bit is `1` to indicate that it is positive, and the third-most-significant bit is `0` to indicate that it is not an MPT. The remaining 61 bits represent the quantity of XRP. Since the maximum amount of XRP (1017 drops) only requires 57 bits, you can calculate XRP serialized format by taking standard 64-bit unsigned integer and performing a bitwise-OR with `0x4000000000000000`. -- **Tokens** +- **Fungible Tokens** - Tokens consist of three segments in order: + Fungible tokens (also called "IOUs") consist of three segments in order: - 1. 64 bits indicating the amount in the [token amount format](#token-amount-format). The first bit is `1` to indicate that this is not XRP. + 1. 64 bits indicating the amount in the [token amount format](#token-amount-format). The first bit is `1` to indicate that this is not XRP nor an MPT. 2. 160 bits indicating the [currency code](data-types/currency-formats.md#currency-codes). The standard API converts 3-character codes such as "USD" into 160-bit codes using the [standard currency code format](data-types/currency-formats.md#standard-currency-codes), but custom 160-bit codes are also possible. 3. 160 bits indicating the issuer's Account ID. (See also: [Account Address Encoding](../../concepts/accounts/addresses.md#address-encoding)) -You can tell which of the two sub-types it is based on the first bit: `0` for XRP; `1` for tokens. +- **MPTs** -The following diagram shows the serialization formats for both XRP amounts and token amounts: + Multi-Purpose Tokens (MPTs) consist of four segments in order: + + 1. 8 bits indicating that this is an MPT. The most significant bit is `0` to indicate that it's not a fungible token. The second bit is `1` to indicate that it is postiive. The third most significant bit is `1` to indicate that it is an MPT. The remaining 5 bits are reserved and must all be `0`. + 2. 64 bits indicating the quantity of the MPT, as a 64-bit _signed_ integer. (However, in most contexts, negative amounts are not allowed.) + 3. 32 bits indicating the `Sequence` number of the transaction that created the MPT issuance. + 4. 160 bits indicating the [AccountID][] of the MPT's issuer. + +You can tell which of the three sub-types an amount is based on the first and third most significant bits: + + - If the first bit is a `1`, it's a fungible token (IOU). + - If the first bit and third bit are both `0`, it's XRP. + - If the first bit is a `0` and the third bit is a `1`, it's an MPT. + +{% admonition type="warning" title="Caution" %} +Not all types of amount are valid in all places. Some fields can only represent XRP, or XRP and fungible tokens but not MPTs. These limitations are defined by the individual transactions and ledger entries. +{% /admonition %} + +The following diagram shows the serialization formats for both XRP amounts and token amounts: ***TODO: update*** [{% inline-svg file="/docs/img/serialization-amount.svg" /%}](/docs/img/serialization-amount.svg 'XRP amounts have a "not XRP" bit, a sign bit, and 62 bits of precision. Token amounts consist of a "not XRP" bit, a sign bit, an exponent (8 bits), significant digits (54 bits), currency code (160 bits), and issuer (160 bits).') @@ -271,11 +294,14 @@ The [`rippled` APIs](../http-websocket-apis/index.md) support a **standard forma The **nonstandard format** is any 160 bits of data as long as the first 8 bits are not `0x00`. +#### MPT Amount Format + +The following diagram shows the amount serialization for MPTs. ***TODO: consolidate or not?*** ### Array Fields -[STArray]: #array-fields +[Array]: #array-fields -Some transaction fields, such as `SignerEntries` (in [SignerListSet transactions][]) and [`Memos`](transactions/common-fields.md#memos-field), are arrays of objects (called the "STArray" type). +Some transaction fields, such as `SignerEntries` (in [SignerListSet transactions][]) and [`Memos`](transactions/common-fields.md#memos-field), are arrays of objects. (Also called the "STArray" type). Arrays contain several [object fields](#object-fields) in their native binary format in a specific order. In JSON, each array member is a JSON "wrapper" object with a single field, which is the name of the member object field. The value of that field is the ("inner") object itself. @@ -289,25 +315,23 @@ The following example shows the serialization format for an array (the `SignerEn ### Blob Fields [Blob]: #blob-fields -The Blob type is a [length-prefixed](#length-prefixing) field with arbitrary data. Two common fields that use this type are `SigningPubKey` and `TxnSignature`, which contain (respectively) the public key and signature that authorize a transaction to be executed. +The _Blob_ type (also called "STBlob") is a [length-prefixed](#length-prefixing) field with arbitrary data. Two common fields that use this type are `SigningPubKey` and `TxnSignature`, which contain (respectively) the public key and signature that authorize a transaction to be executed. Blob fields have no further structure to their contents, so they consist of exactly the amount of bytes indicated in the variable-length encoding, after the Field ID and length prefixes. -### Hash Fields -[Hash128]: #hash-fields -[Hash160]: #hash-fields -[Hash256]: #hash-fields +### Currency Fields +[Currency]: #currency-fields -The XRP Ledger has several "hash" types: Hash128, Hash160, and Hash256. These fields contain arbitrary binary data of the given number of bits, which may or may not represent the result of a hash operation. +Some fields specify a currency code, which could be an a fungible token, the ticker symbol for an off-ledger asset, or some other identifier for a currency. This field type is currently used only in [Price Oracles](../../concepts/decentralized-storage/price-oracles.md). -All such fields are serialized as the specific number of bits, with no length indicator, in big-endian byte order. +These fields consists of 160 bits of binary data. If the data matches the ["standard" currency code format](#currency-codes), it may be represented as a three-letter currency code string in JSON. Otherwise, it is represented as hexadecimal. Client libraries _may_ attempt to interpret this as a string of ASCII or UTF-8, but it is not guaranteed to be valid. ### Issue Fields -[STIssue]: #issue-fields +[Issue]: #issue-fields -Some fields specify a _type_ of asset, which could be XRP or a fungible [token](../../concepts/tokens/index.md), without an amount. These fields have consist of one or two 160-bit segments in order: +Some fields specify a _type_ of asset, which could be XRP or a fungible [token](../../concepts/tokens/index.md), without an amount. This field is also called "STIssue". These fields have consist of one or two 160-bit segments in order: 1. The first 160 bits are the [currency code](#currency-codes) of the asset. For XRP, this is all 0's. 2. If the first 160 bits are all 0's (the asset is XRP), the field ends there. Otherwise, the asset is a token and the next 160 bits are the [AccountID of the token issuer](#accountid-fields). @@ -363,12 +387,23 @@ The following example shows the serialization format for a PathSet: [UInt16]: #uint-fields [UInt32]: #uint-fields [UInt64]: #uint-fields +[UInt96]: #uint-fields +[UInt128]: #uint-fields +[UInt160]: #uint-fields +[UInt256]: #uint-fields -The XRP Ledger has several unsigned integer types: UInt8, UInt16, UInt32, and UInt64. All of these are standard big-endian binary unsigned integers with the specified number of bits. +The XRP Ledger has several unsigned integer types: UInt8, UInt16, UInt32, UInt64, UInt128, UInt160, and UInt256. All of these are standard big-endian binary unsigned integers with the specified number of bits. The larger types such as UInt128, UInt160, and UInt256 were previously named Hash128, Hash160, and Hash256 because they often contain hash function outputs. -When representing these fields in JSON objects, most are represented as JSON numbers by default. One exception is UInt64, which is represented as a string because some JSON decoders may try to represent these integers as 64-bit "double precision" floating point numbers, which cannot represent all distinct UInt64 values with full precision. +When representing these fields in JSON, these fields may be represented as JSON numbers, strings containing hexadecimal, or as strings containing decimal numbers, depending on the bit size and intended use of the data. UInt64 and up are never converted to JSON numbers, because some JSON decoders may try to represent them as "double precision" floating point numbers, which cannot represent all distinct UInt64 values with full precision. UInt128 and UInt256 typically represent hash values or arbitrary data, so they are typically represented in JSON as hexadecimal. -Another special case is the `TransactionType` field. In JSON, this field is conventionally represented as a string with the name of the transaction type, but in binary, this field is a UInt16. The `TRANSACTION_TYPES` object in the [definitions file](#definitions-file) maps these strings to specific numeric values. +The `TransactionType` field is a special case. In JSON, this field is conventionally represented as a string with the name of the transaction type. In binary, this field is a UInt16. The `TRANSACTION_TYPES` object in the [definitions file](#definitions-file) maps these strings to the numeric values used in the binary format. + +### Vector256 Fields +[Vector256]: #vector256-fields + +The _Vector256_ type contains a list of 256-bit values. This field consists of a multiple of 256 bits following the [length prefix](#length-prefixing). Unlike the [Array][] type, which can contain a mix of different nested object types of varying lengths, each member of a Vector256 field is exactly 256 bits with no type prefix. + +The members of a Vector256 field may be [ledger entry IDs](protocol/ledger-data/common-fields.md#ledger-entry-id). However, they can also be Amendment IDs, ledger hashes, or other binary data. ### XChainBridge Fields @@ -379,11 +414,11 @@ Another special case is the `TransactionType` field. In JSON, this field is conv The `XChainBridge` field, used in transactions and ledger entries related to [cross-chain bridges](../../concepts/xrpl-sidechains/cross-chain-bridges.md), is the only field of the XChainBridge type. It consists of 4 parts which together define a bridge between blockchains: - The locking chain door account, a length-prefixed [AccountID][]. -- The locking chain asset type, an [STIssue][]. +- The locking chain asset type, an [Issue][]. - The issuing chain door account, a length-prefixed [AccountID][]. -- The issuing chain asset type, an [STIssue][]. +- The issuing chain asset type, an [Issue][]. -The two nested [STIssue][] types are each either 160 or 320 bits. The STIssue field is 160 bits if the currency code it contains is all 0's, meaning that the bridged asset is the native asset of its respective chain, for example XRP on the XRP Ledger Mainnet. If the currency code is nonzero, then the STIssue field also contains the (non-length-prefixed) AccountID of the token's issuer on its native chain. +The two nested [Issue][] types are each either 160 or 320 bits. The Issue field is 160 bits if the currency code it contains is all 0's, meaning that the bridged asset is the native asset of its respective chain, for example XRP on the XRP Ledger Mainnet. If the currency code is nonzero, then the Issue field also contains the (non-length-prefixed) AccountID of the token's issuer on its native chain. {% admonition type="info" name="Note" %}The door AccountID values are length-prefixed, but the issuer AccountID values are not.{% /admonition %} From 824c335d08d1d1d143f1b94e8a5010d247805e1a Mon Sep 17 00:00:00 2001 From: mDuo13 Date: Fri, 20 Jun 2025 17:24:50 -0700 Subject: [PATCH 2/7] Binary Format updates w/ new types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add Currency, Issue, Number, and additional UInt fields. - Harmonize type names with updated names from the code (for example, Hash128→UInt128) - Update Python sample code for binary serialization. - TODO: Add test cases and confirm implementation of new types - TODO: Update JavaScript sample code. --- .../tx-serialization/py/serialize.py | 71 ++++++++++++++++--- docs/references/protocol/binary-format.md | 8 ++- 2 files changed, 67 insertions(+), 12 deletions(-) diff --git a/_code-samples/tx-serialization/py/serialize.py b/_code-samples/tx-serialization/py/serialize.py index ca1311c07f..288d7a34ef 100755 --- a/_code-samples/tx-serialization/py/serialize.py +++ b/_code-samples/tx-serialization/py/serialize.py @@ -1,9 +1,8 @@ #!/usr/bin/env python3 -# Transaction Serialization Sample Code (Python3 version) +# Transaction Serialization Sample Code (Python version) # Author: rome@ripple.com -# Copyright Ripple 2018 -# Requires Python 3.5+ because of bytes.hex() +# Copyright Ripple 2018-2025 import argparse import json @@ -135,9 +134,11 @@ def accountid_to_bytes(address): def amount_to_bytes(a): """ Serializes an "Amount" type, which can be either XRP or an issued currency: - - XRP: 64 bits; 0, followed by 1 ("is positive"), followed by 62 bit UInt amount - - Issued Currency: 64 bits of amount, followed by 160 bit currency code and + - XRP: total 64 bits: 0, followed by 1 ("is positive"), then 0, then 61 bit UInt amount + - Issued Currency: total 384 bits: 64 bits of amount, followed by 160 bit currency code and 160 bit issuer AccountID. + - MPT: 8-bit header with the binary value 01100000 (0x60), then 64 bit UInt amount, + 32 bit Sequence number, and 160 bit issuer AccountID. """ if type(a) == str: # is XRP @@ -194,6 +195,13 @@ def blob_to_bytes(field_val): vl_contents = bytes.fromhex(field_val) return vl_encode(vl_contents) +def currency_to_bytes(currency): + """ + Serializes a Currency-type field, which can be either 3-character string or + 160-bit hexadecimal. + """ + return currency_code_to_bytes(currency, xrp_ok=True) + def currency_code_to_bytes(code_string, xrp_ok=False): if re.match(r"^[A-Za-z0-9?!@#$%^&*<>(){}\[\]|]{3}$", code_string): # ISO 4217-like code @@ -216,7 +224,7 @@ def currency_code_to_bytes(code_string, xrp_ok=False): return b''.join( ( bytes(12), code_ascii, bytes(5) ) ) elif re.match(r"^[0-9a-fA-F]{40}$", code_string): # raw hex code - return bytes.fromhex(code_string) # requires Python 3.5+ + return bytes.fromhex(code_string) else: raise ValueError("invalid currency code") @@ -224,30 +232,54 @@ def hash128_to_bytes(contents): """ Serializes a hexadecimal string as binary and confirms that it's 128 bits """ - b = hash_to_bytes(contents) + b = hex_to_bytes(contents) if len(b) != 16: # 16 bytes = 128 bits raise ValueError("Hash128 is not 128 bits long") return b def hash160_to_bytes(contents): - b = hash_to_bytes(contents) + b = hex_to_bytes(contents) if len(b) != 20: # 20 bytes = 160 bits raise ValueError("Hash160 is not 160 bits long") return b def hash256_to_bytes(contents): - b = hash_to_bytes(contents) + b = hex_to_bytes(contents) if len(b) != 32: # 32 bytes = 256 bits raise ValueError("Hash256 is not 256 bits long") return b -def hash_to_bytes(contents): +def hex_to_bytes(contents): """ Helper function; serializes a hash value from a hexadecimal string of any length. """ return bytes.fromhex(field_val) +def issue_to_bytes(issue): + """ + Serialize an Issue-type field, which defines a fungible token or XRP + without a quantity. + """ + if type(issue) != dict: + raise ValueError("Issue field must be provided as dictionary") + if len(issue.keys()) == 1 and issue.get("currency") != "XRP": + raise ValueError("Issue field must provide currency and issuer unless currency is XRP") + elif sorted(issue.keys()) != ["currency", "issuer"]: + raise ValueError("Issue field must provide currency and issuer unless currency is XRP") + + currency_code = currency_code_to_bytes(issue["currency"]) + address = decode_address(issue["issuer"]) + return currency_code + address + +def number_to_bytes(str_num): + """ + Serialize a Number-type field, which is a stand-alone quantity in the same + floating point format as a fungible token amount. + """ + amt = IssuedAmount(str_num) + return amt.to_bytes() + def object_to_bytes(obj): """ Serialize an object from decoded JSON. @@ -349,6 +381,18 @@ def uint16_to_bytes(i): def uint32_to_bytes(i): return i.to_bytes(4, byteorder="big", signed=False) +def uint64_to_bytes(i): + # Unlike smaller UInts, UInt64 is serialized as hex in JSON + b = hex_to_bytes(i) + if len(b) != 8: # 8 bytes = 64 bits + raise ValueError("UInt64 is not 64 bits long") + return b + +def uint384_to_bytes(i): + b = hex_to_bytes(i) + if len(b) != 8: # 8 bytes = 64 bits + raise ValueError("UInt64 is not 64 bits long") + return b # Core serialization logic ----------------------------------------------------- @@ -372,15 +416,20 @@ def field_to_bytes(field_name, field_val): "AccountID": accountid_to_bytes, "Amount": amount_to_bytes, "Blob": blob_to_bytes, - "Hash128": hash128_to_bytes, + "Currency": currency_to_bytes, + "Hash128": hash128_to_bytes, # aka UInt128 "Hash160": hash160_to_bytes, "Hash256": hash256_to_bytes, + "Issue": issue_to_bytes, + "Number": number_to_bytes, "PathSet": pathset_to_bytes, "STArray": array_to_bytes, "STObject": object_to_bytes, "UInt8" : uint8_to_bytes, "UInt16": uint16_to_bytes, "UInt32": uint32_to_bytes, + "UInt64": uint64_to_bytes, + "UInt384": uint384_to_bytes, } field_binary = dispatch[field_type](field_val) return b''.join( (id_prefix, field_binary) ) diff --git a/docs/references/protocol/binary-format.md b/docs/references/protocol/binary-format.md index 5a2c935009..199871ca05 100644 --- a/docs/references/protocol/binary-format.md +++ b/docs/references/protocol/binary-format.md @@ -196,6 +196,8 @@ Transactions and ledger entries may contain fields of any of the following types | [UInt160][] | 17 | 160 | No | A 160-bit binary value. This may define a currency code or issuer. | | [UInt192][] | 21 | 192 | No | A 192-bit binary value. This usually represents an MPT issuance. | | [UInt256][] | 5 | 256 | No | A 256-bit binary value. This usually represents the hash of a transaction, ledger version, or ledger entry. | +| [UInt384][] | 22 | 384 | No | **UNUSED.** A 384-bit binary value. | +| [UInt512][] | 23 | 512 | No | **UNUSED.** A 512-bit binary value. | | [Vector256][] | 19 | Variable | Yes | A list of 256-bit binary values. This may be a list of ledger entries or other hash values. | | [XChainBridge][] | 25 | Variable | No | A bridge between two blockchains, identified by the door accounts and issued assets on both chains. | @@ -391,11 +393,15 @@ The following example shows the serialization format for a PathSet: [UInt128]: #uint-fields [UInt160]: #uint-fields [UInt256]: #uint-fields +[UInt384]: #uint-fields +[UInt512]: #uint-fields -The XRP Ledger has several unsigned integer types: UInt8, UInt16, UInt32, UInt64, UInt128, UInt160, and UInt256. All of these are standard big-endian binary unsigned integers with the specified number of bits. The larger types such as UInt128, UInt160, and UInt256 were previously named Hash128, Hash160, and Hash256 because they often contain hash function outputs. +The XRP Ledger has several unsigned integer types: UInt8, UInt16, UInt32, UInt64, UInt128, UInt160, and UInt256. All of these are standard big-endian binary unsigned integers with the specified number of bits. The larger types such as UInt128, UInt160, and UInt256 were previously named `Hash128`, `Hash160`, and `Hash256` because they often contain hash function outputs. (These names are still used in the definitions file.) When representing these fields in JSON, these fields may be represented as JSON numbers, strings containing hexadecimal, or as strings containing decimal numbers, depending on the bit size and intended use of the data. UInt64 and up are never converted to JSON numbers, because some JSON decoders may try to represent them as "double precision" floating point numbers, which cannot represent all distinct UInt64 values with full precision. UInt128 and UInt256 typically represent hash values or arbitrary data, so they are typically represented in JSON as hexadecimal. +The types UInt96, UInt384, and UInt512 are currently defined but not used. + The `TransactionType` field is a special case. In JSON, this field is conventionally represented as a string with the name of the transaction type. In binary, this field is a UInt16. The `TRANSACTION_TYPES` object in the [definitions file](#definitions-file) maps these strings to the numeric values used in the binary format. ### Vector256 Fields From b15f1392b01e6d592b56870b8f064aca8d4b1f0e Mon Sep 17 00:00:00 2001 From: mDuo13 Date: Mon, 23 Jun 2025 18:00:49 -0700 Subject: [PATCH 3/7] Binary serialization: update defs, fix bugs, add test cases --- .../tx-serialization/py/definitions.json | 4651 +++++++++++------ .../tx-serialization/py/serialize.py | 20 +- .../py/test-cases/tx4-binary.txt | 1 + .../tx-serialization/py/test-cases/tx4.json | 13 + .../py/test-cases/tx5-binary.txt | 1 + .../tx-serialization/py/test-cases/tx5.json | 19 + 6 files changed, 3242 insertions(+), 1463 deletions(-) create mode 100644 _code-samples/tx-serialization/py/test-cases/tx4-binary.txt create mode 100644 _code-samples/tx-serialization/py/test-cases/tx4.json create mode 100644 _code-samples/tx-serialization/py/test-cases/tx5-binary.txt create mode 100644 _code-samples/tx-serialization/py/test-cases/tx5.json diff --git a/_code-samples/tx-serialization/py/definitions.json b/_code-samples/tx-serialization/py/definitions.json index cf07fbb033..4899a4df01 100644 --- a/_code-samples/tx-serialization/py/definitions.json +++ b/_code-samples/tx-serialization/py/definitions.json @@ -1,1663 +1,3390 @@ { - "TYPES": { - "Validation": 10003, - "Done": -1, - "Hash128": 4, - "Blob": 7, - "AccountID": 8, - "Amount": 6, - "Hash256": 5, - "UInt8": 16, - "Vector256": 19, - "STObject": 14, - "Unknown": -2, - "Transaction": 10001, - "Hash160": 17, - "PathSet": 18, - "LedgerEntry": 10002, - "UInt16": 1, - "NotPresent": 0, - "UInt64": 3, - "UInt32": 2, - "STArray": 15 - }, - "LEDGER_ENTRY_TYPES": { - "Any": -3, - "Child": -2, - "Invalid": -1, - "AccountRoot": 97, - "DirectoryNode": 100, - "RippleState": 114, - "Ticket": 84, - "SignerList": 83, - "Offer": 111, - "LedgerHashes": 104, - "Amendments": 102, - "FeeSettings": 115, - "Escrow": 117, - "PayChannel": 120, - "DepositPreauth": 112, - "Check": 67, - "Nickname": 110, - "Contract": 99, - "GeneratorMap": 103 - }, "FIELDS": [ [ "Generic", { - "nth": 0, - "isVLEncoded": false, "isSerialized": false, "isSigningField": false, + "isVLEncoded": false, + "nth": 0, "type": "Unknown" } ], [ "Invalid", { + "isSerialized": false, + "isSigningField": false, + "isVLEncoded": false, "nth": -1, - "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, "type": "Unknown" } ], - [ - "LedgerEntryType", - { - "nth": 1, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt16" - } - ], - [ - "TransactionType", - { - "nth": 2, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt16" - } - ], - [ - "SignerWeight", - { - "nth": 3, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt16" - } - ], - [ - "Flags", - { - "nth": 2, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "SourceTag", - { - "nth": 3, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "Sequence", - { - "nth": 4, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "PreviousTxnLgrSeq", - { - "nth": 5, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "LedgerSequence", - { - "nth": 6, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "CloseTime", - { - "nth": 7, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "ParentCloseTime", - { - "nth": 8, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "SigningTime", - { - "nth": 9, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "Expiration", - { - "nth": 10, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "TransferRate", - { - "nth": 11, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "WalletSize", - { - "nth": 12, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "OwnerCount", - { - "nth": 13, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "DestinationTag", - { - "nth": 14, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "HighQualityIn", - { - "nth": 16, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "HighQualityOut", - { - "nth": 17, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "LowQualityIn", - { - "nth": 18, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "LowQualityOut", - { - "nth": 19, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "QualityIn", - { - "nth": 20, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "QualityOut", - { - "nth": 21, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "StampEscrow", - { - "nth": 22, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "BondAmount", - { - "nth": 23, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "LoadFee", - { - "nth": 24, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "OfferSequence", - { - "nth": 25, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "FirstLedgerSequence", - { - "nth": 26, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "LastLedgerSequence", - { - "nth": 27, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "TransactionIndex", - { - "nth": 28, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "OperationLimit", - { - "nth": 29, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "ReferenceFeeUnits", - { - "nth": 30, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "ReserveBase", - { - "nth": 31, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "ReserveIncrement", - { - "nth": 32, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "SetFlag", - { - "nth": 33, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "ClearFlag", - { - "nth": 34, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "SignerQuorum", - { - "nth": 35, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "CancelAfter", - { - "nth": 36, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "FinishAfter", - { - "nth": 37, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "IndexNext", - { - "nth": 1, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "IndexPrevious", - { - "nth": 2, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "BookNode", - { - "nth": 3, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "OwnerNode", - { - "nth": 4, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "BaseFee", - { - "nth": 5, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "ExchangeRate", - { - "nth": 6, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "LowNode", - { - "nth": 7, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "HighNode", - { - "nth": 8, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt64" - } - ], - [ - "EmailHash", - { - "nth": 1, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash128" - } - ], - [ - "LedgerHash", - { - "nth": 1, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "ParentHash", - { - "nth": 2, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "TransactionHash", - { - "nth": 3, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "AccountHash", - { - "nth": 4, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "PreviousTxnID", - { - "nth": 5, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "LedgerIndex", - { - "nth": 6, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "WalletLocator", - { - "nth": 7, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "RootIndex", - { - "nth": 8, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "AccountTxnID", - { - "nth": 9, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "BookDirectory", - { - "nth": 16, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "InvoiceID", - { - "nth": 17, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "Nickname", - { - "nth": 18, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "Amendment", - { - "nth": 19, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "TicketID", - { - "nth": 20, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "Digest", - { - "nth": 21, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash256" - } - ], - [ - "hash", - { - "nth": 257, - "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "Hash256" - } - ], - [ - "index", - { - "nth": 258, - "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "Hash256" - } - ], - [ - "Amount", - { - "nth": 1, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "Balance", - { - "nth": 2, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "LimitAmount", - { - "nth": 3, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "TakerPays", - { - "nth": 4, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "TakerGets", - { - "nth": 5, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "LowLimit", - { - "nth": 6, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "HighLimit", - { - "nth": 7, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "Fee", - { - "nth": 8, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "SendMax", - { - "nth": 9, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "DeliverMin", - { - "nth": 10, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "MinimumOffer", - { - "nth": 16, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "RippleEscrow", - { - "nth": 17, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "DeliveredAmount", - { - "nth": 18, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "taker_gets_funded", - { - "nth": 258, - "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "Amount" - } - ], - [ - "taker_pays_funded", - { - "nth": 259, - "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "Amount" - } - ], - [ - "PublicKey", - { - "nth": 1, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "MessageKey", - { - "nth": 2, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "SigningPubKey", - { - "nth": 3, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "TxnSignature", - { - "nth": 4, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": false, - "type": "Blob" - } - ], - [ - "Generator", - { - "nth": 5, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "Signature", - { - "nth": 6, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": false, - "type": "Blob" - } - ], - [ - "Domain", - { - "nth": 7, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "FundCode", - { - "nth": 8, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "RemoveCode", - { - "nth": 9, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "ExpireCode", - { - "nth": 10, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "CreateCode", - { - "nth": 11, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "MemoType", - { - "nth": 12, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "MemoData", - { - "nth": 13, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "MemoFormat", - { - "nth": 14, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "Fulfillment", - { - "nth": 16, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "Condition", - { - "nth": 17, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "Blob" - } - ], - [ - "MasterSignature", - { - "nth": 18, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": false, - "type": "Blob" - } - ], - [ - "Account", - { - "nth": 1, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "AccountID" - } - ], - [ - "Owner", - { - "nth": 2, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "AccountID" - } - ], - [ - "Destination", - { - "nth": 3, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "AccountID" - } - ], - [ - "Issuer", - { - "nth": 4, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "AccountID" - } - ], - [ - "Authorize", - { - "nth": 5, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "AccountID" - } - ], - [ - "Unauthorize", - { - "nth": 6, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "AccountID" - } - ], - [ - "Target", - { - "nth": 7, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "AccountID" - } - ], - [ - "RegularKey", - { - "nth": 8, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "AccountID" - } - ], [ "ObjectEndMarker", { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, "nth": 1, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "TransactionMetaData", - { - "nth": 2, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "CreatedNode", - { - "nth": 3, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "DeletedNode", - { - "nth": 4, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "ModifiedNode", - { - "nth": 5, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "PreviousFields", - { - "nth": 6, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "FinalFields", - { - "nth": 7, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "NewFields", - { - "nth": 8, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "TemplateEntry", - { - "nth": 9, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "Memo", - { - "nth": 10, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "SignerEntry", - { - "nth": 11, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "Signer", - { - "nth": 16, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "Majority", - { - "nth": 18, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, "type": "STObject" } ], [ "ArrayEndMarker", { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, "nth": 1, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, "type": "STArray" } ], [ - "Signers", + "taker_gets_funded", { - "nth": 3, - "isVLEncoded": false, - "isSerialized": true, + "isSerialized": false, "isSigningField": false, - "type": "STArray" + "isVLEncoded": false, + "nth": 258, + "type": "Amount" } ], [ - "SignerEntries", + "taker_pays_funded", { - "nth": 4, + "isSerialized": false, + "isSigningField": false, "isVLEncoded": false, + "nth": 259, + "type": "Amount" + } + ], + [ + "LedgerEntryType", + { "isSerialized": true, "isSigningField": true, - "type": "STArray" + "isVLEncoded": false, + "nth": 1, + "type": "UInt16" } ], [ - "Template", + "TransactionType", { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 2, + "type": "UInt16" + } + ], + [ + "SignerWeight", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 3, + "type": "UInt16" + } + ], + [ + "TransferFee", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 4, + "type": "UInt16" + } + ], + [ + "TradingFee", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, "nth": 5, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STArray" + "type": "UInt16" } ], [ - "Necessary", + "DiscountedFee", { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, "nth": 6, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STArray" + "type": "UInt16" } ], [ - "Sufficient", + "Version", { - "nth": 7, - "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "STArray" - } - ], - [ - "AffectedNodes", - { - "nth": 8, "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STArray" - } - ], - [ - "Memos", - { - "nth": 9, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STArray" - } - ], - [ - "Majorities", - { "nth": 16, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STArray" + "type": "UInt16" } ], [ - "CloseResolution", + "HookStateChangeCount", { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 17, + "type": "UInt16" + } + ], + [ + "HookEmitCount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 18, + "type": "UInt16" + } + ], + [ + "HookExecutionIndex", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 19, + "type": "UInt16" + } + ], + [ + "HookApiVersion", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 20, + "type": "UInt16" + } + ], + [ + "LedgerFixType", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 21, + "type": "UInt16" + } + ], + [ + "NetworkID", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, "nth": 1, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt8" + "type": "UInt32" } ], [ - "Method", + "Flags", { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, "nth": 2, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt8" + "type": "UInt32" } ], [ - "TransactionResult", + "SourceTag", { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, "nth": 3, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt8" + "type": "UInt32" } ], [ - "TakerPaysCurrency", + "Sequence", { - "nth": 1, - "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Hash160" - } - ], - [ - "TakerPaysIssuer", - { - "nth": 2, "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash160" - } - ], - [ - "TakerGetsCurrency", - { - "nth": 3, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash160" - } - ], - [ - "TakerGetsIssuer", - { "nth": 4, - "isVLEncoded": false, + "type": "UInt32" + } + ], + [ + "PreviousTxnLgrSeq", + { "isSerialized": true, "isSigningField": true, - "type": "Hash160" + "isVLEncoded": false, + "nth": 5, + "type": "UInt32" } ], [ - "Paths", + "LedgerSequence", { - "nth": 1, - "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "PathSet" + "isVLEncoded": false, + "nth": 6, + "type": "UInt32" } ], [ - "Indexes", + "CloseTime", { - "nth": 1, - "isVLEncoded": true, "isSerialized": true, "isSigningField": true, - "type": "Vector256" + "isVLEncoded": false, + "nth": 7, + "type": "UInt32" } ], [ - "Hashes", + "ParentCloseTime", { - "nth": 2, - "isVLEncoded": true, "isSerialized": true, "isSigningField": true, - "type": "Vector256" + "isVLEncoded": false, + "nth": 8, + "type": "UInt32" } ], [ - "Amendments", + "SigningTime", { - "nth": 3, - "isVLEncoded": true, "isSerialized": true, "isSigningField": true, - "type": "Vector256" + "isVLEncoded": false, + "nth": 9, + "type": "UInt32" } ], [ - "Transaction", + "Expiration", { - "nth": 1, + "isSerialized": true, + "isSigningField": true, "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "Transaction" + "nth": 10, + "type": "UInt32" } ], [ - "LedgerEntry", + "TransferRate", { - "nth": 1, + "isSerialized": true, + "isSigningField": true, "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "LedgerEntry" + "nth": 11, + "type": "UInt32" } ], [ - "Validation", + "WalletSize", { - "nth": 1, + "isSerialized": true, + "isSigningField": true, "isVLEncoded": false, - "isSerialized": false, - "isSigningField": false, - "type": "Validation" + "nth": 12, + "type": "UInt32" + } + ], + [ + "OwnerCount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 13, + "type": "UInt32" + } + ], + [ + "DestinationTag", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 14, + "type": "UInt32" + } + ], + [ + "LastUpdateTime", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 15, + "type": "UInt32" + } + ], + [ + "HighQualityIn", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 16, + "type": "UInt32" + } + ], + [ + "HighQualityOut", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 17, + "type": "UInt32" + } + ], + [ + "LowQualityIn", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 18, + "type": "UInt32" + } + ], + [ + "LowQualityOut", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 19, + "type": "UInt32" + } + ], + [ + "QualityIn", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 20, + "type": "UInt32" + } + ], + [ + "QualityOut", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 21, + "type": "UInt32" + } + ], + [ + "StampEscrow", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 22, + "type": "UInt32" + } + ], + [ + "BondAmount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 23, + "type": "UInt32" + } + ], + [ + "LoadFee", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 24, + "type": "UInt32" + } + ], + [ + "OfferSequence", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 25, + "type": "UInt32" + } + ], + [ + "FirstLedgerSequence", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 26, + "type": "UInt32" + } + ], + [ + "LastLedgerSequence", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 27, + "type": "UInt32" + } + ], + [ + "TransactionIndex", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 28, + "type": "UInt32" + } + ], + [ + "OperationLimit", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 29, + "type": "UInt32" + } + ], + [ + "ReferenceFeeUnits", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 30, + "type": "UInt32" + } + ], + [ + "ReserveBase", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 31, + "type": "UInt32" + } + ], + [ + "ReserveIncrement", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 32, + "type": "UInt32" + } + ], + [ + "SetFlag", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 33, + "type": "UInt32" + } + ], + [ + "ClearFlag", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 34, + "type": "UInt32" + } + ], + [ + "SignerQuorum", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 35, + "type": "UInt32" + } + ], + [ + "CancelAfter", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 36, + "type": "UInt32" + } + ], + [ + "FinishAfter", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 37, + "type": "UInt32" } ], [ "SignerListID", { - "nth": 38, - "isVLEncoded": false, "isSerialized": true, "isSigningField": true, + "isVLEncoded": false, + "nth": 38, "type": "UInt32" } ], [ "SettleDelay", { - "nth": 39, - "isVLEncoded": false, "isSerialized": true, "isSigningField": true, + "isVLEncoded": false, + "nth": 39, "type": "UInt32" } ], + [ + "TicketCount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 40, + "type": "UInt32" + } + ], + [ + "TicketSequence", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 41, + "type": "UInt32" + } + ], + [ + "NFTokenTaxon", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 42, + "type": "UInt32" + } + ], + [ + "MintedNFTokens", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 43, + "type": "UInt32" + } + ], + [ + "BurnedNFTokens", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 44, + "type": "UInt32" + } + ], + [ + "HookStateCount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 45, + "type": "UInt32" + } + ], + [ + "EmitGeneration", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 46, + "type": "UInt32" + } + ], + [ + "VoteWeight", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 48, + "type": "UInt32" + } + ], + [ + "FirstNFTokenSequence", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 50, + "type": "UInt32" + } + ], + [ + "OracleDocumentID", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 51, + "type": "UInt32" + } + ], + [ + "PermissionValue", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 52, + "type": "UInt32" + } + ], + [ + "IndexNext", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 1, + "type": "UInt64" + } + ], + [ + "IndexPrevious", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 2, + "type": "UInt64" + } + ], + [ + "BookNode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 3, + "type": "UInt64" + } + ], + [ + "OwnerNode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 4, + "type": "UInt64" + } + ], + [ + "BaseFee", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 5, + "type": "UInt64" + } + ], + [ + "ExchangeRate", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 6, + "type": "UInt64" + } + ], + [ + "LowNode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 7, + "type": "UInt64" + } + ], + [ + "HighNode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 8, + "type": "UInt64" + } + ], + [ + "DestinationNode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 9, + "type": "UInt64" + } + ], + [ + "Cookie", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 10, + "type": "UInt64" + } + ], + [ + "ServerVersion", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 11, + "type": "UInt64" + } + ], + [ + "NFTokenOfferNode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 12, + "type": "UInt64" + } + ], + [ + "EmitBurden", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 13, + "type": "UInt64" + } + ], + [ + "HookOn", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 16, + "type": "UInt64" + } + ], + [ + "HookInstructionCount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 17, + "type": "UInt64" + } + ], + [ + "HookReturnCode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 18, + "type": "UInt64" + } + ], + [ + "ReferenceCount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 19, + "type": "UInt64" + } + ], + [ + "XChainClaimID", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 20, + "type": "UInt64" + } + ], + [ + "XChainAccountCreateCount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 21, + "type": "UInt64" + } + ], + [ + "XChainAccountClaimCount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 22, + "type": "UInt64" + } + ], + [ + "AssetPrice", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 23, + "type": "UInt64" + } + ], + [ + "MaximumAmount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 24, + "type": "UInt64" + } + ], + [ + "OutstandingAmount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 25, + "type": "UInt64" + } + ], + [ + "MPTAmount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 26, + "type": "UInt64" + } + ], + [ + "IssuerNode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 27, + "type": "UInt64" + } + ], + [ + "SubjectNode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 28, + "type": "UInt64" + } + ], + [ + "LockedAmount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 29, + "type": "UInt64" + } + ], + [ + "EmailHash", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 1, + "type": "Hash128" + } + ], + [ + "LedgerHash", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 1, + "type": "Hash256" + } + ], + [ + "ParentHash", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 2, + "type": "Hash256" + } + ], + [ + "TransactionHash", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 3, + "type": "Hash256" + } + ], + [ + "AccountHash", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 4, + "type": "Hash256" + } + ], + [ + "PreviousTxnID", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 5, + "type": "Hash256" + } + ], + [ + "LedgerIndex", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 6, + "type": "Hash256" + } + ], + [ + "WalletLocator", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 7, + "type": "Hash256" + } + ], + [ + "RootIndex", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 8, + "type": "Hash256" + } + ], + [ + "AccountTxnID", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 9, + "type": "Hash256" + } + ], + [ + "NFTokenID", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 10, + "type": "Hash256" + } + ], + [ + "EmitParentTxnID", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 11, + "type": "Hash256" + } + ], + [ + "EmitNonce", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 12, + "type": "Hash256" + } + ], + [ + "EmitHookHash", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 13, + "type": "Hash256" + } + ], + [ + "AMMID", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 14, + "type": "Hash256" + } + ], + [ + "BookDirectory", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 16, + "type": "Hash256" + } + ], + [ + "InvoiceID", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 17, + "type": "Hash256" + } + ], + [ + "Nickname", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 18, + "type": "Hash256" + } + ], + [ + "Amendment", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 19, + "type": "Hash256" + } + ], + [ + "Digest", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 21, + "type": "Hash256" + } + ], [ "Channel", { - "nth": 22, - "isVLEncoded": false, "isSerialized": true, "isSigningField": true, + "isVLEncoded": false, + "nth": 22, "type": "Hash256" } ], [ "ConsensusHash", { - "nth": 23, - "isVLEncoded": false, "isSerialized": true, "isSigningField": true, + "isVLEncoded": false, + "nth": 23, "type": "Hash256" } ], [ "CheckID", { - "nth": 24, - "isVLEncoded": false, "isSerialized": true, "isSigningField": true, + "isVLEncoded": false, + "nth": 24, "type": "Hash256" } ], + [ + "ValidatedHash", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 25, + "type": "Hash256" + } + ], + [ + "PreviousPageMin", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 26, + "type": "Hash256" + } + ], + [ + "NextPageMin", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 27, + "type": "Hash256" + } + ], + [ + "NFTokenBuyOffer", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 28, + "type": "Hash256" + } + ], + [ + "NFTokenSellOffer", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 29, + "type": "Hash256" + } + ], + [ + "HookStateKey", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 30, + "type": "Hash256" + } + ], + [ + "HookHash", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 31, + "type": "Hash256" + } + ], + [ + "HookNamespace", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 32, + "type": "Hash256" + } + ], + [ + "HookSetTxnID", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 33, + "type": "Hash256" + } + ], + [ + "DomainID", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 34, + "type": "Hash256" + } + ], + [ + "VaultID", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 35, + "type": "Hash256" + } + ], + [ + "ParentBatchID", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 36, + "type": "Hash256" + } + ], + [ + "hash", + { + "isSerialized": false, + "isSigningField": false, + "isVLEncoded": false, + "nth": 257, + "type": "Hash256" + } + ], + [ + "index", + { + "isSerialized": false, + "isSigningField": false, + "isVLEncoded": false, + "nth": 258, + "type": "Hash256" + } + ], + [ + "Amount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 1, + "type": "Amount" + } + ], + [ + "Balance", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 2, + "type": "Amount" + } + ], + [ + "LimitAmount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 3, + "type": "Amount" + } + ], + [ + "TakerPays", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 4, + "type": "Amount" + } + ], + [ + "TakerGets", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 5, + "type": "Amount" + } + ], + [ + "LowLimit", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 6, + "type": "Amount" + } + ], + [ + "HighLimit", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 7, + "type": "Amount" + } + ], + [ + "Fee", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 8, + "type": "Amount" + } + ], + [ + "SendMax", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 9, + "type": "Amount" + } + ], + [ + "DeliverMin", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 10, + "type": "Amount" + } + ], + [ + "Amount2", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 11, + "type": "Amount" + } + ], + [ + "BidMin", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 12, + "type": "Amount" + } + ], + [ + "BidMax", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 13, + "type": "Amount" + } + ], + [ + "MinimumOffer", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 16, + "type": "Amount" + } + ], + [ + "RippleEscrow", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 17, + "type": "Amount" + } + ], + [ + "DeliveredAmount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 18, + "type": "Amount" + } + ], + [ + "NFTokenBrokerFee", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 19, + "type": "Amount" + } + ], + [ + "BaseFeeDrops", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 22, + "type": "Amount" + } + ], + [ + "ReserveBaseDrops", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 23, + "type": "Amount" + } + ], + [ + "ReserveIncrementDrops", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 24, + "type": "Amount" + } + ], + [ + "LPTokenOut", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 25, + "type": "Amount" + } + ], + [ + "LPTokenIn", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 26, + "type": "Amount" + } + ], + [ + "EPrice", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 27, + "type": "Amount" + } + ], + [ + "Price", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 28, + "type": "Amount" + } + ], + [ + "SignatureReward", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 29, + "type": "Amount" + } + ], + [ + "MinAccountCreateAmount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 30, + "type": "Amount" + } + ], + [ + "LPTokenBalance", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 31, + "type": "Amount" + } + ], + [ + "PublicKey", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 1, + "type": "Blob" + } + ], + [ + "MessageKey", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 2, + "type": "Blob" + } + ], + [ + "SigningPubKey", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 3, + "type": "Blob" + } + ], + [ + "TxnSignature", + { + "isSerialized": true, + "isSigningField": false, + "isVLEncoded": true, + "nth": 4, + "type": "Blob" + } + ], + [ + "URI", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 5, + "type": "Blob" + } + ], + [ + "Signature", + { + "isSerialized": true, + "isSigningField": false, + "isVLEncoded": true, + "nth": 6, + "type": "Blob" + } + ], + [ + "Domain", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 7, + "type": "Blob" + } + ], + [ + "FundCode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 8, + "type": "Blob" + } + ], + [ + "RemoveCode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 9, + "type": "Blob" + } + ], + [ + "ExpireCode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 10, + "type": "Blob" + } + ], + [ + "CreateCode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 11, + "type": "Blob" + } + ], + [ + "MemoType", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 12, + "type": "Blob" + } + ], + [ + "MemoData", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 13, + "type": "Blob" + } + ], + [ + "MemoFormat", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 14, + "type": "Blob" + } + ], + [ + "Fulfillment", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 16, + "type": "Blob" + } + ], + [ + "Condition", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 17, + "type": "Blob" + } + ], + [ + "MasterSignature", + { + "isSerialized": true, + "isSigningField": false, + "isVLEncoded": true, + "nth": 18, + "type": "Blob" + } + ], + [ + "UNLModifyValidator", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 19, + "type": "Blob" + } + ], + [ + "ValidatorToDisable", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 20, + "type": "Blob" + } + ], + [ + "ValidatorToReEnable", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 21, + "type": "Blob" + } + ], + [ + "HookStateData", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 22, + "type": "Blob" + } + ], + [ + "HookReturnString", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 23, + "type": "Blob" + } + ], + [ + "HookParameterName", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 24, + "type": "Blob" + } + ], + [ + "HookParameterValue", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 25, + "type": "Blob" + } + ], + [ + "DIDDocument", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 26, + "type": "Blob" + } + ], + [ + "Data", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 27, + "type": "Blob" + } + ], + [ + "AssetClass", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 28, + "type": "Blob" + } + ], + [ + "Provider", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 29, + "type": "Blob" + } + ], + [ + "MPTokenMetadata", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 30, + "type": "Blob" + } + ], + [ + "CredentialType", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 31, + "type": "Blob" + } + ], + [ + "Account", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 1, + "type": "AccountID" + } + ], + [ + "Owner", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 2, + "type": "AccountID" + } + ], + [ + "Destination", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 3, + "type": "AccountID" + } + ], + [ + "Issuer", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 4, + "type": "AccountID" + } + ], + [ + "Authorize", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 5, + "type": "AccountID" + } + ], + [ + "Unauthorize", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 6, + "type": "AccountID" + } + ], + [ + "RegularKey", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 8, + "type": "AccountID" + } + ], + [ + "NFTokenMinter", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 9, + "type": "AccountID" + } + ], + [ + "EmitCallback", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 10, + "type": "AccountID" + } + ], + [ + "Holder", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 11, + "type": "AccountID" + } + ], + [ + "Delegate", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 12, + "type": "AccountID" + } + ], + [ + "HookAccount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 16, + "type": "AccountID" + } + ], + [ + "OtherChainSource", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 18, + "type": "AccountID" + } + ], + [ + "OtherChainDestination", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 19, + "type": "AccountID" + } + ], + [ + "AttestationSignerAccount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 20, + "type": "AccountID" + } + ], + [ + "AttestationRewardAccount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 21, + "type": "AccountID" + } + ], + [ + "LockingChainDoor", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 22, + "type": "AccountID" + } + ], + [ + "IssuingChainDoor", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 23, + "type": "AccountID" + } + ], + [ + "Subject", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 24, + "type": "AccountID" + } + ], + [ + "Number", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 1, + "type": "Number" + } + ], + [ + "AssetsAvailable", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 2, + "type": "Number" + } + ], + [ + "AssetsMaximum", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 3, + "type": "Number" + } + ], + [ + "AssetsTotal", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 4, + "type": "Number" + } + ], + [ + "LossUnrealized", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 5, + "type": "Number" + } + ], + [ + "TransactionMetaData", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 2, + "type": "STObject" + } + ], + [ + "CreatedNode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 3, + "type": "STObject" + } + ], + [ + "DeletedNode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 4, + "type": "STObject" + } + ], + [ + "ModifiedNode", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 5, + "type": "STObject" + } + ], + [ + "PreviousFields", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 6, + "type": "STObject" + } + ], + [ + "FinalFields", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 7, + "type": "STObject" + } + ], + [ + "NewFields", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 8, + "type": "STObject" + } + ], + [ + "TemplateEntry", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 9, + "type": "STObject" + } + ], + [ + "Memo", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 10, + "type": "STObject" + } + ], + [ + "SignerEntry", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 11, + "type": "STObject" + } + ], + [ + "NFToken", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 12, + "type": "STObject" + } + ], + [ + "EmitDetails", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 13, + "type": "STObject" + } + ], + [ + "Hook", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 14, + "type": "STObject" + } + ], + [ + "Permission", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 15, + "type": "STObject" + } + ], + [ + "Signer", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 16, + "type": "STObject" + } + ], + [ + "Majority", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 18, + "type": "STObject" + } + ], + [ + "DisabledValidator", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 19, + "type": "STObject" + } + ], + [ + "EmittedTxn", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 20, + "type": "STObject" + } + ], + [ + "HookExecution", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 21, + "type": "STObject" + } + ], + [ + "HookDefinition", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 22, + "type": "STObject" + } + ], + [ + "HookParameter", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 23, + "type": "STObject" + } + ], + [ + "HookGrant", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 24, + "type": "STObject" + } + ], + [ + "VoteEntry", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 25, + "type": "STObject" + } + ], + [ + "AuctionSlot", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 26, + "type": "STObject" + } + ], + [ + "AuthAccount", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 27, + "type": "STObject" + } + ], + [ + "XChainClaimProofSig", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 28, + "type": "STObject" + } + ], + [ + "XChainCreateAccountProofSig", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 29, + "type": "STObject" + } + ], + [ + "XChainClaimAttestationCollectionElement", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 30, + "type": "STObject" + } + ], + [ + "XChainCreateAccountAttestationCollectionElement", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 31, + "type": "STObject" + } + ], + [ + "PriceData", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 32, + "type": "STObject" + } + ], + [ + "Credential", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 33, + "type": "STObject" + } + ], + [ + "RawTransaction", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 34, + "type": "STObject" + } + ], + [ + "BatchSigner", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 35, + "type": "STObject" + } + ], + [ + "Book", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 36, + "type": "STObject" + } + ], + [ + "Signers", + { + "isSerialized": true, + "isSigningField": false, + "isVLEncoded": false, + "nth": 3, + "type": "STArray" + } + ], + [ + "SignerEntries", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 4, + "type": "STArray" + } + ], + [ + "Template", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 5, + "type": "STArray" + } + ], + [ + "Necessary", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 6, + "type": "STArray" + } + ], + [ + "Sufficient", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 7, + "type": "STArray" + } + ], + [ + "AffectedNodes", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 8, + "type": "STArray" + } + ], + [ + "Memos", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 9, + "type": "STArray" + } + ], + [ + "NFTokens", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 10, + "type": "STArray" + } + ], + [ + "Hooks", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 11, + "type": "STArray" + } + ], + [ + "VoteSlots", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 12, + "type": "STArray" + } + ], + [ + "AdditionalBooks", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 13, + "type": "STArray" + } + ], + [ + "Majorities", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 16, + "type": "STArray" + } + ], + [ + "DisabledValidators", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 17, + "type": "STArray" + } + ], + [ + "HookExecutions", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 18, + "type": "STArray" + } + ], + [ + "HookParameters", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 19, + "type": "STArray" + } + ], + [ + "HookGrants", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 20, + "type": "STArray" + } + ], + [ + "XChainClaimAttestations", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 21, + "type": "STArray" + } + ], + [ + "XChainCreateAccountAttestations", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 22, + "type": "STArray" + } + ], + [ + "PriceDataSeries", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 24, + "type": "STArray" + } + ], + [ + "AuthAccounts", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 25, + "type": "STArray" + } + ], + [ + "AuthorizeCredentials", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 26, + "type": "STArray" + } + ], + [ + "UnauthorizeCredentials", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 27, + "type": "STArray" + } + ], + [ + "AcceptedCredentials", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 28, + "type": "STArray" + } + ], + [ + "Permissions", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 29, + "type": "STArray" + } + ], + [ + "RawTransactions", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 30, + "type": "STArray" + } + ], + [ + "BatchSigners", + { + "isSerialized": true, + "isSigningField": false, + "isVLEncoded": false, + "nth": 31, + "type": "STArray" + } + ], + [ + "CloseResolution", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 1, + "type": "UInt8" + } + ], + [ + "Method", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 2, + "type": "UInt8" + } + ], + [ + "TransactionResult", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 3, + "type": "UInt8" + } + ], + [ + "Scale", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 4, + "type": "UInt8" + } + ], + [ + "AssetScale", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 5, + "type": "UInt8" + } + ], [ "TickSize", { - "nth": 16, - "isVLEncoded": false, "isSerialized": true, "isSigningField": true, + "isVLEncoded": false, + "nth": 16, "type": "UInt8" } ], [ - "DestinationNode", + "UNLModifyDisabling", { - "nth": 9, - "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt64" + "isVLEncoded": false, + "nth": 17, + "type": "UInt8" + } + ], + [ + "HookResult", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 18, + "type": "UInt8" + } + ], + [ + "WasLockingChainSend", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 19, + "type": "UInt8" + } + ], + [ + "WithdrawalPolicy", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 20, + "type": "UInt8" + } + ], + [ + "TakerPaysCurrency", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 1, + "type": "Hash160" + } + ], + [ + "TakerPaysIssuer", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 2, + "type": "Hash160" + } + ], + [ + "TakerGetsCurrency", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 3, + "type": "Hash160" + } + ], + [ + "TakerGetsIssuer", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 4, + "type": "Hash160" + } + ], + [ + "Paths", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 1, + "type": "PathSet" + } + ], + [ + "Indexes", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 1, + "type": "Vector256" + } + ], + [ + "Hashes", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 2, + "type": "Vector256" + } + ], + [ + "Amendments", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 3, + "type": "Vector256" + } + ], + [ + "NFTokenOffers", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 4, + "type": "Vector256" + } + ], + [ + "CredentialIDs", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": true, + "nth": 5, + "type": "Vector256" + } + ], + [ + "MPTokenIssuanceID", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 1, + "type": "Hash192" + } + ], + [ + "ShareMPTID", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 2, + "type": "Hash192" + } + ], + [ + "LockingChainIssue", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 1, + "type": "Issue" + } + ], + [ + "IssuingChainIssue", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 2, + "type": "Issue" + } + ], + [ + "Asset", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 3, + "type": "Issue" + } + ], + [ + "Asset2", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 4, + "type": "Issue" + } + ], + [ + "XChainBridge", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 1, + "type": "XChainBridge" + } + ], + [ + "BaseAsset", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 1, + "type": "Currency" + } + ], + [ + "QuoteAsset", + { + "isSerialized": true, + "isSigningField": true, + "isVLEncoded": false, + "nth": 2, + "type": "Currency" + } + ], + [ + "Transaction", + { + "isSerialized": false, + "isSigningField": false, + "isVLEncoded": false, + "nth": 257, + "type": "Transaction" + } + ], + [ + "LedgerEntry", + { + "isSerialized": false, + "isSigningField": false, + "isVLEncoded": false, + "nth": 257, + "type": "LedgerEntry" + } + ], + [ + "Validation", + { + "isSerialized": false, + "isSigningField": false, + "isVLEncoded": false, + "nth": 257, + "type": "Validation" + } + ], + [ + "Metadata", + { + "isSerialized": false, + "isSigningField": false, + "isVLEncoded": false, + "nth": 257, + "type": "Metadata" } ] ], + "LEDGER_ENTRY_TYPES": { + "AMM": 121, + "AccountRoot": 97, + "Amendments": 102, + "Bridge": 105, + "Check": 67, + "Credential": 129, + "DID": 73, + "Delegate": 131, + "DepositPreauth": 112, + "DirectoryNode": 100, + "Escrow": 117, + "FeeSettings": 115, + "Invalid": -1, + "LedgerHashes": 104, + "MPToken": 127, + "MPTokenIssuance": 126, + "NFTokenOffer": 55, + "NFTokenPage": 80, + "NegativeUNL": 78, + "Offer": 111, + "Oracle": 128, + "PayChannel": 120, + "PermissionedDomain": 130, + "RippleState": 114, + "SignerList": 83, + "Ticket": 84, + "Vault": 132, + "XChainOwnedClaimID": 113, + "XChainOwnedCreateAccountClaimID": 116 + }, "TRANSACTION_RESULTS": { - "telNO_DST_PARTIAL": -393, - "temBAD_SRC_ACCOUNT": -281, - "tefPAST_SEQ": -189, - "terNO_ACCOUNT": -96, - "temREDUNDANT": -275, - "tefCREATED": -194, - "temDST_IS_SRC": -279, - "terRETRY": -99, - "temINVALID_FLAG": -276, - "temBAD_SEND_XRP_LIMIT": -288, - "terNO_LINE": -94, - "tefBAD_AUTH": -196, - "temBAD_EXPIRATION": -295, - "temBAD_SEND_XRP_NO_DIRECT": -286, - "temBAD_SEND_XRP_PATHS": -284, - "tefBAD_LEDGER": -195, - "tefNO_AUTH_REQUIRED": -190, - "terOWNERS": -93, - "terLAST": -91, - "terNO_RIPPLE": -90, - "temBAD_FEE": -294, - "terPRE_SEQ": -92, - "tefMASTER_DISABLED": -187, - "temBAD_CURRENCY": -296, - "tefDST_TAG_NEEDED": -193, - "temBAD_SIGNATURE": -282, - "tefFAILURE": -199, - "telBAD_PATH_COUNT": -397, - "temBAD_TRANSFER_RATE": -280, - "tefWRONG_PRIOR": -188, - "telBAD_DOMAIN": -398, - "temBAD_AMOUNT": -298, - "temBAD_AUTH_MASTER": -297, - "temBAD_LIMIT": -292, - "temBAD_ISSUER": -293, - "telBAD_PUBLIC_KEY": -396, - "tefBAD_ADD_AUTH": -197, - "temBAD_OFFER": -291, - "temBAD_SEND_XRP_PARTIAL": -285, - "temDST_NEEDED": -278, - "tefALREADY": -198, - "temUNCERTAIN": -272, - "telLOCAL_ERROR": -399, - "temREDUNDANT_SEND_MAX": -274, - "tefINTERNAL": -191, - "temBAD_PATH_LOOP": -289, - "tefEXCEPTION": -192, - "temRIPPLE_EMPTY": -273, - "telINSUF_FEE_P": -394, - "temBAD_SEQUENCE": -283, - "tefMAX_LEDGER": -186, - "terFUNDS_SPENT": -98, - "temBAD_SEND_XRP_MAX": -287, - "telFAILED_PROCESSING": -395, - "terINSUF_FEE_B": -97, - "tesSUCCESS": 0, - "temBAD_PATH": -290, - "temMALFORMED": -299, - "temUNKNOWN": -271, - "temINVALID": -277, - "terNO_AUTH": -95, - "temBAD_TICK_SIZE": -270, - + "tecAMM_ACCOUNT": 168, + "tecAMM_BALANCE": 163, + "tecAMM_EMPTY": 166, + "tecAMM_FAILED": 164, + "tecAMM_INVALID_TOKENS": 165, + "tecAMM_NOT_EMPTY": 167, + "tecARRAY_EMPTY": 190, + "tecARRAY_TOO_LARGE": 191, + "tecBAD_CREDENTIALS": 193, + "tecCANT_ACCEPT_OWN_NFTOKEN_OFFER": 158, "tecCLAIM": 100, - "tecPATH_PARTIAL": 101, - "tecUNFUNDED_ADD": 102, - "tecUNFUNDED_OFFER": 103, - "tecUNFUNDED_PAYMENT": 104, - "tecFAILED_PROCESSING": 105, + "tecCRYPTOCONDITION_ERROR": 146, "tecDIR_FULL": 121, + "tecDST_TAG_NEEDED": 143, + "tecDUPLICATE": 149, + "tecEMPTY_DID": 187, + "tecEXPIRED": 148, + "tecFAILED_PROCESSING": 105, + "tecFROZEN": 137, + "tecHAS_OBLIGATIONS": 151, + "tecHOOK_REJECTED": 153, + "tecINCOMPLETE": 169, + "tecINSUFFICIENT_FUNDS": 159, + "tecINSUFFICIENT_PAYMENT": 161, + "tecINSUFFICIENT_RESERVE": 141, + "tecINSUFF_FEE": 136, "tecINSUF_RESERVE_LINE": 122, "tecINSUF_RESERVE_OFFER": 123, + "tecINTERNAL": 144, + "tecINVALID_UPDATE_TIME": 188, + "tecINVARIANT_FAILED": 147, + "tecKILLED": 150, + "tecLIMIT_EXCEEDED": 195, + "tecLOCKED": 192, + "tecMAX_SEQUENCE_REACHED": 154, + "tecNEED_MASTER_KEY": 142, + "tecNFTOKEN_BUY_SELL_MISMATCH": 156, + "tecNFTOKEN_OFFER_TYPE_MISMATCH": 157, + "tecNO_ALTERNATIVE_KEY": 130, + "tecNO_AUTH": 134, + "tecNO_DELEGATE_PERMISSION": 198, "tecNO_DST": 124, "tecNO_DST_INSUF_XRP": 125, + "tecNO_ENTRY": 140, + "tecNO_ISSUER": 133, + "tecNO_LINE": 135, "tecNO_LINE_INSUF_RESERVE": 126, "tecNO_LINE_REDUNDANT": 127, - "tecPATH_DRY": 128, - "tecUNFUNDED": 129, - "tecNO_ALTERNATIVE_KEY": 130, - "tecNO_REGULAR_KEY": 131, - "tecOWNERS": 132, - "tecNO_ISSUER": 133, - "tecNO_AUTH": 134, - "tecNO_LINE": 135, - "tecINSUFF_FEE": 136, - "tecFROZEN": 137, - "tecNO_TARGET": 138, "tecNO_PERMISSION": 139, - "tecNO_ENTRY": 140, - "tecINSUFFICIENT_RESERVE": 141, - "tecNEED_MASTER_KEY": 142, - "tecDST_TAG_NEEDED": 143, - "tecINTERNAL": 144, + "tecNO_REGULAR_KEY": 131, + "tecNO_SUITABLE_NFTOKEN_PAGE": 155, + "tecNO_TARGET": 138, + "tecOBJECT_NOT_FOUND": 160, "tecOVERSIZE": 145, - "tecCRYPTOCONDITION_ERROR": 146, - "tecINVARIANT_FAILED": 147, - "tecEXPIRED": 148, - "tecDUPLICATE": 149 + "tecOWNERS": 132, + "tecPATH_DRY": 128, + "tecPATH_PARTIAL": 101, + "tecPRECISION_LOSS": 197, + "tecPSEUDO_ACCOUNT": 196, + "tecTOKEN_PAIR_NOT_FOUND": 189, + "tecTOO_SOON": 152, + "tecUNFUNDED": 129, + "tecUNFUNDED_ADD": 102, + "tecUNFUNDED_AMM": 162, + "tecUNFUNDED_OFFER": 103, + "tecUNFUNDED_PAYMENT": 104, + "tecWRONG_ASSET": 194, + "tecXCHAIN_ACCOUNT_CREATE_PAST": 181, + "tecXCHAIN_ACCOUNT_CREATE_TOO_MANY": 182, + "tecXCHAIN_BAD_CLAIM_ID": 172, + "tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR": 185, + "tecXCHAIN_BAD_TRANSFER_ISSUE": 170, + "tecXCHAIN_CLAIM_NO_QUORUM": 173, + "tecXCHAIN_CREATE_ACCOUNT_DISABLED": 186, + "tecXCHAIN_CREATE_ACCOUNT_NONXRP_ISSUE": 175, + "tecXCHAIN_INSUFF_CREATE_AMOUNT": 180, + "tecXCHAIN_NO_CLAIM_ID": 171, + "tecXCHAIN_NO_SIGNERS_LIST": 178, + "tecXCHAIN_PAYMENT_FAILED": 183, + "tecXCHAIN_PROOF_UNKNOWN_KEY": 174, + "tecXCHAIN_REWARD_MISMATCH": 177, + "tecXCHAIN_SELF_COMMIT": 184, + "tecXCHAIN_SENDING_ACCOUNT_MISMATCH": 179, + "tecXCHAIN_WRONG_CHAIN": 176, + + "tefALREADY": -198, + "tefBAD_ADD_AUTH": -197, + "tefBAD_AUTH": -196, + "tefBAD_AUTH_MASTER": -183, + "tefBAD_LEDGER": -195, + "tefBAD_QUORUM": -185, + "tefBAD_SIGNATURE": -186, + "tefCREATED": -194, + "tefEXCEPTION": -193, + "tefFAILURE": -199, + "tefINTERNAL": -192, + "tefINVALID_LEDGER_FIX_TYPE": -178, + "tefINVARIANT_FAILED": -182, + "tefMASTER_DISABLED": -188, + "tefMAX_LEDGER": -187, + "tefNFTOKEN_IS_NOT_TRANSFERABLE": -179, + "tefNOT_MULTI_SIGNING": -184, + "tefNO_AUTH_REQUIRED": -191, + "tefNO_TICKET": -180, + "tefPAST_SEQ": -190, + "tefTOO_BIG": -181, + "tefWRONG_PRIOR": -189, + + "telBAD_DOMAIN": -398, + "telBAD_PATH_COUNT": -397, + "telBAD_PUBLIC_KEY": -396, + "telCAN_NOT_QUEUE": -392, + "telCAN_NOT_QUEUE_BALANCE": -391, + "telCAN_NOT_QUEUE_BLOCKED": -389, + "telCAN_NOT_QUEUE_BLOCKS": -390, + "telCAN_NOT_QUEUE_FEE": -388, + "telCAN_NOT_QUEUE_FULL": -387, + "telENV_RPC_FAILED": -383, + "telFAILED_PROCESSING": -395, + "telINSUF_FEE_P": -394, + "telLOCAL_ERROR": -399, + "telNETWORK_ID_MAKES_TX_NON_CANONICAL": -384, + "telNO_DST_PARTIAL": -393, + "telREQUIRES_NETWORK_ID": -385, + "telWRONG_NETWORK": -386, + + "temARRAY_EMPTY": -253, + "temARRAY_TOO_LARGE": -252, + "temBAD_AMM_TOKENS": -261, + "temBAD_AMOUNT": -298, + "temBAD_CURRENCY": -297, + "temBAD_EXPIRATION": -296, + "temBAD_FEE": -295, + "temBAD_ISSUER": -294, + "temBAD_LIMIT": -293, + "temBAD_NFTOKEN_TRANSFER_FEE": -262, + "temBAD_OFFER": -292, + "temBAD_PATH": -291, + "temBAD_PATH_LOOP": -290, + "temBAD_QUORUM": -271, + "temBAD_REGKEY": -289, + "temBAD_SEND_XRP_LIMIT": -288, + "temBAD_SEND_XRP_MAX": -287, + "temBAD_SEND_XRP_NO_DIRECT": -286, + "temBAD_SEND_XRP_PARTIAL": -285, + "temBAD_SEND_XRP_PATHS": -284, + "temBAD_SEQUENCE": -283, + "temBAD_SIGNATURE": -282, + "temBAD_SIGNER": -272, + "temBAD_SRC_ACCOUNT": -281, + "temBAD_TICK_SIZE": -269, + "temBAD_TRANSFER_FEE": -251, + "temBAD_TRANSFER_RATE": -280, + "temBAD_WEIGHT": -270, + "temCANNOT_PREAUTH_SELF": -267, + "temDISABLED": -273, + "temDST_IS_SRC": -279, + "temDST_NEEDED": -278, + "temEMPTY_DID": -254, + "temINVALID": -277, + "temINVALID_ACCOUNT_ID": -268, + "temINVALID_COUNT": -266, + "temINVALID_FLAG": -276, + "temINVALID_INNER_BATCH": -250, + "temMALFORMED": -299, + "temREDUNDANT": -275, + "temRIPPLE_EMPTY": -274, + "temSEQ_AND_TICKET": -263, + "temUNCERTAIN": -265, + "temUNKNOWN": -264, + "temXCHAIN_BAD_PROOF": -259, + "temXCHAIN_BRIDGE_BAD_ISSUES": -258, + "temXCHAIN_BRIDGE_BAD_MIN_ACCOUNT_CREATE_AMOUNT": -256, + "temXCHAIN_BRIDGE_BAD_REWARD_AMOUNT": -255, + "temXCHAIN_BRIDGE_NONDOOR_OWNER": -257, + "temXCHAIN_EQUAL_DOOR_ACCOUNTS": -260, + + "terADDRESS_COLLISION": -86, + "terFUNDS_SPENT": -98, + "terINSUF_FEE_B": -97, + "terLAST": -91, + "terNO_ACCOUNT": -96, + "terNO_AMM": -87, + "terNO_AUTH": -95, + "terNO_LINE": -94, + "terNO_RIPPLE": -90, + "terOWNERS": -93, + "terPRE_SEQ": -92, + "terPRE_TICKET": -88, + "terQUEUED": -89, + "terRETRY": -99, + + "tesSUCCESS": 0 }, "TRANSACTION_TYPES": { - "Invalid": -1, - "Payment": 0, + "AMMBid": 39, + "AMMClawback": 31, + "AMMCreate": 35, + "AMMDelete": 40, + "AMMDeposit": 36, + "AMMVote": 38, + "AMMWithdraw": 37, + "AccountDelete": 21, + "AccountSet": 3, + "Batch": 71, + "CheckCancel": 18, + "CheckCash": 17, + "CheckCreate": 16, + "Clawback": 30, + "CredentialAccept": 59, + "CredentialCreate": 58, + "CredentialDelete": 60, + "DIDDelete": 50, + "DIDSet": 49, + "DelegateSet": 64, + "DepositPreauth": 19, + "EnableAmendment": 100, + "EscrowCancel": 4, "EscrowCreate": 1, "EscrowFinish": 2, - "AccountSet": 3, - "EscrowCancel": 4, - "SetRegularKey": 5, - "NickNameSet": 6, - "OfferCreate": 7, + "Invalid": -1, + "LedgerStateFix": 53, + "MPTokenAuthorize": 57, + "MPTokenIssuanceCreate": 54, + "MPTokenIssuanceDestroy": 55, + "MPTokenIssuanceSet": 56, + "NFTokenAcceptOffer": 29, + "NFTokenBurn": 26, + "NFTokenCancelOffer": 28, + "NFTokenCreateOffer": 27, + "NFTokenMint": 25, + "NFTokenModify": 61, "OfferCancel": 8, - "Contract": 9, - "TicketCreate": 10, - "TicketCancel": 11, - "SignerListSet": 12, + "OfferCreate": 7, + "OracleDelete": 52, + "OracleSet": 51, + "Payment": 0, + "PaymentChannelClaim": 15, "PaymentChannelCreate": 13, "PaymentChannelFund": 14, - "PaymentChannelClaim": 15, - "CheckCreate": 16, - "CheckCash": 17, - "CheckCancel": 18, - "DepositPreauth": 19, + "PermissionedDomainDelete": 63, + "PermissionedDomainSet": 62, + "SetFee": 101, + "SetRegularKey": 5, + "SignerListSet": 12, + "TicketCreate": 10, "TrustSet": 20, - "EnableAmendment": 100, - "SetFee": 101 + "UNLModify": 102, + "VaultClawback": 70, + "VaultCreate": 65, + "VaultDelete": 67, + "VaultDeposit": 68, + "VaultSet": 66, + "VaultWithdraw": 69, + "XChainAccountCreateCommit": 44, + "XChainAddAccountCreateAttestation": 46, + "XChainAddClaimAttestation": 45, + "XChainClaim": 43, + "XChainCommit": 42, + "XChainCreateBridge": 48, + "XChainCreateClaimID": 41, + "XChainModifyBridge": 47 + }, + "TYPES": { + "AccountID": 8, + "Amount": 6, + "Blob": 7, + "Currency": 26, + "Done": -1, + "Hash128": 4, + "Hash160": 17, + "Hash192": 21, + "Hash256": 5, + "Issue": 24, + "LedgerEntry": 10002, + "Metadata": 10004, + "NotPresent": 0, + "Number": 9, + "PathSet": 18, + "STArray": 15, + "STObject": 14, + "Transaction": 10001, + "UInt16": 1, + "UInt32": 2, + "UInt384": 22, + "UInt512": 23, + "UInt64": 3, + "UInt8": 16, + "UInt96": 20, + "Unknown": -2, + "Validation": 10003, + "Vector256": 19, + "XChainBridge": 25 } } diff --git a/_code-samples/tx-serialization/py/serialize.py b/_code-samples/tx-serialization/py/serialize.py index 288d7a34ef..53ac1c3815 100755 --- a/_code-samples/tx-serialization/py/serialize.py +++ b/_code-samples/tx-serialization/py/serialize.py @@ -153,6 +153,7 @@ def amount_to_bytes(a): xrp_amt = -xrp_amt return xrp_amt.to_bytes(8, byteorder="big", signed=False) elif type(a) == dict: + #TODO: handle mpt amounts if sorted(a.keys()) != ["currency", "issuer", "value"]: raise ValueError("amount must have currency, value, issuer only (actually had: %s)" % sorted(a.keys())) @@ -254,7 +255,7 @@ def hex_to_bytes(contents): Helper function; serializes a hash value from a hexadecimal string of any length. """ - return bytes.fromhex(field_val) + return bytes.fromhex(contents) def issue_to_bytes(issue): """ @@ -394,6 +395,16 @@ def uint384_to_bytes(i): raise ValueError("UInt64 is not 64 bits long") return b +def vector256_to_bytes(strlist): + """ + Serialize a Vector256 type which is a length-prefixed list of arbitrary + 256-bit values. + """ + binarylist = [] + for item in strlist: + binarylist.append(hash256_to_bytes(item)) + return vl_encode(b''.join(binarylist)) + # Core serialization logic ----------------------------------------------------- def field_to_bytes(field_name, field_val): @@ -430,6 +441,7 @@ def field_to_bytes(field_name, field_val): "UInt32": uint32_to_bytes, "UInt64": uint64_to_bytes, "UInt384": uint384_to_bytes, + "Vector256": vector256_to_bytes, } field_binary = dispatch[field_type](field_val) return b''.join( (id_prefix, field_binary) ) @@ -465,6 +477,12 @@ def serialize_tx(tx, for_signing=False): "Sequence": 2 } """ + # Special case: DeliverMax is an API alias for Amount. De-alias it here. + # See also: https://github.com/XRPLF/rippled/issues/5506 + if "DeliverMax" in tx.keys(): + tx["Amount"] = tx["DeliverMax"] + del tx["DeliverMax"] + field_order = sorted(tx.keys(), key=field_sort_key) logger.debug("Canonical field order: %s" % field_order) diff --git a/_code-samples/tx-serialization/py/test-cases/tx4-binary.txt b/_code-samples/tx-serialization/py/test-cases/tx4-binary.txt new file mode 100644 index 0000000000..16a4f2c3b6 --- /dev/null +++ b/_code-samples/tx-serialization/py/test-cases/tx4-binary.txt @@ -0,0 +1 @@ +12000024003B498561600000000000002710003B49848403524C52FC5B7E804DFE38271A5B1B3E46A93B684000000000000064732102FC20ED4D4D43CFAF4E449A85F68CAEE35B59F19233773818CA05221643A09FBC74473045022100A6FFF3327662DCA0246EA196A2E56754341D614F2A04AF2378A0B273EEB1A87F02207C47C93E185083BEA57C5725947042C279DDEC36EBAE9BACF4880DCCE7D6845181148403524C52FC5B7E804DFE38271A5B1B3E46A93B831412F36D6C45FE5F0C37A6DFA21BE514C45D1E0655 diff --git a/_code-samples/tx-serialization/py/test-cases/tx4.json b/_code-samples/tx-serialization/py/test-cases/tx4.json new file mode 100644 index 0000000000..34d9566a41 --- /dev/null +++ b/_code-samples/tx-serialization/py/test-cases/tx4.json @@ -0,0 +1,13 @@ +{ + "Account": "rDspBaumB5u6YWRdw5BWoBP3rcExFrXxoY", + "DeliverMax": { + "mpt_issuance_id": "003B49848403524C52FC5B7E804DFE38271A5B1B3E46A93B", + "value": "10000" + }, + "Destination": "rpjU8anTxTQX97GKHsuv8TyQ659j6pPak4", + "Fee": "100", + "Sequence": 3885445, + "SigningPubKey": "02FC20ED4D4D43CFAF4E449A85F68CAEE35B59F19233773818CA05221643A09FBC", + "TransactionType": "Payment", + "TxnSignature": "3045022100A6FFF3327662DCA0246EA196A2E56754341D614F2A04AF2378A0B273EEB1A87F02207C47C93E185083BEA57C5725947042C279DDEC36EBAE9BACF4880DCCE7D68451" +} diff --git a/_code-samples/tx-serialization/py/test-cases/tx5-binary.txt b/_code-samples/tx-serialization/py/test-cases/tx5-binary.txt new file mode 100644 index 0000000000..7605e72760 --- /dev/null +++ b/_code-samples/tx-serialization/py/test-cases/tx5-binary.txt @@ -0,0 +1 @@ +1200332FFFFFFFFF2033000004D2750B6469645F6578616D706C65701C0863757272656E6379701D0870726F7669646572811401476926B590BA3245F63C829116A0A3AF7F382DF018E020301700000000000001E2041003011A0000000000000000000000000000000000000000021A0000000000000000000000005553440000000000E1F1 diff --git a/_code-samples/tx-serialization/py/test-cases/tx5.json b/_code-samples/tx-serialization/py/test-cases/tx5.json new file mode 100644 index 0000000000..bac9e03853 --- /dev/null +++ b/_code-samples/tx-serialization/py/test-cases/tx5.json @@ -0,0 +1,19 @@ +{ + "TransactionType": "OracleSet", + "Account": "rfmDuhDyLGgx94qiwf3YF8BUV5j6KSvE8", + "OracleDocumentID": 1234, + "LastUpdateTime": 4294967295, + "PriceDataSeries": [ + { + "PriceData": { + "BaseAsset": "XRP", + "QuoteAsset": "USD", + "AssetPrice": "00000000000001E2", + "Scale": 3 + } + } + ], + "Provider": "70726F7669646572", + "URI": "6469645F6578616D706C65", + "AssetClass": "63757272656E6379" +} From 344d0002bbb3a22edc54720eada00e412e3e5b6a Mon Sep 17 00:00:00 2001 From: mDuo13 Date: Wed, 25 Jun 2025 14:50:57 -0700 Subject: [PATCH 4/7] Binary serialization: implement MPT amounts in sample code --- .../tx-serialization/py/serialize.py | 33 ++++++++++++++----- docs/references/protocol/binary-format.md | 4 +-- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/_code-samples/tx-serialization/py/serialize.py b/_code-samples/tx-serialization/py/serialize.py index 53ac1c3815..c8ca3ad276 100755 --- a/_code-samples/tx-serialization/py/serialize.py +++ b/_code-samples/tx-serialization/py/serialize.py @@ -133,12 +133,13 @@ def accountid_to_bytes(address): def amount_to_bytes(a): """ - Serializes an "Amount" type, which can be either XRP or an issued currency: + Serializes an "Amount" type, which can be XRP, an issued currency, or MPT: - XRP: total 64 bits: 0, followed by 1 ("is positive"), then 0, then 61 bit UInt amount - - Issued Currency: total 384 bits: 64 bits of amount, followed by 160 bit currency code and - 160 bit issuer AccountID. - - MPT: 8-bit header with the binary value 01100000 (0x60), then 64 bit UInt amount, - 32 bit Sequence number, and 160 bit issuer AccountID. + - Issued Currency: total 384 bits: 64 bits of amount, followed by 160 bit + currency code and 160 bit issuer AccountID. + - MPT: total 264 bits: 8-bit header with the binary value 01100000 (0x60), + then 64 bit amount, 32 bit Sequence number, and 160 bit issuer AccountID. + The Sequence and issuer are adjoined as mpt_issuance_id. """ if type(a) == str: # is XRP @@ -153,17 +154,26 @@ def amount_to_bytes(a): xrp_amt = -xrp_amt return xrp_amt.to_bytes(8, byteorder="big", signed=False) elif type(a) == dict: - #TODO: handle mpt amounts - if sorted(a.keys()) != ["currency", "issuer", "value"]: + if sorted(a.keys()) == ["mpt_issuance_id", "value"]: + # MPT Amount + mpt_prefix = uint8_to_bytes(0x60) + mpt_amt = int(a["value"]) + assert mpt_amt < 2**63 and mpt_amt >= 0 + mpt_amt_bytes = mpt_amt.to_bytes(8, byteorder="big", signed=False) + mpt_issuance_id = uint192_to_bytes(a["mpt_issuance_id"]) + return mpt_prefix + mpt_amt_bytes + mpt_issuance_id + + elif sorted(a.keys()) != ["currency", "issuer", "value"]: raise ValueError("amount must have currency, value, issuer only (actually had: %s)" % sorted(a.keys())) + # Fungible token amount (non-MPT) issued_amt = IssuedAmount(a["value"]).to_bytes() logger.debug("Issued amount: %s"%issued_amt.hex()) currency_code = currency_code_to_bytes(a["currency"]) return issued_amt + currency_code + decode_address(a["issuer"]) else: - raise ValueError("amount must be XRP string or {currency, value, issuer}") + raise ValueError("amount must be XRP string, {currency, value, issuer}, or {mpt_issuance_id, value}") def array_to_bytes(array): """ @@ -389,6 +399,12 @@ def uint64_to_bytes(i): raise ValueError("UInt64 is not 64 bits long") return b +def uint192_to_bytes(i): + b = hex_to_bytes(i) + if len(b) != 24: # 24 bytes = 192 bits + raise ValueError("UInt192 is not 192 bits long") + return b + def uint384_to_bytes(i): b = hex_to_bytes(i) if len(b) != 8: # 8 bytes = 64 bits @@ -440,6 +456,7 @@ def field_to_bytes(field_name, field_val): "UInt16": uint16_to_bytes, "UInt32": uint32_to_bytes, "UInt64": uint64_to_bytes, + "UInt192": uint192_to_bytes, "UInt384": uint384_to_bytes, "Vector256": vector256_to_bytes, } diff --git a/docs/references/protocol/binary-format.md b/docs/references/protocol/binary-format.md index 199871ca05..2b2563418c 100644 --- a/docs/references/protocol/binary-format.md +++ b/docs/references/protocol/binary-format.md @@ -244,8 +244,8 @@ The _Amount_ type (also called "STAmount") is a special field type that represen Multi-Purpose Tokens (MPTs) consist of four segments in order: - 1. 8 bits indicating that this is an MPT. The most significant bit is `0` to indicate that it's not a fungible token. The second bit is `1` to indicate that it is postiive. The third most significant bit is `1` to indicate that it is an MPT. The remaining 5 bits are reserved and must all be `0`. - 2. 64 bits indicating the quantity of the MPT, as a 64-bit _signed_ integer. (However, in most contexts, negative amounts are not allowed.) + 1. 8 bits indicating that this is an MPT. The most significant bit is `0` to indicate that it's not a fungible token. The second bit is `1` to indicate that it is postiive. The third most significant bit is `1` to indicate that it is an MPT. The remaining 5 bits are reserved and must all be `0`. In other words, the first byte is `0x60`. + 2. 64 bits indicating the quantity of the MPT, as a 64-bit unsigned integer. (However, the maximum amount cannot be larger than 263-1.) 3. 32 bits indicating the `Sequence` number of the transaction that created the MPT issuance. 4. 160 bits indicating the [AccountID][] of the MPT's issuer. From 88302464bc7f83f88901ebd44907b9472b84d181 Mon Sep 17 00:00:00 2001 From: mDuo13 Date: Wed, 25 Jun 2025 15:12:07 -0700 Subject: [PATCH 5/7] Binary: Add test case with Vector256 --- .../tx-serialization/py/test-cases/tx6-binary.txt | 1 + .../tx-serialization/py/test-cases/tx6.json | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 _code-samples/tx-serialization/py/test-cases/tx6-binary.txt create mode 100644 _code-samples/tx-serialization/py/test-cases/tx6.json diff --git a/_code-samples/tx-serialization/py/test-cases/tx6-binary.txt b/_code-samples/tx-serialization/py/test-cases/tx6-binary.txt new file mode 100644 index 0000000000..a8e3326ab5 --- /dev/null +++ b/_code-samples/tx-serialization/py/test-cases/tx6-binary.txt @@ -0,0 +1 @@ +12001C230606B58324057999CC201B05C8EFD868400000000000000C732103A024842C84B81B95A7F4644AF2C4A51A51417984923C4F9B104992D4C52A882274473045022100FD4B62198CB9E13984D9D9DAC5AE978F326E444A4618AEABD1326826E5FEE0B802206B9D7FAAEEFF32BCDFC32F2C3C16196B92C848FC36BB32082F91FE5076EC930681143461BF0CAF5BFC043B56EF88A36FF4EBC510D652041320822342A1477A13D829EE9A7C4C8590910A297EFCAB0E20D7E5B1686A46C023CB diff --git a/_code-samples/tx-serialization/py/test-cases/tx6.json b/_code-samples/tx-serialization/py/test-cases/tx6.json new file mode 100644 index 0000000000..18bf15d238 --- /dev/null +++ b/_code-samples/tx-serialization/py/test-cases/tx6.json @@ -0,0 +1,13 @@ +{ + "Account": "rnmyNW49mSzh4xKCRNMtvQ2sb69HKnrghA", + "Fee": "12", + "LastLedgerSequence": 97054680, + "NFTokenOffers": [ + "822342A1477A13D829EE9A7C4C8590910A297EFCAB0E20D7E5B1686A46C023CB" + ], + "Sequence": 91855308, + "SigningPubKey": "03A024842C84B81B95A7F4644AF2C4A51A51417984923C4F9B104992D4C52A8822", + "SourceTag": 101102979, + "TransactionType": "NFTokenCancelOffer", + "TxnSignature": "3045022100FD4B62198CB9E13984D9D9DAC5AE978F326E444A4618AEABD1326826E5FEE0B802206B9D7FAAEEFF32BCDFC32F2C3C16196B92C848FC36BB32082F91FE5076EC9306" +} From 81d7531c41d72892f290cd12f868e6aee015e713 Mon Sep 17 00:00:00 2001 From: mDuo13 Date: Wed, 25 Jun 2025 16:38:19 -0700 Subject: [PATCH 6/7] Binary: fix typos breaking the build --- docs/references/protocol/binary-format.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/references/protocol/binary-format.md b/docs/references/protocol/binary-format.md index 2b2563418c..6b80ad5bae 100644 --- a/docs/references/protocol/binary-format.md +++ b/docs/references/protocol/binary-format.md @@ -75,7 +75,7 @@ The following JSON file defines the important constants you need for serializing **** -You can also use the [server_definitions API method](http-websocket-apis/public-api-methods/server-info-methods/server_definitions.md) to get the same data from a server. This can be useful when working with dev networks, in-development features, and sidechains with new fields or data types. +You can also use the [server_definitions API method](../http-websocket-apis/public-api-methods/server-info-methods/server_definitions.md) to get the same data from a server. This can be useful when working with dev networks, in-development features, and sidechains with new fields or data types. The following table defines the top-level fields from the definitions file: @@ -255,7 +255,7 @@ You can tell which of the three sub-types an amount is based on the first and th - If the first bit and third bit are both `0`, it's XRP. - If the first bit is a `0` and the third bit is a `1`, it's an MPT. -{% admonition type="warning" title="Caution" %} +{% admonition type="warning" name="Caution" %} Not all types of amount are valid in all places. Some fields can only represent XRP, or XRP and fungible tokens but not MPTs. These limitations are defined by the individual transactions and ledger entries. {% /admonition %} @@ -409,7 +409,7 @@ The `TransactionType` field is a special case. In JSON, this field is convention The _Vector256_ type contains a list of 256-bit values. This field consists of a multiple of 256 bits following the [length prefix](#length-prefixing). Unlike the [Array][] type, which can contain a mix of different nested object types of varying lengths, each member of a Vector256 field is exactly 256 bits with no type prefix. -The members of a Vector256 field may be [ledger entry IDs](protocol/ledger-data/common-fields.md#ledger-entry-id). However, they can also be Amendment IDs, ledger hashes, or other binary data. +The members of a Vector256 field may be [ledger entry IDs](./ledger-data/common-fields.md#ledger-entry-id), transaction IDs, Amendment IDs, ledger hashes, or other binary data. ### XChainBridge Fields From 08558478e454e6acce22475e0b99a600c3f4f403 Mon Sep 17 00:00:00 2001 From: mDuo13 Date: Mon, 7 Jul 2025 14:33:40 -0700 Subject: [PATCH 7/7] Binary format: edits per review --- .../tx-serialization/py/serialize.py | 4 +- docs/img/_sources/serialization-amount.uxf | 438 +++++++++++++---- docs/img/serialization-amount.svg | 452 ++++++++++++------ docs/references/protocol/binary-format.md | 22 +- 4 files changed, 677 insertions(+), 239 deletions(-) diff --git a/_code-samples/tx-serialization/py/serialize.py b/_code-samples/tx-serialization/py/serialize.py index c8ca3ad276..e4dd1214c1 100755 --- a/_code-samples/tx-serialization/py/serialize.py +++ b/_code-samples/tx-serialization/py/serialize.py @@ -407,8 +407,8 @@ def uint192_to_bytes(i): def uint384_to_bytes(i): b = hex_to_bytes(i) - if len(b) != 8: # 8 bytes = 64 bits - raise ValueError("UInt64 is not 64 bits long") + if len(b) != 48: # 48 bytes = 384 bits + raise ValueError("UInt384 is not 384 bits long") return b def vector256_to_bytes(strlist): diff --git a/docs/img/_sources/serialization-amount.uxf b/docs/img/_sources/serialization-amount.uxf index 61b7d4d3fd..286f5482d9 100644 --- a/docs/img/_sources/serialization-amount.uxf +++ b/docs/img/_sources/serialization-amount.uxf @@ -5,7 +5,7 @@ UMLClass 40 - 270 + 560 20 30 @@ -16,7 +16,7 @@ UMLClass 70 - 270 + 560 20 30 @@ -27,7 +27,7 @@ UMLClass 100 - 270 + 560 150 30 @@ -38,7 +38,7 @@ UMLClass 260 - 270 + 560 190 30 @@ -49,7 +49,7 @@ Relation 70 - 290 + 580 50 60 @@ -60,7 +60,7 @@ Text 100 - 320 + 610 260 30 @@ -72,12 +72,12 @@ style=wordwrap Text 80 - 350 + 640 160 60 - "Not XRP" bit -(0=XRP, 1=not XRP) + Amount type bit +(0=XRP or MPT, 1=fungible token) style=wordwrap @@ -85,7 +85,7 @@ style=wordwrap Relation 40 - 290 + 580 50 90 @@ -96,7 +96,7 @@ style=wordwrap UMLClass 460 - 270 + 560 200 30 @@ -107,18 +107,18 @@ style=wordwrap UMLClass 670 - 270 - 200 + 560 + 220 30 - issuer AccountID (160 bits) + issuer's AccountID (160 bits) UMLClass 40 - 510 + 800 20 30 @@ -129,7 +129,7 @@ style=wordwrap Relation 40 - 520 + 810 60 70 @@ -140,7 +140,7 @@ style=wordwrap Text 80 - 560 + 850 300 40 @@ -152,29 +152,29 @@ style=wordwrap UMLClass 70 - 510 + 800 220 30 - Reserved (88 bits) + reserved (88 bits) UMLClass 460 - 510 + 800 180 30 - Reserved (40 bits) + reserved (40 bits) UMLClass 300 - 510 + 800 150 30 @@ -185,7 +185,7 @@ style=wordwrap Relation 310 - 530 + 820 40 50 @@ -196,7 +196,7 @@ style=wordwrap Text 330 - 550 + 840 130 30 @@ -207,7 +207,7 @@ style=wordwrap Relation 20 - 290 + 580 460 230 @@ -218,7 +218,7 @@ style=wordwrap Relation 640 - 290 + 580 40 230 @@ -228,7 +228,7 @@ style=wordwrap UMLClass - 40 + 30 60 20 30 @@ -239,7 +239,7 @@ style=wordwrap UMLClass - 70 + 60 60 20 30 @@ -247,11 +247,192 @@ style=wordwrap 1 + + Text + + 90 + 120 + 260 + 30 + + Sign bit (always 1 for positive) +style=wordwrap + + + + Relation + + 60 + 80 + 50 + 70 + + lt=<<- + 10.0;10.0;10.0;50.0;30.0;50.0 + + + Text + + 70 + 140 + 160 + 60 + + Amount type bit +(0=XRP or MPT, 1=fungible token) +style=wordwrap + + + + Relation + + 30 + 80 + 60 + 110 + + lt=<<- + 10.0;10.0;10.0;90.0;40.0;90.0 + + + UMLClass + + 120 + 60 + 510 + 30 + + integer drops (61 bits) + + + + UMLClass + + 20 + 50 + 620 + 50 + + + + + + Text + + 20 + 20 + 190 + 30 + + *XRP Amount Format* + + + + Text + + 30 + 520 + 310 + 30 + + *Fungible Token Amount Format* + + + + UMLClass + + 30 + 550 + 870 + 50 + + + + + + Text + + 90 + 760 + 240 + 30 + + Standard Currency Code Format + + + + UMLClass + + 30 + 790 + 620 + 50 + + + + + + Text + + 20 + 240 + 190 + 30 + + *MPT Amount Format* + + + + UMLClass + + 30 + 270 + 670 + 50 + + + + + + UMLClass + + 40 + 280 + 20 + 30 + + 0 + + + + Text + + 80 + 380 + 160 + 60 + + Amount type bit +(0=XRP or MPT, 1=fungible token) +style=wordwrap + + + + Relation + + 40 + 300 + 60 + 130 + + lt=<<- + 10.0;10.0;10.0;110.0;40.0;110.0 + Text 100 - 110 + 350 260 30 @@ -263,7 +444,52 @@ style=wordwrap Relation 70 - 80 + 300 + 50 + 80 + + lt=<<- + 10.0;10.0;10.0;60.0;30.0;60.0 + + + UMLClass + + 70 + 280 + 20 + 30 + + 1 + + + + UMLClass + + 100 + 280 + 20 + 30 + + 1 + + + + Text + + 130 + 330 + 260 + 30 + + MPT indicator bit (1=MPT, 0=XRP) +style=wordwrap + + + + Relation + + 100 + 300 50 60 @@ -271,104 +497,136 @@ style=wordwrap 10.0;10.0;10.0;40.0;30.0;40.0 - Text + UMLClass - 80 - 140 - 160 - 60 + 90 + 60 + 20 + 30 - "Not XRP" bit -(0=XRP, 1=not XRP) -style=wordwrap + 0 Relation - 40 + 90 80 50 - 90 + 50 lt=<<- - 10.0;10.0;10.0;70.0;30.0;70.0 + 10.0;10.0;10.0;30.0;30.0;30.0 - UMLClass + Text - 100 - 60 - 540 + 120 + 100 + 260 30 - integer drops (62 bits) + MPT indicator bit (1=MPT, 0=XRP) +style=wordwrap UMLClass - 30 - 50 - 620 + 130 + 280 + 140 + 30 + + reserved (5 bits) + + + + UMLClass + + 280 + 280 + 190 + 30 + + integer quantity (64 bits) + + + + UMLClass + + 480 + 280 + 210 + 30 + + MPT issuance ID (192 bits) + + + + UMLClass + + 390 + 390 + 510 50 - Text + Relation - 30 - 20 - 160 + 380 + 300 + 120 + 110 + + lt=.. + 10.0;90.0;100.0;10.0 + + + Relation + + 680 + 300 + 210 + 110 + + lt=.. + 190.0;90.0;10.0;10.0 + + + UMLClass + + 400 + 400 + 210 30 - XRP Amount Format + Sequence number (32 bits) + + + + UMLClass + + 620 + 400 + 270 + 30 + + issuer's AccountID (160 bits) Text - 30 - 230 + 430 + 360 240 30 - Token Amount Format - - - - UMLClass - - 30 - 260 - 850 - 50 - - - - - - Text - - 90 - 470 - 240 - 30 - - Standard Currency Code Format - - - - UMLClass - - 30 - 500 - 620 - 50 - - + MPT Issuance ID Format diff --git a/docs/img/serialization-amount.svg b/docs/img/serialization-amount.svg index 601e8cf0c3..3297d25434 100644 --- a/docs/img/serialization-amount.svg +++ b/docs/img/serialization-amount.svg @@ -1,7 +1,7 @@ -MPT Issuance ID Formatissuer's AccountID (160 bits)Sequence number (32 bits)MPT issuance ID (192 bits)integer quantity (64 bits)reserved (5 bits)MPT indicator bit (1=MPT, 0=XRP)0MPT indicator bit (1=MPT, 0=XRP)11Sign bit (always 1 for positive)Amount type bit(0=XRP or MPT,1=fungible token)0MPT Amount FormatStandard Currency Code FormatToken Amount FormatFungible Token Amount FormatXRP Amount Formatinteger drops (62 bits)integer drops (61 bits)"Not XRP" bit(0=XRP, 1=not XRP)Amount type bit(0=XRP or MPT,1=fungible token)Sign bit (always 1 for positive)03 chars of ASCIIISO code (24 bits)Reserved (40 bits)reserved (40 bits)Reserved (88 bits)reserved (88 bits)Type code (8 bits)0x00 for ISO 4217/pseudo-ISO currency00issuer AccountID (160 bits)issuer's AccountID (160 bits)currency code (160 bits)"Not XRP" bit(0=XRP, 1=not XRP)Amount type bit(0=XRP or MPT,1=fungible token)Sign bit (0=negative, 1=positive)significant digits (54 bits)exponent (8 bits)163-1.) - 3. 32 bits indicating the `Sequence` number of the transaction that created the MPT issuance. - 4. 160 bits indicating the [AccountID][] of the MPT's issuer. + 3. 192 bits for the MPT Issuance ID, which is made of the following parts in order: + 1. 32 bits indicating the `Sequence` number of the transaction that created the MPT issuance. + 2. 160 bits indicating the [AccountID][] of the MPT's issuer. You can tell which of the three sub-types an amount is based on the first and third most significant bits: @@ -259,9 +260,9 @@ You can tell which of the three sub-types an amount is based on the first and th Not all types of amount are valid in all places. Some fields can only represent XRP, or XRP and fungible tokens but not MPTs. These limitations are defined by the individual transactions and ledger entries. {% /admonition %} -The following diagram shows the serialization formats for both XRP amounts and token amounts: ***TODO: update*** +The following diagram shows the serialization formats for all three amount formats: -[{% inline-svg file="/docs/img/serialization-amount.svg" /%}](/docs/img/serialization-amount.svg 'XRP amounts have a "not XRP" bit, a sign bit, and 62 bits of precision. Token amounts consist of a "not XRP" bit, a sign bit, an exponent (8 bits), significant digits (54 bits), currency code (160 bits), and issuer (160 bits).') +[{% inline-svg file="/docs/img/serialization-amount.svg" /%}](/docs/img/serialization-amount.svg 'The first bit is an amount type bit (0 = XRP or MPT, 1 = fungible token). XRP has a sign bit (always 1 for positive), an MPT indicator bit (0=XRP) and 61 bits of precision. MPTs have a sign bit (always 1 for positive), an MPT indicator bit (1=MPT), 5 reserved bits, 64 bit integer quantity, and a 192 bit MPT Issuance ID which consists of the 32-bit Sequence number followed by 160-bit issuer AccountID. Fungible Token amounts consist start with an amount type bit of 1, a sign bit which can be 1 or 0, an exponent (8 bits), significant digits (54 bits), currency code (160 bits), and issuer (160 bits).') #### Token Amount Format [[Source]](https://github.com/XRPLF/rippled/blob/35fa20a110e3d43ffc1e9e664fc9017b6f2747ae/src/ripple/protocol/impl/STAmount.cpp "Source") @@ -296,9 +297,6 @@ The [`rippled` APIs](../http-websocket-apis/index.md) support a **standard forma The **nonstandard format** is any 160 bits of data as long as the first 8 bits are not `0x00`. -#### MPT Amount Format - -The following diagram shows the amount serialization for MPTs. ***TODO: consolidate or not?*** ### Array Fields [Array]: #array-fields @@ -325,9 +323,9 @@ Blob fields have no further structure to their contents, so they consist of exac ### Currency Fields [Currency]: #currency-fields -Some fields specify a currency code, which could be an a fungible token, the ticker symbol for an off-ledger asset, or some other identifier for a currency. This field type is currently used only in [Price Oracles](../../concepts/decentralized-storage/price-oracles.md). +Some fields specify a currency code, which could be a fungible token, the ticker symbol for an off-ledger asset, or some other identifier for a currency. This field type is currently used only in [Price Oracles](../../concepts/decentralized-storage/price-oracles.md). -These fields consists of 160 bits of binary data. If the data matches the ["standard" currency code format](#currency-codes), it may be represented as a three-letter currency code string in JSON. Otherwise, it is represented as hexadecimal. Client libraries _may_ attempt to interpret this as a string of ASCII or UTF-8, but it is not guaranteed to be valid. +These fields consist of 160 bits of binary data. If the data matches the ["standard" currency code format](#currency-codes), it may be represented as a three-letter currency code string in JSON. Otherwise, it is represented as hexadecimal. Client libraries _may_ attempt to interpret this as a string of ASCII or UTF-8, but it is not guaranteed to be valid. The {% repo-link path="_code-samples/normalize-currency-codes/" %}Normalize Currency Codes code sample{% /repo-link %} demonstrates best practices for converting most common formats for this data into a string for humans to read. ### Issue Fields