ic_agent 0.1.2 → 0.1.4

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: afda8300e3e7767519eb7322d27268d5f486b0201131ef5de7ae786ae9385239
4
- data.tar.gz: fc2baeee2c47d76345dfc64d668dd5bd6d68f81a4113aae7b07865f85ba8062d
3
+ metadata.gz: 872963d331d311c6a940f64445ef0583397885eb9455464f4d865d325f24ee97
4
+ data.tar.gz: 8b11f6cc71864468b52e66a6577fb3002bcf14cfde2ce93b1dfb6f819eb1df84
5
5
  SHA512:
6
- metadata.gz: c1fa506bb6e618bfe3f0995b1127c14030a4000fb4b07ee40e0af976d968b5d441c4564ee92bd2c877c9b47430f772a671c245467dc15959ff986ec94fb30723
7
- data.tar.gz: e8cf412aeac35f7b37c8fb2a396e0a6d0aa98424e32bc9aadf7f3d84e18a691c8c5cb41f898b458612012bcb6413d82c573e260606b63c5d5b79e7c98b0654ec
6
+ metadata.gz: 5ead16aeb03ac87caa4620ee9f813e7d79399f95d9cb2424cbedd2af828f9dd06f14a1f9d200ac596783ea3b47fdd88f500256608e972011e1dae01e69452cf4
7
+ data.tar.gz: d6ebbda49c03f1e2df8fe3e28ffd2b53424a83e04b386841f8874c6b888f4089d8c0150194930ffdab836e81961cfc657168a6e225e0ddd32c665d03159e1cc3
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ic_agent (0.1.2)
4
+ ic_agent (0.1.4)
5
5
  base32 (~> 0.3.4)
6
6
  bitcoin-ruby (~> 0.0.20)
7
7
  cbor (~> 0.5.9.6)
data/README.md CHANGED
@@ -13,11 +13,13 @@ gem install ic_agent
13
13
 
14
14
  ### Features
15
15
 
16
- 1. candid types encode & decode
17
- 2. support secp256k1 & ed25519 identity, pem file import
18
- 3. canister DID file parsing
19
- 4. canister class, initialized with canister id and DID file
20
- 5. common canister interfaces: ledger, management, nns, cycles wallet
16
+ 1. principal create and generate
17
+ 2. candid types encode & decode
18
+ 3. support secp256k1 & ed25519 identity
19
+ 4. canister DID file parsing
20
+ 5. canister class, initialized with canister id and DID file
21
+ 6. common canister interfaces: ledger, management, nns, cycles wallet
22
+ 7. BLS Verify
21
23
 
22
24
  ### Modules & Usage
23
25
 
