solace 0.1.5 → 0.1.6
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/lib/solace/composers/associated_token_account_program_create_account_composer.rb +6 -6
- data/lib/solace/composers/associated_token_account_program_create_idempotent_account_composer.rb +2 -1
- data/lib/solace/composers/base.rb +1 -1
- data/lib/solace/composers/spl_token_program_close_account_composer.rb +3 -3
- data/lib/solace/composers/spl_token_program_initialize_mint_composer.rb +5 -5
- data/lib/solace/composers/spl_token_program_mint_to_composer.rb +4 -4
- data/lib/solace/composers/spl_token_program_transfer_checked_composer.rb +6 -6
- data/lib/solace/composers/spl_token_program_transfer_composer.rb +4 -4
- data/lib/solace/composers/system_program_create_account_composer.rb +5 -5
- data/lib/solace/composers/system_program_transfer_composer.rb +3 -3
- data/lib/solace/composers/token_2022_program_close_account_composer.rb +3 -3
- data/lib/solace/composers/token_2022_program_initialize_mint_composer.rb +5 -5
- data/lib/solace/composers/token_2022_program_mint_to_composer.rb +4 -4
- data/lib/solace/composers/token_2022_program_transfer_checked_composer.rb +6 -6
- data/lib/solace/composers/token_2022_program_transfer_composer.rb +4 -4
- data/lib/solace/connection.rb +5 -5
- data/lib/solace/errors/confirmation_timeout.rb +4 -4
- data/lib/solace/errors/rpc_error.rb +4 -4
- data/lib/solace/instructions/associated_token_account/create_account_instruction.rb +2 -1
- data/lib/solace/instructions/spl_token/close_account_instruction.rb +2 -2
- data/lib/solace/instructions/spl_token/initialize_account_instruction.rb +2 -2
- data/lib/solace/instructions/spl_token/initialize_mint_instruction.rb +2 -2
- data/lib/solace/instructions/spl_token/mint_to_instruction.rb +2 -2
- data/lib/solace/instructions/spl_token/transfer_checked_instruction.rb +2 -2
- data/lib/solace/instructions/spl_token/transfer_instruction.rb +2 -2
- data/lib/solace/instructions/system_program/create_account_instruction.rb +2 -2
- data/lib/solace/instructions/system_program/transfer_instruction.rb +2 -2
- data/lib/solace/instructions/token_2022/close_account_instruction.rb +2 -2
- data/lib/solace/instructions/token_2022/initialize_account_instruction.rb +2 -2
- data/lib/solace/instructions/token_2022/initialize_mint_instruction.rb +2 -2
- data/lib/solace/instructions/token_2022/mint_to_instruction.rb +2 -2
- data/lib/solace/instructions/token_2022/transfer_checked_instruction.rb +2 -2
- data/lib/solace/instructions/token_2022/transfer_instruction.rb +2 -2
- data/lib/solace/message.rb +5 -5
- data/lib/solace/programs/associated_token_account.rb +10 -9
- data/lib/solace/programs/token_program_interface.rb +18 -18
- data/lib/solace/serializers/address_lookup_table_deserializer.rb +2 -2
- data/lib/solace/serializers/base_deserializer.rb +1 -1
- data/lib/solace/serializers/instruction_deserializer.rb +2 -2
- data/lib/solace/serializers/message_deserializer.rb +3 -3
- data/lib/solace/serializers/transaction_deserializer.rb +1 -1
- data/lib/solace/tokens/token.rb +1 -1
- data/lib/solace/tokens.rb +2 -2
- data/lib/solace/transaction.rb +1 -1
- data/lib/solace/transaction_composer.rb +5 -5
- data/lib/solace/utils/account_context.rb +9 -9
- data/lib/solace/utils/codecs.rb +309 -49
- data/lib/solace/utils/rpc_client.rb +9 -9
- data/lib/solace/version.rb +1 -1
- metadata +111 -9
- data/CHANGELOG +0 -243
- data/LICENSE +0 -21
- data/README.md +0 -578
data/lib/solace/utils/codecs.rb
CHANGED
|
@@ -24,23 +24,204 @@ module Solace
|
|
|
24
24
|
# @see Solace::Keypair
|
|
25
25
|
# @since 0.0.1
|
|
26
26
|
module Utils
|
|
27
|
-
# Module for encoding and decoding data
|
|
27
|
+
# Module for encoding and decoding data.
|
|
28
|
+
#
|
|
29
|
+
# The helpers are grouped by category: base64/base58 string encodings,
|
|
30
|
+
# fixed-width little-endian integers, the Solana compact-u16 (shortvec)
|
|
31
|
+
# varint, length-prefixed byte/pubkey collections, and optionals.
|
|
32
|
+
#
|
|
33
|
+
# Serialization formats referenced below:
|
|
34
|
+
# - "Borsh" — the Anchor serialization spec. Borsh encodes `bool` as a single
|
|
35
|
+
# 0/1 byte, `Vec<T>`/`bytes` with a u32 little-endian length prefix, and
|
|
36
|
+
# `Option<T>` as a 1-byte discriminant (0 = None, 1 = Some) followed by the
|
|
37
|
+
# value. Methods that produce these layouts say so explicitly.
|
|
38
|
+
# - "SmallVec" — a Solana/Anchor-program convention (e.g. Squads) that prefixes
|
|
39
|
+
# a collection with a u8 or u16 length instead of Borsh's u32. NOT Borsh.
|
|
40
|
+
# - "compact-u16" / "shortvec" — Solana's own variable-length integer used in
|
|
41
|
+
# the transaction wire format. NOT Borsh.
|
|
42
|
+
#
|
|
43
|
+
# `extend self` exposes every method both as a module method
|
|
44
|
+
# (Solace::Utils::Codecs.<method>) and as an instance method when the module is
|
|
45
|
+
# included into a composed encoder/decoder.
|
|
28
46
|
#
|
|
29
47
|
# @since 0.0.1
|
|
30
48
|
module Codecs
|
|
49
|
+
extend self
|
|
50
|
+
|
|
51
|
+
# --- Base64 -----------------------------------------------------------
|
|
52
|
+
|
|
31
53
|
# Creates a StringIO from a base64 string.
|
|
32
54
|
#
|
|
33
55
|
# @param base64 [String] The base64 string to decode
|
|
34
56
|
# @return [StringIO] A StringIO object containing the decoded bytes
|
|
35
|
-
def
|
|
57
|
+
def base64_to_bytestream(base64)
|
|
36
58
|
StringIO.new(Base64.decode64(base64))
|
|
37
59
|
end
|
|
38
60
|
|
|
39
|
-
#
|
|
61
|
+
# --- Base58 -----------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
# Encodes a binary string in Base58 format.
|
|
64
|
+
#
|
|
65
|
+
# @param binary [String] The bytes to encode
|
|
66
|
+
# @return [String] The Base58 encoded string
|
|
67
|
+
def binary_to_base58(binary)
|
|
68
|
+
Base58.binary_to_base58(binary, :bitcoin)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Decodes a Base58 string into a binary string
|
|
72
|
+
#
|
|
73
|
+
# @param string [String] The Base58 encoded string
|
|
74
|
+
# @return [String] The decoded binary string
|
|
75
|
+
def base58_to_binary(string)
|
|
76
|
+
base58_to_bytes(string).pack('C*')
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Encodes a byte array in Base58 format
|
|
80
|
+
#
|
|
81
|
+
# @param bytes [Array<Integer>] The bytes to encode
|
|
82
|
+
# @return [String] The Base58 encoded string
|
|
83
|
+
def bytes_to_base58(bytes)
|
|
84
|
+
binary_to_base58(bytes.pack('C*'))
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Decodes a Base58 string into a sequence of bytes
|
|
88
|
+
#
|
|
89
|
+
# @param string [String] The Base58 encoded string
|
|
90
|
+
# @return [Array<Integer>] The decoded bytes
|
|
91
|
+
def base58_to_bytes(string)
|
|
92
|
+
Base58.base58_to_binary(string, :bitcoin).bytes
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Checks if a string is a valid Base58 string
|
|
96
|
+
#
|
|
97
|
+
# @param string [String] The string to check
|
|
98
|
+
# @return [Boolean] True if the string is a valid Base58 string, false otherwise
|
|
99
|
+
def valid_base58?(string)
|
|
100
|
+
return false if string.nil? || string.empty?
|
|
101
|
+
|
|
102
|
+
Base58.decode(string)
|
|
103
|
+
true
|
|
104
|
+
rescue StandardError => _e
|
|
105
|
+
false
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# --- Fixed-width little-endian integers -------------------------------
|
|
109
|
+
|
|
110
|
+
# Encodes a u8 as a single byte.
|
|
111
|
+
#
|
|
112
|
+
# @param byte [Integer] Value in range 0..255.
|
|
113
|
+
# @return [Array<Integer>] A single-element byte array.
|
|
114
|
+
def encode_u8(byte)
|
|
115
|
+
[byte]
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Decodes a u8 from 1 byte.
|
|
119
|
+
#
|
|
120
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
121
|
+
# @return [Integer] Value in range 0..255.
|
|
122
|
+
def decode_u8(stream)
|
|
123
|
+
stream.read(1).unpack1('C')
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Encodes a u16 as 2 little-endian bytes.
|
|
127
|
+
#
|
|
128
|
+
# @param u16 [Integer] Value in range 0..65535.
|
|
129
|
+
# @return [String] 2-byte little-endian binary string.
|
|
130
|
+
def encode_le_u16(u16)
|
|
131
|
+
[u16].pack('S<')
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Decodes a u16 from 2 little-endian bytes.
|
|
135
|
+
#
|
|
136
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
137
|
+
# @return [Integer] Value in range 0..65535.
|
|
138
|
+
def decode_le_u16(stream)
|
|
139
|
+
stream.read(2).unpack1('S<')
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Encodes a u32 as 4 little-endian bytes.
|
|
143
|
+
#
|
|
144
|
+
# @param u32 [Integer] Value in range 0..4294967295.
|
|
145
|
+
# @return [String] 4-byte little-endian binary string.
|
|
146
|
+
def encode_le_u32(u32)
|
|
147
|
+
[u32].pack('L<')
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Decodes a u32 from 4 little-endian bytes.
|
|
151
|
+
#
|
|
152
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
153
|
+
# @return [Integer] Value in range 0..4294967295.
|
|
154
|
+
def decode_le_u32(stream)
|
|
155
|
+
stream.read(4).unpack1('L<')
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Encodes a u64 value in little-endian format
|
|
159
|
+
#
|
|
160
|
+
# @param u64 [Integer] The u64 value to encode
|
|
161
|
+
# @return [String] The little-endian encoded u64 value
|
|
162
|
+
def encode_le_u64(u64)
|
|
163
|
+
[u64].pack('Q<') # 64-bit little-endian
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Decodes a little-endian u64 value from a sequence of bytes
|
|
167
|
+
#
|
|
168
|
+
# @param stream [IO, StringIO] The input to read bytes from.
|
|
169
|
+
# @return [Integer] The decoded u64 value
|
|
170
|
+
def decode_le_u64(stream)
|
|
171
|
+
stream.read(8).unpack1('Q<')
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Encodes a u128 as 16 little-endian bytes (two u64 words, low word first).
|
|
175
|
+
#
|
|
176
|
+
# @param u128 [Integer] Value in range 0..2**128-1.
|
|
177
|
+
# @return [String] 16-byte little-endian binary string.
|
|
178
|
+
def encode_le_u128(u128)
|
|
179
|
+
[u128 & 0xFFFFFFFFFFFFFFFF, u128 >> 64].pack('Q<Q<')
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Decodes a u128 from 16 little-endian bytes (two u64 words, low word first).
|
|
183
|
+
#
|
|
184
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
185
|
+
# @return [Integer] Value in range 0..2**128-1.
|
|
186
|
+
def decode_le_u128(stream)
|
|
187
|
+
lo, hi = stream.read(16).unpack('Q<Q<')
|
|
188
|
+
lo + (hi << 64)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Encodes an i64 as 8 little-endian bytes (two's complement).
|
|
192
|
+
#
|
|
193
|
+
# @param i64 [Integer] Value in range -2**63..2**63-1.
|
|
194
|
+
# @return [String] 8-byte little-endian binary string.
|
|
195
|
+
def encode_le_i64(i64)
|
|
196
|
+
[i64].pack('q<')
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Decodes an i64 from 8 little-endian bytes (two's complement).
|
|
200
|
+
#
|
|
201
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
202
|
+
# @return [Integer] Value in range -2**63..2**63-1.
|
|
203
|
+
def decode_le_i64(stream)
|
|
204
|
+
stream.read(8).unpack1('q<')
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# --- Boolean ----------------------------------------------------------
|
|
208
|
+
|
|
209
|
+
# Encodes a Borsh bool as a single byte: false → 0, true → 1.
|
|
210
|
+
#
|
|
211
|
+
# @param bool [Boolean] The value to encode.
|
|
212
|
+
# @return [Array<Integer>] A single-element byte array.
|
|
213
|
+
def encode_bool(bool)
|
|
214
|
+
[bool ? 1 : 0]
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# --- compact-u16 (Solana shortvec varint) -----------------------------
|
|
218
|
+
|
|
219
|
+
# Encodes an integer as a compact-u16 (shortvec) varint. This is Solana's
|
|
220
|
+
# transaction wire-format length prefix, NOT Borsh.
|
|
40
221
|
#
|
|
41
222
|
# @param u16 [Integer] The compact-u16 value to encode
|
|
42
223
|
# @return [String] The compactly encoded compact-u16 value
|
|
43
|
-
def
|
|
224
|
+
def encode_compact_u16(u16)
|
|
44
225
|
out = []
|
|
45
226
|
|
|
46
227
|
loop do
|
|
@@ -74,23 +255,23 @@ module Solace
|
|
|
74
255
|
out.pack('C*')
|
|
75
256
|
end
|
|
76
257
|
|
|
77
|
-
# Decodes a compact-u16 (
|
|
258
|
+
# Decodes a compact-u16 (shortvec) value from an IO-like object.
|
|
78
259
|
#
|
|
79
260
|
# Reads bytes one at a time, accumulating the result until the MSB is 0.
|
|
80
261
|
#
|
|
81
262
|
# @param stream [IO, StringIO] The input to read bytes from.
|
|
82
263
|
# @return [Integer, Integer] The decoded value and the number of bytes read.
|
|
83
|
-
def
|
|
84
|
-
value
|
|
85
|
-
shift
|
|
264
|
+
def decode_compact_u16(stream)
|
|
265
|
+
value = 0
|
|
266
|
+
shift = 0
|
|
86
267
|
bytes_read = 0
|
|
87
268
|
|
|
88
269
|
loop do
|
|
89
270
|
byte = stream.read(1)
|
|
90
271
|
raise EOFError, 'Unexpected end of input while decoding compact-u16' unless byte
|
|
91
272
|
|
|
92
|
-
byte
|
|
93
|
-
value
|
|
273
|
+
byte = byte.ord
|
|
274
|
+
value |= (byte & 0x7F) << shift
|
|
94
275
|
bytes_read += 1
|
|
95
276
|
break if byte.nobits?(0x80)
|
|
96
277
|
|
|
@@ -100,65 +281,144 @@ module Solace
|
|
|
100
281
|
[value, bytes_read]
|
|
101
282
|
end
|
|
102
283
|
|
|
103
|
-
#
|
|
284
|
+
# --- Length-prefixed byte sequences -----------------------------------
|
|
285
|
+
|
|
286
|
+
# Encodes a Borsh bytes field / Vec<u8>: u32 LE length prefix + raw bytes.
|
|
104
287
|
#
|
|
105
|
-
# @param
|
|
106
|
-
# @return [
|
|
107
|
-
def
|
|
108
|
-
|
|
288
|
+
# @param bytes [Array<Integer>] The raw bytes.
|
|
289
|
+
# @return [Array<Integer>]
|
|
290
|
+
def encode_bytes(bytes)
|
|
291
|
+
encode_le_u32(bytes.length).bytes + bytes
|
|
109
292
|
end
|
|
110
293
|
|
|
111
|
-
# Decodes a
|
|
294
|
+
# Decodes a Borsh bytes / Vec<u8> field: u32 LE length prefix + raw bytes.
|
|
112
295
|
#
|
|
113
|
-
# @param stream [IO, StringIO] The
|
|
114
|
-
# @return [
|
|
115
|
-
def
|
|
116
|
-
stream.read(
|
|
296
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
297
|
+
# @return [String] The raw bytes as a binary string.
|
|
298
|
+
def decode_bytes(stream)
|
|
299
|
+
stream.read(decode_le_u32(stream))
|
|
117
300
|
end
|
|
118
301
|
|
|
119
|
-
# Encodes a
|
|
302
|
+
# Encodes a SmallVec<u8, u8>: u8 length prefix + raw bytes. SmallVec is a
|
|
303
|
+
# Solana/Anchor-program convention, NOT Borsh (which would use a u32 prefix).
|
|
120
304
|
#
|
|
121
|
-
# @param
|
|
122
|
-
# @return [
|
|
123
|
-
def
|
|
124
|
-
|
|
305
|
+
# @param bytes [Array<Integer>] The raw bytes (max 255).
|
|
306
|
+
# @return [Array<Integer>]
|
|
307
|
+
def encode_smallvec_u8_bytes(bytes)
|
|
308
|
+
[bytes.length] + bytes
|
|
125
309
|
end
|
|
126
310
|
|
|
127
|
-
#
|
|
311
|
+
# Encodes a SmallVec<u16, u8>: u16 LE length prefix + raw bytes. SmallVec is a
|
|
312
|
+
# Solana/Anchor-program convention, NOT Borsh (which would use a u32 prefix).
|
|
128
313
|
#
|
|
129
|
-
# @param
|
|
130
|
-
# @return [
|
|
131
|
-
def
|
|
132
|
-
|
|
314
|
+
# @param bytes [Array<Integer>] The raw bytes (max 65535).
|
|
315
|
+
# @return [Array<Integer>]
|
|
316
|
+
def encode_smallvec_u16_bytes(bytes)
|
|
317
|
+
encode_le_u16(bytes.length).bytes + bytes
|
|
133
318
|
end
|
|
134
319
|
|
|
135
|
-
#
|
|
320
|
+
# --- Public keys ------------------------------------------------------
|
|
321
|
+
|
|
322
|
+
# Encodes a public key as 32 raw bytes (a Solana primitive, not a Borsh
|
|
323
|
+
# type). Accepts any representation that resolves to a base58 string via
|
|
324
|
+
# #to_s (String, Keypair, PublicKey).
|
|
136
325
|
#
|
|
137
|
-
# @param
|
|
138
|
-
# @return [
|
|
139
|
-
def
|
|
140
|
-
|
|
326
|
+
# @param pubkey [#to_s] The public key in any representation.
|
|
327
|
+
# @return [Array<Integer>] 32 bytes.
|
|
328
|
+
def encode_pubkey(pubkey)
|
|
329
|
+
base58_to_bytes(pubkey.to_s)
|
|
141
330
|
end
|
|
142
331
|
|
|
143
|
-
# Decodes a
|
|
332
|
+
# Decodes a public key from 32 bytes.
|
|
144
333
|
#
|
|
145
|
-
# @param
|
|
146
|
-
# @return [String]
|
|
147
|
-
def
|
|
148
|
-
|
|
334
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
335
|
+
# @return [String] Base58 public key.
|
|
336
|
+
def decode_pubkey(stream)
|
|
337
|
+
bytes_to_base58(stream.read(32).bytes)
|
|
149
338
|
end
|
|
150
339
|
|
|
151
|
-
#
|
|
340
|
+
# Encodes a Borsh Vec<publicKey>: u32 LE count prefix followed by each
|
|
341
|
+
# 32-byte pubkey.
|
|
152
342
|
#
|
|
153
|
-
# @param
|
|
154
|
-
# @return [
|
|
155
|
-
def
|
|
156
|
-
|
|
343
|
+
# @param pubkeys [Array<#to_s>] The public keys in any representation.
|
|
344
|
+
# @return [Array<Integer>]
|
|
345
|
+
def encode_vec_pubkeys(pubkeys)
|
|
346
|
+
encode_le_u32(pubkeys.length).bytes +
|
|
347
|
+
pubkeys.flat_map { |pubkey| encode_pubkey(pubkey) }
|
|
348
|
+
end
|
|
157
349
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
350
|
+
# Decodes a Borsh Vec<publicKey>: u32 LE count prefix followed by each
|
|
351
|
+
# 32-byte pubkey.
|
|
352
|
+
#
|
|
353
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
354
|
+
# @return [Array<String>] Base58 public keys.
|
|
355
|
+
def decode_vec_pubkeys(stream)
|
|
356
|
+
Array.new(decode_le_u32(stream)) { decode_pubkey(stream) }
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
# Encodes a SmallVec<u8, Pubkey>: u8 count prefix followed by each 32-byte
|
|
360
|
+
# pubkey. SmallVec is a Solana convention (NOT Borsh); used by the
|
|
361
|
+
# transaction message header's account_keys (distinct from
|
|
362
|
+
# encode_vec_pubkeys, which uses Borsh's u32 count).
|
|
363
|
+
#
|
|
364
|
+
# @param pubkeys [Array<#to_s>] The public keys in any representation (max 255).
|
|
365
|
+
# @return [Array<Integer>]
|
|
366
|
+
def encode_smallvec_u8_pubkeys(pubkeys)
|
|
367
|
+
[pubkeys.length] + pubkeys.flat_map { |pubkey| encode_pubkey(pubkey) }
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
# --- Optionals (Borsh Option<T>) --------------------------------------
|
|
371
|
+
|
|
372
|
+
# Encodes a Borsh Option<publicKey>: None → [0], Some(key) → [1] + 32 bytes.
|
|
373
|
+
#
|
|
374
|
+
# @param pubkey [#to_s, nil] Base58 public key or nil.
|
|
375
|
+
# @return [Array<Integer>]
|
|
376
|
+
def encode_option_pubkey(pubkey)
|
|
377
|
+
return [0] if pubkey.nil?
|
|
378
|
+
|
|
379
|
+
[1] + encode_pubkey(pubkey)
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
# Decodes a Borsh Option<publicKey>: None → nil, Some(key) → base58 pubkey.
|
|
383
|
+
#
|
|
384
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
385
|
+
# @return [String, nil] Base58 public key or nil.
|
|
386
|
+
def decode_option_pubkey(stream)
|
|
387
|
+
return nil if decode_u8(stream).zero?
|
|
388
|
+
|
|
389
|
+
decode_pubkey(stream)
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
# Encodes a Borsh Option<i64>: None → [0], Some(i64) → [1] + 8 LE bytes.
|
|
393
|
+
#
|
|
394
|
+
# @param i64 [Integer, nil]
|
|
395
|
+
# @return [Array<Integer>]
|
|
396
|
+
def encode_option_i64(i64)
|
|
397
|
+
return [0] if i64.nil?
|
|
398
|
+
|
|
399
|
+
[1] + encode_le_i64(i64).bytes
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
# Decodes a Borsh Option<i64>: None → nil, Some(i64) → integer.
|
|
403
|
+
#
|
|
404
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
405
|
+
# @return [Integer, nil]
|
|
406
|
+
def decode_option_i64(stream)
|
|
407
|
+
return nil if decode_u8(stream).zero?
|
|
408
|
+
|
|
409
|
+
decode_le_i64(stream)
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
# Encodes a Borsh Option<String>:
|
|
413
|
+
# None → [0], Some(str) → [1] + u32 LE length + UTF-8 bytes.
|
|
414
|
+
#
|
|
415
|
+
# @param str [String, nil]
|
|
416
|
+
# @return [Array<Integer>]
|
|
417
|
+
def encode_option_string(str)
|
|
418
|
+
return [0] if str.nil?
|
|
419
|
+
|
|
420
|
+
bytes = str.encode('UTF-8').bytes
|
|
421
|
+
[1] + encode_le_u32(bytes.length).bytes + bytes
|
|
162
422
|
end
|
|
163
423
|
end
|
|
164
424
|
end
|
|
@@ -35,7 +35,7 @@ module Solace
|
|
|
35
35
|
open_timeout:,
|
|
36
36
|
read_timeout:
|
|
37
37
|
)
|
|
38
|
-
@url
|
|
38
|
+
@url = url
|
|
39
39
|
@open_timeout = open_timeout
|
|
40
40
|
@read_timeout = read_timeout
|
|
41
41
|
end
|
|
@@ -52,7 +52,7 @@ module Solace
|
|
|
52
52
|
# Solace::Errors::ConfirmationTimeout
|
|
53
53
|
# ]
|
|
54
54
|
def rpc_request(method, params = [])
|
|
55
|
-
request
|
|
55
|
+
request = build_rpc_request(method, params)
|
|
56
56
|
response = perform_http_request(*request)
|
|
57
57
|
handle_rpc_response(response)
|
|
58
58
|
end
|
|
@@ -67,10 +67,10 @@ module Solace
|
|
|
67
67
|
def build_rpc_request(method, params)
|
|
68
68
|
uri = URI(url)
|
|
69
69
|
|
|
70
|
-
req
|
|
71
|
-
req['Accept']
|
|
70
|
+
req = Net::HTTP::Post.new(uri)
|
|
71
|
+
req['Accept'] = 'application/json'
|
|
72
72
|
req['Content-Type'] = 'application/json'
|
|
73
|
-
req.body
|
|
73
|
+
req.body = build_request_body(method, params)
|
|
74
74
|
|
|
75
75
|
[uri, req]
|
|
76
76
|
end
|
|
@@ -83,9 +83,9 @@ module Solace
|
|
|
83
83
|
def build_request_body(method, params)
|
|
84
84
|
{
|
|
85
85
|
jsonrpc: '2.0',
|
|
86
|
-
id:
|
|
87
|
-
method:
|
|
88
|
-
params:
|
|
86
|
+
id: SecureRandom.uuid,
|
|
87
|
+
method: method,
|
|
88
|
+
params: params
|
|
89
89
|
}.to_json
|
|
90
90
|
end
|
|
91
91
|
|
|
@@ -99,7 +99,7 @@ module Solace
|
|
|
99
99
|
Net::HTTP.start(
|
|
100
100
|
uri.hostname,
|
|
101
101
|
uri.port,
|
|
102
|
-
use_ssl:
|
|
102
|
+
use_ssl: uri.scheme == 'https',
|
|
103
103
|
open_timeout: open_timeout,
|
|
104
104
|
read_timeout: read_timeout
|
|
105
105
|
) do |http|
|
data/lib/solace/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: solace
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sebastian Scholl
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: bin
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-06-22 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: base58
|
|
@@ -51,6 +52,20 @@ dependencies:
|
|
|
51
52
|
- - "~>"
|
|
52
53
|
- !ruby/object:Gem::Version
|
|
53
54
|
version: '7.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: factory_bot
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
54
69
|
- !ruby/object:Gem::Dependency
|
|
55
70
|
name: minitest
|
|
56
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -65,6 +80,20 @@ dependencies:
|
|
|
65
80
|
- - "~>"
|
|
66
81
|
- !ruby/object:Gem::Version
|
|
67
82
|
version: '5.0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: minitest-hooks
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
68
97
|
- !ruby/object:Gem::Dependency
|
|
69
98
|
name: rake
|
|
70
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -79,6 +108,48 @@ dependencies:
|
|
|
79
108
|
- - "~>"
|
|
80
109
|
- !ruby/object:Gem::Version
|
|
81
110
|
version: '13.0'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: redcarpet
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - ">="
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '0'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - ">="
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: rubocop
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: rubocop-yard
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - ">="
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - ">="
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0'
|
|
82
153
|
- !ruby/object:Gem::Dependency
|
|
83
154
|
name: tty-spinner
|
|
84
155
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -93,6 +164,34 @@ dependencies:
|
|
|
93
164
|
- - ">="
|
|
94
165
|
- !ruby/object:Gem::Version
|
|
95
166
|
version: '0'
|
|
167
|
+
- !ruby/object:Gem::Dependency
|
|
168
|
+
name: yard
|
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
|
170
|
+
requirements:
|
|
171
|
+
- - ">="
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: '0'
|
|
174
|
+
type: :development
|
|
175
|
+
prerelease: false
|
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
177
|
+
requirements:
|
|
178
|
+
- - ">="
|
|
179
|
+
- !ruby/object:Gem::Version
|
|
180
|
+
version: '0'
|
|
181
|
+
- !ruby/object:Gem::Dependency
|
|
182
|
+
name: yardstick
|
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
|
184
|
+
requirements:
|
|
185
|
+
- - ">="
|
|
186
|
+
- !ruby/object:Gem::Version
|
|
187
|
+
version: '0'
|
|
188
|
+
type: :development
|
|
189
|
+
prerelease: false
|
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
191
|
+
requirements:
|
|
192
|
+
- - ">="
|
|
193
|
+
- !ruby/object:Gem::Version
|
|
194
|
+
version: '0'
|
|
96
195
|
description: A Ruby library for working with Solana blockchain. Provides both low-level
|
|
97
196
|
instruction builders and high-level program clients for interacting with Solana
|
|
98
197
|
programs.
|
|
@@ -102,9 +201,6 @@ executables: []
|
|
|
102
201
|
extensions: []
|
|
103
202
|
extra_rdoc_files: []
|
|
104
203
|
files:
|
|
105
|
-
- CHANGELOG
|
|
106
|
-
- LICENSE
|
|
107
|
-
- README.md
|
|
108
204
|
- lib/solace.rb
|
|
109
205
|
- lib/solace/address_lookup_table.rb
|
|
110
206
|
- lib/solace/composers/associated_token_account_program_create_account_composer.rb
|
|
@@ -182,10 +278,15 @@ files:
|
|
|
182
278
|
- lib/solace/utils/pda.rb
|
|
183
279
|
- lib/solace/utils/rpc_client.rb
|
|
184
280
|
- lib/solace/version.rb
|
|
185
|
-
homepage: https://github.com/
|
|
281
|
+
homepage: https://github.com/zarpay/solace
|
|
186
282
|
licenses:
|
|
187
283
|
- MIT
|
|
188
|
-
metadata:
|
|
284
|
+
metadata:
|
|
285
|
+
allowed_push_host: https://rubygems.org
|
|
286
|
+
source_code_uri: https://github.com/zarpay/solace
|
|
287
|
+
changelog_uri: https://github.com/zarpay/solace/blob/main/CHANGELOG
|
|
288
|
+
documentation_uri: https://zarpay.github.io/solace
|
|
289
|
+
rubygems_mfa_required: 'true'
|
|
189
290
|
post_install_message: |2+
|
|
190
291
|
|
|
191
292
|
Thank you for installing Solace!
|
|
@@ -193,7 +294,7 @@ post_install_message: |2+
|
|
|
193
294
|
This gem includes native binaries for curve25519 operations.
|
|
194
295
|
If you encounter any issues with native library loading,
|
|
195
296
|
please check that your platform is supported or file an issue at:
|
|
196
|
-
https://github.com/
|
|
297
|
+
https://github.com/zarpay/solace/issues
|
|
197
298
|
|
|
198
299
|
rdoc_options: []
|
|
199
300
|
require_paths:
|
|
@@ -209,7 +310,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
209
310
|
- !ruby/object:Gem::Version
|
|
210
311
|
version: '0'
|
|
211
312
|
requirements: []
|
|
212
|
-
rubygems_version:
|
|
313
|
+
rubygems_version: 3.5.22
|
|
314
|
+
signing_key:
|
|
213
315
|
specification_version: 4
|
|
214
316
|
summary: Solana ruby library
|
|
215
317
|
test_files: []
|