solana-ruby-kit 0.1.8 → 7.0.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/lib/solana/ruby/kit/errors.rb +37 -5
- data/lib/solana/ruby/kit/instruction_plans/instruction_plan.rb +34 -7
- data/lib/solana/ruby/kit/instruction_plans/max_instructions.rb +59 -0
- data/lib/solana/ruby/kit/instruction_plans/transaction_planner.rb +49 -9
- data/lib/solana/ruby/kit/instruction_plans.rb +1 -0
- data/lib/solana/ruby/kit/resource_limit_estimation.rb +156 -0
- data/lib/solana/ruby/kit/rpc/api/get_signatures_for_address.rb +72 -0
- data/lib/solana/ruby/kit/rpc/api/get_vote_accounts.rb +2 -0
- data/lib/solana/ruby/kit/rpc/client.rb +2 -0
- data/lib/solana/ruby/kit/rpc/transport.rb +3 -4
- data/lib/solana/ruby/kit/transaction_introspection/compiled_transaction_message.rb +168 -0
- data/lib/solana/ruby/kit/transaction_introspection/decode_rpc_transaction.rb +159 -0
- data/lib/solana/ruby/kit/transaction_introspection/get_inner_instructions.rb +86 -0
- data/lib/solana/ruby/kit/transaction_introspection/get_instructions.rb +134 -0
- data/lib/solana/ruby/kit/transaction_introspection/loaded_addresses.rb +19 -0
- data/lib/solana/ruby/kit/transaction_introspection/types.rb +29 -0
- data/lib/solana/ruby/kit/transaction_introspection/walk_instructions.rb +60 -0
- data/lib/solana/ruby/kit/transaction_introspection.rb +13 -0
- data/lib/solana/ruby/kit/transaction_messages/compute_budget.rb +145 -0
- data/lib/solana/ruby/kit/transaction_messages.rb +1 -0
- data/lib/solana/ruby/kit/version.rb +1 -1
- data/lib/solana/ruby/kit.rb +3 -0
- metadata +13 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Helpers for inspecting confirmed Solana transactions and walking their
|
|
5
|
+
# outer and inner instructions.
|
|
6
|
+
# Mirrors @solana/transaction-introspection.
|
|
7
|
+
require_relative 'transaction_introspection/loaded_addresses'
|
|
8
|
+
require_relative 'transaction_introspection/compiled_transaction_message'
|
|
9
|
+
require_relative 'transaction_introspection/types'
|
|
10
|
+
require_relative 'transaction_introspection/get_instructions'
|
|
11
|
+
require_relative 'transaction_introspection/get_inner_instructions'
|
|
12
|
+
require_relative 'transaction_introspection/walk_instructions'
|
|
13
|
+
require_relative 'transaction_introspection/decode_rpc_transaction'
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../addresses/address'
|
|
5
|
+
require_relative '../instructions/instruction'
|
|
6
|
+
require_relative 'transaction_message'
|
|
7
|
+
|
|
8
|
+
module Solana::Ruby::Kit
|
|
9
|
+
module TransactionMessages
|
|
10
|
+
# Address of the Compute Budget program.
|
|
11
|
+
COMPUTE_BUDGET_PROGRAM_ADDRESS = T.let(
|
|
12
|
+
Addresses::Address.new('ComputeBudget111111111111111111111111111111'),
|
|
13
|
+
Addresses::Address
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
# Maximum compute unit limit per transaction (from Agave execution_budget.rs).
|
|
17
|
+
MAX_COMPUTE_UNIT_LIMIT = T.let(1_400_000, Integer)
|
|
18
|
+
|
|
19
|
+
# Maximum loaded accounts data size limit per transaction (64 MiB, from Agave).
|
|
20
|
+
MAX_LOADED_ACCOUNTS_DATA_SIZE_LIMIT = T.let(64 * 1024 * 1024, Integer)
|
|
21
|
+
|
|
22
|
+
SET_COMPUTE_UNIT_LIMIT_DISCRIMINATOR = T.let(2, Integer)
|
|
23
|
+
SET_LOADED_ACCOUNTS_DATA_SIZE_LIMIT_DISCRIMINATOR = T.let(4, Integer)
|
|
24
|
+
|
|
25
|
+
module_function
|
|
26
|
+
|
|
27
|
+
# ---------------------------------------------------------------------------
|
|
28
|
+
# SetComputeUnitLimit instruction helpers
|
|
29
|
+
# ---------------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
sig { params(units: Integer).returns(Instructions::Instruction) }
|
|
32
|
+
def get_set_compute_unit_limit_instruction(units)
|
|
33
|
+
data = ([SET_COMPUTE_UNIT_LIMIT_DISCRIMINATOR].pack('C') + [units].pack('V')).b
|
|
34
|
+
Instructions::Instruction.new(
|
|
35
|
+
program_address: COMPUTE_BUDGET_PROGRAM_ADDRESS,
|
|
36
|
+
accounts: nil,
|
|
37
|
+
data: data
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
sig { params(instruction: Instructions::Instruction).returns(T::Boolean) }
|
|
42
|
+
def set_compute_unit_limit_instruction?(instruction)
|
|
43
|
+
instruction.program_address == COMPUTE_BUDGET_PROGRAM_ADDRESS &&
|
|
44
|
+
!instruction.data.nil? &&
|
|
45
|
+
T.must(instruction.data).bytesize == 5 &&
|
|
46
|
+
T.must(instruction.data).getbyte(0) == SET_COMPUTE_UNIT_LIMIT_DISCRIMINATOR
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
sig { params(data: String).returns(Integer) }
|
|
50
|
+
def compute_unit_limit_from_instruction_data(data)
|
|
51
|
+
T.must(data[1, 4]).unpack1('V')
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Returns the compute unit limit set on a transaction message, or nil if none is set.
|
|
55
|
+
# Mirrors `getTransactionMessageComputeUnitLimit` from @solana/transaction-messages.
|
|
56
|
+
sig { params(message: TransactionMessage).returns(T.nilable(Integer)) }
|
|
57
|
+
def get_transaction_message_compute_unit_limit(message)
|
|
58
|
+
ix = message.instructions.find { |i| set_compute_unit_limit_instruction?(i) }
|
|
59
|
+
ix ? compute_unit_limit_from_instruction_data(T.must(ix.data)) : nil
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Sets the compute unit limit on a transaction message, appending or replacing the
|
|
63
|
+
# SetComputeUnitLimit instruction. Mirrors `setTransactionMessageComputeUnitLimit`.
|
|
64
|
+
sig { params(limit: Integer, message: TransactionMessage).returns(TransactionMessage) }
|
|
65
|
+
def set_transaction_message_compute_unit_limit(limit, message)
|
|
66
|
+
existing_idx = message.instructions.index { |i| set_compute_unit_limit_instruction?(i) }
|
|
67
|
+
new_ix = get_set_compute_unit_limit_instruction(limit)
|
|
68
|
+
|
|
69
|
+
if existing_idx.nil?
|
|
70
|
+
append_instructions(message, [new_ix])
|
|
71
|
+
elsif compute_unit_limit_from_instruction_data(T.must(message.instructions[existing_idx].data)) == limit
|
|
72
|
+
message
|
|
73
|
+
else
|
|
74
|
+
new_instructions = message.instructions.dup
|
|
75
|
+
new_instructions[T.must(existing_idx)] = new_ix
|
|
76
|
+
TransactionMessage.new(
|
|
77
|
+
version: message.version,
|
|
78
|
+
instructions: new_instructions,
|
|
79
|
+
fee_payer: message.fee_payer,
|
|
80
|
+
lifetime_constraint: message.lifetime_constraint,
|
|
81
|
+
address_table_lookups: message.address_table_lookups
|
|
82
|
+
)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# ---------------------------------------------------------------------------
|
|
87
|
+
# SetLoadedAccountsDataSizeLimit instruction helpers
|
|
88
|
+
# ---------------------------------------------------------------------------
|
|
89
|
+
|
|
90
|
+
sig { params(limit: Integer).returns(Instructions::Instruction) }
|
|
91
|
+
def get_set_loaded_accounts_data_size_limit_instruction(limit)
|
|
92
|
+
data = ([SET_LOADED_ACCOUNTS_DATA_SIZE_LIMIT_DISCRIMINATOR].pack('C') + [limit].pack('V')).b
|
|
93
|
+
Instructions::Instruction.new(
|
|
94
|
+
program_address: COMPUTE_BUDGET_PROGRAM_ADDRESS,
|
|
95
|
+
accounts: nil,
|
|
96
|
+
data: data
|
|
97
|
+
)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
sig { params(instruction: Instructions::Instruction).returns(T::Boolean) }
|
|
101
|
+
def set_loaded_accounts_data_size_limit_instruction?(instruction)
|
|
102
|
+
instruction.program_address == COMPUTE_BUDGET_PROGRAM_ADDRESS &&
|
|
103
|
+
!instruction.data.nil? &&
|
|
104
|
+
T.must(instruction.data).bytesize == 5 &&
|
|
105
|
+
T.must(instruction.data).getbyte(0) == SET_LOADED_ACCOUNTS_DATA_SIZE_LIMIT_DISCRIMINATOR
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
sig { params(data: String).returns(Integer) }
|
|
109
|
+
def loaded_accounts_data_size_limit_from_instruction_data(data)
|
|
110
|
+
T.must(data[1, 4]).unpack1('V')
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Returns the loaded accounts data size limit set on a transaction message, or nil.
|
|
114
|
+
# Mirrors `getTransactionMessageLoadedAccountsDataSizeLimit`.
|
|
115
|
+
sig { params(message: TransactionMessage).returns(T.nilable(Integer)) }
|
|
116
|
+
def get_transaction_message_loaded_accounts_data_size_limit(message)
|
|
117
|
+
ix = message.instructions.find { |i| set_loaded_accounts_data_size_limit_instruction?(i) }
|
|
118
|
+
ix ? loaded_accounts_data_size_limit_from_instruction_data(T.must(ix.data)) : nil
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Sets the loaded accounts data size limit on a transaction message.
|
|
122
|
+
# Mirrors `setTransactionMessageLoadedAccountsDataSizeLimit`.
|
|
123
|
+
sig { params(limit: Integer, message: TransactionMessage).returns(TransactionMessage) }
|
|
124
|
+
def set_transaction_message_loaded_accounts_data_size_limit(limit, message)
|
|
125
|
+
existing_idx = message.instructions.index { |i| set_loaded_accounts_data_size_limit_instruction?(i) }
|
|
126
|
+
new_ix = get_set_loaded_accounts_data_size_limit_instruction(limit)
|
|
127
|
+
|
|
128
|
+
if existing_idx.nil?
|
|
129
|
+
append_instructions(message, [new_ix])
|
|
130
|
+
elsif loaded_accounts_data_size_limit_from_instruction_data(T.must(message.instructions[existing_idx].data)) == limit
|
|
131
|
+
message
|
|
132
|
+
else
|
|
133
|
+
new_instructions = message.instructions.dup
|
|
134
|
+
new_instructions[T.must(existing_idx)] = new_ix
|
|
135
|
+
TransactionMessage.new(
|
|
136
|
+
version: message.version,
|
|
137
|
+
instructions: new_instructions,
|
|
138
|
+
fee_payer: message.fee_payer,
|
|
139
|
+
lifetime_constraint: message.lifetime_constraint,
|
|
140
|
+
address_table_lookups: message.address_table_lookups
|
|
141
|
+
)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
data/lib/solana/ruby/kit.rb
CHANGED
|
@@ -50,6 +50,8 @@ require_relative 'kit/programs'
|
|
|
50
50
|
require_relative 'kit/sysvars'
|
|
51
51
|
require_relative 'kit/transaction_confirmation'
|
|
52
52
|
require_relative 'kit/instruction_plans'
|
|
53
|
+
require_relative 'kit/resource_limit_estimation'
|
|
54
|
+
require_relative 'kit/transaction_introspection'
|
|
53
55
|
|
|
54
56
|
# Solana::Ruby::Kit is a Ruby translation of @anza-xyz/kit — the JavaScript SDK for
|
|
55
57
|
# building Solana apps — into idiomatic Ruby with Sorbet static types.
|
|
@@ -79,6 +81,7 @@ require_relative 'kit/instruction_plans'
|
|
|
79
81
|
# Solana::Ruby::Kit::TransactionConfirmation — confirmation polling (@solana/transaction-confirmation)
|
|
80
82
|
# Solana::Ruby::Kit::InstructionPlans — multi-tx planning (@solana/instruction-plans)
|
|
81
83
|
# Solana::Ruby::Kit::WalletStandard — server-side sig verify (@solana/wallet-standard)
|
|
84
|
+
# Solana::Ruby::Kit::TransactionIntrospection — decode/walk instructions (@solana/transaction-introspection)
|
|
82
85
|
|
|
83
86
|
module Solana::Ruby::Kit
|
|
84
87
|
extend T::Sig
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: solana-ruby-kit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 7.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Paul Zupan, Idhra Inc.
|
|
@@ -209,6 +209,7 @@ files:
|
|
|
209
209
|
- lib/solana/ruby/kit/functional.rb
|
|
210
210
|
- lib/solana/ruby/kit/instruction_plans.rb
|
|
211
211
|
- lib/solana/ruby/kit/instruction_plans/instruction_plan.rb
|
|
212
|
+
- lib/solana/ruby/kit/instruction_plans/max_instructions.rb
|
|
212
213
|
- lib/solana/ruby/kit/instruction_plans/plans.rb
|
|
213
214
|
- lib/solana/ruby/kit/instruction_plans/transaction_plan.rb
|
|
214
215
|
- lib/solana/ruby/kit/instruction_plans/transaction_plan_executor.rb
|
|
@@ -235,6 +236,7 @@ files:
|
|
|
235
236
|
- lib/solana/ruby/kit/programs/system_program.rb
|
|
236
237
|
- lib/solana/ruby/kit/promises.rb
|
|
237
238
|
- lib/solana/ruby/kit/railtie.rb
|
|
239
|
+
- lib/solana/ruby/kit/resource_limit_estimation.rb
|
|
238
240
|
- lib/solana/ruby/kit/rpc.rb
|
|
239
241
|
- lib/solana/ruby/kit/rpc/api/get_account_info.rb
|
|
240
242
|
- lib/solana/ruby/kit/rpc/api/get_balance.rb
|
|
@@ -248,6 +250,7 @@ files:
|
|
|
248
250
|
- lib/solana/ruby/kit/rpc/api/get_multiple_accounts.rb
|
|
249
251
|
- lib/solana/ruby/kit/rpc/api/get_program_accounts.rb
|
|
250
252
|
- lib/solana/ruby/kit/rpc/api/get_signature_statuses.rb
|
|
253
|
+
- lib/solana/ruby/kit/rpc/api/get_signatures_for_address.rb
|
|
251
254
|
- lib/solana/ruby/kit/rpc/api/get_slot.rb
|
|
252
255
|
- lib/solana/ruby/kit/rpc/api/get_token_account_balance.rb
|
|
253
256
|
- lib/solana/ruby/kit/rpc/api/get_token_accounts_by_owner.rb
|
|
@@ -296,7 +299,16 @@ files:
|
|
|
296
299
|
- lib/solana/ruby/kit/sysvars/last_restart_slot.rb
|
|
297
300
|
- lib/solana/ruby/kit/sysvars/rent.rb
|
|
298
301
|
- lib/solana/ruby/kit/transaction_confirmation.rb
|
|
302
|
+
- lib/solana/ruby/kit/transaction_introspection.rb
|
|
303
|
+
- lib/solana/ruby/kit/transaction_introspection/compiled_transaction_message.rb
|
|
304
|
+
- lib/solana/ruby/kit/transaction_introspection/decode_rpc_transaction.rb
|
|
305
|
+
- lib/solana/ruby/kit/transaction_introspection/get_inner_instructions.rb
|
|
306
|
+
- lib/solana/ruby/kit/transaction_introspection/get_instructions.rb
|
|
307
|
+
- lib/solana/ruby/kit/transaction_introspection/loaded_addresses.rb
|
|
308
|
+
- lib/solana/ruby/kit/transaction_introspection/types.rb
|
|
309
|
+
- lib/solana/ruby/kit/transaction_introspection/walk_instructions.rb
|
|
299
310
|
- lib/solana/ruby/kit/transaction_messages.rb
|
|
311
|
+
- lib/solana/ruby/kit/transaction_messages/compute_budget.rb
|
|
300
312
|
- lib/solana/ruby/kit/transaction_messages/transaction_message.rb
|
|
301
313
|
- lib/solana/ruby/kit/transactions.rb
|
|
302
314
|
- lib/solana/ruby/kit/transactions/compiler.rb
|