@@ -140,7 +142,27 @@ subnet_public_key = IcAgent::SyetemState.subnet_public_key(agent, "gvbup-jyaaa-a
140
142
  Create a canister instance with candid interface file and canister id, and call canister method with canister instance:
141
143
 
142
144
  ```ruby
143
- gov_canister = IcAgent::Canister.new(@agent, @gov_canister_id, @gov_didl)
145
+ agent = IcAgent::Agent.new(iden, client)
146
+ gov_canister_id = 'rrkah-fqaaa-aaaaa-aaaaq-cai'
147
+ gov_didl = <<~DIDL_DOC
148
+ // type
149
+ type AccountIdentifier = record { hash : vec nat8 };
150
+ type Action = variant {
151
+ RegisterKnownNeuron : KnownNeuron;
152
+ ManageNeuron : ManageNeuron;
153
+ ExecuteNnsFunction : ExecuteNnsFunction;
154
+ RewardNodeProvider : RewardNodeProvider;
155
+ SetDefaultFollowees : SetDefaultFollowees;
156
+ RewardNodeProviders : RewardNodeProviders;
157
+ ManageNetworkEconomics : NetworkEconomics;
158
+ ApproveGenesisKyc : ApproveGenesisKyc;
159
+ AddOrRemoveNodeProvider : AddOrRemoveNodeProvider;
160
+ Motion : Motion;
161
+ };
162
+ ......
163
+ DIDL_DOC
164
+
165
+ gov_canister = IcAgent::Canister.new(agent, gov_canister_id, gov_didl)
144
166
  res = gov_canister.get_neuron_ids()
145
167
  ```
146
168
 
@@ -153,34 +153,10 @@ module IcAgent
153
153
  end
154
154
 
155
155
  def self.get_params_refer_values(type_str)
156
- pure_child_code, replaced_hash = replace_multi_type(type_str)
157
- key_index = 0
158
- value_arr = []
159
- pure_child_arr = pure_child_code.strip.split(';').map(&:strip).collect { |item| item.gsub('{', '').gsub('}', '') }.reject(&:empty?)
160
- pure_child_arr.each do |item|
161
- _, item_value = get_record_key_value(item, ':', key_index)
162
- value_arr << item_value.split(' ')
163
- key_index += 1
164
- end
165
-
166
- replaced_hash.each_key do |key|
167
- item_type = key.index('record') ? 'record' : 'variant'
168
- item_arr = replaced_hash[key].sub('record', '').sub('variant', '').strip.split(';').map(&:strip).collect { |item| item.gsub('{', '').gsub('}', '') }.reject(&:empty?)
169
- item_arr.each do |item|
170
- multi_item_arr = item.strip.split(':')
171
- if multi_item_arr.size > 1
172
- item_value_arr = multi_item_arr[1].strip.split(' ').collect { |v| v.strip.gsub(';', '') }
173
- item_value_arr.delete('{')
174
- item_value_arr.delete('}')
175
- item_value_arr.delete('{}')
176
- value_arr << item_value_arr
177
- else
178
- value_arr << multi_item_arr[0].strip if item_type == 'record'
179
- end
180
- end
181
- value_arr.delete(key)
182
- end
183
- value_arr.flatten.uniq - IcAgent::Candid::ALL_TYPES - replaced_hash.keys
156
+ parser = IcAgent::Ast::StatementParser.new
157
+ parser.parse(type_str)
158
+ refer_type = parser.source_tree.content[:refer_type]
159
+ refer_type
184
160
  end
185
161
 
186
162
  def self.recover_type(type_str, multi_types)
@@ -90,19 +90,19 @@ grammar DIDGrammar
90
90
  end
91
91
 
92
92
  rule service_item
93
- space? service_method_name space? ":" space? "(" service_method_params? ")" space? "->" space? "(" service_method_return_type ")" space? method_query? ';' end_of_line? <IcAgent::Ast::Nodes::IcServiceItem>
93
+ space? service_method_name space? ":" space? "(" service_method_params? ")" space? "->" space? "(" service_method_return_type? ")" space? method_query? ';' end_of_line? <IcAgent::Ast::Nodes::IcServiceItem>
94
94
  end
95
95
 
96
96
  rule service_method_params
97
97
  source_coding (", " source_coding)* <IcAgent::Ast::Nodes::IcServiceMethodParams>
98
98
  end
99
99
 
100
- rule source_coding
101
- [a-zA-Z0-9_{}:;\n ]*
100
+ rule service_method_return_type
101
+ source_coding (", " source_coding)* <IcAgent::Ast::Nodes::IcServiceMethodReturn>
102
102
  end
103
103
 
104
- rule service_method_return_type
105
- [a-zA-Z0-9_{}:;\n ]* <IcAgent::Ast::Nodes::IcServiceMethodReturn>
104
+ rule source_coding
105
+ [a-zA-Z0-9_{}:;\n ]*
106
106
  end
107
107
 
108
108
  rule method_query
@@ -11,8 +11,12 @@ grammar TypeGrammar
11
11
  base_type_base / base_type_vec / base_type_record / base_type_record_null / base_type_variant / base_type_opt / base_type_func / base_type_code
12
12
  end
13
13
 
14
- rule statement_content
15
- (ic_base_type)+ <IcAgent::Ast::Nodes::StatementContent>
14
+ rule record_statement_content
15
+ (ic_base_type_pair / ic_base_type_value)* <IcAgent::Ast::Nodes::StatementContent>
16
+ end
17
+
18
+ rule variant_statement_content
19
+ (ic_base_type_pair / ic_base_type_key)* <IcAgent::Ast::Nodes::StatementContent>
16
20
  end
17
21
 
18
22
  rule base_type
@@ -24,8 +28,16 @@ grammar TypeGrammar
24
28
  'bool' / 'text' / 'null' / 'reserved' / 'empty' / 'principal' / 'nat8' / 'nat16' / 'nat32' / 'nat64' / 'int8' / 'int16' / 'int32' / 'int64' / 'float32' / 'float64' / 'nat' / 'int' / 'blob'
25
29
  end
26
30
 
27
- rule ic_base_type
28
- space? base_type_key space? base_type_value? optional_semicolon <IcAgent::Ast::Nodes::IcBaseTypeChild>
31
+ rule ic_base_type_pair
32
+ space? base_type_key space? ':' space? base_type_value ';'? <IcAgent::Ast::Nodes::IcBaseTypeChild>
33
+ end
34
+
35
+ rule ic_base_type_key
36
+ space? base_type_key space? ';'? <IcAgent::Ast::Nodes::IcBaseTypeChild>
37
+ end
38
+
39
+ rule ic_base_type_value
40
+ base_type_value space? ';'? <IcAgent::Ast::Nodes::IcBaseTypeChild>
29
41
  end
30
42
 
31
43
  rule base_type_base
@@ -41,7 +53,7 @@ grammar TypeGrammar
41
53
  end
42
54
 
43
55
  rule base_type_value
44
- (':' space ic_all_type)* <IcAgent::Ast::Nodes::IcBaseTypeValue>
56
+ space? ic_all_type <IcAgent::Ast::Nodes::IcBaseTypeValue>
45
57
  end
46
58
 
47
59
  rule base_type_vec
@@ -53,7 +65,7 @@ grammar TypeGrammar
53
65
  end
54
66
 
55
67
  rule base_type_record
56
- 'record' space '{' space_and_line statement_content space_and_line '}' <IcAgent::Ast::Nodes::IcBaseTypeRecord>
68
+ 'record' space '{' space_and_line? record_statement_content space_and_line? '}' <IcAgent::Ast::Nodes::IcBaseTypeRecord>
57
69
  end
58
70
 
59
71
  rule base_type_record_null
@@ -61,7 +73,7 @@ grammar TypeGrammar
61
73
  end
62
74
 
63
75
  rule base_type_variant
64
- 'variant' space '{' space_and_line statement_content space_and_line '}' <IcAgent::Ast::Nodes::IcBaseTypeVariant>
76
+ 'variant' space '{' space_and_line variant_statement_content space_and_line '}' <IcAgent::Ast::Nodes::IcBaseTypeVariant>
65
77
  end
66
78
 
67
79
  rule base_type_func
@@ -19,6 +19,10 @@ module IcAgent
19
19
  def elements_to_s
20
20
  elements.map(&:to_s).join("\n")
21
21
  end
22
+
23
+ def source_content
24
+ self.text_value.strip
25
+ end
22
26
  end
23
27
 
24
28
  class Instruction < NamedNode
@@ -57,11 +61,11 @@ module IcAgent
57
61
  end
58
62
 
59
63
  def type_param_name
60
- elements[0].text_value
64
+ elements[0].source_content
61
65
  end
62
66
 
63
67
  def type_param_content
64
- elements[1].text_value.gsub("\n", '').gsub(';}', '}')
68
+ elements[1].source_content.gsub("\n", '').gsub(';}', '}')
65
69
  end
66
70
 
67
71
  def type_root_opt_code
@@ -0,0 +1,22 @@
1
+ grammar RecordParser
2
+ # record { key1: text; key2: 42; value1; value2; }
3
+ rule record
4
+ 'record' space '{' space? (pair / value)* space? '}' <IcAgent::Ast::Nodes::IcBaseTypeRecord>
5
+ end
6
+
7
+ rule pair
8
+ space? identifier space? ':' space? identifier ';' <IcAgent::Ast::Nodes::IcBaseTypeChild>
9
+ end
10
+
11
+ rule value
12
+ space? identifier ';' <IcAgent::Ast::Nodes::IcBaseTypeChild>
13
+ end
14
+
15
+ rule identifier
16
+ [a-zA-Z0-9_]*
17
+ end
18
+
19
+ rule space
20
+ [\s]+
21
+ end
22
+ end
@@ -29,9 +29,9 @@ module IcAgent
29
29
  tree = @parser.parse(data)
30
30
  raise Exception, "Parse error at offset: #{@parser.index} #{@parser.failure_reason}" if tree.nil?
31
31
 
32
-
33
32
  # this edits the tree in place
34
33
  clean_tree(tree)
34
+
35
35
  # generate soure tree
36
36
  gen_source_tree(tree)
37
37
  @tree = tree
@@ -64,8 +64,16 @@ module IcAgent
64
64
 
65
65
  # set refer_type
66
66
  unless Regexp.union(REFER_TYPE_KEYS) === root_node.source_content
67
- param_arr = root_node.source_content.strip.split(' ').collect { |v| v.strip.gsub(';', '') }
68
- param_arr = param_arr - IcAgent::Candid::ALL_TYPES
67
+ # func type content
68
+ if root_node.source_content.index('->')
69
+ param_arr = []
70
+ temp_param_arr = root_node.source_content.strip.split(' ').collect { |v| v.strip.gsub(';', '') }
71
+ temp_param_arr.delete_if {|v| !v.index('(') && !v.index(')') }
72
+ temp_param_arr.each {|v| param_arr = param_arr + v.sub('(', '').sub(')', '').split(',')}
73
+ else
74
+ param_arr = root_node.source_content.strip.split(' ').collect { |v| v.strip.gsub(';', '') }
75
+ param_arr = param_arr - IcAgent::Candid::ALL_TYPES
76
+ end
69
77
  tree_root_node.content[:refer_type] = (tree_root_node.content[:refer_type] + param_arr).uniq
70
78
  end
71
79
 
@@ -0,0 +1,21 @@
1
+ grammar VariantParser
2
+ rule variant
3
+ 'variant' space? '{' space? (pair / key)* space? '}' <IcAgent::Ast::Nodes::IcBaseTypeVariant>
4
+ end
5
+
6
+ rule pair
7
+ space? identifier space? ':' space? identifier ';' <IcAgent::Ast::Nodes::IcBaseTypeChild>
8
+ end
9
+
10
+ rule key
11
+ space? identifier ';' <IcAgent::Ast::Nodes::IcBaseTypeChild>
12
+ end
13
+
14
+ rule identifier
15
+ [a-zA-Z0-9_]*
16
+ end
17
+
18
+ rule space
19
+ [\s]+
20
+ end
21
+ end
@@ -33,9 +33,14 @@ module IcAgent
33
33
  args_arr.each do |arg|
34
34
  args_type_arrs << get_param_to_ic_type(parser, arg)
35
35
  end
36
- ret_type = get_param_to_ic_type(parser, rets)
37
36
 
38
- add_caniter_method(method_name, args, args_type_arrs, ret_type, anno)
37
+ rets_arr = rets.nil? ? [] : rets.split(',').map(&:strip)
38
+ rets_type_arr = []
39
+ rets_arr.each do |ret|
40
+ rets_type_arr << get_param_to_ic_type(parser, ret)
41
+ end
42
+
43
+ add_caniter_method(method_name, args, args_type_arrs, rets_type_arr, anno)
39
44
  end
40
45
  end
41
46
 
@@ -183,14 +188,11 @@ module IcAgent
183
188
  refer_type.empty? ? nil : refer_type[0]
184
189
  end
185
190
 
186
- def only_refer_type?(param)
187
- refer_types = IcAgent::Ast::Assembler.get_params_refer_values(param)
188
- param.index(' ').nil? && refer_types.size == 1
189
- end
190
-
191
191
  def get_param_to_ic_type(parser, param)
192
192
  ic_refer_types = {}
193
193
  refer_types = IcAgent::Ast::Assembler.get_params_refer_values(param)
194
+ # param self is refer_values
195
+ refer_types << param unless param.index(' ') || IcAgent::Candid::ALL_TYPES.any?(param)
194
196
  refer_types.each do |refer_code|
195
197
  ic_refer_types[refer_code] = build_param_tree(parser, refer_code, nil, nil).content[:ic_type]
196
198
  end
@@ -235,14 +237,14 @@ module IcAgent
235
237
  new_root_text
236
238
  end
237
239
 
238
- def add_caniter_method(method_name, type_args, args_types, rets_type, anno = nil)
240
+ def add_caniter_method(method_name, type_args, args_types, rets_types, anno = nil)
239
241
  self.class.class_eval do
240
242
  define_method(method_name) do |*args|
241
243
  init_method_name = method_name
242
244
  init_method_args = type_args.nil? ? [] : type_args.split(',').map(&:strip)
243
245
  init_method_anno = anno
244
246
  init_method_types = args_types
245
- init_method_ret_type = rets_type
247
+ init_method_ret_type = rets_types
246
248
 
247
249
  if init_method_args.length != args.length
248
250
  raise ArgumentError, 'Arguments length not match'
@@ -228,7 +228,7 @@ module IcAgent
228
228
  wallet_balance128: () -> (record { amount: nat }) query;
229
229
  wallet_send: (record { canister: principal; amount: nat64 }) -> (WalletResult);
230
230
  wallet_send128: (record { canister: principal; amount: nat }) -> (WalletResult);
231
- wallet_receive: (opt ReceiveOptions) -> (); // Endpoint for receiving cycles.
231
+ wallet_receive: (opt ReceiveOptions) -> ();
232
232
  wallet_create_canister: (CreateCanisterArgs) -> (WalletResultCreate);
233
233
  wallet_create_canister128: (CreateCanisterArgs128) -> (WalletResultCreate);
234
234
  wallet_create_wallet: (CreateCanisterArgs) -> (WalletResultCreate);
@@ -248,9 +248,7 @@ module IcAgent
248
248
  args: blob;
249
249
  cycles: nat;
250
250
  }) -> (WalletResultCall);
