ic_agent 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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