tezos_client 1.2.3 → 1.3.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +2 -5
  4. data/Gemfile.lock +63 -55
  5. data/README.md +15 -36
  6. data/lib/tezos_client.rb +21 -2
  7. data/lib/tezos_client/commands.rb +3 -1
  8. data/lib/tezos_client/crypto.rb +1 -1
  9. data/lib/tezos_client/logger.rb +1 -1
  10. data/lib/tezos_client/operation_mgr.rb +28 -29
  11. data/lib/tezos_client/rpc_interface/contracts.rb +4 -0
  12. data/lib/tezos_client/smartpy_interface.rb +10 -10
  13. data/lib/tezos_client/tools/annots_to_type.rb +38 -7
  14. data/lib/tezos_client/tools/convert_to_hash.rb +2 -2
  15. data/lib/tezos_client/tools/convert_to_hash/base.rb +2 -2
  16. data/lib/tezos_client/tools/convert_to_hash/option.rb +20 -0
  17. data/lib/tezos_client/tools/convert_to_hash/timestamp.rb +2 -0
  18. data/lib/tezos_client/tools/hash_to_micheline.rb +20 -44
  19. data/lib/tezos_client/tools/hash_to_micheline/address.rb +14 -0
  20. data/lib/tezos_client/tools/hash_to_micheline/base.rb +52 -0
  21. data/lib/tezos_client/tools/hash_to_micheline/bytes.rb +14 -0
  22. data/lib/tezos_client/tools/hash_to_micheline/contract.rb +14 -0
  23. data/lib/tezos_client/tools/hash_to_micheline/int.rb +13 -0
  24. data/lib/tezos_client/tools/hash_to_micheline/key.rb +14 -0
  25. data/lib/tezos_client/tools/hash_to_micheline/nat.rb +13 -0
  26. data/lib/tezos_client/tools/hash_to_micheline/option.rb +23 -0
  27. data/lib/tezos_client/tools/hash_to_micheline/pair.rb +45 -0
  28. data/lib/tezos_client/tools/hash_to_micheline/signature.rb +14 -0
  29. data/lib/tezos_client/tools/hash_to_micheline/string.rb +14 -0
  30. data/lib/tezos_client/tools/hash_to_micheline/timestamp.rb +14 -0
  31. data/lib/tezos_client/tools/system_call.rb +1 -1
  32. data/lib/tezos_client/version.rb +1 -1
  33. data/tezos_client.gemspec +1 -1
  34. data/travis-scripts/prepare-ubuntu.sh +6 -1
  35. metadata +20 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1edfdfe5f7332ebbe4ecafd4baa3f03998e02204e33f854d9f394ba84cbf98c3
4
- data.tar.gz: 7544eba6b1a6d602b24025a5c2831c1e803f53f92ae5f0925daa05a0b2ef3167
3
+ metadata.gz: 5257dbe976b3fba269aa9e6d4a966d2fbc7e4deaac30d5efc76a8a5699529623
4
+ data.tar.gz: 4b55b56b163c326a644fbaf62eda1e3e63b70f77e68af76ce0030f71a740c315
5
5
  SHA512:
6
- metadata.gz: 4a4e3ddacd06478d21821ce1e38ac5d731f2602d6cbca55e2440828de46c5933aaa8b77df00d3d989295ee325318ff53284725dc91d165ed32918cd2b3de9d8a
7
- data.tar.gz: 980264f44b9761e4f7e716675a5775d1b2f3cbfd6de5d09024154c53000a1a95cc3c168efe259c1fd7b78d9a877d23a6c0fa4feea8a8bda942b753122cf73bc7
6
+ metadata.gz: ae3837fedb178aaf48381cb110379c184097e32cfc547122c68dcf725c3b795c12bba2e172187f68da8096024abaa3e556e46804e5b31d9649920f65672038b8
7
+ data.tar.gz: 04fa056b5ae0c34c4f01f4c481999a389e2246df3f6dc698327964ced7250d353e87f1533d1deb04548b578c78cda91256eb6136eb778ed85082617991bb6ccd
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.5.1
1
+ 2.6.5
data/.travis.yml CHANGED
@@ -13,11 +13,8 @@ rvm:
13
13
  before_install:
14
14
  - sh travis-scripts/prepare-ubuntu.sh
15
15
  - mkdir -p $HOME/bin
16
- - curl -s https://SmartPy.io/SmartPyBasic/SmartPy.sh > SmartPy.sh
17
- - chmod +x ./SmartPy.sh
18
- - ./SmartPy.sh local-install $HOME/bin/smartpy
19
- - rm ./SmartPy.sh
20
- - export PATH="$PATH:$HOME/bin/:$HOME/bin/smartpy/SmartPyBasic/"
16
+ - curl -s https://smartpy.io/cli/install.sh > SmartPyInstaller.sh && yes | sh SmartPyInstaller.sh
17
+ - export PATH="$PATH:$HOME/bin/:$HOME/smartpy-cli/"
21
18
  - npm link michelson-to-micheline
22
19
  - gem install bundler -v 1.16.3
23
20
  script:
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tezos_client (1.2.3)
5
- active_interaction (~> 3.7)
4
+ tezos_client (1.3.4)
5
+ active_interaction (> 3.8)
6
6
  activesupport (~> 6.0.0)
7
7
  base58 (~> 0.2.3)
