erpc-sdk 0.5.0 → 0.6.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/README.md +17 -3
- data/lib/erpc_sdk/client.rb +70 -1
- data/lib/erpc_sdk/rpc.rb +94 -6
- data/lib/erpc_sdk/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4152582a8b2cdb14a5b98a90761f07abf0ab2313540e5f46cef71d0111a6c531
|
|
4
|
+
data.tar.gz: 6f8d52e59d11fe4aa9d7d81af2941c65e59adfb98b5bade3a478f25c91d2bc52
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8f14e31048992941c30e753cf0ad84e066063ec667b66d5718c4d442acf2e5e1202b9bb7d70c391f720f32554cb518cde25de19c0166da4c2722cbe2ac66b0bf
|
|
7
|
+
data.tar.gz: '094c74f0c2939dab9312171da51889a121b8a1f6baed947bc11942ebde119211373f785abf5d8d81b8b1f9cf4818e3b2b8d6bedfe9ace572a7ce6beab765b73a'
|
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ERPC SDK for Ruby
|
|
2
2
|
|
|
3
3
|
Synchronous Ruby client for ERPC. It covers standard Solana, Ethereum, and
|
|
4
|
-
Avalanche C-
|
|
4
|
+
Avalanche C/P/X-chain JSON-RPC, indexed data, analytics, WebSocket subscriptions,
|
|
5
5
|
price REST and server-sent events, account usage, and scoped Cloud reads.
|
|
6
6
|
|
|
7
7
|
```bash
|
|
@@ -47,14 +47,28 @@ only when `send` is called. `request` restricts calls to the namespace catalog;
|
|
|
47
47
|
| `erpc.ethereum.subscriptions` | Ethereum WebSocket subscriptions |
|
|
48
48
|
| `erpc.avalanche.rpc` | Avalanche C-Chain EVM-compatible JSON-RPC |
|
|
49
49
|
| `erpc.avalanche.subscriptions` | Avalanche C-Chain WebSocket subscriptions |
|
|
50
|
+
| `erpc.avalanche.avax` | C-Chain AVAX atomic transaction API |
|
|
51
|
+
| `erpc.avalanche.x_chain` | X-Chain API |
|
|
52
|
+
| `erpc.avalanche.p_chain` | P-Chain API |
|
|
53
|
+
| `erpc.avalanche.proposer_vm` | P-Chain proposer VM API |
|
|
54
|
+
| `erpc.avalanche.info` | Network upgrade information |
|
|
55
|
+
| `erpc.avalanche.index` | C/P/X block and X transaction indexes |
|
|
50
56
|
| `erpc.price` | Price metadata, updates, and SSE streams |
|
|
51
57
|
| `erpc.account` | Token balance |
|
|
52
58
|
| `erpc.usage` | Masked monthly API-key usage |
|
|
53
59
|
|
|
54
60
|
`avalanche_endpoint` defaults to `https://ava-rpc.erpc.global` and can be
|
|
55
61
|
overridden independently. The SDK uses its `/ava` HTTP route and `/ava-ws`
|
|
56
|
-
WebSocket route.
|
|
57
|
-
|
|
62
|
+
WebSocket route. Native methods use named Hash parameters and Index calls use
|
|
63
|
+
explicit chain/container paths. Native and Index batches are rejected locally;
|
|
64
|
+
use `raw` with an exact wire method name for forward compatibility.
|
|
65
|
+
|
|
66
|
+
```ruby
|
|
67
|
+
p_height = erpc.avalanche.p_chain.get_height.send
|
|
68
|
+
indexed_tx = erpc.avalanche.index.x_chain_transactions
|
|
69
|
+
.get_container_by_id(id: transaction_id)
|
|
70
|
+
.send
|
|
71
|
+
```
|
|
58
72
|
|
|
59
73
|
## Intact batches
|
|
60
74
|
|
data/lib/erpc_sdk/client.rb
CHANGED
|
@@ -3,7 +3,24 @@
|
|
|
3
3
|
module ERPC
|
|
4
4
|
SolanaClient = Struct.new(:rpc, :das, :history, :leaders, :analytics, :subscriptions, keyword_init: true)
|
|
5
5
|
EthereumClient = Struct.new(:rpc, :subscriptions, keyword_init: true)
|
|
6
|
-
|
|
6
|
+
AvalancheIndexClient = Struct.new(
|
|
7
|
+
:c_chain_blocks,
|
|
8
|
+
:p_chain_blocks,
|
|
9
|
+
:x_chain_blocks,
|
|
10
|
+
:x_chain_transactions,
|
|
11
|
+
keyword_init: true
|
|
12
|
+
)
|
|
13
|
+
AvalancheClient = Struct.new(
|
|
14
|
+
:rpc,
|
|
15
|
+
:avax,
|
|
16
|
+
:x_chain,
|
|
17
|
+
:p_chain,
|
|
18
|
+
:proposer_vm,
|
|
19
|
+
:info,
|
|
20
|
+
:index,
|
|
21
|
+
:subscriptions,
|
|
22
|
+
keyword_init: true
|
|
23
|
+
)
|
|
7
24
|
|
|
8
25
|
class Client
|
|
9
26
|
attr_reader :solana, :ethereum, :avalanche, :price, :account, :usage
|
|
@@ -31,6 +48,15 @@ module ERPC
|
|
|
31
48
|
timeout: config.timeout,
|
|
32
49
|
adapter: adapter
|
|
33
50
|
)
|
|
51
|
+
avalanche_index_transport = lambda do |path|
|
|
52
|
+
HttpJsonRpcTransport.new(
|
|
53
|
+
api_key: config.api_key,
|
|
54
|
+
endpoint: URLs.with_path(config.avalanche_endpoint, path),
|
|
55
|
+
headers: config.headers,
|
|
56
|
+
timeout: config.timeout,
|
|
57
|
+
adapter: adapter
|
|
58
|
+
)
|
|
59
|
+
end
|
|
34
60
|
solana_ws = WebSocketJsonRpcTransport.new(
|
|
35
61
|
URLs.websocket(config.endpoint, config.api_key),
|
|
36
62
|
config.api_key,
|
|
@@ -78,6 +104,37 @@ module ERPC
|
|
|
78
104
|
)
|
|
79
105
|
@avalanche = AvalancheClient.new(
|
|
80
106
|
rpc: RpcNamespace.new(avalanche_transport, ETHEREUM_RPC_METHODS, parameter_mode: :positional),
|
|
107
|
+
avax: avalanche_namespace(avalanche_transport, AVALANCHE_AVAX_METHODS, "avax"),
|
|
108
|
+
x_chain: avalanche_namespace(avalanche_transport, AVALANCHE_X_CHAIN_METHODS, "avm"),
|
|
109
|
+
p_chain: avalanche_namespace(avalanche_transport, AVALANCHE_P_CHAIN_METHODS, "platform"),
|
|
110
|
+
proposer_vm: avalanche_namespace(
|
|
111
|
+
avalanche_transport,
|
|
112
|
+
AVALANCHE_PROPOSER_VM_METHODS,
|
|
113
|
+
"proposervm"
|
|
114
|
+
),
|
|
115
|
+
info: avalanche_namespace(avalanche_transport, AVALANCHE_INFO_METHODS, "info"),
|
|
116
|
+
index: AvalancheIndexClient.new(
|
|
117
|
+
c_chain_blocks: avalanche_namespace(
|
|
118
|
+
avalanche_index_transport.call("/ava/ext/index/C/block"),
|
|
119
|
+
AVALANCHE_INDEX_METHODS,
|
|
120
|
+
"index"
|
|
121
|
+
),
|
|
122
|
+
p_chain_blocks: avalanche_namespace(
|
|
123
|
+
avalanche_index_transport.call("/ava/ext/index/P/block"),
|
|
124
|
+
AVALANCHE_INDEX_METHODS,
|
|
125
|
+
"index"
|
|
126
|
+
),
|
|
127
|
+
x_chain_blocks: avalanche_namespace(
|
|
128
|
+
avalanche_index_transport.call("/ava/ext/index/X/block"),
|
|
129
|
+
AVALANCHE_INDEX_METHODS,
|
|
130
|
+
"index"
|
|
131
|
+
),
|
|
132
|
+
x_chain_transactions: avalanche_namespace(
|
|
133
|
+
avalanche_index_transport.call("/ava/ext/index/X/tx"),
|
|
134
|
+
AVALANCHE_INDEX_METHODS,
|
|
135
|
+
"index"
|
|
136
|
+
)
|
|
137
|
+
),
|
|
81
138
|
subscriptions: EthereumSubscriptions.new(avalanche_ws)
|
|
82
139
|
)
|
|
83
140
|
@price = PriceClient.new(
|
|
@@ -119,6 +176,18 @@ module ERPC
|
|
|
119
176
|
avalanche.subscriptions.close
|
|
120
177
|
nil
|
|
121
178
|
end
|
|
179
|
+
|
|
180
|
+
private
|
|
181
|
+
|
|
182
|
+
def avalanche_namespace(transport, methods, prefix)
|
|
183
|
+
RpcNamespace.new(
|
|
184
|
+
transport,
|
|
185
|
+
methods,
|
|
186
|
+
parameter_mode: :named,
|
|
187
|
+
batch_policy: :unsupported,
|
|
188
|
+
method_prefix: prefix
|
|
189
|
+
)
|
|
190
|
+
end
|
|
122
191
|
end
|
|
123
192
|
|
|
124
193
|
class CloudClient
|
data/lib/erpc_sdk/rpc.rb
CHANGED
|
@@ -162,6 +162,72 @@ module ERPC
|
|
|
162
162
|
"eth_unsubscribe"
|
|
163
163
|
].freeze
|
|
164
164
|
|
|
165
|
+
AVALANCHE_AVAX_METHODS = [
|
|
166
|
+
"avax.getAtomicTx",
|
|
167
|
+
"avax.getAtomicTxStatus",
|
|
168
|
+
"avax.getUTXOs",
|
|
169
|
+
"avax.issueTx"
|
|
170
|
+
].freeze
|
|
171
|
+
|
|
172
|
+
AVALANCHE_X_CHAIN_METHODS = [
|
|
173
|
+
"avm.buildGenesis",
|
|
174
|
+
"avm.getAllBalances",
|
|
175
|
+
"avm.getAssetDescription",
|
|
176
|
+
"avm.getBalance",
|
|
177
|
+
"avm.getBlockByHeight",
|
|
178
|
+
"avm.getHeight",
|
|
179
|
+
"avm.getTx",
|
|
180
|
+
"avm.getTxFee",
|
|
181
|
+
"avm.getTxStatus",
|
|
182
|
+
"avm.getUTXOs",
|
|
183
|
+
"avm.issueTx"
|
|
184
|
+
].freeze
|
|
185
|
+
|
|
186
|
+
AVALANCHE_P_CHAIN_METHODS = [
|
|
187
|
+
"platform.getAllValidatorsAt",
|
|
188
|
+
"platform.getBalance",
|
|
189
|
+
"platform.getBlockchainStatus",
|
|
190
|
+
"platform.getBlockchains",
|
|
191
|
+
"platform.getCurrentSupply",
|
|
192
|
+
"platform.getCurrentValidators",
|
|
193
|
+
"platform.getFeeConfig",
|
|
194
|
+
"platform.getFeeState",
|
|
195
|
+
"platform.getHeight",
|
|
196
|
+
"platform.getMinStake",
|
|
197
|
+
"platform.getRewardUTXOs",
|
|
198
|
+
"platform.getStake",
|
|
199
|
+
"platform.getStakingAssetID",
|
|
200
|
+
"platform.getSubnets",
|
|
201
|
+
"platform.getTimestamp",
|
|
202
|
+
"platform.getTotalStake",
|
|
203
|
+
"platform.getTx",
|
|
204
|
+
"platform.getTxStatus",
|
|
205
|
+
"platform.getUTXOs",
|
|
206
|
+
"platform.getValidatorFeeConfig",
|
|
207
|
+
"platform.getValidatorFeeState",
|
|
208
|
+
"platform.getValidatorsAt",
|
|
209
|
+
"platform.issueTx",
|
|
210
|
+
"platform.sampleValidators",
|
|
211
|
+
"platform.validatedBy",
|
|
212
|
+
"platform.validates"
|
|
213
|
+
].freeze
|
|
214
|
+
|
|
215
|
+
AVALANCHE_PROPOSER_VM_METHODS = [
|
|
216
|
+
"proposervm.getCurrentEpoch",
|
|
217
|
+
"proposervm.getProposedHeight"
|
|
218
|
+
].freeze
|
|
219
|
+
|
|
220
|
+
AVALANCHE_INFO_METHODS = ["info.upgrades"].freeze
|
|
221
|
+
|
|
222
|
+
AVALANCHE_INDEX_METHODS = [
|
|
223
|
+
"index.getContainerByID",
|
|
224
|
+
"index.getContainerByIndex",
|
|
225
|
+
"index.getContainerRange",
|
|
226
|
+
"index.getIndex",
|
|
227
|
+
"index.getLastAccepted",
|
|
228
|
+
"index.isAccepted"
|
|
229
|
+
].freeze
|
|
230
|
+
|
|
165
231
|
HEAVY_SOLANA_METHODS = %w[
|
|
166
232
|
getPriorityFeeEstimate
|
|
167
233
|
getProgramAccounts
|
|
@@ -197,11 +263,16 @@ module ERPC
|
|
|
197
263
|
class RpcNamespace
|
|
198
264
|
attr_reader :endpoint
|
|
199
265
|
|
|
200
|
-
def initialize(transport, methods, parameter_mode:, batch_policy: :any)
|
|
266
|
+
def initialize(transport, methods, parameter_mode:, batch_policy: :any, method_prefix: nil)
|
|
201
267
|
@transport = transport
|
|
202
268
|
@endpoint = transport.endpoint
|
|
203
|
-
|
|
204
|
-
@
|
|
269
|
+
prefix = method_prefix.nil? ? "" : "#{method_prefix}."
|
|
270
|
+
@wire_methods = methods.to_h do |method|
|
|
271
|
+
public_method = method.start_with?(prefix) ? method.delete_prefix(prefix) : method
|
|
272
|
+
[public_method, method]
|
|
273
|
+
end.freeze
|
|
274
|
+
@methods = @wire_methods.transform_values { true }.freeze
|
|
275
|
+
@aliases = @methods.to_h { |method, _| [snake_case(method), method] }.freeze
|
|
205
276
|
@parameter_mode = parameter_mode
|
|
206
277
|
@batch_policy = batch_policy
|
|
207
278
|
end
|
|
@@ -211,7 +282,7 @@ module ERPC
|
|
|
211
282
|
raise ConfigError, "#{method.inspect} is not in this namespace; use raw for forward-compatible methods"
|
|
212
283
|
end
|
|
213
284
|
|
|
214
|
-
PendingRpcRequest.new(@transport, method, params, decoder || ->(value) { value })
|
|
285
|
+
PendingRpcRequest.new(@transport, @wire_methods.fetch(method), params, decoder || ->(value) { value })
|
|
215
286
|
end
|
|
216
287
|
|
|
217
288
|
def raw(method, params = nil, decoder: nil)
|
|
@@ -222,7 +293,7 @@ module ERPC
|
|
|
222
293
|
|
|
223
294
|
def batch(calls)
|
|
224
295
|
if @batch_policy == :unsupported && !calls.empty?
|
|
225
|
-
raise BatchPolicyError, "
|
|
296
|
+
raise BatchPolicyError, "This RPC namespace does not support batching"
|
|
226
297
|
end
|
|
227
298
|
if @batch_policy == :solana_standard
|
|
228
299
|
methods = calls.map { |call| call[:method] || call["method"] }
|
|
@@ -233,7 +304,12 @@ module ERPC
|
|
|
233
304
|
end
|
|
234
305
|
end
|
|
235
306
|
|
|
236
|
-
|
|
307
|
+
wire_calls = if @wire_methods.any? { |method, wire| method != wire }
|
|
308
|
+
calls.map { |call| wire_call(call) }
|
|
309
|
+
else
|
|
310
|
+
calls
|
|
311
|
+
end
|
|
312
|
+
PendingRpcBatchRequest.new(@transport, wire_calls)
|
|
237
313
|
end
|
|
238
314
|
|
|
239
315
|
def method_missing(name, *arguments, &block)
|
|
@@ -262,6 +338,18 @@ module ERPC
|
|
|
262
338
|
|
|
263
339
|
private
|
|
264
340
|
|
|
341
|
+
def wire_call(call)
|
|
342
|
+
method = call[:method] || call["method"]
|
|
343
|
+
unless @wire_methods.key?(method)
|
|
344
|
+
raise ConfigError, "#{method.inspect} is not in this namespace; use raw for forward-compatible methods"
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
mapped = { method: @wire_methods.fetch(method) }
|
|
348
|
+
mapped[:params] = call[:params] if call.key?(:params)
|
|
349
|
+
mapped[:params] = call["params"] if call.key?("params")
|
|
350
|
+
mapped
|
|
351
|
+
end
|
|
352
|
+
|
|
265
353
|
def snake_case(value)
|
|
266
354
|
value.gsub(/(?<=[a-z0-9])(?=[A-Z])/, "_").downcase
|
|
267
355
|
end
|
data/lib/erpc_sdk/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: erpc-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ELSOUL LABO B.V.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: minitest
|