xrpl-ruby 0.0.3 → 0.5.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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/address-codec/address_codec.rb +22 -4
  3. data/lib/address-codec/codec.rb +15 -2
  4. data/lib/address-codec/xrp_codec.rb +29 -2
  5. data/lib/binary-codec/binary_codec.rb +62 -0
  6. data/lib/binary-codec/enums/constants.rb +8 -0
  7. data/lib/binary-codec/enums/definitions.json +3774 -0
  8. data/lib/binary-codec/enums/definitions.rb +90 -0
  9. data/lib/binary-codec/enums/fields.rb +104 -0
  10. data/lib/binary-codec/serdes/binary_parser.rb +183 -0
  11. data/lib/binary-codec/serdes/binary_serializer.rb +93 -0
  12. data/lib/binary-codec/serdes/bytes_list.rb +47 -0
  13. data/lib/binary-codec/types/account_id.rb +60 -0
  14. data/lib/binary-codec/types/amount.rb +304 -0
  15. data/lib/binary-codec/types/blob.rb +41 -0
  16. data/lib/binary-codec/types/currency.rb +116 -0
  17. data/lib/binary-codec/types/hash.rb +106 -0
  18. data/lib/binary-codec/types/issue.rb +50 -0
  19. data/lib/binary-codec/types/path_set.rb +93 -0
  20. data/lib/binary-codec/types/serialized_type.rb +157 -0
  21. data/lib/binary-codec/types/st_array.rb +71 -0
  22. data/lib/binary-codec/types/st_object.rb +157 -0
  23. data/lib/binary-codec/types/uint.rb +166 -0
  24. data/lib/binary-codec/types/vector256.rb +53 -0
  25. data/lib/binary-codec/types/xchain_bridge.rb +47 -0
  26. data/lib/binary-codec/utilities.rb +98 -0
  27. data/lib/core/base_58_xrp.rb +2 -0
  28. data/lib/core/base_x.rb +10 -0
  29. data/lib/core/core.rb +79 -6
  30. data/lib/core/utilities.rb +38 -0
  31. data/lib/key-pairs/ed25519.rb +64 -0
  32. data/lib/key-pairs/key_pairs.rb +92 -0
  33. data/lib/key-pairs/secp256k1.rb +116 -0
  34. data/lib/wallet/wallet.rb +117 -0
  35. data/lib/xrpl-ruby.rb +32 -1
  36. metadata +44 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 601db38742606f9188b1f301ca9e6800308d7650ec4d6c7dd655db9eed6bab27
4
- data.tar.gz: 188e2ff1112b079a7aed430882fe0c0599a839946dd9ed5842d6e55df964c5e8
3
+ metadata.gz: 6c84782686e7934255929a23850a5f514d0435ff79e47cde2739ed1e940a0235
4
+ data.tar.gz: b6b1c24d77a63365e8bf45f8a8b702332315057a8a7ec820ef830264e3ba446e
5
5
  SHA512:
6
- metadata.gz: 4e819838c6ada42db05efebc7fec715ce22dd890911c7a40242a2945bacde3b832f9fbf4139cee2ffbc384a662a0cbda36336cf8e659eebf69820deae25797f0
7
- data.tar.gz: 46f08dc1d555d518ce8b98760881e94f29871b1a32c49b6d1003a1197a0e7bd354ec09d415e2ccf4f85f343add4ccb742fdd3587dfabd0f764ed4f397cb47a9a
6
+ metadata.gz: 9cdee47951edf9ac0a804e8f8335aea13625f0cf61f6262f229f1c7e8e569892821a201b80916f0f274ac8ed9c2de677a77e32c5ed113bfc5102d7dca7f0cafa
7
+ data.tar.gz: 6c6e8309646053ab8039c7eb9bac814d08c9984f8dba4a64ae290ce349ac5e8c739b7a81e1ecf6305d93623f2ca9ce5015e1435757b6aa9a3bf6e74e2c1a6759
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module AddressCodec
3
4
 
4
5
  class AddressCodec < XrpCodec
@@ -10,21 +11,31 @@ module AddressCodec
10
11
 
11
12
  MAX_32_BIT_UNSIGNED_INT = 4294967295
12
13
 