8
8
  bip_mnemonic (~> 0.0.2)
@@ -14,24 +14,24 @@ PATH
14
14
  GEM
15
15
  remote: https://rubygems.org/
16
16
  specs:
17
- actionpack (6.0.3.2)
18
- actionview (= 6.0.3.2)
19
- activesupport (= 6.0.3.2)
17
+ actionpack (6.0.3.5)
18
+ actionview (= 6.0.3.5)
19
+ activesupport (= 6.0.3.5)
20
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.3.2)
25
- activesupport (= 6.0.3.2)
24
+ actionview (6.0.3.5)
25
+ activesupport (= 6.0.3.5)
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.8.2)
31
- activemodel (>= 4, < 7)
32
- activemodel (6.0.3.2)
33
- activesupport (= 6.0.3.2)
34
- activesupport (6.0.3.2)
30
+ active_interaction (4.0.0)
31
+ activemodel (>= 5, < 7)
32
+ activemodel (6.0.3.5)
33
+ activesupport (= 6.0.3.5)
34
+ activesupport (6.0.3.5)
35
35
  concurrent-ruby (~> 1.0, >= 1.0.2)
36
36
  i18n (>= 0.7, < 2)
37
37
  minitest (~> 5.1)
@@ -39,51 +39,52 @@ GEM
39
39
  zeitwerk (~> 2.2, >= 2.2.2)
40
40
  addressable (2.7.0)
41
41
  public_suffix (>= 2.0.2, < 5.0)
42
- ast (2.4.0)
42
+ ast (2.4.2)
43
43
  base58 (0.2.3)
44
44
  bip_mnemonic (0.0.4)
45
45
  builder (3.2.4)
46
- coderay (1.1.2)
47
- concurrent-ruby (1.1.6)
48
- crack (0.4.3)
49
- safe_yaml (~> 1.0.0)
46
+ coderay (1.1.3)
47
+ concurrent-ruby (1.1.8)
48
+ crack (0.4.5)
49
+ rexml
50
50
  crass (1.0.6)
51
- diff-lcs (1.3)
51
+ diff-lcs (1.4.4)
52
52
  domain_name (0.5.20190701)
53
53
  unf (>= 0.0.5, < 1.0.0)
54
- erubi (1.9.0)
55
- ffi (1.13.1)
56
- hashdiff (1.0.0)
54
+ erubi (1.10.0)
55
+ ffi (1.14.2)
56
+ hashdiff (1.0.1)
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.8.3)
62
+ i18n (1.8.9)
63
63
  concurrent-ruby (~> 1.0)
64
- jaro_winkler (1.5.3)
65
- loofah (2.6.0)
64
+ loofah (2.9.0)
66
65
  crass (~> 1.0.2)
67
66
  nokogiri (>= 1.5.9)
68
67
  method_source (0.9.2)
69
68
  mime-types (3.3.1)
70
69
  mime-types-data (~> 3.2015)
71
- mime-types-data (3.2020.0512)
72
- mini_portile2 (2.4.0)
73
- minitest (5.14.1)
70
+ mime-types-data (3.2021.0225)
71
+ mini_portile2 (2.5.0)
72
+ minitest (5.14.4)
74
73
  money-tree (0.10.0)
75
74
  ffi
76
75
  multi_xml (0.6.0)
77
76
  netrc (0.11.0)
78
- nokogiri (1.10.9)
79
- mini_portile2 (~> 2.4.0)
80
- parallel (1.18.0)
81
- parser (2.6.5.0)
82
- ast (~> 2.4.0)
77
+ nokogiri (1.11.1)
78
+ mini_portile2 (~> 2.5.0)
79
+ racc (~> 1.4)
80
+ parallel (1.20.1)
81
+ parser (3.0.0.0)
82
+ ast (~> 2.4.1)
83
83
  pry (0.12.2)
84
84
  coderay (~> 1.1.0)
85
85
  method_source (~> 0.9.0)
86
- public_suffix (4.0.1)
86
+ public_suffix (4.0.6)
87
+ racc (1.5.2)
87
88
  rack (2.2.3)
88
89
  rack-test (1.1.0)
89
90
  rack (>= 1.0, < 3)
@@ -92,9 +93,9 @@ GEM
92
93
  nokogiri (>= 1.6)
93
94
  rails-html-sanitizer (1.3.0)
94
95
  loofah (~> 2.3)
95
- railties (6.0.3.2)
96
- actionpack (= 6.0.3.2)
97
- activesupport (= 6.0.3.2)
96
+ railties (6.0.3.5)
97
+ actionpack (= 6.0.3.5)
98
+ activesupport (= 6.0.3.5)
98
99
  method_source
99
100
  rake (>= 0.8.7)
100
101
  thor (>= 0.20.3, < 2.0)
@@ -102,56 +103,63 @@ GEM
102
103
  rake (13.0.1)
103
104
  rbnacl (5.0.0)
104
105
  ffi
106
+ regexp_parser (2.1.1)
105
107
  rest-client (2.0.2)
106
108
  http-cookie (>= 1.0.2, < 2.0)
107
109
  mime-types (>= 1.16, < 4.0)
108
110
  netrc (~> 0.8)
111
+ rexml (3.2.4)
109
112
  rspec (3.9.0)
110
113
  rspec-core (~> 3.9.0)
111
114
  rspec-expectations (~> 3.9.0)
