flow-ruby 0.2.1

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.
@@ -0,0 +1,87 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # Source: flow/access/access.proto for package 'flow.access'
3
+
4
+ require 'grpc'
5
+ require 'flow/access/access_pb'
6
+
7
+ module Flow
8
+ module Access
9
+ module AccessAPI
10
+ # AccessAPI is the public-facing API provided by access nodes.
11
+ class Service
12
+
13
+ include GRPC::GenericService
14
+
15
+ self.marshal_class_method = :encode
16
+ self.unmarshal_class_method = :decode
17
+ self.service_name = 'flow.access.AccessAPI'
18
+
19
+ # Ping is used to check if the access node is alive and healthy.
20
+ rpc :Ping, ::Flow::Access::PingRequest, ::Flow::Access::PingResponse
21
+ # Block Headers
22
+ #
23
+ # GetLatestBlockHeader gets the latest sealed or unsealed block header.
24
+ rpc :GetLatestBlockHeader, ::Flow::Access::GetLatestBlockHeaderRequest, ::Flow::Access::BlockHeaderResponse
25
+ # GetBlockHeaderByID gets a block header by ID.
26
+ rpc :GetBlockHeaderByID, ::Flow::Access::GetBlockHeaderByIDRequest, ::Flow::Access::BlockHeaderResponse
27
+ # GetBlockHeaderByHeight gets a block header by height.
28
+ rpc :GetBlockHeaderByHeight, ::Flow::Access::GetBlockHeaderByHeightRequest, ::Flow::Access::BlockHeaderResponse
29
+ # Blocks
30
+ #
31
+ # GetLatestBlock gets the full payload of the latest sealed or unsealed block.
32
+ rpc :GetLatestBlock, ::Flow::Access::GetLatestBlockRequest, ::Flow::Access::BlockResponse
33
+ # GetBlockByID gets a full block by ID.
34
+ rpc :GetBlockByID, ::Flow::Access::GetBlockByIDRequest, ::Flow::Access::BlockResponse
35
+ # GetBlockByHeight gets a full block by height.
36
+ rpc :GetBlockByHeight, ::Flow::Access::GetBlockByHeightRequest, ::Flow::Access::BlockResponse
37
+ # Collections
38
+ #
39
+ # GetCollectionByID gets a collection by ID.
40
+ rpc :GetCollectionByID, ::Flow::Access::GetCollectionByIDRequest, ::Flow::Access::CollectionResponse
41
+ # Transactions
42
+ #
43
+ # SendTransaction submits a transaction to the network.
44
+ rpc :SendTransaction, ::Flow::Access::SendTransactionRequest, ::Flow::Access::SendTransactionResponse
45
+ # GetTransaction gets a transaction by ID.
46
+ rpc :GetTransaction, ::Flow::Access::GetTransactionRequest, ::Flow::Access::TransactionResponse
47
+ # GetTransactionResult gets the result of a transaction.
48
+ rpc :GetTransactionResult, ::Flow::Access::GetTransactionRequest, ::Flow::Access::TransactionResultResponse
49
+ # Accounts
50
+ #
51
+ # GetAccount is an alias for GetAccountAtLatestBlock.
52
+ #
53
+ # Warning: this function is deprecated. It behaves identically to GetAccountAtLatestBlock and will be removed in a future version.
54
+ rpc :GetAccount, ::Flow::Access::GetAccountRequest, ::Flow::Access::GetAccountResponse
55
+ # GetAccountAtLatestBlock gets an account by address from the latest sealed execution state.
56
+ rpc :GetAccountAtLatestBlock, ::Flow::Access::GetAccountAtLatestBlockRequest, ::Flow::Access::AccountResponse
57
+ # GetAccountAtBlockHeight gets an account by address at the given block height
58
+ rpc :GetAccountAtBlockHeight, ::Flow::Access::GetAccountAtBlockHeightRequest, ::Flow::Access::AccountResponse
59
+ # Scripts
60
+ #
61
+ # ExecuteScriptAtLatestBlock executes a read-only Cadence script against the latest sealed execution state.
62
+ rpc :ExecuteScriptAtLatestBlock, ::Flow::Access::ExecuteScriptAtLatestBlockRequest, ::Flow::Access::ExecuteScriptResponse
63
+ # ExecuteScriptAtBlockID executes a ready-only Cadence script against the execution state at the block with the given ID.
64
+ rpc :ExecuteScriptAtBlockID, ::Flow::Access::ExecuteScriptAtBlockIDRequest, ::Flow::Access::ExecuteScriptResponse
65
+ # ExecuteScriptAtBlockHeight executes a ready-only Cadence script against the execution state at the given block height.
66
+ rpc :ExecuteScriptAtBlockHeight, ::Flow::Access::ExecuteScriptAtBlockHeightRequest, ::Flow::Access::ExecuteScriptResponse
67
+ # Events
68
+ #
69
+ # GetEventsForHeightRange retrieves events emitted within the specified block range.
70
+ rpc :GetEventsForHeightRange, ::Flow::Access::GetEventsForHeightRangeRequest, ::Flow::Access::EventsResponse
71
+ # GetEventsForBlockIDs retrieves events for the specified block IDs and event type.
72
+ rpc :GetEventsForBlockIDs, ::Flow::Access::GetEventsForBlockIDsRequest, ::Flow::Access::EventsResponse
73
+ # NetworkParameters
74
+ #
75
+ # GetNetworkParameters retrieves the Flow network details
76
+ rpc :GetNetworkParameters, ::Flow::Access::GetNetworkParametersRequest, ::Flow::Access::GetNetworkParametersResponse
77
+ # ProtocolState
78
+ #
79
+ # GetLatestProtocolStateSnapshot retrieves the latest sealed protocol state snapshot.
80
+ # Used by Flow nodes joining the network to bootstrap a space-efficient local state.
81
+ rpc :GetLatestProtocolStateSnapshot, ::Flow::Access::GetLatestProtocolStateSnapshotRequest, ::Flow::Access::ProtocolStateSnapshotResponse
82
+ end
83
+
84
+ Stub = Service.rpc_stub_class
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,358 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flow
4
+ #
5
+ # The client class is used to access the Flow API
6
+ #
7
+ class Client
8
+ NODES = {
9
+ mainnet: "access.mainnet.nodes.onflow.org:9000",
10
+ testnet: "access.devnet.nodes.onflow.org:9000",
11
+ canarynet: "access.canary.nodes.onflow.org:9000"
12
+ }.freeze
13
+
14
+ #
15
+ # @param node [Symbol, String] the node address used in the stub
16
+ #
17
+ def initialize(node: :mainnet)
18
+ @stub = Access::AccessAPI::Stub.new(detect_node(node), :this_channel_is_insecure)
19
+ end
20
+
21
+ #
22
+ # Check if the Access API is ready and available
23
+ #
24
+ # @return [Flow::Access::PingResponse]
25
+ #
26
+ def ping
27
+ @stub.ping(Access::PingRequest.new)
28
+ end
29
+
30
+ ####
31
+ # Block Headers
32
+ #
33
+ # The following methods query information about block headers
34
+ ####
35
+
36
+ #
37
+ # Get the latest sealed or unsealed block header
38
+ #
39
+ # @param is_sealed [Boolean]
40
+ #
41
+ # @return [Flow::Entities::BlockHeader]
42
+ #
43
+ def get_latest_block_header(is_sealed: false)
44
+ req = Access::GetLatestBlockHeaderRequest.new(is_sealed: is_sealed)
45
+ res = @stub.get_latest_block_header(req)
46
+ res.block
47
+ end
48
+
49
+ #
50
+ # Get a block header by ID
51
+ #
52
+ # @todo The ID should be +bytes+ or it should be formatted automatically
53
+ #
54
+ # @param id [String]
55
+ #
56
+ # @return [Flow::Entities::BlockHeader]
57
+ #
58
+ def get_block_header_by_id(id)
59
+ req = Access::GetBlockHeaderByIDRequest.new(id: id)
60
+ res = @stub.get_block_header_by_id(req)
61
+ res.block
62
+ end
63
+
64
+ #
65
+ # Get a block header by height
66
+ #
67
+ # @param height [uint64]
68
+ #
69
+ # @return [Flow::Entities::BlockHeader]
70
+ #
71
+ def get_block_header_by_height(height)
72
+ req = Access::GetBlockHeaderByHeightRequest.new(height: height)
73
+ res = @stub.get_block_header_by_height(req)
74
+ res.block
75
+ end
76
+
77
+ ####
78
+ # Blocks
79
+ #
80
+ # The following methods query information about full blocks
81
+ ####
82
+
83
+ #
84
+ # Get the full payload of the latest sealed or unsealed block
85
+ #
86
+ # @param is_sealed [Boolean]
87
+ #
88
+ # @return [Flow::Entities::Block]
89
+ #
90
+ def get_latest_block(is_sealed: false)
91
+ req = Access::GetLatestBlockRequest.new(is_sealed: is_sealed)
92
+ res = @stub.get_latest_block(req)
93
+ res.block
94
+ end
95
+
96
+ #
97
+ # Get a full block by ID
98
+ #
99
+ # @todo The ID should be +bytes+ or it should be formatted automatically
100
+ #
101
+ # @param id [String]
102
+ #
103
+ # @return [Flow::Entities::Block]
104
+ #
105
+ def get_block_by_id(id)
106
+ req = Access::GetBlockByIDRequest.new(id: id)
107
+ res = @stub.get_block_by_id(req)
108
+ res.block
109
+ end
110
+
111
+ #
112
+ # Get a full block by height
113
+ #
114
+ # @param height [uint64]
115
+ #
116
+ # @return [Flow::Entities::Block]
117
+ #
118
+ def get_block_by_height(height)
119
+ req = Access::GetBlockByHeightRequest.new(height: height)
120
+ res = @stub.get_block_by_height(req)
121
+ res.block
122
+ end
123
+
124
+ ####
125
+ # Collections
126
+ #
127
+ # The following methods query information about collections
128
+ ####
129
+
130
+ #
131
+ # Gets a collection by ID
132
+ #
133
+ # @todo The ID should be +bytes+ or it should be formatted automatically
134
+ #
135
+ # @param id [String]
136
+ #
137
+ # @return [Flow::Entities::Collection]
138
+ #
139
+ def get_collection_by_id(id)
140
+ req = Access::GetCollectionByIDRequest.new(id: id)
141
+ res = @stub.get_collection_by_id(req)
142
+ res.collection
143
+ end
144
+
145
+ ####
146
+ # Transactions
147
+ #
148
+ # The following methods can be used to submit transactions and fetch their results
149
+ ####
150
+
151
+ #
152
+ # Submit a transaction to the network
153
+ #
154
+ #
155
+ #
156
+ #
157
+ # def send_transaction()
158
+ # # TODO: build and sign transaction here
159
+ # # req = Access::SendTransactionRequest.new()
160
+ # # @stub.send_transaction(req)
161
+ # end
162
+
163
+ #
164
+ # Get a transaction by ID
165
+ #
166
+ # @todo The ID should be +bytes+ or it should be formatted automatically
167
+ #
168
+ # @param id [String]
169
+ #
170
+ # @return [Flow::Entities::Transaction]
171
+ #
172
+ def get_transaction(id)
173
+ req = Access::GetTransactionRequest.new(id: id)
174
+ res = @stub.get_transaction(req)
175
+ res.transaction
176
+ end
177
+
178
+ #
179
+ # Get the execution result of a transaction
180
+ #
181
+ # @todo The ID should be +bytes+ or it should be formatted automatically
182
+ # @todo We might want to change the return value here, TransactionReturnResponse has
183
+ # these available keys: status, status_code, error_message, events
184
+ #
185
+ # @param id [String]
186
+ #
187
+ # @return [Flow::Access::TransactionResultResponse]
188
+ #
189
+ def get_transaction_result(id)
190
+ req = Access::GetTransactionRequest.new(id: id)
191
+ @stub.get_transaction_result(req)
192
+ end
193
+
194
+ ####
195
+ # Accounts
196
+ ####
197
+
198
+ #
199
+ # Get an account by address
200
+ #
201
+ # @param address [String]
202
+ #
203
+ # @return [Flow::Entities::Account]
204
+ #
205
+ def get_account_at_latest_block(address)
206
+ req = Access::GetAccountAtLatestBlockRequest.new(address: to_bytes(address))
207
+ res = @stub.get_account_at_latest_block(req)
208
+ res.account
209
+ end
210
+
211
+ #
212
+ # Get an account by address at the given block height
213
+ #
214
+ # @param address [String]
215
+ # @param block_height [uint64]
216
+ #
217
+ # @return [Flow::Entities::Account]
218
+ #
219
+ def get_account_at_block_height(address, block_height)
220
+ req = Access::GetAccountAtBlockHeightRequest.new(
221
+ address: to_bytes(address),
222
+ block_height: block_height
223
+ )
224
+
225
+ res = @stub.get_account_at_latest_block(req)
226
+ res.account
227
+ end
228
+
229
+ ####
230
+ # Scripts
231
+ ####
232
+
233
+ #
234
+ # Execute a read-only Cadence script against the latest sealed execution state
235
+ #
236
+ # @param script [String] cadence script
237
+ # @param args [Array] array of args
238
+ #
239
+ # @return [OpenStruct]
240
+ #
241
+ def execute_script(script, args = [])
242
+ req = Access::ExecuteScriptAtLatestBlockRequest.new(
243
+ script: script,
244
+ arguments: args
245
+ )
246
+
247
+ res = @stub.execute_script_at_latest_block(req)
248
+ parse_json(res.value)
249
+ end
250
+
251
+ ####
252
+ # Events
253
+ #
254
+ # The following methods can be used to query for on-chain events
255
+ ####
256
+
257
+ #
258
+ # Retrieve events emitted within the specified block range
259
+ #
260
+ # @todo Scope the response further
261
+ #
262
+ # @param type [String]
263
+ # @param start_height [uint64]
264
+ # @param end_height [uint64]
265
+ #
266
+ # @return [EventsResponse]
267
+ #
268
+ def get_events_for_height_range(type, start_height: 2, end_height: 3)
269
+ req = Access::GetEventsForHeightRangeRequest.new(
270
+ type: type,
271
+ start_height: start_height,
272
+ end_height: end_height
273
+ )
274
+
275
+ @stub.get_events_for_height_range(req)
276
+ end
277
+
278
+ #
279
+ # Retrieve events for the specified block IDs and event type
280
+ #
281
+ # @todo Scope the response further
282
+ #
283
+ # @param type [String]
284
+ # @param block_ids [Array]
285
+ #
286
+ # @return [EventsResponse]
287
+ #
288
+ def get_events_for_block_ids(type, block_ids = [])
289
+ req = Access::GetEventsForBlockIDsRequest.new(
290
+ type: type,
291
+ block_ids: block_ids
292
+ )
293
+
294
+ @stub.get_events_for_block_ids(req)
295
+ end
296
+
297
+ ####
298
+ # Network Parameters
299
+ #
300
+ # Network parameters provide information about the Flow network.
301
+ # Currently, it only includes the chain ID.
302
+ # The following method can be used to query for network parameters
303
+ ####
304
+
305
+ #
306
+ # Retrieve the network parameters
307
+ #
308
+ # @return [Hash]
309
+ #
310
+ def get_network_parameters
311
+ req = Access::GetNetworkParametersRequest.new
312
+ res = @stub.get_network_parameters(req)
313
+ res.to_h
314
+ end
315
+
316
+ ####
317
+ # Protocol state snapshot
318
+ #
319
+ # The following method can be used to query the latest protocol state snapshot
320
+ ####
321
+
322
+ #
323
+ # Retrieve the latest Protocol state snapshot serialized as a byte array.
324
+ # It is used by Flow nodes joining the network to bootstrap a space-efficient local state
325
+ #
326
+ # @todo Fix. This currently fails with unimplemented_error
327
+ #
328
+ # @return
329
+ #
330
+ def get_latest_protocol_state_snapshot
331
+ req = Access::GetLatestProtocolStateSnapshotRequest.new
332
+ @stub.get_latest_protocol_state_snapshot(req)
333
+ end
334
+
335
+ private
336
+
337
+ def detect_node(node)
338
+ case node.to_sym
339
+ when :mainnet then NODES[:mainnet]
340
+ when :testnet then NODES[:testnet]
341
+ when :canarynet then NODES[:canarynet]
342
+ else node
343
+ end
344
+ end
345
+
346
+ def parse_json(event_payload)
347
+ JSON.parse(event_payload, object_class: OpenStruct)
348
+ end
349
+
350
+ def to_bytes(string)
351
+ [string].pack("H*")
352
+ end
353
+
354
+ def to_string(bytes)
355
+ bytes.unpack1("H*")
356
+ end
357
+ end
358
+ end
@@ -0,0 +1,32 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: flow/entities/account.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_file("flow/entities/account.proto", :syntax => :proto3) do
8
+ add_message "flow.entities.Account" do
9
+ optional :address, :bytes, 1
10
+ optional :balance, :uint64, 2
11
+ optional :code, :bytes, 3
12
+ repeated :keys, :message, 4, "flow.entities.AccountKey"
13
+ map :contracts, :string, :bytes, 5
14
+ end
15
+ add_message "flow.entities.AccountKey" do
16
+ optional :index, :uint32, 1
17
+ optional :public_key, :bytes, 2
18
+ optional :sign_algo, :uint32, 3
19
+ optional :hash_algo, :uint32, 4
20
+ optional :weight, :uint32, 5
21
+ optional :sequence_number, :uint32, 6
22
+ optional :revoked, :bool, 7
23
+ end
24
+ end
25
+ end
26
+
27
+ module Flow
28
+ module Entities
29
+ Account = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("flow.entities.Account").msgclass
30
+ AccountKey = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("flow.entities.AccountKey").msgclass
31
+ end
32
+ end