14
+ # Converts a classic address to an X-address.
15
+ # @param classic_address [String] The classic XRPL address to convert.
16
+ # @param tag [Integer, false, nil] The destination tag.
17
+ # @param test [Boolean] Whether the address is for a test network.
18
+ # @return [String] The encoded X-address.
13
19
  def classic_address_to_x_address(classic_address, tag, test)
14
20
  account_id = decode_account_id(classic_address)
15
21
  encode_x_address(account_id, tag, test)
16
22
  end
17
23
 
24
+ # Encodes an account ID and tag into an X-address.
25
+ # @param account_id [Array<Integer>] 20 bytes for the account ID.
26
+ # @param tag [Integer, false, nil] The destination tag.
27
+ # @param test [Boolean] Whether the address is for a test network.
28
+ # @return [String] The encoded X-address.
18
29
  def encode_x_address(account_id, tag, test)
19
30
  if account_id.length != 20
20
31
  # RIPEMD160 -> 160 Bits = 20 Bytes
21
32
  raise 'Account ID must be 20 bytes'
22
33
  end
23
- if tag != false && tag > MAX_32_BIT_UNSIGNED_INT
34
+ if tag && tag != false && tag > MAX_32_BIT_UNSIGNED_INT
24
35
  raise 'Invalid tag'
25
36
  end
26
37
  the_tag = tag || 0
27
- flag = tag == false || tag.nil? ? 0 : 1
38
+ flag = (tag == false || tag.nil?) ? 0 : 1
28
39
 
29
40
  bytes = concat_args(
30
41
  test ? PREFIX_BYTES[:test] : PREFIX_BYTES[:main],
@@ -45,6 +56,9 @@ module AddressCodec
45
56
  encode_checked(bytes)
46
57
  end
47
58
 
59
+ # Converts an X-address to a classic address.
60
+ # @param x_address [String] The X-address string to convert.
61
+ # @return [Hash] A hash containing :classic_address, :tag, and :test.
48
62
  def x_address_to_classic_address(x_address)
49
63
  decoded = decode_x_address(x_address)
50
64
  account_id = decoded[:account_id]
@@ -58,6 +72,9 @@ module AddressCodec
58
72
  }
59
73
  end
60
74
 
75
+ # Decodes an X-address into its underlying account ID, tag, and network type.
76
+ # @param x_address [String] The X-address string to decode.
77
+ # @return [Hash] A hash containing :account_id, :tag, and :test.
61
78
  def decode_x_address(x_address)
62
79
  decoded = decode_checked(x_address)
63
80
  test = is_uint8_array_for_test_address(decoded)
@@ -70,6 +87,9 @@ module AddressCodec
70
87
  }
71
88
  end
72
89
 
90
+ # Checks if a string is a valid X-address.
91
+ # @param x_address [String] The X-address string to check.
92
+ # @return [Boolean] True if the X-address is valid, false otherwise.
73
93
  def valid_x_address?(x_address)
74
94
  begin
75
95
  decode_x_address(x_address)
@@ -96,11 +116,9 @@ module AddressCodec
96
116
  def tag_from_uint8_array(bytes)
97
117
  flag = bytes[22]
98
118
  if flag >= 2
99
- # Keine Unterstützung für 64-Bit-Tags zu diesem Zeitpunkt
100
119
  raise 'Unsupported X-address'
101
120
  end
102
121
  if flag == 1
103
- # Little-endian zu Big-endian
104
122
  return bytes[23] + bytes[24] * 0x100 + bytes[25] * 0x10000 + bytes[26] * 0x1000000
105
123
  end
106
124
  if flag != 0
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
- require 'digest'
3
2
 
4
- require_relative "../core/core"
3
+ require 'digest'
5
4
 
6
5
  module AddressCodec
7
6
  class Codec
@@ -10,11 +9,19 @@ module AddressCodec
10
9
  @codec = Core::Base58XRP.new
11
10
  end
12
11
 
12
+ # Encodes a byte array into a base58 string with a version prefix and checksum.
13
+ # @param bytes [Array<Integer>] The byte array to encode.
14
+ # @param opts [Hash] Options for encoding (e.g., :versions, :expected_length).
15
+ # @return [String] The encoded base58 string.
13
16
  def encode(bytes, opts)
14
17
  versions = opts[:versions]
15
18
  encode_versioned(bytes, versions, opts[:expected_length])
16
19
  end
17
20
 