112
115
  rspec-mocks (~> 3.9.0)
113
- rspec-core (3.9.0)
114
- rspec-support (~> 3.9.0)
115
- rspec-expectations (3.9.0)
116
+ rspec-core (3.9.3)
117
+ rspec-support (~> 3.9.3)
118
+ rspec-expectations (3.9.4)
116
119
  diff-lcs (>= 1.2.0, < 2.0)
117
120
  rspec-support (~> 3.9.0)
118
- rspec-mocks (3.9.0)
121
+ rspec-mocks (3.9.1)
119
122
  diff-lcs (>= 1.2.0, < 2.0)
120
123
  rspec-support (~> 3.9.0)
121
- rspec-support (3.9.0)
122
- rubocop (0.75.1)
123
- jaro_winkler (~> 1.5.1)
124
+ rspec-support (3.9.4)
125
+ rubocop (0.93.1)
124
126
  parallel (~> 1.10)
125
- parser (>= 2.6)
127
+ parser (>= 2.7.1.5)
126
128
  rainbow (>= 2.2.2, < 4.0)
129
+ regexp_parser (>= 1.8)
130
+ rexml
131
+ rubocop-ast (>= 0.6.0)
127
132
  ruby-progressbar (~> 1.7)
128
- unicode-display_width (>= 1.4.0, < 1.7)
129
- rubocop-performance (1.5.0)
130
- rubocop (>= 0.71.0)
131
- rubocop-rails (2.3.2)
133
+ unicode-display_width (>= 1.4.0, < 2.0)
134
+ rubocop-ast (1.4.1)
135
+ parser (>= 2.7.1.5)
136
+ rubocop-performance (1.10.1)
137
+ rubocop (>= 0.90.0, < 2.0)
138
+ rubocop-ast (>= 0.4.0)
139
+ rubocop-rails (2.9.1)
140
+ activesupport (>= 4.2.0)
132
141
  rack (>= 1.1)
133
- rubocop (>= 0.72.0)
142
+ rubocop (>= 0.90.0, < 2.0)
134
143
  rubocop-rails_config (0.7.3)
135
144
  railties (>= 3.0)
136
145
  rubocop (~> 0.74)
137
146
  rubocop-performance (~> 1.3)
138
147
  rubocop-rails (~> 2.0)
139
- ruby-progressbar (1.10.1)
140
- safe_yaml (1.0.5)
141
- thor (1.0.1)
148
+ ruby-progressbar (1.11.0)
149
+ thor (1.1.0)
142
150
  thread_safe (0.3.6)
143
- tzinfo (1.2.7)
151
+ tzinfo (1.2.9)
144
152
  thread_safe (~> 0.1)
145
153
  unf (0.1.4)
146
154
  unf_ext
147
155
  unf_ext (0.0.7.7)
148
- unicode-display_width (1.6.0)
156
+ unicode-display_width (1.7.0)
149
157
  vcr (4.0.0)
150
158
  webmock (3.7.6)
151
159
  addressable (>= 2.3.6)
152
160
  crack (>= 0.3.2)
153
161
  hashdiff (>= 0.4.0, < 2.0.0)
154
- zeitwerk (2.3.0)
162
+ zeitwerk (2.4.2)
155
163
 
156
164
  PLATFORMS
157
165
  ruby
data/README.md CHANGED
@@ -4,11 +4,12 @@
4
4
 
