tezos_client 1.1.1 → 1.2.2

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: 6de17ecf9250b846d61ac7c09163ae7d724bbf2cef921accfb363c17642d09bd
4
- data.tar.gz: eceb944bc3de48585b37adb47d9004193b3b96b6803071ccb543c969d8d11888
3
+ metadata.gz: a1459f7dd534e408bd13520b14789b9f719a6cec9b004f5ab3ca00c151da1ac4
4
+ data.tar.gz: 2aa7c36fc10c82537de03593e592703274daedcff36edec84130c98cc385098f
5
5
  SHA512:
6
- metadata.gz: af341ffed833a6f8683653b96f8a3cbc0b9397e7b5d56e734a6a528f96904c2ec45d252bd05be6ea8f009a54b55cc7d758784006c99c393ac3d4871913aeede9
7
- data.tar.gz: 4a0ae7f0d075caace39047dcc9a012811484a0569a86223a508e8bb8fbbad578456bea5852c3243ff1b99ec4fdbc847abefd8dddaa24d3dd5e6490fb1e44323a
6
+ metadata.gz: fa9dc95f337c4bbbda410392c03d6305c93ee8f4dfec1810f629c0143a4beb3ce88789f5c4eaa809ae572bb4871ad44b0e87d35071727f9800cc9167f290492f
7
+ data.tar.gz: e625840ea65befc0adc6ece5e334d8e869daabbaa2e6a9fc51881dda0ba3971dcec2f0d3274968e07a7e9268e1af93469c1f70f1395fa3d773119e871ab55f2a
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tezos_client (1.1.1)
4
+ tezos_client (1.2.2)
5
5
  active_interaction (~> 3.7)
6
6
  activesupport (~> 6.0.0)
7
7
  base58 (~> 0.2.3)
@@ -14,68 +14,68 @@ PATH
14
14
  GEM
15
15
  remote: https://rubygems.org/
16
16
  specs:
17
- actionpack (6.0.0)
18
- actionview (= 6.0.0)
19
- activesupport (= 6.0.0)
20
- rack (~> 2.0)
17
+ actionpack (6.0.3.2)
18
+ actionview (= 6.0.3.2)
19
+ activesupport (= 6.0.3.2)
20
+ rack (~> 2.0, >= 2.0.8)
21
21
  rack-test (>= 0.6.3)
22
22
  rails-dom-testing (~> 2.0)
23
23
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
24
- actionview (6.0.0)
25
- activesupport (= 6.0.0)
24
+ actionview (6.0.3.2)
25
+ activesupport (= 6.0.3.2)
26
26
  builder (~> 3.1)
27
27
  erubi (~> 1.4)
28
28
  rails-dom-testing (~> 2.0)
29
29
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
30
- active_interaction (3.7.1)
30
+ active_interaction (3.8.2)
31
31
  activemodel (>= 4, < 7)
32
- activemodel (6.0.0)
33
- activesupport (= 6.0.0)
34
- activesupport (6.0.0)
32
+ activemodel (6.0.3.2)
33
+ activesupport (= 6.0.3.2)
34
+ activesupport (6.0.3.2)
35
35
  concurrent-ruby (~> 1.0, >= 1.0.2)
36
36
  i18n (>= 0.7, < 2)
37
37
  minitest (~> 5.1)
38
38
  tzinfo (~> 1.1)
39
- zeitwerk (~> 2.1, >= 2.1.8)
39
+ zeitwerk (~> 2.2, >= 2.2.2)
40
40
  addressable (2.7.0)
41
41
  public_suffix (>= 2.0.2, < 5.0)
42
42
  ast (2.4.0)
43
43
  base58 (0.2.3)
44
44
  bip_mnemonic (0.0.4)
45
- builder (3.2.3)
45
+ builder (3.2.4)
46
46
  coderay (1.1.2)
47
- concurrent-ruby (1.1.5)
47
+ concurrent-ruby (1.1.6)
48
48
  crack (0.4.3)
49
49
  safe_yaml (~> 1.0.0)
