flow_client 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6f5ab2e4ba804c2d62cb6483b8f79944ac2d9d8e3b29f9c31b4f3fb40bbc8650
4
- data.tar.gz: 6cfdbcf1263662d94b7e7623c43904baeb63d992a1fb7ab572b38564377b20d6
3
+ metadata.gz: 91c782ac6146b291f2691e51a0ff9bf09fafb58d1fec9ec9d10ae80e3ea6c058
4
+ data.tar.gz: e53438e01826e7a68c0868bed486ca51f256e42b2f574e62bee710be88217450
5
5
  SHA512:
6
- metadata.gz: 7accd7d47a96f1f8867870b04e7c3fa987a6d157f124c236997fc9b8da42796affa0678ca607696f0e172ab5c4bc10ce363c7a3d42eae538c49051dbde932874
7
- data.tar.gz: fcd4d4672971546ac525e378bd33175a94bb69ca83bef0af257a7762cdc911330fb8e28fcc0825a20ae97282ba27d666fcbd1c93b68911ae94e83cc6743d3264
6
+ metadata.gz: ecec4b82c34c78f62daf55f048cd7a384e17e14a721162eb40b69b00f9d24bc96bae36a03d9c81105fdaa0beb04632a6ce5a05f57b424d97dd1326db460b58a3
7
+ data.tar.gz: a61e7d290d229a990df2e75af28f27f01ef73afbc5aaf8fabea882d8efbbf15e631fcaedf975076e1776a018194cc8ad6c3d304d0baaf5e344c962fc02e2d626
data/CHANGELOG.md CHANGED
@@ -12,4 +12,9 @@
12
12
 
13
13
  - Added multiple signature support
14
14
  - Added multi-party signing
15
- - Added account creation
15
+ - Added account creation
16
+ -
17
+ ## [0.2.1] - 2021-11-08
18
+
19
+ - Fixed incorrect CadenceType conversions
20
+ - Updated usage examples
data/README.md CHANGED
@@ -62,7 +62,7 @@ res = client.ping
62
62
  After you have established a connection with an access node, you can query the Flow network to retrieve data about blocks, accounts, events and transactions. We will explore how to retrieve each of these entities in the sections below.
63
63
 
64
64
  ### Get Blocks
65
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
65
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Client)
66
66
 
67
67
  Query the network for block by id, height or get the latest block.
68
68
 
@@ -104,7 +104,7 @@ Result output:
104
104
  ```
105
105
 
106
106
  ### Get Account
107
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
107
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient%2FClient:get_account)
108
108
 
109
109
  Retrieve any account from Flow network's latest block or from a specified block height.
110
110
 
@@ -133,7 +133,7 @@ Result output:
133
133
 
134
134
 
135
135
  ### Get Transactions
136
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
136
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Client#get_transaction-instance_method)
137
137
 
138
138
  Retrieve transactions from the network by providing a transaction ID. After a transaction has been submitted, you can also get the transaction result to check the status.
139
139
 
@@ -233,7 +233,7 @@ Example output:
233
233
 
234
234
 
235
235
  ### Get Events
236
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
236
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Client#get_events-instance_method)
237
237
 
238
238
  Retrieve events by a given type in a specified block height range or through a list of block IDs.
239
239
 
@@ -277,7 +277,7 @@ Example output:
277
277
  ```
278
278
 
279
279
  ### Get Collections
280
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
280
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Client#get_collection_by_id-instance_method)
281
281
 
282
282
  Retrieve a batch of transactions that have been included in the same block, known as ***collections***.
283
283
  Collections are used to improve consensus throughput by increasing the number of transactions per block and they act as a link between a block and a transaction.
@@ -294,7 +294,7 @@ Example output:
294
294
  ```
295
295
 
296
296
  ### Execute Scripts
297
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
297
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Client#execute_script-instance_method)
298
298
 
299
299
  Scripts allow you to write arbitrary non-mutating Cadence code on the Flow blockchain and return data. You can learn more about [Cadence and scripts here](https://docs.onflow.org/cadence/language/), but we are now only interested in executing the script code and getting back the data.
300
300
 
@@ -312,7 +312,7 @@ script = %{
312
312
  }
313
313
  }
314
314
 
315
- args = [{ type: 'Int', value: "1" }.to_json]
315
+ args = [FlowClient::CadenceType.Int(1)]
316
316
  res = client.execute_script(script, args)
317
317
  ```
318
318
 
@@ -407,7 +407,7 @@ A transaction will be rejected if it is submitted past its expiry block. Flow ca
407
407
  A transaction expires after `600` blocks are committed on top of the reference block, which takes about 10 minutes at average Mainnet block rates.
408
408
 
409
409
  ### Build Transactions
410
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
410
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Transaction)
411
411
 
412
412
  Building a transaction involves setting the required properties explained above and producing a transaction object.
413
413
 
@@ -456,7 +456,7 @@ transaction.arguments = arguments
456
456
  After you have successfully [built a transaction](#build-transactions) the next step in the process is to sign it.
457
457
 
458
458
  ### Sign Transactions
459
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
459
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Transaction)
460
460
 
461
461
  Flow introduces new concepts that allow for more flexibility when creating and signing transactions.