5
5
  [![Build Status](https://travis-ci.org/moneytrackio/tezos_client.svg?branch=master)](https://travis-ci.org/moneytrackio/tezos_client)
6
6
 
7
- Tezos Client interracts with tezos nodes using RPC commands.
7
+ Tezos Client interacts with Tezos nodes using RPC commands.
8
8
 
9
- ## Requirements:
10
- Tezos client requires liquidity to be installed in order to work properly.
11
- For installing on linux, you can basically follow the steps coded in travis-script folder.
9
+ ## Requirements
10
+
11
+ Tezos client requires SmartPy to be installed in order to work properly.
12
+ To install it on Linux, you can basically follow the steps coded in travis-script folder.
12
13
 
13
14
  ## Dependency
14
15
 
@@ -18,16 +19,12 @@ sudo apt-get install nodejs
18
19
  npm i -g michelson-to-micheline
19
20
  ```
20
21
 
21
- ### liquidity
22
- [liquidity installation](http://www.liquidity-lang.org/doc/installation/index.html)
23
-
24
- need the tezos version (not Dune version)
25
-
26
22
  ### SmartPy
27
23
  [SmartPy](https://smartpy.io/)
28
24
 
29
25
  ```bash
30
- sh <(curl -s https://SmartPy.io/SmartPyBasic/SmartPy.sh) local-install /
26
+ sh <(curl -s https://smartpy.io/dev-20200924-23b26494361d96abf034bdbb1ad1af396f95fd61/cli/SmartPy.sh) local-install-auto
27
+ export PATH=$PATH:$HOME/smartpy-cli/
31
28
  ```
32
29
 
33
30
  ### TypeScript (for dev)
@@ -53,9 +50,10 @@ Or install it yourself as:
53
50
 
54
51
  ## Usage
55
52
 
56
- ### Generate Tezos key paris
53
+ ### Generate Tezos key pairs
54
+
55
+ Generate a perfectly random key pair:
57
56
 
58
- Generate a prefectly random key pair:
59
57
  ```ruby
60
58
  client = TezosClient.new
61
59
  key = subject.generate_key
@@ -68,6 +66,7 @@ key = subject.generate_key
68
66
  ```
69
67
 
70
68
  Generate a key pair from a seed and a BIP 44 Path:
69
+
71
70
  ```ruby
72
71
  key = subject.generate_key(wallet_seed:"000102030405060708090a0b0c0d0e0f", path: "m/44'/1729'/0'/0'/0'")
73
72
  expect(key[:address]).to eq "tz1RfnzRopJXH32SSDap2wMYGULBAnmHxdP1"
@@ -77,7 +76,8 @@ key = subject.generate_key(wallet_seed:"000102030405060708090a0b0c0d0e0f", path:
77
76
  # :address=>"tz1a97x7GAvMDyrwwKTLQo131CoidXyUef48"
78
77
  # }
79
78
  ```
80
- Generate a key pair from a BIP-39 mnemonic sentence and a BIP 44 Path:
79
+ Generate a key pair from a BIP-39 mnemonic sentence and a BIP 44 Path:
80
+
81
81
  ```ruby
82
82
  key = subject.generate_key(
83
83
  mnemonic: "below dove cushion divide future artefact orange congress maple fiscal flower enable",
@@ -117,28 +117,6 @@ client.transfer(
117
117
  )
118
118
  ```
119
119
 
120
- ### Originate a contract written in liquidity
121
-
122
- ```ruby
123
- script = File.expand_path("./spec/fixtures/demo.py")
124
- source = "tz1ZWiiPXowuhN1UqNGVTrgNyf5tdxp4XUUq"
125
- secret_key = "edsk4EcqupPmaebat5mP57ZQ3zo8NDkwv8vQmafdYZyeXxrSc72pjN"
126
- amount = 0
127
- init_params= "MyContract()"
128
- client = TezosClient.new
129
-
130
- res = client.originate_contract(
131
- from: source,
132
- amount: amount,
133
- script: script,
134
- secret_key: secret_key,
135
- init_params: init_params
136
- )
137
-
138
- puts "Origination operation: #{res[:operation_id]}"
139
- puts "Contract address: #{res[:originated_contract]}"
140
- ```
141
-
142
120
  ### Originate a contract written in SmartPy
143
121
 
144
122
  ```ruby
@@ -146,7 +124,7 @@ script = File.expand_path("./spec/fixtures/demo.py")
146
124
  source = "tz1ZWiiPXowuhN1UqNGVTrgNyf5tdxp4XUUq"
147
125
  secret_key = "edsk4EcqupPmaebat5mP57ZQ3zo8NDkwv8vQmafdYZyeXxrSc72pjN"
148
126
  amount = 0
149
- init_params = "MyContract(1, 1)"
127
+ init_params= "MyContract()"
150
128
  client = TezosClient.new
151
129
 
152
130
  res = client.originate_contract(
@@ -162,6 +140,7 @@ puts "Contract address: #{res[:originated_contract]}"
162
140
  ```
163
141
 
164
142
  ### Call a contract written in SmartPy
143
+
165
144
  ```ruby
166
145
  TezosClient.new.call_contract(
167
146
  from: "tz1ZWiiPXowuhN1UqNGVTrgNyf5tdxp4XUUq",
data/lib/tezos_client.rb CHANGED
@@ -4,6 +4,8 @@ require "pp"
4
4
  require "active_support/core_ext/hash/indifferent_access"
5
5
  require "active_support/core_ext/string/inflections"
6
6
  require "active_support/core_ext/module/delegation"
7
+ require "active_support/core_ext/time"
8
+ require "active_support/core_ext/array"
7
9
  require "timeout"
8
10
  require "benchmark"
9
11
  require "open3"
@@ -165,14 +167,19 @@ class TezosClient
165
167
  end
166
168
 
167
169
  def call_contract(dry_run: false, entrypoint:, params:, params_type:, **args)
170
+ _entrypoint = select_entrypoint(
171
+ contract_address: args[:to],
172
+ entrypoint: entrypoint
173
+ )
174
+
168
175
  json_params = micheline_params(
169
176
  params: params,
170
- entrypoint: entrypoint,
177
+ entrypoint: _entrypoint,
171
178
  params_type: params_type
172
179
  )
173
180
 
174
181
  transfer_args = args.merge(
175
- entrypoint: entrypoint,
182
+ entrypoint: _entrypoint,
176
183
  parameters: json_params,
177
184
  dry_run: dry_run
178
185
  )
@@ -180,6 +187,18 @@ class TezosClient
180
187
  transfer(transfer_args)
181
188
  end
182
189
 
190
+ def select_entrypoint(contract_address:, entrypoint:)
191
+ entrypoints = entrypoints(contract_address)["entrypoints"].keys
192
+
193
+ if entrypoints.count == 0
194
+ "default"
195
+ elsif entrypoints.include?(entrypoint)
196
+ entrypoint
197
+ else
198
+ raise ::ArgumentError, "entrypoint #{entrypoint} not found in #{entrypoints}"
199
+ end
200
+ end
201
+
183
202
  def inject_raw_operations(secret_key:, raw_operations:, dry_run: false, **args)
184
203
  public_key = secret_key_to_public_key(secret_key)
185
204
  from = public_key_to_address(public_key)
@@ -25,6 +25,8 @@ class TezosClient
25
25
  :contract_big_maps,
26
26
  :block_operations,
27
27
  :contract_storage_type,
28
- :entrypoint
28
+ :entrypoint,
29
+ :entrypoints,
30
+ :select_entrypoint
29
31
  end
30
32
  end
@@ -238,7 +238,7 @@ class TezosClient
238
238
  end
239
239
 
240
240
  def ignore_0x(payload)
241
- payload.starts_with?("0x") ? payload[2..-1] : payload
241
+ payload.start_with?("0x") ? payload[2..-1] : payload
242
242
  end
243
243
  end
244
244
  end
@@ -13,7 +13,7 @@ class TezosClient
13
13
  self.class.logger << out + "\n"
14
14
  end
15
15
 
16
- FILTERED_KEYS = [:code, :contractCode]
16
+ FILTERED_KEYS = [:code, :contractCode, :contract_code]
17
17
  def tezos_contents_log_filter(content)
18
18
  if content.is_a? Array
19
19
  content.map { |el| tezos_contents_log_filter(el) }
@@ -202,40 +202,39 @@ class TezosClient
202
202
  end
203
203
 
204
204
  private
205
+ def ensure_applied!(rpc_responses)
206
+ metadatas = rpc_responses.map { |response| response[:metadata] }
207
+ operation_results = metadatas.map { |metadata| metadata[:operation_result] }
208
+ internal_operations = metadatas.map { |metadata| metadata[:internal_operation_results] }.flatten.compact
209
+ operation_results.concat(internal_operations.map { |internal_operation| internal_operation[:result] })
210
+
211
+ failed = operation_results.detect do |operation_result|
212
+ operation_result != nil && operation_result[:status] != "applied"
213
+ end
205
214
 
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
-
212
- failed = operation_results.detect do |operation_result|
213
- operation_result != nil && operation_result[:status] != "applied"
214
- end
215
+ return metadatas if failed.nil?
215
216
 
216
- return metadatas if failed.nil?
217
+ failed_operation_result = operation_results.detect do |operation_result|
218
+ operation_result[:status] == "failed"
219
+ end
217
220
 
218
- failed_operation_result = operation_results.detect do |operation_result|
219
- operation_result[:status] == "failed"
221
+ failed!("failed", failed_operation_result[:errors], operation_results)
220
222
  end
221
223
 
222
- failed!("failed", failed_operation_result[:errors], operation_results)
223
- end
224
-
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
224
+ def exception_klass(errors)
225
+ error = errors[0]
226
+ case error[:id]
227
+ when TezBalanceTooLow::FIRST_ERROR_REGEXP
228
+ TezBalanceTooLow
229
+ when ScriptRuntimeError::FIRST_ERROR_REGEXP
230
+ ScriptRuntimeError
231
+ else
232
+ OperationFailure
233
+ end
234
234
  end
235
- end
236
235
 
237
- def failed!(status, errors, metadata)
238
- raise exception_klass(errors).new(metadata: metadata, errors: errors, status: status)
239
- end
236
+ def failed!(status, errors, metadata)
237
+ raise exception_klass(errors).new(metadata: metadata, errors: errors, status: status)
238
+ end
240
239
  end
241
- end
240
+ end
@@ -37,6 +37,10 @@ class TezosClient
37
37
  get "#{contract_link(contract_id)}/storage"
38
38
  end
39
39
 
40
+ def entrypoints(contract_id)
41
+ get("#{contract_link(contract_id)}/entrypoints")
42
+ end
43
+
40
44
  def entrypoint(contract_id, entrypoint)
41
45
  get("#{contract_link(contract_id)}/entrypoints/#{entrypoint}")
42
46
  end
@@ -30,16 +30,16 @@ class TezosClient
30
30
  end
31
31
 
32
32
  private
33
- def compile_to_michelson(args)
34
- Tools::TemporaryFile.with_file_copy(args[:script]) do |script_copy_path|
35
- script_basename = script_copy_path.split("/").last.sub(/.py$/, "")
36
- script_path = "/tmp/#{script_basename}/"
37
- init_script_filename = "contractStorage.tz"
38
- contract_script_filename = "contractCode.tz.json"
39
- call_smartpy ["local-compile", script_copy_path, args[:init_params], script_path]
40
-
41
- yield(script_path + contract_script_filename, script_path + init_script_filename)
42
- end
33
+ def compile_to_michelson(args)
34
+ Tools::TemporaryFile.with_file_copy(args[:script]) do |script_copy_path|
35
+ script_basename = script_copy_path.split("/").last.sub(/.py$/, "")
36
+ script_path = "/tmp/#{script_basename}/"
37
+ init_script_filename = "#{script_basename}_storage_init.tz"
38
+ contract_script_filename = "#{script_basename}_compiled.json"
39
+ call_smartpy ["compile", script_copy_path, args[:init_params], script_path]
40
+
41
+ yield(script_path + contract_script_filename, script_path + init_script_filename)
43
42
  end
43
+ end
44
44
  end
45
45
  end
@@ -11,6 +11,17 @@ class TezosClient::Tools::AnnotsToType < ActiveInteraction::Base
11
11
 
12
12
  validate :validate_types
13
13
 
14
+ TYPES_MAPPING = {
15
+ int: :int,
16
+ nat: :int,
17
+ string: :string,
18
+ signature: :string,
19
+ bytes: :bytes,
20
+ timestamp: :int,
21
+ key: :string,
22
+ address: :string
23
+ }.freeze
24
+
14
25
  def execute
15
26
  return { "prim" => typed_annots.values.first } if typed_annots.size == 1
16
27
 
@@ -18,30 +29,50 @@ class TezosClient::Tools::AnnotsToType < ActiveInteraction::Base
18
29
  end
19
30
 
20
31
  private
32
+ def micheline_type(annot_type, annot)
33
+ if annot_type.to_s.start_with?("optional_")
34
+ {
35
+ "prim" => "option",
36
+ "args" => [{ "prim" => annot_type.to_s.delete_prefix("optional_") }],
37
+ "annots" => ["%#{annot}"]
38
+ }
39
+ else
40
+ {
41
+ "prim" => annot_type,
42
+ "annots" => ["%#{annot}"]
43
+ }
44
+ end
45
+ end
46
+
21
47
  def generate_type_args(annots)
22
48
  annot = annots.pop
23
49
  annot_type = typed_annots[annot]
24
50
 
25
51
  unless annots.size == 1
26
- return [{ "prim" => "pair", "args" => generate_type_args(annots) },
27
- { "prim" => annot_type, "annots" => ["%#{annot}"] }]
52
+ return [
53
+ micheline_type(annot_type, annot),
54
+ {
55
+ "prim" => "pair",
56
+ "args" => generate_type_args(annots)
57
+ }
58
+ ]
28
59
  end
29
60
 
30
- generated_args = [{ "prim" => annot_type, "annots" => ["%#{annot}"] }]
61
+ generated_args = [micheline_type(annot_type, annot)]
31
62
  annot = annots.pop
32
63
  annot_type = typed_annots[annot]
33
- generated_args.unshift({ "prim" => annot_type, "annots" => ["%#{annot}"] })
64
+ generated_args.append(micheline_type(annot_type, annot))
34
65
 
35
66
  generated_args
36
67
  end
37
68
 
38
69
  def ordered_annots
39
- @ordered_annots ||= typed_annots.keys.sort
70
+ @ordered_annots ||= typed_annots.keys.sort.reverse
40
71
  end
41
72
 
42
73
  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 }
74
+ allowed_types = TYPES_MAPPING.keys
75
+ return if typed_annots.values.map{|type| type.to_s.delete_prefix("optional_").to_sym}.all? { |type| allowed_types.include? type }
45
76
 
46
77
  errors.add(:base, "The allowed types are: #{allowed_types.join(', ')}")
47
78
  end
@@ -7,8 +7,8 @@ Dir[File.join(__dir__, "convert_to_hash", "*.rb")].each { |file| require file }
7
7
  class TezosClient
8
8
  module Tools
9
9
  class ConvertToHash < ActiveInteraction::Base
10
- interface :data
11
- interface :type
10
+ interface :data, methods: []
11
+ interface :type, methods: []
12
12
 
13
13
  def execute
14
14
  TezosClient::Tools::ConvertToHash::Base.new(data: data, type: type).value
@@ -22,7 +22,7 @@ class TezosClient
22
22
  type: type
23
23
  ).decode
24
24
 
25
- rescue NameError => e
25
+ rescue NameError
26
26
  raise NotImplementedError, "type '#{type[:prim]}' not implemented"
27
27
  end
28
28
 
@@ -42,7 +42,7 @@ class TezosClient
42
42
 
43
43
  private
44
44
  def klass
45
- "TezosClient::Tools::ConvertToHash::#{type[:prim].camelize}".constantize
45
+ "#{self.class.name.deconstantize}::#{type[:prim].camelize}".constantize
46
46
  end
47
47
  end
48
48
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class ConvertToHash < ActiveInteraction::Base
6
+ class Option < Base
7
+ def decode
8
+ if data[:prim] == "None"
9
+ return nil
10
+ elsif data[:prim] == "Some"
11
+ TezosClient::Tools::ConvertToHash::Base.new(
12
+ data: data[:args][0],
13
+ type: type[:args][0]
14
+ ).value
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -8,6 +8,8 @@ class TezosClient
8
8
  if data.key? :int
9
9
  Time.zone.at(data[:int].to_i)
10
10
  elsif data.key? :string
11
+ return Time.zone.at(data[:string].to_i) if data[:string].match?(/\A\d+\z/)
12
+
11
13
  Time.zone.parse(data[:string])
12
14
  else
13
15
  raise "Can not convert timestamp: #{data}"
@@ -1,18 +1,11 @@
1
1
  # frozen_string_literal: true
2
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
3
+ require_relative "hash_to_micheline/base"
4
+
5
+ Dir[File.join(__dir__, "hash_to_micheline", "*.rb")].each { |file| require file }
6
+
15
7
 
8
+ class TezosClient::Tools::HashToMicheline < ActiveInteraction::Base
16
9
  string :contract_address, default: nil
17
10
  string :entrypoint, default: nil
18
11
  # example of params:
@@ -20,57 +13,40 @@ class TezosClient::Tools::HashToMicheline < ActiveInteraction::Base
20
13
  # spending_ref: "toto",
21
14
  # expires_at: Time.now
22
15
  # }
23
- hash :params, strip: false
16
+ interface :params, methods: []
24
17
  hash :storage_type, strip: false, default: {}
25
- interface :blockchain_client, methods: [:entrypoint], default: -> { TezosClient.new }
18
+ interface :blockchain_client, methods: %i[entrypoint entrypoints select_entrypoint], default: -> { TezosClient.new }
26
19
 
27
20
  # if storage_type is not received, it is fetched from the blockchain using
28
21
  # contract_address and entrypoint (that are mandatory in this case)
29
22
  validate :storage_type_or_contract_address_presence
30
23
 
31
24
  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]) }
25
+ TezosClient::Tools::HashToMicheline::Base.new(data: _params, type: _storage_type).value
35
26
  end
36
27
 
37
28
  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))
29
+ def _params
30
+ if params.respond_to?(:keys) && params.keys.size == 1 && !_storage_type.key?(:annots)
31
+ params.values.first
32
+ else
33
+ params
44
34
  end
45
35
  end
46
36
 
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 }
37
+ def _entrypoint
38
+ @_entrypoint ||= blockchain_client.select_entrypoint(
39
+ contract_address: contract_address,
40
+ entrypoint: entrypoint
41
+ )
66
42
  end