50
- crass (1.0.5)
50
+ crass (1.0.6)
51
51
  diff-lcs (1.3)
52
52
  domain_name (0.5.20190701)
53
53
  unf (>= 0.0.5, < 1.0.0)
54
54
  erubi (1.9.0)
55
- ffi (1.12.2)
55
+ ffi (1.13.1)
56
56
  hashdiff (1.0.0)
57
57
  http-cookie (1.0.3)
58
58
  domain_name (~> 0.5)
59
59
  httparty (0.17.3)
60
60
  mime-types (~> 3.0)
61
61
  multi_xml (>= 0.5.2)
62
- i18n (1.7.0)
62
+ i18n (1.8.3)
63
63
  concurrent-ruby (~> 1.0)
64
64
  jaro_winkler (1.5.3)
65
- loofah (2.3.1)
65
+ loofah (2.6.0)
66
66
  crass (~> 1.0.2)
67
67
  nokogiri (>= 1.5.9)
68
68
  method_source (0.9.2)
69
69
  mime-types (3.3.1)
70
70
  mime-types-data (~> 3.2015)
71
- mime-types-data (3.2019.1009)
71
+ mime-types-data (3.2020.0512)
72
72
  mini_portile2 (2.4.0)
73
- minitest (5.13.0)
73
+ minitest (5.14.1)
74
74
  money-tree (0.10.0)
75
75
  ffi
76
76
  multi_xml (0.6.0)
77
77
  netrc (0.11.0)
78
- nokogiri (1.10.8)
78
+ nokogiri (1.10.9)
79
79
  mini_portile2 (~> 2.4.0)
80
80
  parallel (1.18.0)
81
81
  parser (2.6.5.0)
@@ -84,7 +84,7 @@ GEM
84
84
  coderay (~> 1.1.0)
85
85
  method_source (~> 0.9.0)
86
86
  public_suffix (4.0.1)
87
- rack (2.0.8)
87
+ rack (2.2.3)
88
88
  rack-test (1.1.0)
89
89
  rack (>= 1.0, < 3)
90
90
  rails-dom-testing (2.0.3)
@@ -92,14 +92,14 @@ GEM
92
92
  nokogiri (>= 1.6)
93
93
  rails-html-sanitizer (1.3.0)
94
94
  loofah (~> 2.3)
95
- railties (6.0.0)
96
- actionpack (= 6.0.0)
97
- activesupport (= 6.0.0)
95
+ railties (6.0.3.2)
96
+ actionpack (= 6.0.3.2)
97
+ activesupport (= 6.0.3.2)
98
98
  method_source
99
99
  rake (>= 0.8.7)
100
100
  thor (>= 0.20.3, < 2.0)
101
101
  rainbow (3.0.0)
102
- rake (10.5.0)
102
+ rake (13.0.1)
103
103
  rbnacl (5.0.0)
104
104
  ffi
105
105
  rest-client (2.0.2)
@@ -138,20 +138,20 @@ GEM
138
138
  rubocop-rails (~> 2.0)
139
139
  ruby-progressbar (1.10.1)
140
140
  safe_yaml (1.0.5)
141
- thor (0.20.3)
141
+ thor (1.0.1)
142
142
  thread_safe (0.3.6)
143
- tzinfo (1.2.5)
143
+ tzinfo (1.2.7)
144
144
  thread_safe (~> 0.1)
145
145
  unf (0.1.4)
146
146
  unf_ext
147
- unf_ext (0.0.7.6)
147
+ unf_ext (0.0.7.7)
148
148
  unicode-display_width (1.6.0)
149
149
  vcr (4.0.0)
150
150
  webmock (3.7.6)
151
151
  addressable (>= 2.3.6)
152
152
  crack (>= 0.3.2)
153
153
  hashdiff (>= 0.4.0, < 2.0.0)
154
- zeitwerk (2.2.1)
154
+ zeitwerk (2.3.0)
155
155
 
156
156
  PLATFORMS
157
157
  ruby
@@ -159,7 +159,7 @@ PLATFORMS
159
159
  DEPENDENCIES
