xrpl-ruby 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +82 -0
- data/README.md +57 -3
- data/lib/binary-codec/binary_codec.rb +22 -1
- data/lib/binary-codec/enums/definitions.json +84 -288
- data/lib/binary-codec/enums/definitions.rb +38 -1
- data/lib/binary-codec/types/uint.rb +32 -39
- data/lib/wallet/wallet.rb +32 -0
- data/lib/xrpl/client.rb +30 -6
- data/lib/xrpl/fee.rb +82 -0
- data/lib/xrpl/ledger_entry.rb +53 -0
- data/lib/xrpl/model.rb +239 -0
- data/lib/xrpl/transaction.rb +14 -163
- data/lib/xrpl/version.rb +1 -1
- data/lib/xrpl-ruby.rb +3 -0
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cb8b3e628ddf6a9d9a7e329e6e8c51e4b0cd4f872eb609e589d78795aa9f4782
|
|
4
|
+
data.tar.gz: 2f5b18b34cb386901a8ad1a7549f7cca241facce58c0841f36a10a4c200413cc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f066a56166ec0aa81ec3acb34106d504962a6e1cf2cee89eb13103719467f9ded35a34d432d9901c8a81f11b7dedc93311d8ebd184dc21564585163536e18558
|
|
7
|
+
data.tar.gz: 97397fe795b08eed3c56111b876d5476da705e2577c635f12e6aeee9ebc5ef86106fd44e525dc67c3716c11472b273bd4235764d9df2b7bf8bcc3e0d152078a7
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,88 @@ All notable changes to this project are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.8.0] - 2026-09-24
|
|
9
|
+
|
|
10
|
+
The codec now targets **rippled 3.4.0** (released 2026-09-17) and passes the
|
|
11
|
+
ripple-binary-codec 2.11.0 fixture set: 39 transactions and 263 ledger
|
|
12
|
+
entries, both directions (302 cases; 287 before). Measured before the change:
|
|
13
|
+
transactions 38/39, accountState 262/263 decode.
|
|
14
|
+
|
|
15
|
+
### Breaking
|
|
16
|
+
|
|
17
|
+
- **`definitions.json` is rippled 3.4.0.** It is what a 3.4.0 node reports
|
|
18
|
+
through `server_definitions` (s1.ripple.com), with the node's own digest in
|
|
19
|
+
`hash`. FIELDS 381 → 357: the 27 `Hook*` fields plus `EmitGeneration` and
|
|
20
|
+
`EmittedTxn` are gone, because rippled dropped Hooks; a blob carrying one
|
|
21
|
+
of them no longer decodes. Added: `VaultKind`, `SubscriptionDate`,
|
|
22
|
+
`RedemptionDate`, `LEVersion`, `ContractResult` (LendingProtocolV1_1,
|
|
23
|
+
closed-ended vaults), and `CredentialIDs` on `VaultWithdraw` and
|
|
24
|
+
`LoanBrokerCoverWithdraw`. ripple-binary-codec's `main` additionally
|
|
25
|
+
carries four `*KeyEpoch` fields from rippled's development branch; they
|
|
26
|
+
are in no release and deliberately not here.
|
|
27
|
+
- **`PermissionValue` decodes to its name.** A `DelegateSet` permission is
|
|
28
|
+
a UInt32 that rippled renders by name: a transaction type as its code plus
|
|
29
|
+
one (`"Payment"` = 1), the twelve granular permissions from 65537
|
|
30
|
+
(`"TrustlineAuthorize"`). Encoding accepts the names; they were silently
|
|
31
|
+
serialised as 0 before.
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- **Ledger entry models** — `XRPL::LedgerEntry::AccountRoot`,
|
|
36
|
+
`::RippleState`, `::Offer` and the other 28 types, generated from
|
|
37
|
+
`LEDGER_ENTRY_FORMATS` the way the transaction models are generated from
|
|
38
|
+
`TRANSACTION_FORMATS`. `XRPL::LedgerEntry.from(node)` builds the right
|
|
39
|
+
class from anything `ledger_entry`, `account_objects` or `ledger_data`
|
|
40
|
+
returns and keeps rippled's `index` alongside. Every `lsf` flag is a
|
|
41
|
+
constant on its type. All 263 reference ledger entries round-trip through
|
|
42
|
+
their model unchanged.
|
|
43
|
+
- **Flag helpers** on transactions and ledger entries: `#flag?` takes the
|
|
44
|
+
ledger's name, the constant's name or the bit, `#flag_names` lists what
|
|
45
|
+
is set.
|
|
46
|
+
- **Fees by transaction type.** `autofill` now charges what rippled charges:
|
|
47
|
+
`EscrowFinish` pays for its `Fulfillment` (base × (33 + bytes / 16)),
|
|
48
|
+
`AccountDelete`, `AMMCreate` and `VaultCreate` cost the owner reserve
|
|
49
|
+
from `server_state`, a `Batch` pays two base fees plus those of its inner
|
|
50
|
+
transactions, the confidential MPT transactions cost ten base fees, and
|
|
51
|
+
multisigning adds one base fee per signature. Ordinary fees are capped at
|
|
52
|
+
2 XRP (`Client.new(url, max_fee_drops:)`); the reserve-priced types are
|
|
53
|
+
not. The rules are a pure module, `XRPL::Fee.calculate`, and the same
|
|
54
|
+
ones xrpl.js applies. Before, every transaction paid the base fee, so an
|
|
55
|
+
AccountDelete or an EscrowFinish with a fulfillment could not be
|
|
56
|
+
autofilled.
|
|
57
|
+
- **Payment channel claims.** `Wallet#sign_payment_channel_claim(channel,
|
|
58
|
+
drops)` and `#verify_payment_channel_claim`, plus
|
|
59
|
+
`Wallet.verify_payment_channel_claim(..., public_key)` for the receiving
|
|
60
|
+
side; `BinaryCodec.signing_claim_data` underneath. Checked against the
|
|
61
|
+
xrpl.js signature vector byte for byte.
|
|
62
|
+
- The hash prefixes for batch, counterparty and sponsor signatures
|
|
63
|
+
(`fixCleanup3_4_0`) are in `BinaryCodec::HASH_PREFIX`; the signing
|
|
64
|
+
helpers for them are not written yet.
|
|
65
|
+
- `Definitions#delegatable_permissions`, and readers for the transaction
|
|
66
|
+
type, ledger entry type and result tables the codec resolves names
|
|
67
|
+
against.
|
|
68
|
+
|
|
69
|
+
### Changed
|
|
70
|
+
|
|
71
|
+
- `XRPL::Transaction` is built on a new `XRPL::Model` base shared with
|
|
72
|
+
`XRPL::LedgerEntry`. Its public surface is unchanged;
|
|
73
|
+
`Transaction::ValidationError` is now `Model::ValidationError`, reachable
|
|
74
|
+
under both names. A model rejects a hash whose type field contradicts the
|
|
75
|
+
class (`Payment.new('TransactionType' => 'TrustSet')`), where it used to
|
|
76
|
+
keep the foreign value and serialise a TrustSet.
|
|
77
|
+
- The transaction models pick up the 3.4.0 fields without a code change:
|
|
78
|
+
`VaultCreate.new(vault_kind:, subscription_date:, redemption_date:)`.
|
|
79
|
+
- A parity spec that pins `definitions.json` to the 3.4.0 digest and fails
|
|
80
|
+
if a Hook or development-branch field comes back.
|
|
81
|
+
|
|
82
|
+
### Fixed
|
|
83
|
+
|
|
84
|
+
- `ConfidentialOutstandingAmount` renders in base 10 like the other MPToken
|
|
85
|
+
amounts, not as a 16 digit hex string.
|
|
86
|
+
- `Definitions#get_field_instance` returns `nil` for an unknown field name.
|
|
87
|
+
Serialising a hash with a foreign key now fails with "Field x is not
|
|
88
|
+
defined" instead of a `NoMethodError` on `nil`.
|
|
89
|
+
|
|
8
90
|
## [0.7.0] - 2026-08-26
|
|
9
91
|
|
|
10
92
|
The binary codec now passes the full ripple-binary-codec reference fixture set
|
data/README.md
CHANGED
|
@@ -12,14 +12,19 @@ A pure-Ruby library to interact with the [XRP Ledger](https://xrpl.org) (XRPL) b
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
14
14
|
- Key and wallet management (secp256k1 and ed25519)
|
|
15
|
-
- Address codec and binary
|
|
15
|
+
- Address codec and binary codec, conformant with rippled 3.4.0 and the
|
|
16
|
+
ripple-binary-codec reference fixtures
|
|
17
|
+
- Transaction and ledger entry models generated from the ledger's own
|
|
18
|
+
definitions
|
|
16
19
|
- WebSocket client for the XRP Ledger public API
|
|
17
20
|
- Testnet faucet helper to create and fund wallets
|
|
18
|
-
- Transaction lifecycle: autofill, sign, submit, and
|
|
21
|
+
- Transaction lifecycle: autofill with per-type fees, sign, submit, and
|
|
22
|
+
reliable "submit and wait"
|
|
23
|
+
- Payment channel claims, signed and verified locally
|
|
19
24
|
|
|
20
25
|
## Requirements
|
|
21
26
|
|
|
22
|
-
- Ruby 3.
|
|
27
|
+
- Ruby 3.2 or later
|
|
23
28
|
|
|
24
29
|
## Installation
|
|
25
30
|
|
|
@@ -111,6 +116,55 @@ hash, which is useful for anything read back off the ledger. Note that
|
|
|
111
116
|
`validate!` follows rippled's formats: it checks what the ledger requires for
|
|
112
117
|
serialisation, which is not always what a transaction needs to be meaningful.
|
|
113
118
|
|
|
119
|
+
Flags can be asked about by any of their names:
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
payment.flag?(:tf_partial_payment) # => true
|
|
123
|
+
payment.flag_names # => ["tfPartialPayment"]
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Fees
|
|
127
|
+
|
|
128
|
+
`autofill` sets the fee the transaction type actually needs, following the
|
|
129
|
+
same rules as xrpl.js: an `EscrowFinish` pays for the size of its
|
|
130
|
+
`Fulfillment`, `AccountDelete`, `AMMCreate` and `VaultCreate` cost the owner
|
|
131
|
+
reserve, a `Batch` pays for its inner transactions, and multisigning adds one
|
|
132
|
+
base fee per signature. Ordinary fees are capped at 2 XRP; pass
|
|
133
|
+
`max_fee_drops:` to `Client.new` to change that. The rules are available on
|
|
134
|
+
their own as `XRPL::Fee.calculate`.
|
|
135
|
+
|
|
136
|
+
## Ledger entries
|
|
137
|
+
|
|
138
|
+
The objects that make up the ledger's state - `AccountRoot`, `RippleState`,
|
|
139
|
+
`Offer`, `Escrow` and the rest - have models too, generated from
|
|
140
|
+
`LEDGER_ENTRY_FORMATS` the same way:
|
|
141
|
+
|
|
142
|
+
```ruby
|
|
143
|
+
node = client.request_with_retry('ledger_entry', account_root: address).dig('result', 'node')
|
|
144
|
+
entry = XRPL::LedgerEntry.from(node)
|
|
145
|
+
|
|
146
|
+
entry.class # => XRPL::LedgerEntry::AccountRoot
|
|
147
|
+
entry.balance # => "370000000"
|
|
148
|
+
entry.flag?(:lsf_default_ripple) # => true
|
|
149
|
+
entry.flag_names # => ["lsfDefaultRipple", "lsfDisableMaster"]
|
|
150
|
+
entry.index # the entry's hash, as rippled reports it
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Every flag rippled defines is a constant on its type, e.g.
|
|
154
|
+
`XRPL::LedgerEntry::AccountRoot::LSF_DEPOSIT_AUTH`.
|
|
155
|
+
|
|
156
|
+
## Payment channel claims
|
|
157
|
+
|
|
158
|
+
A claim is signed off-ledger and redeemed later with a `PaymentChannelClaim`
|
|
159
|
+
transaction. Amounts are in drops:
|
|
160
|
+
|
|
161
|
+
```ruby
|
|
162
|
+
signature = wallet.sign_payment_channel_claim(channel_id, '1000000')
|
|
163
|
+
|
|
164
|
+
# On the receiving side, against the channel's PublicKey:
|
|
165
|
+
Wallet::Wallet.verify_payment_channel_claim(channel_id, '1000000', signature, public_key)
|
|
166
|
+
```
|
|
167
|
+
|
|
114
168
|
The client is silent by default. To see diagnostic output, pass a logger:
|
|
115
169
|
|
|
116
170
|
```ruby
|
|
@@ -6,7 +6,15 @@ module BinaryCodec
|
|
|
6
6
|
transaction_sig: 0x53545800, # 'STX\0'
|
|
7
7
|
transaction_multi_sig: 0x534D5400, # 'SMT\0'
|
|
8
8
|
validation: 0x56414C00, # 'VAL\0'
|
|
9
|
-
proposal: 0x50525000 # 'PRP\0'
|
|
9
|
+
proposal: 0x50525000, # 'PRP\0'
|
|
10
|
+
payment_channel_claim: 0x434C4D00, # 'CLM\0'
|
|
11
|
+
batch: 0x42434800, # 'BCH\0'
|
|
12
|
+
# Role-specific prefixes from fixCleanup3_4_0, so a signature made for
|
|
13
|
+
# one role cannot be replayed as another.
|
|
14
|
+
counterparty_sig: 0x43505400, # 'CPT\0'
|
|
15
|
+
counterparty_multi_sig: 0x43504D00, # 'CPM\0'
|
|
16
|
+
sponsor_sig: 0x53504E00, # 'SPN\0'
|
|
17
|
+
sponsor_multi_sig: 0x53504D00 # 'SPM\0'
|
|
10
18
|
}.freeze
|
|
11
19
|
|
|
12
20
|
# from here: https://github.com/XRPLF/xrpl.js/blob/main/packages/ripple-binary-codec/src/binary.ts
|
|
@@ -38,6 +46,19 @@ module BinaryCodec
|
|
|
38
46
|
st_object.from(json).to_hex
|
|
39
47
|
end
|
|
40
48
|
|
|
49
|
+
# The bytes a payment channel claim is signed over: the 'CLM\0' prefix,
|
|
50
|
+
# the channel ID and the amount in drops. Same as xrpl.js
|
|
51
|
+
# encodeForSigningClaim.
|
|
52
|
+
#
|
|
53
|
+
# @param channel [String] the channel ID, 64 hex characters
|
|
54
|
+
# @param amount [String, Integer] the amount in drops
|
|
55
|
+
# @return [Array<Integer>] the signing data
|
|
56
|
+
def signing_claim_data(channel:, amount:)
|
|
57
|
+
int_to_bytes(HASH_PREFIX[:payment_channel_claim], 4) +
|
|
58
|
+
Hash256.from(channel).to_bytes +
|
|
59
|
+
Uint64.from(Integer(amount)).to_bytes
|
|
60
|
+
end
|
|
61
|
+
|
|
41
62
|
# Generates signing data for a transaction.
|
|
42
63
|
# @param transaction [Hash] The transaction to serialize.
|
|
43
64
|
# @param prefix [Integer] The prefix to add to the serialized data.
|