21
+ # Decodes a base58 string and verifies its version and checksum.
22
+ # @param base58string [String] The base58 string to decode.
23
+ # @param opts [Hash] Options for decoding (e.g., :versions, :version_types, :expected_length).
24
+ # @return [Hash] The decoded data including version, bytes, and type.
18
25
  def decode(base58string, opts)
19
26
  versions = opts[:versions]
20
27
  types = opts[:version_types]
@@ -44,11 +51,17 @@ module AddressCodec
44
51
  raise 'version_invalid: version bytes do not match any of the provided version(s)'
45
52
  end
46
53
 
54
+ # Encodes a byte array into a base58 string with a checksum.
55
+ # @param bytes [Array<Integer>] The byte array to encode.
56
+ # @return [String] The encoded base58 string.
47
57
  def encode_checked(bytes)
48
58
  check = sha256(sha256(bytes))[0, 4]
49
59
  encode_raw(bytes + check)
50
60
  end
51
61
 
62
+ # Decodes a base58 string and verifies its checksum.
63
+ # @param base58string [String] The base58 string to decode.
64
+ # @return [Array<Integer>] The decoded byte array (without checksum).
52
65
  def decode_checked(base58string)
53
66
  bytes = decode_raw(base58string)
54
67
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../core/core"
4
-
5
3
  module AddressCodec
6
4
 
7
5
  class XrpCodec < Codec
@@ -13,6 +11,10 @@ module AddressCodec
13
11
  NODE_PUBLIC = 0x1c # 28; Validation public key (33 bytes)
14
12
  ED25519_SEED = [0x01, 0xe1, 0x4b].freeze # [1, 225, 75]
15
13
 
14
+ # Encodes entropy into a seed string.
15
+ # @param entropy [Array<Integer>] 16 bytes of entropy.
16
+ # @param type [String, nil] The seed type ('ed25519' or 'secp256k1').
17
+ # @return [String] The encoded seed string.
16
18
  def encode_seed(entropy, type = nil)
17
19
  unless check_byte_length(entropy, 16)
18
20
  raise 'entropy must have length 16'
@@ -27,6 +29,10 @@ module AddressCodec
27
29
  encode(entropy, opts)
28
30
  end
29
31
 