160
160
  bundler (~> 1.16)
161
161
  pry
162
- rake (~> 10.0)
162
+ rake (~> 13.0)
163
163
  rspec (~> 3.0)
164
164
  rubocop-rails_config
165
165
  tezos_client!
@@ -36,6 +36,8 @@ require "tezos_client/smartpy_interface"
36
36
 
37
37
  require "tezos_client/tools/convert_to_hash"
38
38
  require "tezos_client/tools/find_big_maps_in_storage"
39
+ require "tezos_client/tools/hash_to_micheline"
40
+ require "tezos_client/tools/annots_to_type"
39
41
 
40
42
  class TezosClient
41
43
  using CurrencyUtils
@@ -22,6 +22,9 @@ class TezosClient
22
22
  :pending_operations,
23
23
  :pack_data,
24
24
  :big_map_value,
25
- :list_big_map_by_contract
25
+ :contract_big_maps,
26
+ :block_operations,
27
+ :contract_storage_type,
28
+ :entrypoint
26
29
  end
27
30
  end
@@ -184,7 +184,8 @@ class TezosClient
184
184
  operations: rpc_operation_args,
185
185
  signature: base_58_signature,
186
186
  protocol: protocol,
187
- branch: branch)
187
+ branch: branch
188
+ )
188
189
 
189
190
  ensure_applied!(rpc_responses)
190
191
 
@@ -201,37 +202,40 @@ class TezosClient
201
202
  end
202
203
 
203
204
  private
204
- def ensure_applied!(rpc_responses)
205
- metadatas = rpc_responses.map { |response| response[:metadata] }
206
- operation_results = metadatas.map { |metadata| metadata[:operation_result] }
207
205
 
208
- failed = operation_results.detect do |operation_result|
209
- operation_result != nil && operation_result[:status] != "applied"
210
- end
206
+ def ensure_applied!(rpc_responses)
207
+ metadatas = rpc_responses.map { |response| response[:metadata] }
208
+ operation_results = metadatas.map { |metadata| metadata[:operation_result] }
209
+ internal_operations = metadatas.map { |metadata| metadata[:internal_operation_results] }.flatten.compact
210
+ operation_results.concat(internal_operations.map { |internal_operation| internal_operation[:result] })
211
211
 
212
- return metadatas if failed.nil?
212
+ failed = operation_results.detect do |operation_result|
213
+ operation_result != nil && operation_result[:status] != "applied"
214
+ end
213
215
 
214
- failed_operation_result = operation_results.detect do |operation_result|
215
- operation_result[:status] == "failed"
216
- end
216
+ return metadatas if failed.nil?
217
217
 
218
- failed!("failed", failed_operation_result[:errors], operation_results)
218
+ failed_operation_result = operation_results.detect do |operation_result|
219
+ operation_result[:status] == "failed"
219
220
  end
220
221
 
221
- def exception_klass(errors)
222
- error = errors[0]
223
- case error[:id]
224
- when TezBalanceTooLow::FIRST_ERROR_REGEXP
225
- TezBalanceTooLow
226
- when ScriptRuntimeError::FIRST_ERROR_REGEXP
227
- ScriptRuntimeError
228
- else
229
- OperationFailure
230
- end
231
- end
222
+ failed!("failed", failed_operation_result[:errors], operation_results)
223
+ end
232
224
 
233
- def failed!(status, errors, metadata)
234
- raise exception_klass(errors).new(metadata: metadata, errors: errors, status: status)
225
+ def exception_klass(errors)
226
+ error = errors[0]
227
+ case error[:id]
228
+ when TezBalanceTooLow::FIRST_ERROR_REGEXP
229
+ TezBalanceTooLow
230
+ when ScriptRuntimeError::FIRST_ERROR_REGEXP
231
+ ScriptRuntimeError
232
+ else
233
+ OperationFailure
235
234
  end
235
+ end
236
+
237
+ def failed!(status, errors, metadata)
238
+ raise exception_klass(errors).new(metadata: metadata, errors: errors, status: status)
239
+ end
236
240
  end