67
43
 
68
44
  def _storage_type
69
- (storage_type.presence || blockchain_client.entrypoint(contract_address, entrypoint)).deep_symbolize_keys
45
+ (storage_type.presence || blockchain_client.entrypoint(contract_address, _entrypoint)).deep_symbolize_keys
70
46
  end
71
47
 
72
48
  def storage_type_or_contract_address_presence
73
- return if storage_type.present? ^ (contract_address.present? && entrypoint.present?)
49
+ return if storage_type.present? ^ (contract_address.present?)
74
50
 
75
51
  errors.add(:base,
76
52
  "You should provide the contract_address and the entrypoint only if storage_type is not provided")
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class HashToMicheline < ActiveInteraction::Base
6
+ class Address < Base
7
+ def encode
8
+ raise "#{data} #{data.class} Not a 'String' type" unless data.is_a? ::String
9
+ { string: data }
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class HashToMicheline < 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
+ @data = anonymous? ? @data : @data.fetch(var_name)
16
+ encode
17
+ end
18
+
19
+ protected
20
+ def encode
21
+ klass.new(
22
+ data: data,
23
+ type: type
24
+ ).encode
25
+
26
+ rescue NameError
27
+ raise
28
+ raise NotImplementedError, "type '#{type[:prim]}' not implemented"
29
+ end
30
+
31
+ def anonymous?
32
+ !(type.key?(:annots) && type[:annots].any?)
33
+ end
34
+
35
+ def var_name_annot
36
+ type[:annots].first
37
+ end
38
+
39
+ def var_name
40
+ return nil if anonymous?
41
+
42
+ "#{var_name_annot[1..-1]}".to_sym
43
+ end
44
+
45
+ private
46
+ def klass
47
+ "#{self.class.name.deconstantize}::#{type[:prim].to_s.camelize}".constantize
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class HashToMicheline < ActiveInteraction::Base
6
+ class Bytes < Base
7
+ def encode
8
+ raise "#{data} #{data.class} Not a 'String' type" unless data.is_a? ::String
9
+ { bytes: data }
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class HashToMicheline < ActiveInteraction::Base
6
+ class Contract < Base
7
+ def encode
8
+ raise "#{data} #{data.class} Not a 'String' type" unless data.is_a? ::String
9
+ { string: data }
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class HashToMicheline < ActiveInteraction::Base
6
+ class Int < Base
7
+ def encode
8
+ { int: data.to_s }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class HashToMicheline < ActiveInteraction::Base
6
+ class Key < Base
7
+ def encode
8
+ raise "#{data} #{data.class} Not a 'String' type" unless data.is_a? ::String
9
+ { string: data }
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class HashToMicheline < ActiveInteraction::Base
6
+ class Nat < Base
7
+ def encode
8
+ { int: data.to_s }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class HashToMicheline < ActiveInteraction::Base
6
+ class Option < Base
7
+ def encode
8
+ return { prim: "None" } if data.nil?
9
+
10
+ {
11
+ prim: "Some",
12
+ args: [
13
+ TezosClient::Tools::HashToMicheline::Base.new(
14
+ data: data,
15
+ type: type[:args][0]
16
+ ).value
17
+ ]
18
+ }
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class HashToMicheline < ActiveInteraction::Base
6
+ class Pair < Base
7
+ def encode
8
+ {
9
+ prim: "Pair",
10
+ args: [
11
+ TezosClient::Tools::HashToMicheline::Base.new(
12
+ data: data_0,
13
+ type: type[:args][0]
14
+ ).value,
15
+ TezosClient::Tools::HashToMicheline::Base.new(
16
+ data: data_1,
17
+ type: type[:args][1]
18
+ ).value
19
+ ]
20
+ }
21
+ end
22
+
23
+ def data_0
24
+ if data.is_a? ::Array
25
+ data[0]
26
+ else
27
+ data
28
+ end
29
+ end
30
+
31
+ def data_1
32
+ if data.is_a? ::Array
33
+ if data.size > 2
34
+ data.drop(1)
35
+ else
36
+ data[1]
37
+ end
38
+ else
39
+ data
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class HashToMicheline < ActiveInteraction::Base
6
+ class Signature < Base
7
+ def encode
8
+ raise "#{data} does not seem to be a signature" unless data.start_with?("edsig")
9
+ { string: data }
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class HashToMicheline < ActiveInteraction::Base
6
+ class String < Base
7
+ def encode
8
+ raise "#{data} #{data.class} Not a 'String' type" unless data.is_a? ::String
9
+ { string: data }
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TezosClient
4
+ module Tools
5
+ class HashToMicheline < ActiveInteraction::Base
6
+ class Timestamp < Base
7
+ def encode
8
+ raise "timestamp input (#{data}) must be an instance of Time" unless data.is_a? Time
9
+ { int: data.to_i.to_s }
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -5,10 +5,10 @@ class TezosClient
5
5
  module SystemCall
