scale_rb 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rspec +0 -0
- data/.rubocop.yml +0 -0
- data/.travis.yml +0 -0
- data/CODE_OF_CONDUCT.md +0 -0
- data/Gemfile +0 -0
- data/Gemfile.lock +50 -2
- data/LICENSE.txt +0 -0
- data/README.md +7 -4
- data/Rakefile +0 -0
- data/examples/http_client_1.rb +9 -0
- data/examples/http_client_2.rb +9 -0
- data/examples/ws_client_1.rb +14 -0
- data/examples/ws_client_2.rb +9 -0
- data/examples/ws_client_3.rb +21 -0
- data/examples/ws_client_4.rb +13 -0
- data/lib/address.rb +0 -0
- data/lib/client/client_ext.rb +214 -0
- data/lib/client/http_client.rb +37 -77
- data/lib/client/ws_client.rb +202 -0
- data/lib/codec.rb +0 -0
- data/lib/hasher.rb +0 -0
- data/lib/metadata/metadata.rb +0 -0
- data/lib/metadata/metadata_v10.rb +0 -0
- data/lib/metadata/metadata_v11.rb +0 -0
- data/lib/metadata/metadata_v12.rb +0 -0
- data/lib/metadata/metadata_v13.rb +0 -0
- data/lib/metadata/metadata_v14.rb +0 -0
- data/lib/metadata/metadata_v9.rb +0 -0
- data/lib/monkey_patching.rb +0 -0
- data/lib/portable_codec.rb +0 -0
- data/lib/registry.rb +0 -0
- data/lib/scale_rb/version.rb +1 -1
- data/lib/scale_rb.rb +4 -4
- data/lib/storage_helper.rb +0 -0
- data/scale_rb.gemspec +7 -3
- data/tea.yaml +6 -0
- metadata +61 -13
- data/lib/client/abstract_ws_client.rb +0 -104
- data/lib/client/http_client_metadata.rb +0 -78
- data/lib/client/http_client_storage.rb +0 -180
- data/lib/client/rpc_request_builder.rb +0 -55
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79d55aeb610c1a4a11410703445983aa6b02cbf8ee21653a38d425b06c41e3dc
|
4
|
+
data.tar.gz: 8e7832aa2495fed7226797bd21bc23db257754c8d5160cba57f7830879fe592f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 879a524038c25c42b98724a95c9db2658ba41a952386fa4132eb56ceff4d3403aa3fc519c4add1d29fc1ad6e413bdb5f1bc8ab4585a836327bc233dc7750ab43
|
7
|
+
data.tar.gz: 4529731208f640854a9b9b3676ffdd3727b9344833ab026cd593f5d10e17ea0428bd651bc01aa774cb80fd68350249ba68be4b99eea54db6fe597b6f3732723a
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
File without changes
|
data/.rubocop.yml
CHANGED
File without changes
|
data/.travis.yml
CHANGED
File without changes
|
data/CODE_OF_CONDUCT.md
CHANGED
File without changes
|
data/Gemfile
CHANGED
File without changes
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
scale_rb (0.
|
4
|
+
scale_rb (0.3.0)
|
5
|
+
async
|
6
|
+
async-http (~> 0.69.0)
|
7
|
+
async-websocket (~> 0.26.2)
|
5
8
|
base58
|
6
9
|
blake2b_rs (~> 0.1.4)
|
7
10
|
xxhash
|
@@ -9,13 +12,57 @@ PATH
|
|
9
12
|
GEM
|
10
13
|
remote: https://rubygems.org/
|
11
14
|
specs:
|
15
|
+
async (2.14.0)
|
16
|
+
console (~> 1.25, >= 1.25.2)
|
17
|
+
fiber-annotation
|
18
|
+
io-event (~> 1.6, >= 1.6.5)
|
19
|
+
async-http (0.69.0)
|
20
|
+
async (>= 2.10.2)
|
21
|
+
async-pool (~> 0.7)
|
22
|
+
io-endpoint (~> 0.11)
|
23
|
+
io-stream (~> 0.4)
|
24
|
+
protocol-http (~> 0.26)
|
25
|
+
protocol-http1 (~> 0.19)
|
26
|
+
protocol-http2 (~> 0.18)
|
27
|
+
traces (>= 0.10)
|
28
|
+
async-pool (0.7.0)
|
29
|
+
async (>= 1.25)
|
30
|
+
async-websocket (0.26.2)
|
31
|
+
async-http (~> 0.54)
|
32
|
+
protocol-rack (~> 0.5)
|
33
|
+
protocol-websocket (~> 0.14)
|
12
34
|
base58 (0.2.3)
|
13
35
|
blake2b_rs (0.1.4)
|
14
36
|
ffi (~> 1.0)
|
15
37
|
thermite (~> 0)
|
38
|
+
console (1.25.2)
|
39
|
+
fiber-annotation
|
40
|
+
fiber-local (~> 1.1)
|
41
|
+
json
|
16
42
|
diff-lcs (1.5.0)
|
17
|
-
ffi (1.
|
43
|
+
ffi (1.17.0)
|
44
|
+
fiber-annotation (0.2.0)
|
45
|
+
fiber-local (1.1.0)
|
46
|
+
fiber-storage
|
47
|
+
fiber-storage (0.1.2)
|
48
|
+
io-endpoint (0.11.0)
|
49
|
+
io-event (1.6.5)
|
50
|
+
io-stream (0.4.0)
|
51
|
+
json (2.7.2)
|
18
52
|
minitar (0.9)
|
53
|
+
protocol-hpack (1.4.3)
|
54
|
+
protocol-http (0.27.0)
|
55
|
+
protocol-http1 (0.19.1)
|
56
|
+
protocol-http (~> 0.22)
|
57
|
+
protocol-http2 (0.18.0)
|
58
|
+
protocol-hpack (~> 1.4)
|
59
|
+
protocol-http (~> 0.18)
|
60
|
+
protocol-rack (0.6.0)
|
61
|
+
protocol-http (~> 0.23)
|
62
|
+
rack (>= 1.0)
|
63
|
+
protocol-websocket (0.15.0)
|
64
|
+
protocol-http (~> 0.2)
|
65
|
+
rack (3.1.7)
|
19
66
|
rake (12.3.3)
|
20
67
|
rspec (3.11.0)
|
21
68
|
rspec-core (~> 3.11.0)
|
@@ -35,6 +82,7 @@ GEM
|
|
35
82
|
rake (>= 10)
|
36
83
|
tomlrb (~> 1.2)
|
37
84
|
tomlrb (1.3.0)
|
85
|
+
traces (0.11.1)
|
38
86
|
xxhash (0.5.0)
|
39
87
|
|
40
88
|
PLATFORMS
|
data/LICENSE.txt
CHANGED
File without changes
|
data/README.md
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# ScaleRb
|
2
2
|
|
3
|
-
*WARNING: UNDER DEVELOPMENT*
|
4
|
-
|
5
3
|
## Installation
|
6
4
|
|
7
5
|
Add this line to your application's Gemfile:
|
@@ -18,9 +16,14 @@ Or install it yourself as:
|
|
18
16
|
|
19
17
|
$ gem install scale_rb
|
20
18
|
|
21
|
-
##
|
19
|
+
## Run examples
|
22
20
|
|
23
|
-
|
21
|
+
```bash
|
22
|
+
git clone https://github.com/wuminzhe/scale_rb.git
|
23
|
+
cd scale_rb
|
24
|
+
bundle install
|
25
|
+
bundle exec ruby examples/http_client_1.rb
|
26
|
+
```
|
24
27
|
|
25
28
|
## Development
|
26
29
|
|
data/Rakefile
CHANGED
File without changes
|
@@ -0,0 +1,9 @@
|
|
1
|
+
|
2
|
+
require 'scale_rb'
|
3
|
+
|
4
|
+
ScaleRb.logger.level = Logger::DEBUG
|
5
|
+
|
6
|
+
client = ScaleRb::HttpClient.new('https://polkadot-rpc.dwellir.com')
|
7
|
+
block_hash = client.chain_getBlockHash(21585684)
|
8
|
+
runtime_version = client.state_getRuntimeVersion(block_hash)
|
9
|
+
puts runtime_version
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'scale_rb'
|
2
|
+
|
3
|
+
ScaleRb.logger.level = Logger::DEBUG
|
4
|
+
|
5
|
+
client = ScaleRb::HttpClient.new('https://polkadot-rpc.dwellir.com')
|
6
|
+
block_number = 21585684
|
7
|
+
block_hash = client.chain_getBlockHash(block_number)
|
8
|
+
storage = client.get_storage(block_hash, 'System', 'Events')
|
9
|
+
puts "block #{block_number}(#{block_hash}) has #{storage.length} events"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'scale_rb'
|
2
|
+
|
3
|
+
ScaleRb.logger.level = Logger::DEBUG
|
4
|
+
|
5
|
+
# the commented code below is the same as the code above
|
6
|
+
ScaleRb::WsClient.start('wss://polkadot-rpc.dwellir.com') do |client|
|
7
|
+
block_hash = client.chain_getBlockHash(21585684)
|
8
|
+
# block_hash = client.request('chain_getBlockHash', [21585684])
|
9
|
+
|
10
|
+
runtime_version = client.state_getRuntimeVersion(block_hash)
|
11
|
+
# runtime_version = client.request('state_getRuntimeVersion', [block_hash])
|
12
|
+
|
13
|
+
puts runtime_version
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'scale_rb'
|
2
|
+
|
3
|
+
ScaleRb.logger.level = Logger::DEBUG
|
4
|
+
|
5
|
+
ScaleRb::WsClient.start('wss://polkadot-rpc.dwellir.com') do |client|
|
6
|
+
count = 0
|
7
|
+
|
8
|
+
subscription_id = client.chain_subscribeNewHead do |head|
|
9
|
+
count = count + 1
|
10
|
+
|
11
|
+
if count < 5
|
12
|
+
block_number = head['number'].to_i(16)
|
13
|
+
block_hash = client.chain_getBlockHash(block_number)
|
14
|
+
puts "Received new head at height: #{block_number}, block hash: #{block_hash}"
|
15
|
+
else
|
16
|
+
client.chain_unsubscribeNewHead(subscription_id)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
puts "Subscribed to new heads with subscription id: #{subscription_id}"
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'scale_rb'
|
2
|
+
|
3
|
+
# ScaleRb.logger.level = Logger::DEBUG
|
4
|
+
|
5
|
+
ScaleRb::WsClient.start('wss://polkadot-rpc.dwellir.com') do |client|
|
6
|
+
client.chain_subscribeFinalizedHeads do |head|
|
7
|
+
block_number = head['number'].to_i(16)
|
8
|
+
block_hash = client.chain_getBlockHash(block_number)
|
9
|
+
|
10
|
+
storage = client.get_storage(block_hash, 'System', 'Events')
|
11
|
+
puts "block #{block_number}(#{block_hash}) has #{storage.length} events"
|
12
|
+
end
|
13
|
+
end
|
data/lib/address.rb
CHANGED
File without changes
|
@@ -0,0 +1,214 @@
|
|
1
|
+
module ScaleRb
|
2
|
+
module ClientExt
|
3
|
+
def get_metadata(block_hash)
|
4
|
+
dir = ENV['SCALE_RB_METADATA_DIR'] || File.join(Dir.pwd, 'metadata')
|
5
|
+
|
6
|
+
get_metadata_by_block_hash(dir, block_hash)
|
7
|
+
end
|
8
|
+
|
9
|
+
# get storage at block_hash
|
10
|
+
def get_storage(block_hash, pallet_name, storage_name, key_part1: nil, key_part2: nil)
|
11
|
+
metadata = get_metadata(block_hash)
|
12
|
+
|
13
|
+
# storeage item
|
14
|
+
pallet_name = to_pascal pallet_name
|
15
|
+
storage_name = to_pascal storage_name
|
16
|
+
|
17
|
+
# storage param
|
18
|
+
key = [key_part1, key_part2].compact
|
19
|
+
ScaleRb.logger.debug "#{pallet_name}.#{storage_name}(#{key.join(', ')})"
|
20
|
+
key = key.map { |part_of_key| c(part_of_key) }
|
21
|
+
ScaleRb.logger.debug "converted key: #{key}"
|
22
|
+
|
23
|
+
get_storage2(
|
24
|
+
block_hash, # at
|
25
|
+
pallet_name,
|
26
|
+
storage_name,
|
27
|
+
key,
|
28
|
+
metadata
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def get_metadata_by_block_hash(cache_dir, block_hash)
|
35
|
+
# Get metadata from cache if it exists
|
36
|
+
runtime_version = state_getRuntimeVersion(block_hash)
|
37
|
+
spec_name = runtime_version['specName']
|
38
|
+
spec_version = runtime_version['specVersion']
|
39
|
+
metadata = cached_metadata(spec_name, spec_version, cache_dir)
|
40
|
+
return metadata if metadata
|
41
|
+
|
42
|
+
# Get metadata from node
|
43
|
+
metadata_hex = state_getMetadata(block_hash)
|
44
|
+
metadata = ScaleRb::Metadata.decode_metadata(metadata_hex.strip._to_bytes)
|
45
|
+
|
46
|
+
# cache it
|
47
|
+
save_metadata_to_file(spec_name, spec_version, metadata, cache_dir)
|
48
|
+
|
49
|
+
return metadata
|
50
|
+
end
|
51
|
+
|
52
|
+
def cached_metadata(spec_name, spec_version, dir)
|
53
|
+
file_path = File.join(dir, "#{spec_name}-#{spec_version}.json")
|
54
|
+
return unless File.exist?(file_path)
|
55
|
+
|
56
|
+
JSON.parse(File.read(file_path))
|
57
|
+
end
|
58
|
+
|
59
|
+
def save_metadata_to_file(spec_name, spec_version, metadata, dir)
|
60
|
+
FileUtils.mkdir_p(dir)
|
61
|
+
|
62
|
+
File.open(File.join(dir, "#{spec_name}-#{spec_version}.json"), 'w') do |f|
|
63
|
+
f.write(JSON.pretty_generate(metadata))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
####
|
68
|
+
|
69
|
+
def query_storage_at(block_hash, storage_keys, type_id, default, registry)
|
70
|
+
result = state_queryStorageAt(storage_keys, block_hash)
|
71
|
+
result.map do |item|
|
72
|
+
item['changes'].map do |change|
|
73
|
+
storage_key = change[0]
|
74
|
+
data = change[1] || default
|
75
|
+
storage = data.nil? ? nil : PortableCodec.decode(type_id, data._to_bytes, registry)[0]
|
76
|
+
{ storage_key: storage_key, storage: storage }
|
77
|
+
end
|
78
|
+
end.flatten
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_storage_keys_by_partial_key(block_hash, partial_storage_key, start_key = nil)
|
82
|
+
storage_keys = state_getKeysPaged(partial_storage_key, 1000, start_key, block_hash)
|
83
|
+
if storage_keys.length == 1000
|
84
|
+
storage_keys + get_storage_keys_by_partial_key(block_hash, partial_storage_key, storage_keys.last)
|
85
|
+
else
|
86
|
+
storage_keys
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_storages_by_partial_key(block_hash, partial_storage_key, type_id_of_value, default, registry)
|
91
|
+
storage_keys = get_storage_keys_by_partial_key(block_hash, partial_storage_key, partial_storage_key)
|
92
|
+
storage_keys.each_slice(250).map do |slice|
|
93
|
+
query_storage_at(
|
94
|
+
slice,
|
95
|
+
type_id_of_value,
|
96
|
+
default,
|
97
|
+
registry,
|
98
|
+
block_hash
|
99
|
+
)
|
100
|
+
end.flatten
|
101
|
+
end
|
102
|
+
|
103
|
+
# 1. Plain
|
104
|
+
# key: nil
|
105
|
+
# value: { type: 3, modifier: 'Default', callback: '' }
|
106
|
+
#
|
107
|
+
# 2. Map
|
108
|
+
# key: { value: value, type: 0, hashers: ['Blake2128Concat'] }
|
109
|
+
# value: { type: 3, modifier: 'Default', callback: '' }
|
110
|
+
#
|
111
|
+
# 3. Map, but key.value is nil
|
112
|
+
# key: { value: nil, type: 0, hashers: ['Blake2128Concat'] }
|
113
|
+
# value: { type: 3, modifier: 'Default', callback: '' }
|
114
|
+
#
|
115
|
+
# example:
|
116
|
+
# 'System',
|
117
|
+
# 'Account',
|
118
|
+
# key = {
|
119
|
+
# value: [['0x724d50824542b56f422588421643c4a162b90b5416ef063f2266a1eae6651641'._to_bytes]], # [AccountId]
|
120
|
+
# type: 0,
|
121
|
+
# hashers: ['Blake2128Concat']
|
122
|
+
# },
|
123
|
+
# value = {
|
124
|
+
# type: 3,
|
125
|
+
# modifier: 'Default',
|
126
|
+
# callback: '0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
127
|
+
# },
|
128
|
+
# ..
|
129
|
+
#
|
130
|
+
# TODO: part of the key is provided, but not all
|
131
|
+
def get_storage1(block_hash, pallet_name, item_name, key, value, registry)
|
132
|
+
if key
|
133
|
+
if key[:value].nil? || key[:value].empty?
|
134
|
+
# map, but no key's value provided. get all storages under the partial storage key
|
135
|
+
partial_storage_key = StorageHelper.encode_storage_key(pallet_name, item_name)._to_hex
|
136
|
+
get_storages_by_partial_key(
|
137
|
+
block_hash,
|
138
|
+
partial_storage_key,
|
139
|
+
value[:type],
|
140
|
+
value[:modifier] == 'Default' ? value[:fallback] : nil,
|
141
|
+
registry
|
142
|
+
)
|
143
|
+
elsif key[:value].length != key[:hashers].length
|
144
|
+
# map with multi parts, but not have all values
|
145
|
+
partial_storage_key = StorageHelper.encode_storage_key(pallet_name, item_name, key, registry)._to_hex
|
146
|
+
get_storages_by_partial_key(
|
147
|
+
block_hash,
|
148
|
+
partial_storage_key,
|
149
|
+
value[:type],
|
150
|
+
value[:modifier] == 'Default' ? value[:fallback] : nil,
|
151
|
+
registry
|
152
|
+
)
|
153
|
+
end
|
154
|
+
else
|
155
|
+
storage_key = StorageHelper.encode_storage_key(pallet_name, item_name, key, registry)._to_hex
|
156
|
+
data = state_getStorage(storage_key, block_hash)
|
157
|
+
StorageHelper.decode_storage(data, value[:type], value[:modifier] == 'Optional', value[:fallback], registry)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def get_storage2(block_hash, pallet_name, item_name, value_of_key, metadata)
|
162
|
+
raise 'Metadata should not be nil' if metadata.nil?
|
163
|
+
|
164
|
+
registry = Metadata.build_registry(metadata)
|
165
|
+
item = Metadata.get_storage_item(
|
166
|
+
pallet_name, item_name, metadata
|
167
|
+
)
|
168
|
+
raise "No such storage item: `#{pallet_name}`.`#{item_name}`" if item.nil?
|
169
|
+
|
170
|
+
modifier = item._get(:modifier) # Default | Optional
|
171
|
+
fallback = item._get(:fallback)
|
172
|
+
type = item._get(:type)
|
173
|
+
|
174
|
+
plain = type._get(:plain)
|
175
|
+
map = type._get(:map)
|
176
|
+
# debug
|
177
|
+
|
178
|
+
key, value =
|
179
|
+
if plain
|
180
|
+
[
|
181
|
+
nil,
|
182
|
+
{ type: plain,
|
183
|
+
modifier: modifier, fallback: fallback }
|
184
|
+
]
|
185
|
+
elsif map
|
186
|
+
[
|
187
|
+
{ value: value_of_key,
|
188
|
+
type: map._get(:key), hashers: map._get(:hashers) },
|
189
|
+
{ type: map._get(:value),
|
190
|
+
modifier: modifier, fallback: fallback }
|
191
|
+
]
|
192
|
+
else
|
193
|
+
raise 'NoSuchStorageType'
|
194
|
+
end
|
195
|
+
get_storage1(block_hash, pallet_name, item_name, key, value, registry)
|
196
|
+
end
|
197
|
+
|
198
|
+
def to_pascal(str)
|
199
|
+
str.split('_').collect(&:capitalize).join
|
200
|
+
end
|
201
|
+
|
202
|
+
# convert key to byte array
|
203
|
+
def c(key)
|
204
|
+
if key.start_with?('0x')
|
205
|
+
key._to_bytes
|
206
|
+
elsif key.to_i.to_s == key # check if key is a number
|
207
|
+
key.to_i
|
208
|
+
else
|
209
|
+
key
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
end
|
data/lib/client/http_client.rb
CHANGED
@@ -3,95 +3,55 @@
|
|
3
3
|
require 'uri'
|
4
4
|
require 'net/http'
|
5
5
|
require 'json'
|
6
|
-
require_relative './rpc_request_builder'
|
7
|
-
require_relative './http_client_metadata'
|
8
|
-
require_relative './http_client_storage'
|
9
6
|
|
10
|
-
|
7
|
+
require_relative 'client_ext'
|
8
|
+
|
11
9
|
module ScaleRb
|
12
|
-
|
13
|
-
|
10
|
+
class HttpClient
|
11
|
+
include ClientExt
|
12
|
+
attr_accessor :supported_methods
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
uri = URI(url)
|
20
|
-
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
|
21
|
-
req.body = body
|
22
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
23
|
-
http.use_ssl = true if uri.instance_of? URI::HTTPS
|
24
|
-
res = http.request(req)
|
14
|
+
def initialize(url)
|
15
|
+
# check if the url is started with http or https
|
16
|
+
url_regex = %r{^https?://}
|
17
|
+
raise 'url format is not correct' unless url.match?(url_regex)
|
25
18
|
|
26
|
-
|
19
|
+
@uri = URI.parse(url)
|
20
|
+
@supported_methods = request('rpc_methods', [])['methods']
|
21
|
+
end
|
27
22
|
|
28
|
-
|
29
|
-
|
30
|
-
|
23
|
+
def request(method, params = [])
|
24
|
+
# don't check for rpc_methods, because there is no @supported_methods when initializing
|
25
|
+
if method != 'rpc_methods' && !@supported_methods.include?(method)
|
26
|
+
raise "Method `#{method}` is not supported. It should be in [#{@supported_methods.join(', ')}]."
|
27
|
+
end
|
31
28
|
|
32
|
-
|
33
|
-
|
34
|
-
raise e unless tries < 5
|
29
|
+
http = Net::HTTP.new(@uri.host, @uri.port)
|
30
|
+
http.use_ssl = @uri.scheme == 'https'
|
35
31
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
request(url, body, tries + 1)
|
40
|
-
end
|
32
|
+
request = Net::HTTP::Post.new(@uri, 'Content-Type' => 'application/json')
|
33
|
+
request.body = { jsonrpc: '2.0', method: method, params: params, id: Time.now.to_i }.to_json
|
34
|
+
ScaleRb.logger.debug "Request: #{request.body}"
|
41
35
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
36
|
+
# https://docs.ruby-lang.org/en/master/Net/HTTPResponse.html
|
37
|
+
response = http.request(request)
|
38
|
+
raise response unless response.is_a?(Net::HTTPOK)
|
46
39
|
|
47
|
-
|
48
|
-
|
49
|
-
|
40
|
+
body = JSON.parse(response.body)
|
41
|
+
ScaleRb.logger.debug "Response: #{body}"
|
42
|
+
raise body['error'] if body['error']
|
50
43
|
|
51
|
-
|
52
|
-
|
53
|
-
# check if the first argument is a url
|
54
|
-
url_regex = %r{^https?://}
|
55
|
-
raise 'url format is not correct' unless args[0].match?(url_regex)
|
44
|
+
body['result']
|
45
|
+
end
|
56
46
|
|
57
|
-
|
58
|
-
|
47
|
+
def respond_to_missing?(*_args)
|
48
|
+
true
|
49
|
+
end
|
59
50
|
|
60
|
-
|
61
|
-
|
51
|
+
def method_missing(method, *args)
|
52
|
+
ScaleRb.logger.debug "#{method}(#{args.join(', ')})"
|
62
53
|
|
63
|
-
|
64
|
-
result = json_rpc_call(url, 'rpc_methods', [])
|
65
|
-
result['methods']
|
66
|
-
end
|
54
|
+
request(method.to_s, args)
|
67
55
|
end
|
68
56
|
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# https://polkadot.js.org/docs/substrate/rpc/
|
72
|
-
#
|
73
|
-
# Examples:
|
74
|
-
# # Get all supported rpc methods
|
75
|
-
# ScaleRb::HttpClient.rpc_methods("https://rpc.darwinia.network")
|
76
|
-
#
|
77
|
-
# # eth_blockNumber
|
78
|
-
# ScaleRb::HttpClient.eth_blockNumber("https://rpc.darwinia.network")
|
79
|
-
#
|
80
|
-
# # system_name
|
81
|
-
# ScaleRb::HttpClient.system_name("https://rpc.darwinia.network")
|
82
|
-
#
|
83
|
-
# # chain_getHead
|
84
|
-
# ScaleRb::HttpClient.chain_getHead("https://rpc.darwinia.network")
|
85
|
-
#
|
86
|
-
# # state_getMetadata of darwinia block #1582
|
87
|
-
# ScaleRb::HttpClient.state_getMetadata(
|
88
|
-
# "https://rpc.darwinia.network",
|
89
|
-
# "0xb5a4f16d0feba7531e75315432b4d31a5b918987e026437890a2cbf5b8d9956d"
|
90
|
-
# )
|
91
|
-
#
|
92
|
-
# # eth_getBalance of address 0x0000000000000000000000000000000000000000 at block #1582
|
93
|
-
# ScaleRb::HttpClient.eth_getBalance(
|
94
|
-
# "https://rpc.darwinia.network",
|
95
|
-
# "0x0000000000000000000000000000000000000000",
|
96
|
-
# 1582
|
97
|
-
# )
|
57
|
+
end
|