237
- end
241
+ end
@@ -28,20 +28,28 @@ class TezosClient
28
28
  get "#{contract_link(contract_id)}/manager_key"
29
29
  end
30
30
 
31
+ def contract_storage_type(contract_id)
32
+ contract = contract_detail(contract_id)
33
+ contract[:script][:code].find { |elem| elem[:prim] == "storage" }[:args].first
34
+ end
35
+
31
36
  def contract_storage(contract_id)
32
37
  get "#{contract_link(contract_id)}/storage"
33
38
  end
34
39
 
40
+ def entrypoint(contract_id, entrypoint)
41
+ get("#{contract_link(contract_id)}/entrypoints/#{entrypoint}")
42
+ end
43
+
35
44
  def big_map_value(big_map_id:, key:, key_type:)
36
45
  expr_key = encode_script_expr(data: key, type: key_type)
37
46
 
38
47
  get "/chains/main/blocks/head/context/big_maps/#{big_map_id}/#{expr_key}"
39
48
  end
40
49
 
41
- def list_big_map_by_contract(contract_address:)
50
+ def contract_big_maps(contract_address)
42
51
  contract_storage = contract_storage(contract_address)
43
- contract = contract_detail(contract_address)
44
- storage_type = contract[:script][:code].find { |elem| elem[:prim] == "storage" }[:args].first
52
+ storage_type = contract_storage_type(contract_address)
45
53
 
