tezos_client 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -5
  3. data/Gemfile.lock +63 -55
  4. data/README.md +16 -37
  5. data/lib/tezos_client.rb +24 -5
  6. data/lib/tezos_client/commands.rb +2 -1
  7. data/lib/tezos_client/crypto.rb +1 -1
  8. data/lib/tezos_client/logger.rb +1 -1
  9. data/lib/tezos_client/smartpy_interface.rb +39 -7
  10. data/lib/tezos_client/tools/annots_to_type.rb +31 -8
  11. data/lib/tezos_client/tools/convert_to_hash.rb +2 -2
  12. data/lib/tezos_client/tools/convert_to_hash/base.rb +1 -1
  13. data/lib/tezos_client/tools/convert_to_hash/timestamp.rb +2 -0
  14. data/lib/tezos_client/tools/hash_to_micheline.rb +17 -73
  15. data/lib/tezos_client/tools/hash_to_micheline/address.rb +14 -0
  16. data/lib/tezos_client/tools/hash_to_micheline/base.rb +52 -0
  17. data/lib/tezos_client/tools/hash_to_micheline/bytes.rb +14 -0
  18. data/lib/tezos_client/tools/hash_to_micheline/contract.rb +14 -0
  19. data/lib/tezos_client/tools/hash_to_micheline/int.rb +13 -0
  20. data/lib/tezos_client/tools/hash_to_micheline/key.rb +14 -0
  21. data/lib/tezos_client/tools/hash_to_micheline/nat.rb +13 -0
  22. data/lib/tezos_client/tools/hash_to_micheline/option.rb +23 -0
  23. data/lib/tezos_client/tools/hash_to_micheline/pair.rb +45 -0
  24. data/lib/tezos_client/tools/hash_to_micheline/signature.rb +14 -0
  25. data/lib/tezos_client/tools/hash_to_micheline/string.rb +14 -0
  26. data/lib/tezos_client/tools/hash_to_micheline/timestamp.rb +14 -0
  27. data/lib/tezos_client/version.rb +1 -1
  28. data/tezos_client.gemspec +1 -1
  29. data/travis-scripts/prepare-ubuntu.sh +6 -1
  30. metadata +19 -8
  31. data/lib/tezos_client/smartpy_inteface/micheline_serializer_wrapper.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e2dc6502a81aa8acb23cab552f03edbb1c94d7e21bfa2e653f9d662b0f2f5b5
4
- data.tar.gz: 807c964c0919c93331e3e45610195705bed3ead65ca71a51f46b13d557ba4b14
3
+ metadata.gz: 2f5b9a5c58bf1640c1dea1b7e50476ec7f73d8921f643aae09ee78bc6c52831f
4
+ data.tar.gz: d6ab0bf0fe3a61153e932f826495cc63a4ef111d58059a998461f4a75a45dbe7
5
5
  SHA512:
6
- metadata.gz: 6b8d7f60f470bc533c3305cc33c007614b87461c5c0ec64e9d0a535ded2ba5707108cd5c359b89b5f292d215a2aa1ed2eaeffed9c55efa6a0c8f0dd51b46d08a
7
- data.tar.gz: 80532f0a06a7f8d4e810c80ef4c90ddac5e1bf4513bb17e10bc2b1659ed0e7319ed620649f655285d03fe34b1e5a971359d7fa676192f02b0089c17a08f8bd39
6
+ metadata.gz: 97e1173843fbd7856cd3b533cdb7dafc0377825709756c07f32ac17b2645264b77fa3bc96dffba72bcd9142c6312911497d2117b237dfe04c8b91aa26eeded29
7
+ data.tar.gz: 28f6dddae3bef46b9dfa12ec10195c33c6a4cef8dbae0a629123d8b6bea92a289a0e378fde25a27c68cb3c83f183a332b720b8ad2d89b72f2c7e11eeac749fc4
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/dev-20200912-bbb4b34cb579f3d52320c3d2aed8ebcef04429b0/cli/SmartPy.sh > SmartPy.sh
17
- - chmod +x ./SmartPy.sh
18
- - ./SmartPy.sh local-install-auto $HOME/bin/smartpy/cli
19
- - rm ./SmartPy.sh
20
- - export PATH="$PATH:$HOME/bin/:$HOME/bin/smartpy/cli/"
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.3.1)
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.3)
18
- actionview (= 6.0.3.3)
19
- activesupport (= 6.0.3.3)
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.3)
25
- activesupport (= 6.0.3.3)
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.3)
31
- activemodel (>= 4, < 7)
32
- activemodel (6.0.3.3)
33
- activesupport (= 6.0.3.3)
34
- activesupport (6.0.3.3)
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.7)
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.5)
62
+ i18n (1.8.9)
63
63
  concurrent-ruby (~> 1.0)