6
6
  def self.execute(cmd)
7
7
  Open3.popen3(*cmd) do |_stdin, stdout, stderr, wait_thr|
8
- err = stderr.read
9
8
  status = wait_thr.value.exitstatus
10
9
 
11
10
  if status != 0
11
+ err = stdout.read + stderr.read
12
12
  raise ::TezosClient::SysCallError, "command '#{cmd}' existed with status #{status}: #{err}"
13
13
  end
14
14
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class TezosClient
4
- VERSION = "1.2.3"
4
+ VERSION = "1.3.4"
5
5
  end
data/tezos_client.gemspec CHANGED
@@ -41,7 +41,7 @@ Gem::Specification.new do |spec|
41
41
  spec.add_development_dependency "vcr", "~> 4.0.0"
42
42
  spec.add_development_dependency "pry"
43
43
 
44
- spec.add_dependency "active_interaction", "~> 3.7"
44
+ spec.add_dependency "active_interaction", "> 3.8"
45
45
  spec.add_dependency "base58", "~> 0.2.3"
46
46
  spec.add_dependency "httparty", "~> 0.17.0"
47
47
  spec.add_dependency "rbnacl", "~> 5.0.0"
@@ -11,4 +11,9 @@ sudo add-apt-repository "deb http://fr.archive.ubuntu.com/ubuntu bionic main uni
11
11
  sudo apt-get update -qq