32
+ # Decodes a seed string into its underlying bytes and type.
33
+ # @param seed [String] The seed string to decode.
34
+ # @param opts [Hash] Options for decoding (e.g., :versions, :version_types, :expected_length).
35
+ # @return [Hash] The decoded data including version, bytes, and type.
30
36
  def decode_seed(seed, opts = {
31
37
  version_types: ['ed25519', 'secp256k1'],
32
38
  versions: [ED25519_SEED, FAMILY_SEED],
@@ -35,36 +41,57 @@ module AddressCodec
35
41
  decode(seed, opts)
36
42
  end
37
43
 
44
+ # Encodes a byte array into an account ID string.
45
+ # @param bytes [Array<Integer>] 20 bytes for the account ID.
46
+ # @return [String] The encoded account ID string.
38
47
  def encode_account_id(bytes)
39
48
  opts = { versions: [ACCOUNT_ID], expected_length: 20 }
40
49
  encode(bytes, opts)
41
50
  end
42
51
 
52
+ # Decodes an account ID string into its underlying bytes.
53
+ # @param account_id [String] The account ID string to decode.
54
+ # @return [Array<Integer>] The decoded bytes.
43
55
  def decode_account_id(account_id)
44
56
  opts = { versions: [ACCOUNT_ID], expected_length: 20 }
45
57
  decode(account_id, opts)[:bytes]
46
58
  end
47
59
 
60
+ # Decodes a node public key string into its underlying bytes.
61
+ # @param base58string [String] The node public key string to decode.
62
+ # @return [Array<Integer>] The decoded bytes.
48
63
  def decode_node_public(base58string)
49
64
  opts = { versions: [NODE_PUBLIC], expected_length: 33 }
50
65
  decode(base58string, opts)[:bytes]
51
66
  end
52
67
 
68
+ # Encodes a byte array into a node public key string.
69
+ # @param bytes [Array<Integer>] 33 bytes for the node public key.
70
+ # @return [String] The encoded node public key string.
53
71
  def encode_node_public(bytes)
54
72
  opts = { versions: [NODE_PUBLIC], expected_length: 33 }
55
73
  encode(bytes, opts)
56
74
  end
57
75
 
76
+ # Encodes a byte array into an account public key string.
77
+ # @param bytes [Array<Integer>] 33 bytes for the account public key.
78
+ # @return [String] The encoded account public key string.
58
79
  def encode_account_public(bytes)
59
80
  opts = { versions: [ACCOUNT_PUBLIC_KEY], expected_length: 33 }
60
81
  encode(bytes, opts)
61
82
  end
62
83
 
84
+ # Decodes an account public key string into its underlying bytes.
85
+ # @param base58string [String] The account public key string to decode.
86
+ # @return [Array<Integer>] The decoded bytes.
63
87
  def decode_account_public(base58string)
64
88
  opts = { versions: [ACCOUNT_PUBLIC_KEY], expected_length: 33 }
65
89
  decode(base58string, opts)[:bytes]
66
90
  end
67
91
 
92
+ # Checks if a string is a valid classic XRPL address.
93
+ # @param address [String] The address string to check.
94
+ # @return [Boolean] True if the address is valid, false otherwise.
68
95
  def valid_classic_address?(address)
69
96
  begin
70
97
  decode_account_id(address)
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BinaryCodec
4
+ # Hash prefixes for serialization.
5
+ HASH_PREFIX = {
6
+ transaction_sig: 0x53545800, # 'STX\0'
7
+ transaction_multi_sig: 0x534D5400, # 'SMT\0'
8
+ validation: 0x56414C00, # 'VAL\0'
9
+ proposal: 0x50525000 # 'PRP\0'
10
+ }.freeze
11
+
12
+ # from here: https://github.com/XRPLF/xrpl.js/blob/main/packages/ripple-binary-codec/src/binary.ts
13
+ class << self
14
+ # Creates a BinaryParser for the given bytes.
15
+ # @param bytes [String, Array<Integer>] The bytes to parse (hex string or byte array).
16
+ # @param definitions [Definitions, nil] Optional definitions.
17
+ # @return [BinaryParser] The created parser.
18
+ def make_parser(bytes, definitions = nil)
19
+ BinaryParser.new(bytes.is_a?(String) ? bytes : bytes_to_hex(bytes))
20
+ end
21
+
22
+ # Converts a hex string to its JSON representation.
23
+ # @param hex [String] The hex string to convert.
24
+ # @return [Hash] The decoded JSON object.
25
+ def binary_to_json(hex)
26
+ parser = make_parser(hex)
27
+ st_object = SerializedType.get_type_by_name('STObject')
28
+ JSON.parse(st_object.from_parser(parser).to_json)
29
+ end
30
+
31
+ # Converts a JSON object to its binary representation.
32
+ # @param json [Hash] The JSON object to convert.
33
+ # @return [String] The serialized hex string.
34
+ def json_to_binary(json)
35
+ st_object = SerializedType.get_type_by_name('STObject')
36
+ st_object.from(json).to_hex
37
+ end
38
+
39
+ # Generates signing data for a transaction.
40
+ # @param transaction [Hash] The transaction to serialize.
41
+ # @param prefix [Integer] The prefix to add to the serialized data.
42
+ # @param opts [Hash] Optional settings (e.g., :definitions, :signing_fields_only).
43
+ # @return [Array<Integer>] The serialized signing data.
44
+ def signing_data(transaction, prefix = HASH_PREFIX[:transaction_sig], opts = {})
45
+ # 1. Start with the prefix bytes
46
+ prefix_bytes = int_to_bytes(prefix, 4)
47
+
48
+ # 2. Serialize the object, only including signing fields
49
+ st_object_class = SerializedType.get_type_by_name('STObject')
50
+
51
+ filter = if opts[:signing_fields_only]
52
+ lambda { |field_name| Definitions.instance.get_field_instance(field_name).is_signing_field }
53
+ else
54
+ nil
55
+ end
56
+
57
+ serialized_bytes = st_object_class.from(transaction, filter).to_bytes
58
+
59
+ prefix_bytes + serialized_bytes
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BinaryCodec
4
+ TYPE_WIDTH = 2
5
+ LEDGER_ENTRY_WIDTH = 2
6
+ TRANSACTION_TYPE_WIDTH = 2
7
+ TRANSACTION_RESULT_WIDTH = 1
8
+ end