251
- add_address: (address: AddressEntry) -> ();
252
251
  list_addresses: () -> (vec AddressEntry) query;
253
- remove_address: (address: principal) -> (WalletResult);
254
252
  get_events: (opt record { from: opt nat32; to: opt nat32; }) -> (vec Event) query;
255
253
  get_events128: (opt record { from: opt nat32; to: opt nat32; }) -> (vec Event128) query;
256
254
  get_chart: (opt record { count: opt nat32; precision: opt nat64; } ) -> (vec record { nat64; nat64; }) query;
@@ -258,7 +256,6 @@ module IcAgent
258
256
  get_managed_canister_events: (record { canister: principal; from: opt nat32; to: opt nat32; }) -> (opt vec ManagedCanisterEvent) query;
259
257
  get_managed_canister_events128: (record { canister: principal; from: opt nat32; to: opt nat32; }) -> (opt vec ManagedCanisterEvent128) query;
260
258
  set_short_name: (principal, opt text) -> (opt ManagedCanisterInfo);
261
- http_request: (request: HttpRequest) -> (HttpResponse) query;
262
259
  }
263
260
  DIDL_DOC
264
261
 
@@ -72,7 +72,7 @@ module IcAgent
72
72
  end
73
73
 
74
74
  def to_account_id(sub_account = 0)