12
12
  sudo apt-get install -y -qq \
13
13
  libsecp256k1-dev libsecp256k1-0 libsodium-dev libssl-dev \
14
- bubblewrap libev-dev libhidapi-dev npm
14
+ bubblewrap libev-dev libhidapi-dev
15
+
16
+ wget -qO- https://deb.nodesource.com/setup_14.x | sudo -E bash -
17
+ sudo apt install -y nodejs
18
+ node --version
19
+ npm --version
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.2.3
4
+ version: 1.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pierre Michard
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-24 00:00:00.000000000 Z
11
+ date: 2021-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -112,16 +112,16 @@ dependencies:
112
112
  name: active_interaction
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - "~>"
115
+ - - ">"
116
116
  - !ruby/object:Gem::Version
117
- version: '3.7'
117
+ version: '3.8'
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - "~>"
122
+ - - ">"
123
123
  - !ruby/object:Gem::Version
124
- version: '3.7'
124
+ version: '3.8'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: base58
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -285,12 +285,25 @@ files:
285
285
  - lib/tezos_client/tools/convert_to_hash/list.rb
286
286
  - lib/tezos_client/tools/convert_to_hash/map.rb
287
287
  - lib/tezos_client/tools/convert_to_hash/nat.rb
288
+ - lib/tezos_client/tools/convert_to_hash/option.rb
288
289
  - lib/tezos_client/tools/convert_to_hash/pair.rb