462
462
  Before trying the examples below, we recommend that you read through the [transaction signature documentation](https://docs.onflow.org/concepts/accounts-and-keys/).
@@ -478,7 +478,7 @@ Signatures can be generated more securely using keys stored in a hardware device
478
478
 
479
479
  Simple signature example:
480
480
  ```ruby
481
- account = FlowClient::Account.new(address: 0x01)
481
+ account = client.get_account("0x01")
482
482
  signer = FlowClient::LocalSigner.new("<private key hex>")
483
483
 
484
484
  transaction.proposer_address = account.address
@@ -503,7 +503,7 @@ Flow supports great flexibility when it comes to transaction signing, we can def
503
503
  | `0x01` | 1 | 1.0 |
504
504
 
505
505
  ```ruby
506
- account = FlowClient::Account.new(address: 0x01)
506
+ account = client.get_account("0x01")
507
507
 
508
508
  transaction = FlowClient::Transaction.new
509
509
  transaction.reference_block_id = client.get_latest_block.id
@@ -532,7 +532,7 @@ transaction.add_envelope_signature(account.address, account.keys.first.index, si
532
532
  | `0x01` | 2 | 0.5 |
533
533
 
534
534
  ```ruby
535
- account = FlowClient::Account.new(address: 0x01)
535
+ account = client.get_account("0x01")
536
536
 
537
537
  transaction = FlowClient::Transaction.new
538
538
  transaction.reference_block_id = client.get_latest_block.id
@@ -563,10 +563,10 @@ transaction.add_envelope_signature(account.address, account.keys[1].index, signe
563
563
 
564
564
  ```ruby
565
565
  payer_signer = FlowClient::LocalSigner.new("<private key hex>")
566
- payer_account = FlowClient::Account.new(address: 0x02)
566
+ payer_account = client.get_account("0x02")
567
567
 
568
568
  proposer_signer = FlowClient::LocalSigner.new("<private key hex>")
569
- proposer_account = FlowClient::Account.new(address: 0x01)
569
+ proposer_account = client.get_account("0x01")
570
570
 
571
571
  @transaction = FlowClient::Transaction.new
572
572
  @transaction.reference_block_id = client.get_latest_block.id
@@ -599,10 +599,10 @@ proposer_account = FlowClient::Account.new(address: 0x01)
599
599
 
600
600
  ```ruby
601
601
  payer_signer = FlowClient::LocalSigner.new("<private key hex>")
602
- payer_account = FlowClient::Account.new(address: 0x02)
602
+ payer_account = client.get_account("0x02")
603
603
 
604
604
  proposer_signer = FlowClient::LocalSigner.new("<private key hex>")
605
- proposer_account = FlowClient::Account.new(address: 0x01)
605
+ proposer_account = client.get_account("0x01")
606
606
 
607
607
  @transaction = FlowClient::Transaction.new
608
608
  @transaction.reference_block_id = client.get_latest_block.id
@@ -637,10 +637,10 @@ proposer_account = FlowClient::Account.new(address: 0x01)
637
637
 
638
638
  ```ruby
639
639
  payer_signer = FlowClient::LocalSigner.new("<private key hex>")
640
- payer_account = FlowClient::Account.new(address: 0x02)
640
+ payer_account = client.get_account("0x02")
641
641
 
642
642
  proposer_signer = FlowClient::LocalSigner.new("<private key hex>")
643
- proposer_account = FlowClient::Account.new(address: 0x01)
643
+ proposer_account = client.get_account("0x01")
644
644
 
645
645
  @transaction = FlowClient::Transaction.new
646
646
  @transaction.reference_block_id = client.get_latest_block.id
@@ -661,7 +661,7 @@ proposer_account = FlowClient::Account.new(address: 0x01)
661
661
 
662
662
 
663
663
  ### Send Transactions
664
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
664
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Client#send_transaction-instance_method)
665
665
 
666
666
  After a transaction has been [built](#build-transactions) and [signed](#sign-transactions), it can be sent to the Flow blockchain where it will be executed. If sending was successful you can then [retrieve the transaction result](#get-transactions).
667
667
 
@@ -675,7 +675,7 @@ end
675
675
 
676
676
 
677
677
  ### Create Accounts
678
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
678
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Client#create_account-instance_method)
679
679
 
680
680
  On Flow, account creation happens inside a transaction. Because the network allows for a many-to-many relationship between public keys and accounts, it's not possible to derive a new account address from a public key offline.
681
681
 
@@ -700,13 +700,13 @@ Account creation happens inside a transaction, which means that somebody must pa
700
700
 
701
701
  ```ruby
702
702
  # The account that will pay for the creation of the new account
703
- account = FlowClient::Account.new(address: "f8d6e0586b0a20c7")
703
+ payer_account = client.get_account("f8d6e0586b0a20c7")
704
704
  # Create an in-memory signer with the payer's private key
705
705
  signer = FlowClient::LocalSigner.new("4d9287571c8bff7482ffc27ef68d5b4990f9bd009a1e9fa812aae08ba167d57f")
706
706
  # Generate a public key for the new account
707
707
  _private_key, public_key = FlowClient::Crypto.generate_key_pair(FlowClient::Crypto::Curves::P256)
708
708
  # Create the account
709
- res = client.create_account([public_key], { "ContractName": "<contract cadence code>" }, account, signer)
709
+ res = client.create_account([public_key], { "ContractName": "<contract cadence code>" }, payer_account, signer)
710
710
  ```
711
711
 
712
712
  ```ruby
@@ -726,7 +726,7 @@ res.address
726
726
  ```
727
727
 
728
728
  ### Generate Keys
729
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
729
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Crypto#generate_key_pair-class_method)
730
730
 
731
731
  Flow uses [ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) signatures to control access to user accounts. Each key pair can be used in combination with the `SHA2-256` or `SHA3-256` hashing algorithms.
732
732
 
@@ -744,4 +744,4 @@ The example above uses an ECDSA key pair on the P-256 (secp256r1) elliptic curve
744
744
 
745
745
  ```ruby
746
746
  private_key, public_key = FlowClient::Crypto.generate_key_pair(FlowClient::Crypto::Curves::SECP256K1)
747
- ```
747
+ ```
@@ -2,14 +2,6 @@ require "ostruct"
2
2
 
3
3
  module FlowClient
4
4
  module CadenceType
5
- # class CadenceType
6
- # def to_json
7
- # end
8
- # end
9
-
10
- # class String
11
- # end
12
-
13
5
  def self.String(value)
14
6
  OpenStruct.new(type: "String", value: value.to_s)
15
7
  end
@@ -35,111 +27,87 @@ module FlowClient
35
27
  end
36
28
 
37
29
  def self.UInt(value)
38
- OpenStruct.new(type: "UInt", value: value.to_i)
30
+ OpenStruct.new(type: "UInt", value: value.to_s)
39
31
  end
40
32
 
41
33
  def self.Int8(value)
42
- OpenStruct.new(type: "Int8", value: value.to_i)
34
+ OpenStruct.new(type: "Int8", value: value.to_s)
43
35
  end
44
36
 
45
37
  def self.UInt8(value)
46
- OpenStruct.new(type: "UInt8", value: value.to_i)
38
+ OpenStruct.new(type: "UInt8", value: value.to_s)
47
39
  end
48
40
 
49
41
  def self.Int16(value)
50
- OpenStruct.new(type: "Int16", value: value.to_i)
42
+ OpenStruct.new(type: "Int16", value: value.to_s)
51
43
  end
52
44
 
53
45
  def self.UInt16(value)
54
- OpenStruct.new(type: "UInt16", value: value.to_i)
46
+ OpenStruct.new(type: "UInt16", value: value.to_s)
55
47
  end
56
48
 
57
49
  def self.Int32(value)
58
- OpenStruct.new(type: "Int32", value: value.to_i)
50
+ OpenStruct.new(type: "Int32", value: value.to_s)
59
51
  end
60
52
 
61
53
  def self.UInt32(value)
62
- OpenStruct.new(type: "UInt32", value: value.to_i)
54
+ OpenStruct.new(type: "UInt32", value: value.to_s)
63
55
  end
64
56
 
65
57
  def self.Int64(value)
66
- OpenStruct.new(type: "Int64", value: value.to_i)
58
+ OpenStruct.new(type: "Int64", value: value.to_s)
67
59
  end
68
60
 
69
61
  def self.UInt64(value)
70
- OpenStruct.new(type: "UInt64", value: value.to_i)
62
+ OpenStruct.new(type: "UInt64", value: value.to_s)
71
63
  end
72
64
 
73
65
  def self.Int64(value)
74
- OpenStruct.new(type: "Int64", value: value.to_i)
66
+ OpenStruct.new(type: "Int64", value: value.to_s)
75
67
  end
76
68
 
77
69
  def self.UInt64(value)
78
- OpenStruct.new(type: "UInt64", value: value.to_i)
70
+ OpenStruct.new(type: "UInt64", value: value.to_s)
79
71
  end
80
72
 
81
73
  def self.Int128(value)
82
- OpenStruct.new(type: "Int128", value: value.to_i)
74
+ OpenStruct.new(type: "Int128", value: value.to_s)
83
75
  end
84
76
 
85
77
  def self.UInt128(value)
86
- OpenStruct.new(type: "UInt128", value: value.to_i)
78
+ OpenStruct.new(type: "UInt128", value: value.to_s)
87
79
  end
88
80
 
89
81
  def self.Int256(value)
90
- OpenStruct.new(type: "Int256", value: value.to_i)
82
+ OpenStruct.new(type: "Int256", value: value.to_s)
91
83
  end
92
84
 
93
85
  def self.UInt256(value)
94
- OpenStruct.new(type: "UInt256", value: value.to_i)
95
- end
96
-
97
- def self.Word8(value)
98
- OpenStruct.new(type: "Word8", value: value.to_i)
86
+ OpenStruct.new(type: "UInt256", value: value.to_s)
99
87
  end
100
88
 
101
89
  def self.Word8(value)
102
- OpenStruct.new(type: "Word8", value: value.to_i)
90
+ OpenStruct.new(type: "Word8", value: value.to_s)
103
91
  end
104
92
 
105
93
  def self.Word16(value)
106
- OpenStruct.new(type: "Word16", value: value.to_i)
107
- end
108
-
109
- def self.Word16(value)
110
- OpenStruct.new(type: "Word16", value: value.to_i)
111
- end
112
-
113
- def self.Word32(value)
114
- OpenStruct.new(type: "Word32", value: value.to_i)
94
+ OpenStruct.new(type: "Word16", value: value.to_s)
115
95
  end
116
96
 
117
97
  def self.Word32(value)
118
- OpenStruct.new(type: "Word32", value: value.to_i)
98
+ OpenStruct.new(type: "Word32", value: value.to_s)
119
99
  end
120
100
 
121
101
  def self.Word64(value)
122
- OpenStruct.new(type: "Word64", value: value.to_i)
123
- end
124
-
125
- def self.Word64(value)
126
- OpenStruct.new(type: "Word64", value: value.to_i)
127
- end
128
-
129
- def self.Fix64(value)
130
- OpenStruct.new(type: "Fix64", value: value.to_i)
102
+ OpenStruct.new(type: "Word64", value: value.to_s)
131
103
  end
132
104
 
133
105
  def self.Fix64(value)
134
- OpenStruct.new(type: "Fix64", value: value.to_i)
135
- end
136
-
137
- def self.UFix64(value)
138
- OpenStruct.new(type: "Fix64", value: value.to_i)
106
+ OpenStruct.new(type: "Fix64", value: value.to_s)
139
107
  end
140
108
 
141
109
  def self.UFix64(value)
142
- OpenStruct.new(type: "Fix64", value: value.to_i)
110
+ OpenStruct.new(type: "UFix64", value: value.to_s)
143
111
  end
144
112
 
145
113
  def self.Array(values)
@@ -171,11 +139,11 @@ module FlowClient
171
139
 
172
140
  def self.Capability(path, address, borrow_type)
173
141
  OpenStruct.new(
174
- type: "Type",
142
+ type: "Capability",
175
143
  value: OpenStruct.new(
176
144
  path: path.to_s,
177
145
  address: address.to_s,
178
- borrow_type: borrow_type.to_s
146
+ borrowType: borrow_type.to_s
179
147
  )
180
148
  )
181
149
  end
@@ -26,9 +26,12 @@ module FlowClient
26
26
  @stub.ping(req)
27
27
  end
28
28
 
29
- # Accounts
29
+ # :section: Accounts
30
30
 
31
- # Gets an account
31
+ # Returns an account for the address specified at the latest
32
+ # block.
33
+ #
34
+ # @return [FlowClient::Account] the account
32
35
  def get_account(address)
33
36
  req = Access::GetAccountAtLatestBlockRequest.new(address: to_bytes(address))
34
37
 
@@ -53,14 +56,13 @@ module FlowClient
53
56
  end
54
57
 
55
58
  account.contracts = res.account.contracts
56
-
57
59
  account
58
60
  end
59
61
  end
60
62
 
61
63
  # Creates a new account
62
64
  #
63
- #
65
+ # @return [FlowClient::Account] the newly created account
64
66
  def create_account(new_account_public_keys, contracts, payer_account, signer)
65
67
  script = File.read(File.join("lib", "cadence", "templates", "create-account.cdc"))
66
68
 
@@ -105,14 +107,8 @@ module FlowClient
105
107
  script = File.read(File.join("lib", "cadence", "templates", "add-account-key.cdc"))
106
108
 
107
109
  arguments = [
108
- {
109
- type: "String",
110
- value: public_key_hex
111
- }.to_json,
112
- {
113
- type: "UFix64",
114
- value: weight.to_s
115
- }.to_json
110
+ CadenceType.String(public_key_hex),
111
+ CadenceType.UFix64(weight)
116
112
  ]
117
113
 
118
114
  transaction = FlowClient::Transaction.new
@@ -138,14 +134,8 @@ module FlowClient
138
134
  code_hex = code.unpack1("H*")
139
135
 
140
136
  arguments = [
141
- {
142
- type: "String",
143
- value: name
144
- }.to_json,
145
- {
146
- type: "String",
147
- value: code_hex
148
- }.to_json
137
+ CadenceType.String(name),
138
+ CadenceType.String(code_hex)
149
139
  ]
150
140
 
151
141
  transaction = FlowClient::Transaction.new
@@ -170,10 +160,7 @@ module FlowClient
170
160
  script = File.read(File.join("lib", "cadence", "templates", "remove-contract.cdc"))
171
161
 
172
162
  arguments = [
173
- {
174
- type: "String",
175
- value: name
176
- }.to_json
163
+ CadenceType.String(name),
177
164
  ]
178
165
 
179
166
  transaction = FlowClient::Transaction.new
@@ -199,14 +186,8 @@ module FlowClient
199
186
  code_hex = code.unpack1("H*")
200
187
 
201
188
  arguments = [
202
- {
203
- type: "String",
204
- value: name
205
- }.to_json,
206
- {
207
- type: "String",
208
- value: code_hex
209
- }.to_json
189
+ CadenceType.String(name),
190
+ CadenceType.String(code_hex)
210
191
  ]
211
192
 
212
193
  transaction = FlowClient::Transaction.new
@@ -226,7 +207,9 @@ module FlowClient
226
207
  end
227
208
  end
228
209
 
229
- # Scripts
210
+ # :section: Scripts
211
+
212
+ # Executes a script on the blockchain
230
213
  def execute_script(script, args = [])
231
214
  processed_args = []
232
215
  args.to_a.each do |arg|
@@ -243,7 +226,11 @@ module FlowClient
243
226
  parse_json(res.value)
244
227
  end
245
228
 
246
- # Blocks
229
+ # :section: Blocks
230
+
231
+ # Returns the latest block
232
+ #
233
+ # @return [FlowClient::Block] the block
247
234
  def get_latest_block(is_sealed: true)
248
235
  req = Access::GetLatestBlockRequest.new(
249
236
  is_sealed: is_sealed
@@ -252,6 +239,9 @@ module FlowClient
252
239
  Block.parse_grpc_block_response(res)
253
240
  end
254
241
 
242
+ # Returns the block with id
243
+ #
244
+ # @return [FlowClient::Block] the block
255
245
  def get_block_by_id(id)
256
246
  req = Access::GetBlockByIDRequest.new(
257
247
  id: to_bytes(id)
@@ -260,6 +250,9 @@ module FlowClient
260
250
  Block.parse_grpc_block_response(res)
261
251
  end
262
252
 
253
+ # Returns the latest with height
254
+ #
255
+ # @return [FlowClient::Block] the block
263
256
  def get_block_by_height(height)
264
257
  req = Access::GetBlockByHeightRequest.new(
265
258
  height: height
@@ -268,7 +261,11 @@ module FlowClient
268
261
  Block.parse_grpc_block_response(res)
269
262
  end
270
263
 
271
- # Collections
264
+ # :section: Collections
265
+
266
+ # Returns the collection with id
267
+ #
268
+ # @return [FlowClient::Collection] the collection
272
269
  def get_collection_by_id(id)
273
270
  req = Access::GetCollectionByIDRequest.new(
274
271
  id: to_bytes(id)
@@ -277,7 +274,9 @@ module FlowClient
277
274
  Collection.parse_grpc_type(res)
278
275
  end
279
276
 
280
- # Events
277
+ # :section: Events
278
+
279
+ # Returns events of the given type between the start and end block heights.
281
280
  def get_events(type, start_height, end_height)
282
281
  req = Access::GetEventsForHeightRangeRequest.new(
283
282
  type: type,
@@ -293,9 +292,11 @@ module FlowClient
293
292
  end
294
293
  end
295
294
 
296
- # Transactions
295
+ # :section: Transactions
297
296
 
298
297
  # Sends a transaction to the blockchain
298
+ #
299
+ # @return [FlowClient::TransactionResponse] the transaction response
299
300
  def send_transaction(transaction)
300
301
  transaction.address_aliases = @address_aliases
301
302
  req = Access::SendTransactionRequest.new(
@@ -311,6 +312,9 @@ module FlowClient
311
312
  end
312
313
  end
313
314
 
315
+ # Returns the transaction with transaction_id
316
+ #
317
+ # @return [FlowClient::Transaction] the transaction
314
318
  def get_transaction(transaction_id)
315
319
  req = Access::GetTransactionRequest.new(
316
320
  id: to_bytes(transaction_id)
@@ -326,6 +330,8 @@ module FlowClient
326
330
  end
327
331
 
328
332
  # Returns a transaction result
333
+ #
334
+ # @return [FlowClient::TransactionResult] the transaction result
329
335
  def get_transaction_result(transaction_id)
330
336
  req = Access::GetTransactionRequest.new(
331
337
  id: to_bytes(transaction_id)
@@ -340,9 +346,11 @@ module FlowClient
340
346
  end
341
347
  end
342
348
 
349
+ # Polls the blockchain for the transaction result until it is sealed
350
+ # or expired
343
351
  def wait_for_transaction(transaction_id)
344
352
  response = get_transaction_result(transaction_id)
345
- while response.status != :SEALED
353
+ while ![:SEALED, :EXPIRED].include? response.status
346
354
  sleep(0.5)
347
355
  response = get_transaction_result(transaction_id)
348
356
  end
@@ -26,7 +26,7 @@ module FlowClient
26
26
  @authorizer_addresses = []
27
27
  @arguments = []
28
28
  @script = ""
29
- @gas_limit = 0
29
+ @gas_limit = 999
30
30
  @envelope_signatures = []
31
31
  @payload_signatures = []
32
32
  @address_aliases = {}
@@ -57,51 +57,6 @@ module FlowClient
57
57
  Utils.right_pad_bytes(TRANSACTION_DOMAIN_TAG.bytes, 32).pack("c*")
58
58
  end
59
59
 
60
- def payload_canonical_form
61
- [
62
- resolved_script, @arguments,
63
- [@reference_block_id].pack("H*"), @gas_limit,
64
- padded_address(@proposal_key.address), @proposal_key.key_id,
65
- @proposal_key.sequence_number, padded_address(@payer_address),
66
- @authorizer_addresses.map { |address| padded_address(address) }
67
- ]
68
- end
69
-
70
- def payload_message
71
- payload = payload_canonical_form
72
- RLP.encode(payload)
73
- end
74
-
75
- def envelope_canonical_form
76
- @signers[@proposal_key.address] = 0
77
-
78
- @payload_signatures.each do |sig|
79
- @signers[sig.address] = @signers.keys.count
80
- end
81
-
82
- signatures = []
83
- @payload_signatures.each do |sig|
84
- signatures << [
85
- @signers[sig.address.unpack1("H*")],
86
- sig.key_id,
87
- sig.signature
88
- ]
89
- end
90
-
91
- [
92
- payload_canonical_form,
93
- signatures
94
- ]
95
- end
96
-
97
- def envelope_message
98
- RLP.encode(envelope_canonical_form)
99
- end
100
-
101
- def payload_message
102
- RLP.encode(payload_canonical_form)
103
- end
104
-
105
60
  def add_envelope_signature(signer_address, key_index, signer)
106
61
  domain_tagged_envelope = (Transaction.padded_transaction_domain_tag.bytes + envelope_message.bytes).pack("C*")
107
62
 
@@ -160,6 +115,51 @@ module FlowClient
160
115
  def padded_address(address_hex_string)
161
116
  Utils.left_pad_bytes([address_hex_string].pack("H*").bytes, 8).pack("C*")
162
117
  end
118
+
119
+ def payload_canonical_form
120
+ [
121
+ resolved_script, @arguments,
122
+ [@reference_block_id].pack("H*"), @gas_limit,
123
+ padded_address(@proposal_key.address), @proposal_key.key_id,
124
+ @proposal_key.sequence_number, padded_address(@payer_address),
125
+ @authorizer_addresses.map { |address| padded_address(address) }
126
+ ]
127
+ end
128
+
129
+ def payload_message
130
+ payload = payload_canonical_form
131
+ RLP.encode(payload)
132
+ end
133
+
134
+ def envelope_canonical_form
135
+ @signers[@proposal_key.address] = 0
136
+
137
+ @payload_signatures.each do |sig|
138
+ @signers[sig.address] = @signers.keys.count
139
+ end
140
+
141
+ signatures = []
142
+ @payload_signatures.each do |sig|
143
+ signatures << [
144
+ @signers[sig.address.unpack1("H*")],
145
+ sig.key_id,
146
+ sig.signature
147
+ ]
148
+ end
149
+
150
+ [
151
+ payload_canonical_form,
152
+ signatures
153
+ ]
154
+ end
155
+
156
+ def envelope_message
157
+ RLP.encode(envelope_canonical_form)
158
+ end
159
+
160
+ def payload_message
161
+ RLP.encode(payload_canonical_form)
162
+ end
163
163
  end
164
164
 
165
165
  class TransactionResult
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FlowClient
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.1"
5
5
  end
data/template.md CHANGED
@@ -62,7 +62,7 @@ res = client.ping
62
62
  After you have established a connection with an access node, you can query the Flow network to retrieve data about blocks, accounts, events and transactions. We will explore how to retrieve each of these entities in the sections below.
63
63
 
64
64
  ### Get Blocks
65
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
65
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Client)
66
66
 
67
67
  Query the network for block by id, height or get the latest block.
68
68
 
@@ -104,7 +104,7 @@ Result output:
104
104
  ```
105
105
 
106
106
  ### Get Account
107
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
107
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient%2FClient:get_account)
108
108
 
109
109
  Retrieve any account from Flow network's latest block or from a specified block height.
110
110
 
@@ -133,7 +133,7 @@ Result output:
133
133
 
134
134
 
135
135
  ### Get Transactions
136
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
136
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Client#get_transaction-instance_method)
137
137
 
138
138
  Retrieve transactions from the network by providing a transaction ID. After a transaction has been submitted, you can also get the transaction result to check the status.
139
139
 
@@ -233,7 +233,7 @@ Example output:
233
233
 
234
234
 
235
235
  ### Get Events
236
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
236
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Client#get_events-instance_method)
237
237
 
238
238
  Retrieve events by a given type in a specified block height range or through a list of block IDs.
239
239
 
@@ -277,7 +277,7 @@ Example output:
277
277
  ```
278
278
 
279
279
  ### Get Collections
280
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
280
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Client#get_collection_by_id-instance_method)
281
281
 
282
282
  Retrieve a batch of transactions that have been included in the same block, known as ***collections***.
283
283
  Collections are used to improve consensus throughput by increasing the number of transactions per block and they act as a link between a block and a transaction.
@@ -294,7 +294,7 @@ Example output:
294
294
  ```
295
295
 
296
296
  ### Execute Scripts
297
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
297
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Client#execute_script-instance_method)
298
298
 
299
299
  Scripts allow you to write arbitrary non-mutating Cadence code on the Flow blockchain and return data. You can learn more about [Cadence and scripts here](https://docs.onflow.org/cadence/language/), but we are now only interested in executing the script code and getting back the data.
300
300
 
@@ -312,7 +312,7 @@ script = %{
312
312
  }
313
313
  }
314
314
 
315
- args = [{ type: 'Int', value: "1" }.to_json]
315
+ args = [FlowClient::CadenceType.Int(1)]
316
316
  res = client.execute_script(script, args)
317
317
  ```
318
318
 
@@ -407,7 +407,7 @@ A transaction will be rejected if it is submitted past its expiry block. Flow ca
407
407
  A transaction expires after `600` blocks are committed on top of the reference block, which takes about 10 minutes at average Mainnet block rates.
408
408
 
409
409
  ### Build Transactions
410
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
410
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Transaction)
411
411
 
412
412
  Building a transaction involves setting the required properties explained above and producing a transaction object.
413
413
 
@@ -456,7 +456,7 @@ transaction.arguments = arguments
456
456
  After you have successfully [built a transaction](#build-transactions) the next step in the process is to sign it.
457
457
 
458
458
  ### Sign Transactions
459
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
459
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Transaction)
460
460
 
461
461
  Flow introduces new concepts that allow for more flexibility when creating and signing transactions.
462
462
  Before trying the examples below, we recommend that you read through the [transaction signature documentation](https://docs.onflow.org/concepts/accounts-and-keys/).
@@ -478,7 +478,7 @@ Signatures can be generated more securely using keys stored in a hardware device
478
478
 
479
479
  Simple signature example:
480
480
  ```ruby
481
- account = FlowClient::Account.new(address: 0x01)
481
+ account = client.get_account("0x01")
482
482
  signer = FlowClient::LocalSigner.new("<private key hex>")
483
483
 
484
484
  transaction.proposer_address = account.address
@@ -503,7 +503,7 @@ Flow supports great flexibility when it comes to transaction signing, we can def
503
503
  | `0x01` | 1 | 1.0 |
504
504
 
505
505
  ```ruby
506
- account = FlowClient::Account.new(address: 0x01)
506
+ account = client.get_account("0x01")
507
507
 
508
508
  transaction = FlowClient::Transaction.new
509
509
  transaction.reference_block_id = client.get_latest_block.id
@@ -532,7 +532,7 @@ transaction.add_envelope_signature(account.address, account.keys.first.index, si
532
532
  | `0x01` | 2 | 0.5 |
533
533
 
534
534
  ```ruby
535
- account = FlowClient::Account.new(address: 0x01)
535
+ account = client.get_account("0x01")
536
536
 
537
537
  transaction = FlowClient::Transaction.new
538
538
  transaction.reference_block_id = client.get_latest_block.id
@@ -563,10 +563,10 @@ transaction.add_envelope_signature(account.address, account.keys[1].index, signe
563
563
 
564
564
  ```ruby
565
565
  payer_signer = FlowClient::LocalSigner.new("<private key hex>")
566
- payer_account = FlowClient::Account.new(address: 0x02)
566
+ payer_account = client.get_account("0x02")
567
567
 
568
568
  proposer_signer = FlowClient::LocalSigner.new("<private key hex>")
569
- proposer_account = FlowClient::Account.new(address: 0x01)
569
+ proposer_account = client.get_account("0x01")
570
570
 
571
571
  @transaction = FlowClient::Transaction.new
572
572
  @transaction.reference_block_id = client.get_latest_block.id
@@ -599,10 +599,10 @@ proposer_account = FlowClient::Account.new(address: 0x01)
599
599
 
600
600
  ```ruby
601
601
  payer_signer = FlowClient::LocalSigner.new("<private key hex>")
602
- payer_account = FlowClient::Account.new(address: 0x02)
602
+ payer_account = client.get_account("0x02")
603
603
 
604
604
  proposer_signer = FlowClient::LocalSigner.new("<private key hex>")
605
- proposer_account = FlowClient::Account.new(address: 0x01)
605
+ proposer_account = client.get_account("0x01")
606
606
 
607
607
  @transaction = FlowClient::Transaction.new
608
608
  @transaction.reference_block_id = client.get_latest_block.id
@@ -637,10 +637,10 @@ proposer_account = FlowClient::Account.new(address: 0x01)
637
637
 
638
638
  ```ruby
639
639
  payer_signer = FlowClient::LocalSigner.new("<private key hex>")
640
- payer_account = FlowClient::Account.new(address: 0x02)
640
+ payer_account = client.get_account("0x02")
641
641
 
642
642
  proposer_signer = FlowClient::LocalSigner.new("<private key hex>")
643
- proposer_account = FlowClient::Account.new(address: 0x01)
643
+ proposer_account = client.get_account("0x01")
644
644
 
645
645
  @transaction = FlowClient::Transaction.new
646
646
  @transaction.reference_block_id = client.get_latest_block.id
@@ -661,7 +661,7 @@ proposer_account = FlowClient::Account.new(address: 0x01)
661
661
 
662
662
 
663
663
  ### Send Transactions
664
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
664
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Client#send_transaction-instance_method)
665
665
 
666
666
  After a transaction has been [built](#build-transactions) and [signed](#sign-transactions), it can be sent to the Flow blockchain where it will be executed. If sending was successful you can then [retrieve the transaction result](#get-transactions).
667
667
 
@@ -675,7 +675,7 @@ end
675
675
 
676
676
 
677
677
  ### Create Accounts
678
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
678
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Client#create_account-instance_method)
679
679
 
680
680
  On Flow, account creation happens inside a transaction. Because the network allows for a many-to-many relationship between public keys and accounts, it's not possible to derive a new account address from a public key offline.
681
681
 
@@ -700,13 +700,13 @@ Account creation happens inside a transaction, which means that somebody must pa
700
700
 
701
701
  ```ruby
702
702
  # The account that will pay for the creation of the new account
703
- account = FlowClient::Account.new(address: "f8d6e0586b0a20c7")
703
+ payer_account = client.get_account("f8d6e0586b0a20c7")
704
704
  # Create an in-memory signer with the payer's private key
705
705
  signer = FlowClient::LocalSigner.new("4d9287571c8bff7482ffc27ef68d5b4990f9bd009a1e9fa812aae08ba167d57f")
706
706
  # Generate a public key for the new account
707
707
  _private_key, public_key = FlowClient::Crypto.generate_key_pair(FlowClient::Crypto::Curves::P256)
708
708
  # Create the account
709
- res = client.create_account([public_key], { "ContractName": "<contract cadence code>" }, account, signer)
709
+ res = client.create_account([public_key], { "ContractName": "<contract cadence code>" }, payer_account, signer)
710
710
  ```
711
711
 
712
712
  ```ruby
@@ -726,7 +726,7 @@ res.address
726
726
  ```
727
727
 
728
728
  ### Generate Keys
729
- [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://github.com/glucode/flow_client)
729
+ [<img src="https://raw.githubusercontent.com/onflow/sdks/main/templates/documentation/ref.svg" width="130">](https://www.rubydoc.info/gems/flow_client/FlowClient/Crypto#generate_key_pair-class_method)
730
730
 
731
731
  Flow uses [ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) signatures to control access to user accounts. Each key pair can be used in combination with the `SHA2-256` or `SHA3-256` hashing algorithms.
732
732
 
@@ -744,4 +744,4 @@ The example above uses an ECDSA key pair on the P-256 (secp256r1) elliptic curve
744
744
 
745
745
  ```ruby
746
746
  private_key, public_key = FlowClient::Crypto.generate_key_pair(FlowClient::Crypto::Curves::SECP256K1)
747
- ```
747
+ ```
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flow_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nico du Plessis
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-08 00:00:00.000000000 Z
11
+ date: 2021-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grpc
@@ -94,7 +94,6 @@ files:
94
94
  - CHANGELOG.md
95
95
  - CODE_OF_CONDUCT.md
96
96
  - Gemfile
97
- - Gemfile.lock
98
97
  - Guardfile
99
98
  - LICENSE.txt
100
99
  - README.md
@@ -156,7 +155,7 @@ metadata:
156
155
  homepage_uri: https://github.com/glucode/flow_client
157
156
  source_code_uri: https://github.com/glucode/flow_client
158
157
  changelog_uri: https://github.com/glucode/flow_client
159
- post_install_message:
158
+ post_install_message:
160
159
  rdoc_options: []
161
160
  require_paths:
162
161
  - lib
@@ -171,8 +170,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
171
170
  - !ruby/object:Gem::Version
172
171
  version: '0'
173
172
  requirements: []
174
- rubygems_version: 3.2.15
175
- signing_key:
173
+ rubygems_version: 3.0.3.1
174
+ signing_key:
176
175
  specification_version: 4
177
176
  summary: A Ruby client for the Flow blockchain
178
177
  test_files: []
data/Gemfile.lock DELETED
@@ -1,108 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- flow_client (0.2.0)
5
- grpc
6
- grpc-tools
7
- json
8
- openssl
9
- rlp
10
-
11
- GEM
12
- remote: https://rubygems.org/
13
- specs:
14
- ast (2.4.2)
15
- coderay (1.1.3)
16
- diff-lcs (1.4.4)
17
- ffi (1.15.4)
18
- formatador (0.3.0)
19
- google-protobuf (3.19.1-x86_64-darwin)
20
- googleapis-common-protos-types (1.3.0)
21
- google-protobuf (~> 3.14)
22
- grpc (1.41.0-universal-darwin)
23
- google-protobuf (~> 3.17)
24
- googleapis-common-protos-types (~> 1.0)
25
- grpc-tools (1.41.0)
26
- guard (2.18.0)
27
- formatador (>= 0.2.4)
28
- listen (>= 2.7, < 4.0)
29
- lumberjack (>= 1.0.12, < 2.0)
30
- nenv (~> 0.1)
31
- notiffany (~> 0.0)
32
- pry (>= 0.13.0)
33
- shellany (~> 0.0)
34
- thor (>= 0.18.1)
35
- guard-compat (1.2.1)
36
- guard-rspec (4.7.3)
37
- guard (~> 2.1)
38
- guard-compat (~> 1.1)
39
- rspec (>= 2.99.0, < 4.0)
40
- ipaddr (1.2.3)
41
- json (2.6.1)
42
- listen (3.7.0)
43
- rb-fsevent (~> 0.10, >= 0.10.3)
44
- rb-inotify (~> 0.9, >= 0.9.10)
45
- lumberjack (1.2.8)
46
- method_source (1.0.0)
47
- nenv (0.3.0)
48
- notiffany (0.1.3)
49
- nenv (~> 0.1)
50
- shellany (~> 0.0)
51
- openssl (2.2.1)
52
- ipaddr
53
- parallel (1.21.0)
54
- parser (3.0.2.0)
55
- ast (~> 2.4.1)
56
- pry (0.14.1)
57
- coderay (~> 1.1)
58
- method_source (~> 1.0)
59
- rainbow (3.0.0)
60
- rake (13.0.6)
61
- rb-fsevent (0.11.0)
62
- rb-inotify (0.10.1)
63
- ffi (~> 1.0)
64
- regexp_parser (2.1.1)
65
- rexml (3.2.5)
66
- rlp (0.7.3)
67
- rspec (3.10.0)
68
- rspec-core (~> 3.10.0)
69
- rspec-expectations (~> 3.10.0)
70
- rspec-mocks (~> 3.10.0)
71
- rspec-core (3.10.1)
72
- rspec-support (~> 3.10.0)
73
- rspec-expectations (3.10.1)
74
- diff-lcs (>= 1.2.0, < 2.0)
75
- rspec-support (~> 3.10.0)
76
- rspec-mocks (3.10.2)
77
- diff-lcs (>= 1.2.0, < 2.0)
78
- rspec-support (~> 3.10.0)
79
- rspec-support (3.10.2)
80
- rubocop (1.22.1)
81
- parallel (~> 1.10)
82
- parser (>= 3.0.0.0)
83
- rainbow (>= 2.2.2, < 4.0)
84
- regexp_parser (>= 1.8, < 3.0)
85
- rexml
86
- rubocop-ast (>= 1.12.0, < 2.0)
87
- ruby-progressbar (~> 1.7)
88
- unicode-display_width (>= 1.4.0, < 3.0)
89
- rubocop-ast (1.12.0)
90
- parser (>= 3.0.1.1)
91
- ruby-progressbar (1.11.0)
92
- shellany (0.0.1)
93
- thor (1.1.0)
94
- unicode-display_width (2.1.0)
95
-
96
- PLATFORMS
97
- x86_64-darwin-20
98
- x86_64-linux
99
-
100
- DEPENDENCIES
101
- flow_client!
102
- guard-rspec (~> 4.7)
103
- rake (~> 13.0)
104
- rspec (~> 3.0)
105
- rubocop (~> 1.22)
106
-
107
- BUNDLED WITH
108
- 2.2.26