erpc-sdk 0.9.1 → 0.11.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/LICENSES/Apache-2.0.txt +201 -0
- data/LICENSES/BSD-3-Clause-Google-Protobuf.txt +29 -0
- data/README.md +46 -9
- data/THIRD_PARTY_NOTICES.md +41 -0
- data/lib/erpc_sdk/arbitrum.rb +62 -0
- data/lib/erpc_sdk/arc.rb +33 -0
- data/lib/erpc_sdk/base.rb +333 -0
- data/lib/erpc_sdk/bitcoin.rb +126 -0
- data/lib/erpc_sdk/bitcoin_codec.rb +574 -0
- data/lib/erpc_sdk/bitcoin_transport.rb +369 -0
- data/lib/erpc_sdk/bsc.rb +33 -0
- data/lib/erpc_sdk/client.rb +109 -1
- data/lib/erpc_sdk/config.rb +168 -5
- data/lib/erpc_sdk/errors.rb +31 -1
- data/lib/erpc_sdk/generated/rpc_network_contract.rb +3196 -0
- data/lib/erpc_sdk/hyperliquid.rb +33 -0
- data/lib/erpc_sdk/kaia.rb +33 -0
- data/lib/erpc_sdk/monad.rb +33 -0
- data/lib/erpc_sdk/near.rb +276 -0
- data/lib/erpc_sdk/near_transport.rb +345 -0
- data/lib/erpc_sdk/optimism.rb +33 -0
- data/lib/erpc_sdk/polygon.rb +33 -0
- data/lib/erpc_sdk/robinhood.rb +33 -0
- data/lib/erpc_sdk/soneium.rb +33 -0
- data/lib/erpc_sdk/sui.rb +5 -0
- data/lib/erpc_sdk/sui_grpc_web.rb +226 -0
- data/lib/erpc_sdk/sui_proto.rb +370 -0
- data/lib/erpc_sdk/transport.rb +28 -0
- data/lib/erpc_sdk/tron.rb +33 -0
- data/lib/erpc_sdk/version.rb +1 -1
- data/lib/erpc_sdk.rb +21 -0
- metadata +43 -7
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "base"
|
|
4
|
+
|
|
5
|
+
module ERPC
|
|
6
|
+
HYPERLIQUID_TRANSPORT_FACTS = SealedEvmContract.facts_from_contract(RPC_NETWORK_CONTRACT, "client-hyperliquid-rpc")
|
|
7
|
+
HYPERLIQUID_RPC_METHODS = HYPERLIQUID_TRANSPORT_FACTS.method_names
|
|
8
|
+
private_constant :HYPERLIQUID_TRANSPORT_FACTS
|
|
9
|
+
|
|
10
|
+
class HyperliquidRpc < BaseRpc
|
|
11
|
+
alias_method :endpoint, :endpoint
|
|
12
|
+
alias_method :eth_chain_id, :eth_chain_id
|
|
13
|
+
alias_method :eth_get_balance, :eth_get_balance
|
|
14
|
+
alias_method :eth_call, :eth_call
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class HyperliquidClient
|
|
18
|
+
attr_reader :rpc
|
|
19
|
+
|
|
20
|
+
def initialize(transport)
|
|
21
|
+
@rpc = HyperliquidRpc.new(transport)
|
|
22
|
+
freeze
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module Hyperliquid
|
|
27
|
+
module_function
|
|
28
|
+
|
|
29
|
+
def create_client(transport)
|
|
30
|
+
HyperliquidClient.new(transport)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "base"
|
|
4
|
+
|
|
5
|
+
module ERPC
|
|
6
|
+
KAIA_TRANSPORT_FACTS = SealedEvmContract.facts_from_contract(RPC_NETWORK_CONTRACT, "client-kaia-rpc")
|
|
7
|
+
KAIA_RPC_METHODS = KAIA_TRANSPORT_FACTS.method_names
|
|
8
|
+
private_constant :KAIA_TRANSPORT_FACTS
|
|
9
|
+
|
|
10
|
+
class KaiaRpc < BaseRpc
|
|
11
|
+
alias_method :endpoint, :endpoint
|
|
12
|
+
alias_method :eth_chain_id, :eth_chain_id
|
|
13
|
+
alias_method :eth_get_balance, :eth_get_balance
|
|
14
|
+
alias_method :eth_call, :eth_call
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class KaiaClient
|
|
18
|
+
attr_reader :rpc
|
|
19
|
+
|
|
20
|
+
def initialize(transport)
|
|
21
|
+
@rpc = KaiaRpc.new(transport)
|
|
22
|
+
freeze
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module Kaia
|
|
27
|
+
module_function
|
|
28
|
+
|
|
29
|
+
def create_client(transport)
|
|
30
|
+
KaiaClient.new(transport)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "base"
|
|
4
|
+
|
|
5
|
+
module ERPC
|
|
6
|
+
MONAD_TRANSPORT_FACTS = SealedEvmContract.facts_from_contract(RPC_NETWORK_CONTRACT, "client-monad-rpc")
|
|
7
|
+
MONAD_RPC_METHODS = MONAD_TRANSPORT_FACTS.method_names
|
|
8
|
+
private_constant :MONAD_TRANSPORT_FACTS
|
|
9
|
+
|
|
10
|
+
class MonadRpc < BaseRpc
|
|
11
|
+
alias_method :endpoint, :endpoint
|
|
12
|
+
alias_method :eth_chain_id, :eth_chain_id
|
|
13
|
+
alias_method :eth_get_balance, :eth_get_balance
|
|
14
|
+
alias_method :eth_call, :eth_call
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class MonadClient
|
|
18
|
+
attr_reader :rpc
|
|
19
|
+
|
|
20
|
+
def initialize(transport)
|
|
21
|
+
@rpc = MonadRpc.new(transport)
|
|
22
|
+
freeze
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module Monad
|
|
27
|
+
module_function
|
|
28
|
+
|
|
29
|
+
def create_client(transport)
|
|
30
|
+
MonadClient.new(transport)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bigdecimal"
|
|
4
|
+
|
|
5
|
+
require_relative "near_transport"
|
|
6
|
+
|
|
7
|
+
module ERPC
|
|
8
|
+
module NearFinality
|
|
9
|
+
FINAL = "final".freeze
|
|
10
|
+
OPTIMISTIC = "optimistic".freeze
|
|
11
|
+
VALUES = [FINAL, OPTIMISTIC].freeze
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class NearBlockReference
|
|
15
|
+
attr_reader :kind, :value
|
|
16
|
+
|
|
17
|
+
def self.final
|
|
18
|
+
new(:finality, NearFinality::FINAL)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.optimistic
|
|
22
|
+
new(:finality, NearFinality::OPTIMISTIC)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.height(value)
|
|
26
|
+
new(:block_id, validate_height(value))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.from_hash(value)
|
|
30
|
+
raise ConfigError, "NEAR block hash must be a non-empty string", cause: nil unless value.is_a?(String) && !value.empty? && !value.match?(/[\x00-\x1f\x7f]/)
|
|
31
|
+
new(:block_id, value.freeze)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.validate_height(value)
|
|
35
|
+
raise ConfigError, "NEAR block height must be an unsigned integer", cause: nil unless value.is_a?(Integer) && !value.is_a?(TrueClass) && value >= 0 && value <= 18_446_744_073_709_551_615
|
|
36
|
+
value
|
|
37
|
+
end
|
|
38
|
+
private_class_method :validate_height
|
|
39
|
+
|
|
40
|
+
def initialize(kind, value)
|
|
41
|
+
@kind = kind.to_sym
|
|
42
|
+
@value = case @kind
|
|
43
|
+
when :finality
|
|
44
|
+
raise ConfigError, "NEAR finality must be final or optimistic", cause: nil unless [NearFinality::FINAL, NearFinality::OPTIMISTIC].include?(value)
|
|
45
|
+
value.dup.freeze
|
|
46
|
+
when :block_id
|
|
47
|
+
if value.is_a?(Integer) && !value.is_a?(TrueClass) && !value.is_a?(FalseClass)
|
|
48
|
+
self.class.send(:validate_height, value)
|
|
49
|
+
elsif value.is_a?(String) && !value.empty? && !value.match?(/[\x00-\x1f\x7f]/)
|
|
50
|
+
value.dup.freeze
|
|
51
|
+
else
|
|
52
|
+
raise ConfigError, "NEAR block_id must be an opaque hash or u64 height", cause: nil
|
|
53
|
+
end
|
|
54
|
+
else
|
|
55
|
+
raise ConfigError, "NEAR block reference kind is unsupported", cause: nil
|
|
56
|
+
end
|
|
57
|
+
freeze
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def to_h
|
|
61
|
+
{ kind == :finality ? "finality" : "block_id" => value }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def self.selector(reference)
|
|
65
|
+
raise ConfigError, "NEAR block reference is invalid", cause: nil unless reference.instance_of?(self)
|
|
66
|
+
kind = reference.instance_variable_get(:@kind)
|
|
67
|
+
value = reference.instance_variable_get(:@value)
|
|
68
|
+
checked = new(kind, value)
|
|
69
|
+
{ checked.kind == :finality ? "finality" : "block_id" => checked.value }
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
class NearPendingRequest
|
|
74
|
+
def initialize(&block)
|
|
75
|
+
@block = block
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def send
|
|
79
|
+
@block.call
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
module NearTypedValue
|
|
84
|
+
module_function
|
|
85
|
+
U64_MAX = 18_446_744_073_709_551_615
|
|
86
|
+
|
|
87
|
+
def hash(value)
|
|
88
|
+
raise InvalidResponseError.new("ERPC returned an invalid NEAR response"), cause: nil unless value.is_a?(Hash)
|
|
89
|
+
value
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def string(value)
|
|
93
|
+
raise InvalidResponseError.new("ERPC returned an invalid NEAR response"), cause: nil unless value.is_a?(String)
|
|
94
|
+
value
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def integer(value)
|
|
98
|
+
raise InvalidResponseError.new("ERPC returned an invalid NEAR response"), cause: nil unless value.is_a?(Integer) && !value.is_a?(TrueClass) && !value.is_a?(FalseClass) && value.between?(0, U64_MAX)
|
|
99
|
+
value
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def boolean(value)
|
|
103
|
+
raise InvalidResponseError.new("ERPC returned an invalid NEAR response"), cause: nil unless value == true || value == false
|
|
104
|
+
value
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def optional_string(value)
|
|
108
|
+
value.nil? ? nil : string(value)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def optional_integer(value)
|
|
112
|
+
value.nil? ? nil : integer(value)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def additional(value, known)
|
|
116
|
+
value.each_with_object({}) { |(key, item), result| result[key] = item unless known.include?(key) }.freeze
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
class NearSyncInfo
|
|
121
|
+
attr_reader :latest_block_hash, :latest_block_height, :latest_block_time, :latest_state_root, :syncing, :additional
|
|
122
|
+
|
|
123
|
+
def self.from(value)
|
|
124
|
+
hash = NearTypedValue.hash(value)
|
|
125
|
+
known = %w[latest_block_hash latest_block_height latest_block_time latest_state_root syncing]
|
|
126
|
+
new(
|
|
127
|
+
NearTypedValue.string(hash.fetch("latest_block_hash")),
|
|
128
|
+
NearTypedValue.integer(hash.fetch("latest_block_height")),
|
|
129
|
+
NearTypedValue.string(hash.fetch("latest_block_time")),
|
|
130
|
+
NearTypedValue.string(hash.fetch("latest_state_root")),
|
|
131
|
+
NearTypedValue.boolean(hash.fetch("syncing")),
|
|
132
|
+
NearTypedValue.additional(hash, known)
|
|
133
|
+
)
|
|
134
|
+
rescue KeyError
|
|
135
|
+
raise InvalidResponseError.new("ERPC returned an invalid NEAR response"), cause: nil
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def initialize(latest_block_hash, latest_block_height, latest_block_time, latest_state_root, syncing, additional)
|
|
139
|
+
@latest_block_hash = latest_block_hash; @latest_block_height = latest_block_height; @latest_block_time = latest_block_time
|
|
140
|
+
@latest_state_root = latest_state_root; @syncing = syncing; @additional = additional; freeze
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
class NearNodeVersion
|
|
145
|
+
attr_reader :version, :build, :rustc_version, :additional
|
|
146
|
+
|
|
147
|
+
def self.from(value)
|
|
148
|
+
hash = NearTypedValue.hash(value); known = %w[version build rustc_version]
|
|
149
|
+
new(NearTypedValue.string(hash.fetch("version")), NearTypedValue.string(hash.fetch("build")), NearTypedValue.optional_string(hash["rustc_version"]), NearTypedValue.additional(hash, known))
|
|
150
|
+
rescue KeyError
|
|
151
|
+
raise InvalidResponseError.new("ERPC returned an invalid NEAR response"), cause: nil
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def initialize(version, build, rustc_version, additional)
|
|
155
|
+
@version = version; @build = build; @rustc_version = rustc_version; @additional = additional; freeze
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
class NearStatus
|
|
160
|
+
attr_reader :chain_id, :genesis_hash, :latest_protocol_version, :protocol_version, :sync_info, :version, :additional
|
|
161
|
+
|
|
162
|
+
def self.from(value)
|
|
163
|
+
hash = NearTypedValue.hash(value); known = %w[chain_id genesis_hash latest_protocol_version protocol_version sync_info version]
|
|
164
|
+
new(NearTypedValue.string(hash.fetch("chain_id")), NearTypedValue.string(hash.fetch("genesis_hash")), NearTypedValue.integer(hash.fetch("latest_protocol_version")), NearTypedValue.integer(hash.fetch("protocol_version")), NearSyncInfo.from(hash.fetch("sync_info")), NearNodeVersion.from(hash.fetch("version")), NearTypedValue.additional(hash, known))
|
|
165
|
+
rescue KeyError
|
|
166
|
+
raise InvalidResponseError.new("ERPC returned an invalid NEAR response"), cause: nil
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def initialize(chain_id, genesis_hash, latest_protocol_version, protocol_version, sync_info, version, additional)
|
|
170
|
+
@chain_id = chain_id; @genesis_hash = genesis_hash; @latest_protocol_version = latest_protocol_version; @protocol_version = protocol_version
|
|
171
|
+
@sync_info = sync_info; @version = version; @additional = additional; freeze
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
class NearBlockHeader
|
|
176
|
+
attr_reader :block_hash, :height, :prev_hash, :timestamp, :timestamp_nanosec, :gas_price, :total_supply, :additional
|
|
177
|
+
|
|
178
|
+
def self.from(value)
|
|
179
|
+
hash = NearTypedValue.hash(value); known = %w[hash height prev_hash timestamp timestamp_nanosec gas_price total_supply]
|
|
180
|
+
new(NearTypedValue.string(hash.fetch("hash")), NearTypedValue.integer(hash.fetch("height")), NearTypedValue.string(hash.fetch("prev_hash")), NearTypedValue.integer(hash.fetch("timestamp")), NearTypedValue.string(hash.fetch("timestamp_nanosec")), NearTypedValue.string(hash.fetch("gas_price")), NearTypedValue.string(hash.fetch("total_supply")), NearTypedValue.additional(hash, known))
|
|
181
|
+
rescue KeyError
|
|
182
|
+
raise InvalidResponseError.new("ERPC returned an invalid NEAR response"), cause: nil
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def initialize(*values)
|
|
186
|
+
@block_hash, @height, @prev_hash, @timestamp, @timestamp_nanosec, @gas_price, @total_supply, @additional = values
|
|
187
|
+
freeze
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
class NearBlockView
|
|
192
|
+
attr_reader :author, :header, :chunks, :additional
|
|
193
|
+
|
|
194
|
+
def self.from(value)
|
|
195
|
+
hash = NearTypedValue.hash(value); known = %w[author header chunks]
|
|
196
|
+
chunks = hash.fetch("chunks")
|
|
197
|
+
raise InvalidResponseError.new("ERPC returned an invalid NEAR response"), cause: nil unless chunks.is_a?(Array)
|
|
198
|
+
new(NearTypedValue.string(hash.fetch("author")), NearBlockHeader.from(hash.fetch("header")), chunks.freeze, NearTypedValue.additional(hash, known))
|
|
199
|
+
rescue KeyError
|
|
200
|
+
raise InvalidResponseError.new("ERPC returned an invalid NEAR response"), cause: nil
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def initialize(author, header, chunks, additional)
|
|
204
|
+
@author = author; @header = header; @chunks = chunks; @additional = additional; freeze
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
class NearAccountView
|
|
209
|
+
attr_reader :amount, :locked, :code_hash, :storage_usage, :storage_paid_at, :block_height, :block_hash, :state, :bootstrap_nonce, :global_contract_account_id, :global_contract_hash, :additional
|
|
210
|
+
|
|
211
|
+
def self.from(value)
|
|
212
|
+
hash = NearTypedValue.hash(value); known = %w[amount locked code_hash storage_usage storage_paid_at block_height block_hash state bootstrap_nonce global_contract_account_id global_contract_hash]
|
|
213
|
+
new(NearTypedValue.string(hash.fetch("amount")), NearTypedValue.string(hash.fetch("locked")), NearTypedValue.string(hash.fetch("code_hash")), NearTypedValue.integer(hash.fetch("storage_usage")), NearTypedValue.optional_integer(hash["storage_paid_at"]), NearTypedValue.integer(hash.fetch("block_height")), NearTypedValue.string(hash.fetch("block_hash")), NearTypedValue.optional_string(hash["state"]), NearTypedValue.optional_integer(hash["bootstrap_nonce"]), NearTypedValue.optional_string(hash["global_contract_account_id"]), NearTypedValue.optional_string(hash["global_contract_hash"]), NearTypedValue.additional(hash, known))
|
|
214
|
+
rescue KeyError
|
|
215
|
+
raise InvalidResponseError.new("ERPC returned an invalid NEAR response"), cause: nil
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def initialize(*values)
|
|
219
|
+
names = %i[amount locked code_hash storage_usage storage_paid_at block_height block_hash state bootstrap_nonce global_contract_account_id global_contract_hash additional]
|
|
220
|
+
names.each_with_index { |name, index| instance_variable_set("@#{name}", values[index]) }
|
|
221
|
+
freeze
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
class NearRpc
|
|
226
|
+
attr_reader :endpoint
|
|
227
|
+
|
|
228
|
+
def initialize(transport)
|
|
229
|
+
@transport = transport; @endpoint = transport.endpoint
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def inspect
|
|
233
|
+
"#<#{self.class} endpoint=#{endpoint.inspect}>"
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def status
|
|
237
|
+
NearPendingRequest.new { NearStatus.from(@transport.request("status", [])) }
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def block(reference)
|
|
241
|
+
selector = validate_reference(reference)
|
|
242
|
+
NearPendingRequest.new { NearBlockView.from(@transport.request("block", selector)) }
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def view_account(account_id, reference)
|
|
246
|
+
selector = validate_reference(reference)
|
|
247
|
+
raise ConfigError, "NEAR account_id must be a non-empty string", cause: nil unless account_id.is_a?(String) && !account_id.empty?
|
|
248
|
+
params = { "request_type" => "view_account", "account_id" => account_id }.merge(selector)
|
|
249
|
+
NearPendingRequest.new { NearAccountView.from(@transport.request("query", params)) }
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
private
|
|
253
|
+
|
|
254
|
+
def validate_reference(reference)
|
|
255
|
+
NearBlockReference.selector(reference)
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
class NearClient
|
|
260
|
+
attr_reader :rpc
|
|
261
|
+
|
|
262
|
+
def initialize(transport)
|
|
263
|
+
@rpc = NearRpc.new(transport); freeze
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
module Near
|
|
268
|
+
module_function
|
|
269
|
+
|
|
270
|
+
def create_client(transport)
|
|
271
|
+
NearClient.new(transport)
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
private_constant :NearTypedValue, :NearPendingRequest
|
|
276
|
+
end
|