289
290
  - lib/tezos_client/tools/convert_to_hash/signature.rb
290
291
  - lib/tezos_client/tools/convert_to_hash/string.rb
291
292
  - lib/tezos_client/tools/convert_to_hash/timestamp.rb
292
293
  - lib/tezos_client/tools/find_big_maps_in_storage.rb
293
294
  - lib/tezos_client/tools/hash_to_micheline.rb
295
+ - lib/tezos_client/tools/hash_to_micheline/address.rb
296
+ - lib/tezos_client/tools/hash_to_micheline/base.rb
297
+ - lib/tezos_client/tools/hash_to_micheline/bytes.rb
298
+ - lib/tezos_client/tools/hash_to_micheline/contract.rb
299
+ - lib/tezos_client/tools/hash_to_micheline/int.rb
300
+ - lib/tezos_client/tools/hash_to_micheline/key.rb
301
+ - lib/tezos_client/tools/hash_to_micheline/nat.rb
302
+ - lib/tezos_client/tools/hash_to_micheline/option.rb
303
+ - lib/tezos_client/tools/hash_to_micheline/pair.rb
304
+ - lib/tezos_client/tools/hash_to_micheline/signature.rb
305
+ - lib/tezos_client/tools/hash_to_micheline/string.rb
306
+ - lib/tezos_client/tools/hash_to_micheline/timestamp.rb
294
307
  - lib/tezos_client/tools/system_call.rb
295
308
  - lib/tezos_client/tools/temporary_file.rb
296
309
  - lib/tezos_client/version.rb
@@ -316,7 +329,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
316
329
  - !ruby/object:Gem::Version
317
330
  version: '0'
318
331
  requirements: []
319
- rubygems_version: 3.0.4
332
+ rubygems_version: 3.0.3
320
333
  signing_key:
321
334
  specification_version: 4
322
335
  summary: Wrapper to the tezos client.