75
- AccountIdentifier.new(self, sub_account)
75
+ AccountIdentifier.generate(self, sub_account)
76
76
  end
77
77
 
78
78
  def to_s
@@ -97,11 +97,12 @@ module IcAgent
97
97
  to_str
98
98
  end
99
99
 
100
- def self.new(principal, sub_account = 0)
101
- sha224 = Digest::SHA224.new
100
+ def self.generate(principal, sub_account = 0)
101
+ sha224 = OpenSSL::Digest::SHA224.new
102
102
  sha224 << "\naccount-id"
103
103
  sha224 << principal.bytes
104
- sub_account = [sub_account].pack('N')
104
+ format_sub_account = "%08d" % sub_account
105
+ sub_account = format_sub_account.chars.map {|c| c.to_i}.pack('N*')
105
106
  sha224 << sub_account
106
107
  hash = sha224.digest
107
108
  checksum = Zlib.crc32(hash) & 0xFFFFFFFF
@@ -66,6 +66,10 @@ module IcAgent
66
66
  s = vec.sort.join
67
67
  Digest::SHA256.digest(s)
68
68
  end
69
+
70
+ def self.decode_blob(blob_bytes)
71
+ blob_bytes.pack('C*')
72
+ end
69
73
  end
70
74
  end
71
75
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IcAgent
4
- VERSION = '0.1.2'
4
+ VERSION = '0.1.4'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ic_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Terry.Tu
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-15 00:00:00.000000000 Z
11
+ date: 2023-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base32
@@ -247,7 +247,9 @@ files:
247
247
  - lib/ic_agent/ast/nodes/statement_nodes.rb
248
248
  - lib/ic_agent/ast/nodes/string_literal.rb
249
249
  - lib/ic_agent/ast/parser.rb
250
+ - lib/ic_agent/ast/record_parser.treetop
250
251
  - lib/ic_agent/ast/statement_parser.rb
252
+ - lib/ic_agent/ast/variant_parser.treetop
251
253
  - lib/ic_agent/ast/writer.rb
252
254
  - lib/ic_agent/candid.rb
253
255
  - lib/ic_agent/canister.rb