46
54
  TezosClient::Tools::FindBigMapsInStorage.run!(
47
55
  storage: contract_storage,
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient::Tools::AnnotsToType < ActiveInteraction::Base
4
+ # example of typed_annots :
5
+ # {
6
+ # spending_ref: "string",
7
+ # remainder_amount: "nat",
8
+ # expires_at: "timestamp"
9
+ # }
10
+ hash :typed_annots, strip: false
11
+
12
+ validate :validate_types
13
+
14
+ def execute
15
+ return { "prim" => typed_annots.values.first } if typed_annots.size == 1
16
+
17
+ { "prim" => "pair", "args" => generate_type_args(ordered_annots) }
18
+ end
19
+
20
+ private
21
+ def generate_type_args(annots)
22
+ annot = annots.pop
23
+ annot_type = typed_annots[annot]
24
+
25
+ unless annots.size == 1
26
+ return [{ "prim" => "pair", "args" => generate_type_args(annots) },
27
+ { "prim" => annot_type, "annots" => ["%#{annot}"] }]
28
+ end
29
+
30
+ generated_args = [{ "prim" => annot_type, "annots" => ["%#{annot}"] }]
31
+ annot = annots.pop
32
+ annot_type = typed_annots[annot]
33
+ generated_args.unshift({ "prim" => annot_type, "annots" => ["%#{annot}"] })
34
+
35
+ generated_args
36
+ end
37
+
38
+ def ordered_annots
39
+ @ordered_annots ||= typed_annots.keys.sort
40
+ end
41
+
42
+ def validate_types
43
+ allowed_types = TezosClient::Tools::HashToMicheline::TYPES_MAPPING.keys
44
+ return if typed_annots.values.map(&:to_sym).all? { |type| type.in? allowed_types }
45
+
46
+ errors.add(:base, "The allowed types are: #{allowed_types.join(', ')}")
47
+ end
48
+ end
@@ -1,87 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class TezosClient::Tools::ConvertToHash < ActiveInteraction::Base
4
- interface :data
5
- interface :type
3
+ require_relative "convert_to_hash/base"
6
4
 
7
- def execute
8
- case type[:prim]
9
- when "pair"
10
- pair_type(data: data, type: type)
11
- when "list"
12
- list_type(data: data, type: type)
13
- when "int"
14
- int_type(data: data, type: type)
15
- when "nat"
16
- int_type(data: data, type: type)
17
- when "key"
18
- key_type(data: data, type: type)
19
- when "timestamp"
20
- timestamp_type(data: data, type: type)
21
- when "string"
22
- string_type(data: data, type: type)
23
- when "address"
24
- address_type(data: data, type: type)
25
- else
26
- raise "type '#{type[:prim]}' not implemented"
27
- end
28
- end
29
-
30
- private
31
- def pair_type(data:, type:)
32
- raise "Not a 'Pair' type" unless data[:prim] == "Pair"
33
- raise "Difference detected between data and type \nDATA: #{data} \nTYPE:#{type} " unless data[:args].size == type[:args].size
34
-
35
- result = {}
36
- data[:args].size.times do |iter|
37
- result.merge!(
38
- compose(
39
- TezosClient::Tools::ConvertToHash,
40
- data: data[:args][iter],
41
- type: type[:args][iter]
42
- )
43
- )
44
- end
45
- result
46
- end
5
+ Dir[File.join(__dir__, "convert_to_hash", "*.rb")].each { |file| require file }
47
6
 
48
- def list_type(data:, type:)
49
- {
50
- var_name(type) => convert_list_element(data: data, element_type: type[:args].first)
51
- }
52
- end
7
+ class TezosClient
8
+ module Tools
9
+ class ConvertToHash < ActiveInteraction::Base
10
+ interface :data
11
+ interface :type
53
12
 
54
- def convert_list_element(data:, element_type:)
55
- data.map do |elem|
56
- compose(
57
- TezosClient::Tools::ConvertToHash,
58
- data: elem,
59
- type: element_type
60
- )
13
+ def execute
14
+ TezosClient::Tools::ConvertToHash::Base.new(data: data, type: type).value
61
15
  end
62
16
  end
63
-
64
- def int_type(data:, type:)
65
- { var_name(type) => data[:int].to_i }
66
- end
67
-
68
- def key_type(data:, type:)
69
- { var_name(type) => data[:bytes] || data[:string] }
70
- end
71
-
72
- def timestamp_type(data:, type:)
73
- { var_name(type) => Time.zone.at(data[:int].to_i) }
74
- end
75
-
76
- def string_type(data:, type:)
77
- { var_name(type) => data[:string] }
78
- end
79
-
80
- def address_type(data:, type:)
81
- { var_name(type) => data[:bytes] || data[:string] }
82
- end
83
-
84
- def var_name(type)
85
- "#{type[:annots].first[1..-1]}".to_sym
86
- end
17
+ end
87
18
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class ConvertToHash < ActiveInteraction::Base
6
+ class Address < Base
7
+ include TezosClient::Crypto
8
+
9
+ def decode
10
+ if data.key?(:bytes)
11
+ if data[:bytes].start_with?("0000")
12
+ encode_tz(:tz1, data[:bytes][4..-1])
13
+ elsif data[:bytes].start_with?("0001")
14
+ encode_tz(:tz2, data[:bytes][4..-1])
15
+ elsif data[:bytes].start_with?("0002")
16
+ encode_tz(:tz3, data[:bytes][4..-1])
17
+ elsif data[:bytes].start_with?("01")
18
+ encode_tz(:KT, data[:bytes][2..-3])
19
+ else
20
+ data[:bytes]
21
+ end
22
+ else
23
+ data[:string]
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class ConvertToHash < ActiveInteraction::Base
6
+ class Base
7
+ def initialize(data:, type:)
8
+ @data = data
9
+ @type = type
10
+ end
11
+
12
+ attr_accessor :data, :type
13
+
14
+ def value
15
+ anonymous? ? decode : { var_name => decode }
16
+ end
17
+
18
+ protected
19
+ def decode
20
+ klass.new(
21
+ data: data,
22
+ type: type
23
+ ).decode
24
+
25
+ rescue NameError => e
26
+ raise NotImplementedError, "type '#{type[:prim]}' not implemented"
27
+ end
28
+
29
+ def anonymous?
30
+ !(type.key?(:annots) && type[:annots].any?)
31
+ end
32
+
33
+ def var_name_annot
34
+ type[:annots].first
35
+ end
36
+
37
+ def var_name
38
+ return nil if anonymous?
39
+
40
+ "#{var_name_annot[1..-1]}".to_sym
41
+ end
42
+
43
+ private
44
+ def klass
45
+ "TezosClient::Tools::ConvertToHash::#{type[:prim].camelize}".constantize
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ class BigMap < Struct.new(:name, :id, :value_type, :key_type); end
5
+
6
+ module Tools
7
+ class ConvertToHash < ActiveInteraction::Base
8
+ class BigMap < Base
9
+ def decode
10
+ ::TezosClient::BigMap.new(
11
+ var_name,
12
+ data[:int],
13
+ type[:args].second,
14
+ type[:args].first
15
+ )
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class ConvertToHash < ActiveInteraction::Base
6
+ class Bytes < Base
7
+ def decode
8
+ data[:bytes] || data[:string]
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class ConvertToHash < ActiveInteraction::Base
6
+ class Int < Base
7
+ def decode
8
+ data[:int].to_i
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class ConvertToHash < ActiveInteraction::Base
6
+ class Key < Base
7
+ include TezosClient::Crypto
8
+
9
+ def decode
10
+ if data.key?(:bytes)
11
+ if data[:bytes].start_with?("00")
12
+ encode_tz(:edpk, data[:bytes][2..-1])
13
+ elsif data[:bytes].start_with?("01")
14
+ encode_tz(:sppk, data[:bytes][2..-1])
15
+ elsif data[:bytes].start_with?("02")
16
+ encode_tz(:p2pk, data[:bytes][2..-1])
17
+ else
18
+ data[:bytes]
19
+ end
20
+ else
21
+ data[:string]
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class ConvertToHash < ActiveInteraction::Base
6
+ class List < Base
7
+ def decode
8
+ data.map do |elem|
9
+ TezosClient::Tools::ConvertToHash::Base.new(
10
+ data: elem,
11
+ type: elem_type
12
+ ).value
13
+ end
14
+ end
15
+
16
+ def elem_type
17
+ type[:args].first
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class ConvertToHash < ActiveInteraction::Base
6
+ class Map < Base
7
+ def decode
8
+ new_map = {}
9
+
10
+ data.each do |elem|
11
+ raise "Not a 'Map' type" unless elem[:prim] == "Elt"
12
+
13
+ key = TezosClient::Tools::ConvertToHash::Base.new(
14
+ data: elem[:args].first,
15
+ type: type[:args].first
16
+ ).value
17
+
18
+ value = TezosClient::Tools::ConvertToHash::Base.new(
19
+ data: elem[:args].second,
20
+ type: type[:args].second
21
+ ).value
22
+
23
+ new_map[key] = value
24
+ end
25
+
26
+ new_map
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class ConvertToHash < ActiveInteraction::Base
6
+ class Nat < Base
7
+ def decode
8
+ data[:int].to_i
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class ConvertToHash < ActiveInteraction::Base
6
+ class Pair < Base
7
+ def decode
8
+ raise "Not a 'Pair' type" unless data[:prim] == "Pair"
9
+ raise "Difference detected between data and type \nDATA: #{data} \nTYPE:#{type} " unless data[:args].size == type[:args].size
10
+
11
+ (data[:args]).zip(type[:args]).map do |data_n, type_n|
12
+ TezosClient::Tools::ConvertToHash::Base.new(
13
+ data: data_n,
14
+ type: type_n
15
+ ).value
16
+ end.reduce({}, &:merge)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class ConvertToHash < ActiveInteraction::Base
6
+ class Signature < Base
7
+ include TezosClient::Crypto
8
+
9
+ def decode
10
+ if data.key?(:bytes)
11
+ encode_tz(:edsig, data[:bytes])
12
+ else
13
+ data[:string]
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class ConvertToHash < ActiveInteraction::Base
6
+ class String < Base
7
+ def decode
8
+ data[:string]
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class ConvertToHash < ActiveInteraction::Base
6
+ class Timestamp < Base
7
+ def decode
8
+ if data.key? :int
9
+ Time.zone.at(data[:int].to_i)
10
+ elsif data.key? :string
11
+ Time.zone.parse(data[:string])
12
+ else
13
+ raise "Can not convert timestamp: #{data}"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -7,50 +7,19 @@ class TezosClient::Tools::FindBigMapsInStorage < ActiveInteraction::Base
7
7
  strip: false
8
8
 
9
9
  def execute
10
- case storage_type[:prim]
11
- when "pair"
12
- pair_type(data: storage, type: storage_type)
13
- when "list"
14
- list_type(data: storage, type: storage_type)
15
- when "big_map"
16
- big_map_type(data: storage, type: storage_type)
17
- end
18
- end
19
-
20
- def pair_type(data:, type:)
21
- raise "Not a 'Pair' type" unless data[:prim] == "Pair"
22
- raise "Difference detected between data and type \nDATA: #{data} \nTYPE:#{type} " unless data[:args].size == type[:args].size
23
-
24
- (0 .. data[:args].size - 1).map do |iter|
25
- compose(
26
- TezosClient::Tools::FindBigMapsInStorage,
27
- storage: data[:args][iter],
28
- storage_type: type[:args][iter]
29
- )
30
- end.compact.flatten
10
+ hash_storage
11
+ .map(&:last)
12
+ .select { |value| value.is_a? TezosClient::BigMap }
13
+ .map(&:to_h)
14
+ .map(&:with_indifferent_access)
31
15
  end
32
16
 
33
- def list_type(data:, type:)
34
- element_type = type[:args].first
35
- data.map do |elem|
17
+ private
18
+ def hash_storage
36
19
  compose(
37
20
  TezosClient::Tools::ConvertToHash,
38
- data: elem,
39
- type: element_type
21
+ data: storage,
22
+ type: storage_type
40
23
  )
41
24
  end
42
- end
43
-
44
- def big_map_type(data:, type:)
45
- {
46
- name: var_name(type),
47
- id: data[:int],
48
- value_type: type[:args].second,
49
- key_type: type[:args].first
50
- }.with_indifferent_access
51
- end
52
-
53
- def var_name(type)
54
- "#{type[:annots].first[1..-1]}".to_sym
55
- end
56
25
  end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient::Tools::HashToMicheline < ActiveInteraction::Base
4
+ # TODO: handle Arrays and Maps
5
+ TYPES_MAPPING = {
6
+ int: :int,
7
+ nat: :int,
8
+ string: :string,
9
+ signature: :string,
10
+ bytes: :bytes,
11
+ timestamp: :int,
12
+ key: :string,
13
+ address: :string
14
+ }.freeze
15
+
16
+ string :contract_address, default: nil
17
+ string :entrypoint, default: nil
18
+ # example of params:
19
+ # {
20
+ # spending_ref: "toto",
21
+ # expires_at: Time.now
22
+ # }
23
+ hash :params, strip: false
24
+ hash :storage_type, strip: false, default: {}
25
+ interface :blockchain_client, methods: [:entrypoint], default: -> { TezosClient.new }
26
+
27
+ # if storage_type is not received, it is fetched from the blockchain using
28
+ # contract_address and entrypoint (that are mandatory in this case)
29
+ validate :storage_type_or_contract_address_presence
30
+
31
+ def execute
32
+ return hash_type_to_hash_data(_storage_type.fetch(:prim), params.values.first) if params.size == 1
33
+
34
+ { prim: "Pair", args: generate_micheline(_storage_type[:args]) }
35
+ end
36
+
37
+ private
38
+ def generate_micheline(remaining_storage_type)
39
+ remaining_storage_type.each_with_object([]) do |h, acc|
40
+ next acc << { prim: "Pair", args: generate_micheline(h[:args]) } if h[:prim] == "pair"
41
+
42
+ annot = h[:annots].first.slice(1..-1).to_sym # remove '%'
43
+ acc << hash_type_to_hash_data(h[:prim], params.fetch(annot))
44
+ end
45
+ end
46
+
47
+ def convert_type(michelson_type)
48
+ TYPES_MAPPING.fetch(michelson_type.to_sym)
49
+ end
50
+
51
+ def hash_type_to_hash_data(michelson_type, value)
52
+ type = convert_type(michelson_type)
53
+
54
+ converted_value = case michelson_type.to_sym
55
+ when :nat, :int
56
+ value.to_s
57
+ when :timestamp
58
+ errors.add(:base, "timestamp input must be an instance of Time") unless value.is_a? Time
59
+
60
+ value.to_i.to_s
61
+ else
62
+ value
63
+ end
64
+
65
+ { type => converted_value }
66
+ end
67
+
68
+ def _storage_type
69
+ (storage_type.presence || blockchain_client.entrypoint(contract_address, entrypoint)).deep_symbolize_keys
70
+ end
71
+
72
+ def storage_type_or_contract_address_presence
73
+ return if storage_type.present? ^ (contract_address.present? && entrypoint.present?)
74
+
75
+ errors.add(:base,
76
+ "You should provide the contract_address and the entrypoint only if storage_type is not provided")
77
+ end
78
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class TezosClient
4
- VERSION = "1.1.1"
4
+ VERSION = "1.2.2"
5
5
  end
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.require_paths = ["lib"]
35
35
 
36
36
  spec.add_development_dependency "bundler", "~> 1.16"
37
- spec.add_development_dependency "rake", "~> 10.0"
37
+ spec.add_development_dependency "rake", "~> 13.0"
38
38
  spec.add_development_dependency "rspec", "~> 3.0"
39
39
  spec.add_development_dependency "rubocop-rails_config"
40
40
  spec.add_development_dependency "webmock"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tezos_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pierre Michard
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-27 00:00:00.000000000 Z
11
+ date: 2020-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '13.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '13.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -274,8 +274,23 @@ files:
274
274
  - lib/tezos_client/smartpy_inteface/smartpy_wrapper.rb
275
275
  - lib/tezos_client/smartpy_interface.rb
276
276
  - lib/tezos_client/string_utils.rb
277
+ - lib/tezos_client/tools/annots_to_type.rb
277
278
  - lib/tezos_client/tools/convert_to_hash.rb
279
+ - lib/tezos_client/tools/convert_to_hash/address.rb
280
+ - lib/tezos_client/tools/convert_to_hash/base.rb
281
+ - lib/tezos_client/tools/convert_to_hash/big_map.rb
282
+ - lib/tezos_client/tools/convert_to_hash/bytes.rb
283
+ - lib/tezos_client/tools/convert_to_hash/int.rb
284
+ - lib/tezos_client/tools/convert_to_hash/key.rb
285
+ - lib/tezos_client/tools/convert_to_hash/list.rb
286
+ - lib/tezos_client/tools/convert_to_hash/map.rb
287
+ - lib/tezos_client/tools/convert_to_hash/nat.rb
288
+ - lib/tezos_client/tools/convert_to_hash/pair.rb
289
+ - lib/tezos_client/tools/convert_to_hash/signature.rb
290
+ - lib/tezos_client/tools/convert_to_hash/string.rb
291
+ - lib/tezos_client/tools/convert_to_hash/timestamp.rb
278
292
  - lib/tezos_client/tools/find_big_maps_in_storage.rb
293
+ - lib/tezos_client/tools/hash_to_micheline.rb
279
294
  - lib/tezos_client/tools/system_call.rb
280
295
  - lib/tezos_client/tools/temporary_file.rb
281
296
  - lib/tezos_client/version.rb
@@ -286,7 +301,7 @@ licenses:
286
301
  - MIT
287
302
  metadata:
288
303
  allowed_push_host: https://rubygems.org
289
- post_install_message:
304
+ post_install_message:
290
305
  rdoc_options: []
291
306
  require_paths:
292
307
  - lib
@@ -301,9 +316,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
301
316
  - !ruby/object:Gem::Version
302
317
  version: '0'
303
318
  requirements: []
304
- rubyforge_project:
305
- rubygems_version: 2.7.6
306
- signing_key:
319
+ rubygems_version: 3.0.4
320
+ signing_key:
307
321
  specification_version: 4
308
322
  summary: Wrapper to the tezos client.
309
323
  test_files: []