64
- jaro_winkler (1.5.3)
65
- loofah (2.7.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.2)
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.10)
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.3)
96
- actionpack (= 6.0.3.3)
97
- activesupport (= 6.0.3.3)
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.4.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
- [SmartPy](https://smartpy.io/)
23
+ [SmartPy](https://smartpy.io/releases/20210317-bc925bb73dc885ac2b4dde9689e805d9b0bc6125/)
28
24
 
29
25
  ```bash
30
- sh <(curl -s https://SmartPy.io/SmartPyBasic/SmartPy.sh) local-install /
26
+ sh <(curl -s https://smartpy.io/releases/20210317-bc925bb73dc885ac2b4dde9689e805d9b0bc6125/cli/install.sh)
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"
@@ -80,7 +82,7 @@ class TezosClient
80
82
  #
81
83
  # @return [Hash] result of the origination containing :operation_id, :operation_result and :originated_contract
82
84
  #
83
- def originate_contract(from:, amount:, secret_key: nil, script: nil, init_params: nil, dry_run: false, **args)
85
+ def originate_contract(from:, amount:, secret_key: nil, script: nil, init_params: [], dry_run: false, **args)
84
86
  origination_args = {
85
87
  rpc_interface: rpc_interface,
86
88
  from: from,
@@ -90,9 +92,9 @@ class TezosClient
90
92
  }
91
93
 
92
94
  origination_args[:script] = contract_interface(script).origination_script(
93
- from: from,
94
95
  script: script,
95
- init_params: init_params
96
+ init_params: init_params,
97
+ **args
96
98
  )
97
99
 
98
100
  operation = OriginationOperation.new(origination_args)
@@ -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)
@@ -26,6 +26,7 @@ class TezosClient
26
26
  :block_operations,
27
27
  :contract_storage_type,
28
28
  :entrypoint,
29
- :entrypoints
29
+ :entrypoints,
30
+ :select_entrypoint
30
31
  end
31
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) }
@@ -1,20 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "smartpy_inteface/smartpy_wrapper"
4
- require_relative "smartpy_inteface/micheline_serializer_wrapper"
5
4
 
6
5
  class TezosClient
7
6
  class SmartpyInterface
8
7
  include Logger
9
8
  include SmartpyWrapper
10
- include MichelineSerializerWrapper
11
9
 
12
10
  attr_reader :options
13
11
 
14
12
  def json_scripts(args)
15
13
  compile_to_michelson(args) do |contract_script_filename, init_script_filename|
16
14
  micheline_contract = File.read(contract_script_filename)
17
- micheline_storage = convert_michelson_to_micheline(File.read(init_script_filename))
15
+ micheline_storage = File.read(init_script_filename)
18
16
 
19
17
  [JSON.parse(micheline_storage), JSON.parse(micheline_contract)]
20
18
  end
@@ -34,12 +32,46 @@ class TezosClient
34
32
  Tools::TemporaryFile.with_file_copy(args[:script]) do |script_copy_path|
35
33
  script_basename = script_copy_path.split("/").last.sub(/.py$/, "")
36
34
  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]
35
+ init_script_filename = "step_000_cont_0_storage.json"
36
+ contract_script_filename = "step_000_cont_0_contract.json"
40
37
 
41
- yield(script_path + contract_script_filename, script_path + init_script_filename)
38
+ cmd_line = ["compile", script_copy_path, script_path].concat(
39
+ optional_inputs(args[:smartpy_flags], args[:init_params])
40
+ )
41
+
42
+ call_smartpy cmd_line
43
+
44
+ yield(script_path + "default/" + contract_script_filename, script_path + "default/" + init_script_filename)
42
45
  end
43
46
  end
47
+
48
+ def optional_inputs(flags, init_params)
49
+ inputs = []
50
+
51
+ inputs.concat(optional_flags(flags))
52
+ inputs.concat(optional_args(init_params))
53
+
54
+ inputs
55
+ end
56
+
57
+ def optional_flags(flags)
58
+ (flags || {}).map do |key, value|
59
+ if value.is_a?(FalseClass) || value.is_a?(TrueClass)
60
+ "--#{key}"
61
+ else
62
+ ["--#{key}", value.to_s]
63
+ end
64
+ end.flatten
65
+ end
66
+
67
+ def optional_args(init_params = [])
68
+ return [] if init_params.count.zero?
69
+
70
+ ["--"].concat(
71
+ init_params.map do |init_param|
72
+ init_param.to_json
73
+ end
74
+ )
75
+ end
44
76
  end
45
77
  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,16 +29,28 @@ 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
52
  return [
27
- {
28
- "prim" => annot_type,
29
- "annots" => ["%#{annot}"]
30
- },
53
+ micheline_type(annot_type, annot),
31
54
  {
32
55
  "prim" => "pair",
33
56
  "args" => generate_type_args(annots)
@@ -35,10 +58,10 @@ class TezosClient::Tools::AnnotsToType < ActiveInteraction::Base
35
58
  ]
36
59
  end
37
60
 
38
- generated_args = [{ "prim" => annot_type, "annots" => ["%#{annot}"] }]
61
+ generated_args = [micheline_type(annot_type, annot)]
39
62
  annot = annots.pop
40
63
  annot_type = typed_annots[annot]
41
- generated_args.append({ "prim" => annot_type, "annots" => ["%#{annot}"] })
64
+ generated_args.append(micheline_type(annot_type, annot))
42
65
 
43
66
  generated_args
44
67
  end
@@ -48,8 +71,8 @@ class TezosClient::Tools::AnnotsToType < ActiveInteraction::Base
48
71
  end
49
72
 
50
73
  def validate_types
51
- allowed_types = TezosClient::Tools::HashToMicheline::TYPES_MAPPING.keys
52
- 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 }
53
76
 
54
77
  errors.add(:base, "The allowed types are: #{allowed_types.join(', ')}")
55
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
@@ -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
@@ -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,81 +13,32 @@ 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: %i[entrypoint entrypoints], 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
-
44
- if h[:prim] == "option"
45
- value = params.fetch(annot)
46
- if value
47
- acc << {
48
- "prim": "Some",
49
- "args": [
50
- hash_type_to_hash_data(h[:args][0][:prim], params.fetch(annot))
51
- ]
52
- }
53
- else
54
- acc << {
55
- "prim": "None"
56
- }
57
- end
58
- else
59
- acc << hash_type_to_hash_data(h[:prim], params.fetch(annot))
60
- end
61
- end
62
- end
63
-
64
- def convert_type(michelson_type)
65
- TYPES_MAPPING.fetch(michelson_type.to_sym)
66
- end
67
-
68
- def hash_type_to_hash_data(michelson_type, value)
69
- type = convert_type(michelson_type)
70
-
71
- converted_value = case michelson_type.to_sym
72
- when :nat, :int
73
- value.to_s
74
- when :timestamp
75
- errors.add(:base, "timestamp input must be an instance of Time") unless value.is_a? Time
76
-
77
- value.to_i.to_s
78
- else
79
- value
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
80
34
  end
81
-
82
- { type => converted_value }
83
35
  end
84
36
 
85
37
  def _entrypoint
86
- @_entrypoint ||= select_entrypoint
87
- end
88
-
89
- def select_entrypoint
90
- entrypoints = blockchain_client.entrypoints(contract_address)["entrypoints"].keys
91
- if entrypoints.count == 0
92
- "default"
93
- elsif entrypoints.include?(entrypoint)
94
- entrypoint
95
- else
96
- errors.add(:entrypoint, :not_found)
97
- end
38
+ @_entrypoint ||= blockchain_client.select_entrypoint(
39
+ contract_address: contract_address,
40
+ entrypoint: entrypoint
41
+ )
98
42
  end
99
43
 
100
44
  def _storage_type
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class TezosClient
4
- VERSION = "1.3.1"
4
+ VERSION = "1.4.0"
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.3.1
4
+ version: 1.4.0
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-09-24 00:00:00.000000000 Z
11
+ date: 2021-04-13 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
@@ -270,7 +270,6 @@ files:
270
270
  - lib/tezos_client/rpc_interface/monitor.rb
271
271
  - lib/tezos_client/rpc_interface/operations.rb
272
272
  - lib/tezos_client/rpc_interface/request_manager.rb
273
- - lib/tezos_client/smartpy_inteface/micheline_serializer_wrapper.rb
274
273
  - lib/tezos_client/smartpy_inteface/smartpy_wrapper.rb
275
274
  - lib/tezos_client/smartpy_interface.rb
276
275
  - lib/tezos_client/string_utils.rb
@@ -292,6 +291,18 @@ files:
292
291
  - lib/tezos_client/tools/convert_to_hash/timestamp.rb
293
292
  - lib/tezos_client/tools/find_big_maps_in_storage.rb
294
293
  - lib/tezos_client/tools/hash_to_micheline.rb
294
+ - lib/tezos_client/tools/hash_to_micheline/address.rb
295
+ - lib/tezos_client/tools/hash_to_micheline/base.rb
296
+ - lib/tezos_client/tools/hash_to_micheline/bytes.rb
297
+ - lib/tezos_client/tools/hash_to_micheline/contract.rb
298
+ - lib/tezos_client/tools/hash_to_micheline/int.rb
299
+ - lib/tezos_client/tools/hash_to_micheline/key.rb
300
+ - lib/tezos_client/tools/hash_to_micheline/nat.rb
301
+ - lib/tezos_client/tools/hash_to_micheline/option.rb
302
+ - lib/tezos_client/tools/hash_to_micheline/pair.rb
303
+ - lib/tezos_client/tools/hash_to_micheline/signature.rb
304
+ - lib/tezos_client/tools/hash_to_micheline/string.rb
305
+ - lib/tezos_client/tools/hash_to_micheline/timestamp.rb
295
306
  - lib/tezos_client/tools/system_call.rb
296
307
  - lib/tezos_client/tools/temporary_file.rb
297
308
  - lib/tezos_client/version.rb
@@ -317,7 +328,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
317
328
  - !ruby/object:Gem::Version
318
329
  version: '0'
319
330
  requirements: []
320
- rubygems_version: 3.0.3
331
+ rubygems_version: 3.0.8
321
332
  signing_key:
322
333
  specification_version: 4
323
334
  summary: Wrapper to the tezos client.
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class TezosClient
4
- class SmartpyInterface
5
- module MichelineSerializerWrapper
6
- def convert_michelson_to_micheline(script)
7
- cmd = ["michelson-to-micheline", script]
8
-
9
- Tools::SystemCall.execute(cmd)
10
- end
11
-
12
- def actual_project_path
13
- TezosClient.root_path
14
- end
15
- end
16
- end
17
- end