ton-client-ruby 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/ton-client-ruby +42 -0
- data/lib/code_generator/api_converter.rb +399 -0
- data/lib/code_generator/code_generator.rb +325 -0
- data/lib/code_generator/helpers.rb +13 -0
- data/lib/ton-client-ruby.rb +1 -0
- data/lib/ton-client-ruby/Binding/binding.rb +3 -6
- data/lib/ton-client-ruby/Client/Abi.rb +88 -6
- data/lib/ton-client-ruby/Client/Boc.rb +53 -6
- data/lib/ton-client-ruby/Client/Client.rb +41 -25
- data/lib/ton-client-ruby/Client/Context.rb +7 -2
- data/lib/ton-client-ruby/Client/Crypto.rb +200 -30
- data/lib/ton-client-ruby/Client/Debot.rb +22 -6
- data/lib/ton-client-ruby/Client/Net.rb +79 -12
- data/lib/ton-client-ruby/Client/Processing.rb +31 -6
- data/lib/ton-client-ruby/Client/Tvm.rb +36 -6
- data/lib/ton-client-ruby/Client/Utils.rb +21 -6
- data/lib/ton-client-ruby/Helpers/CommonHelpers.rb +35 -0
- data/lib/ton-client-ruby/version.rb +1 -1
- metadata +10 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d9f09aaabae6ed86f5adc9a77082f2c94ad685437fb7457e490253086ca80b5
|
4
|
+
data.tar.gz: 6e2e1b73de3671c362fbb0ebdb919e9fdc7b94fabe8302b46fc3159ba42100af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 621cc074093d4de7603aa1135dc597681aaf72337f42bab12bb9e3692f58462f7eb7696e04b029945abda6c85dbc584bc8d72804d89882d1d98966a69a139acd
|
7
|
+
data.tar.gz: 9cf4d820e210ab28a1a64dbf6474b954de1b35166c692321b648464b3258b88a033678382a222237814a93b206c0f5ce07734399e0bd72774ff5a1f207a856be
|
data/bin/ton-client-ruby
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../lib/code_generator/api_converter.rb'
|
4
|
+
require File.dirname(__FILE__) + '/../lib/code_generator/code_generator.rb'
|
5
|
+
|
6
|
+
GEM_DIR = File.dirname(__FILE__) + '/..'
|
7
|
+
|
8
|
+
if ARGV[0] == 'update'
|
9
|
+
if !ARGV[1]
|
10
|
+
puts ''
|
11
|
+
puts ''
|
12
|
+
p "PLEASE DOWNLOAD api.json from https://github.com/tonlabs/TON-SDK/blob/master/tools/api.json and pass as second parameter."
|
13
|
+
p "Example: ton-client-ruby update ./api.json"
|
14
|
+
puts ''
|
15
|
+
return
|
16
|
+
end
|
17
|
+
api_json_path = ARGV[1]
|
18
|
+
json = ''
|
19
|
+
if File.exists?(api_json_path)
|
20
|
+
json = File.read(api_json_path)
|
21
|
+
else
|
22
|
+
p "Current directory: #{Dir.pwd}. File #{api_json_path} is not exist"
|
23
|
+
exit 0
|
24
|
+
end
|
25
|
+
converter = ApiConverter.new(json)
|
26
|
+
types = converter.convert
|
27
|
+
generator = CodeGenerator.new(types, GEM_DIR)
|
28
|
+
generator.generate_self_code
|
29
|
+
elsif ARGV[0] == 'update' && ARGV[1] == nil
|
30
|
+
p 'soon from github'
|
31
|
+
elsif ARGV[0] == 'setup'
|
32
|
+
raise "\nPLEASE INSTALL RUST TO YOUR SYSTEM. \nTry this command: \ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh" if `which rustc`.strip.empty?
|
33
|
+
unless Dir.exist?("#{GEM_DIR}/TON-SDK")
|
34
|
+
system("cd #{GEM_DIR} && git clone https://github.com/tonlabs/TON-SDK ./TON-SDK")
|
35
|
+
end
|
36
|
+
system("cd #{GEM_DIR}/TON-SDK && git pull --ff-only")
|
37
|
+
system("cd #{GEM_DIR}/TON-SDK && cargo update")
|
38
|
+
system("cd #{GEM_DIR}/TON-SDK && cargo build --release")
|
39
|
+
puts ''
|
40
|
+
puts "PATH TO YOR DYNAMIC LIBRARY IS: #{GEM_DIR}/TON-SDK/target/release/libton_client.dylib"
|
41
|
+
puts ''
|
42
|
+
end
|
@@ -0,0 +1,399 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'byebug'
|
3
|
+
require File.dirname(__FILE__) + '/helpers.rb'
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
class ApiConverter
|
8
|
+
include InstanceHelpers
|
9
|
+
|
10
|
+
attr_reader :api_hash
|
11
|
+
|
12
|
+
def initialize(api_json)
|
13
|
+
@api_hash = JSON.parse(api_json)
|
14
|
+
end
|
15
|
+
|
16
|
+
def convert
|
17
|
+
ruby_types = ApiRubyTypes.new(version: api_hash['version'], modules: [])
|
18
|
+
|
19
|
+
(api_hash['modules'] || []).each do |mod|
|
20
|
+
new_mod = convert_module(mod)
|
21
|
+
ruby_types.modules << new_mod
|
22
|
+
ruby_types.all_types.merge!(new_mod.types_hash)
|
23
|
+
end
|
24
|
+
|
25
|
+
ruby_types
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def convert_module(mod)
|
31
|
+
new_module = Module.new(name: mod['name'], alias: [], functions: [], enums: [], types: [], summary: mod['summary'], description: mod['description'])
|
32
|
+
(mod['types'] || []).each do |type|
|
33
|
+
if type['type'] == 'EnumOfTypes'
|
34
|
+
new_enum, new_struct = convert_fucking_enum_of_types(type)
|
35
|
+
new_module.enums << new_enum
|
36
|
+
new_module.types << new_struct
|
37
|
+
new_module.types_hash[new_enum.name] = new_enum
|
38
|
+
new_module.types_hash[new_struct.name] = new_struct
|
39
|
+
elsif type['type'] == 'EnumOfConsts'
|
40
|
+
new_type = convertEnumOfConsts(type)
|
41
|
+
new_module.enums << new_type
|
42
|
+
new_module.types_hash[new_type.name] = new_type
|
43
|
+
elsif type['type'] == 'Struct'
|
44
|
+
new_type = convertStruct(type)
|
45
|
+
new_module.types << new_type
|
46
|
+
new_module.types_hash[new_type.name] = new_type
|
47
|
+
elsif type['type'] == 'Number'
|
48
|
+
new_type = convertTypeAlias(type)
|
49
|
+
new_module.alias << new_type
|
50
|
+
new_module.types_hash[new_type.name] = new_type
|
51
|
+
else
|
52
|
+
raise "Unkown NEW TYPE for module #{type['name']} \"types\": #{type['types']}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# /// FUNCTIONS
|
57
|
+
(mod['functions'] || []).each do |function|
|
58
|
+
result = ""
|
59
|
+
if function['result']['type'] == "Generic"
|
60
|
+
ref_type = function['result']['generic_args'].first&.send(:[], 'type') || ""
|
61
|
+
if ref_type == "Ref"
|
62
|
+
ref_name = function['result']['generic_args'].first&.send(:[], 'ref_name') || ""
|
63
|
+
if ref_name[/^(.+)\.(.+)$/]
|
64
|
+
mod = $1
|
65
|
+
type = $2
|
66
|
+
result = "#{lib_prefix}#{type}"
|
67
|
+
else
|
68
|
+
raise "Bad function result ref_name: #{ref_name}, function name: #{function['name']}, result: #{function['result']}"
|
69
|
+
end
|
70
|
+
elsif ref_type == "None"
|
71
|
+
result = "Void"
|
72
|
+
end
|
73
|
+
else
|
74
|
+
raise "New function result type !"
|
75
|
+
end
|
76
|
+
|
77
|
+
# /// function
|
78
|
+
newFunction = StructFunction.new(name: checkFunctionName(function['name']), arguments: [], result: result, summary: function['summary'], description: function['description'])
|
79
|
+
# /// FUNCTION PARAMETERS
|
80
|
+
paramsCount = 0
|
81
|
+
(function['params'] || []).each do |parameter|
|
82
|
+
if parameter['name'] == "params"
|
83
|
+
paramsCount += 1
|
84
|
+
if parameter['type'] == "Ref"
|
85
|
+
ref_name = parameter['ref_name'] || ""
|
86
|
+
if ref_name[/^(.+)\.(.+)$/]
|
87
|
+
mod = $1
|
88
|
+
type = $2
|
89
|
+
newFunction.arguments << FunctionArgument.new(name: "payload", type: "#{lib_prefix}#{type}")
|
90
|
+
else
|
91
|
+
raise "Bad function params ref_name: #{ref_name}, function name: #{function['name']}, result: #{function['result']}"
|
92
|
+
end
|
93
|
+
else
|
94
|
+
raise "NEW CASE! New parameter type: #{parameter['type']}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
raise "NEW CASE ! More then one parameter for functions !" if paramsCount > 1
|
98
|
+
end
|
99
|
+
|
100
|
+
new_module.functions << newFunction
|
101
|
+
end
|
102
|
+
|
103
|
+
new_module
|
104
|
+
end
|
105
|
+
|
106
|
+
def convertTypeAlias(from)
|
107
|
+
TypeAlias.new(name: "#{lib_prefix}#{from['name']}", type: generateType(from))
|
108
|
+
end
|
109
|
+
|
110
|
+
def convertStruct(from)
|
111
|
+
result = TypeStruct.new(name: "#{lib_prefix}#{from['name']}", parents: [], fields: [], functions: [])
|
112
|
+
(from['struct_fields'] || []).each do |field|
|
113
|
+
if isValidPropertyName(field['name'])
|
114
|
+
type = generateType(field)
|
115
|
+
if ( (from['name'] || "")[/Params/] || (field['name'] || "")[/input/]) && type[/Value/]
|
116
|
+
type = "Value"
|
117
|
+
elsif (field['name'] || "")[/^dictionary$/]
|
118
|
+
type = "#{lib_prefix}MnemonicDictionary"
|
119
|
+
elsif type[/Abi<Optional>/]
|
120
|
+
type = "Value<Optional>"
|
121
|
+
elsif type[/Abi/]
|
122
|
+
type = "Value"
|
123
|
+
end
|
124
|
+
property = StructField.new(name: checkPropertyName(field['name']), type: type, summary: field['summary'], description: field['description'])
|
125
|
+
result.fields << property
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
result
|
130
|
+
end
|
131
|
+
|
132
|
+
private def checkPropertyName(name)
|
133
|
+
result = ""
|
134
|
+
raise "Property Name is nil" unless name
|
135
|
+
|
136
|
+
case name
|
137
|
+
when "public"
|
138
|
+
result = "public"
|
139
|
+
else
|
140
|
+
result = name
|
141
|
+
end
|
142
|
+
|
143
|
+
return result
|
144
|
+
end
|
145
|
+
|
146
|
+
private def checkFunctionName(name)
|
147
|
+
result = ""
|
148
|
+
raise "Property Name is nil" unless name
|
149
|
+
case name
|
150
|
+
when "init"
|
151
|
+
result = "init"
|
152
|
+
else
|
153
|
+
result = name
|
154
|
+
end
|
155
|
+
|
156
|
+
return result
|
157
|
+
end
|
158
|
+
|
159
|
+
private def isValidPropertyName(name)
|
160
|
+
!(name || " ")[/\s/]
|
161
|
+
end
|
162
|
+
|
163
|
+
def convertEnumOfConsts(from)
|
164
|
+
result = TypeEnum.new(name: "#{lib_prefix}#{from['name']}", parents: [], cases: [], summary: from['summary'], description: from['description'])
|
165
|
+
(from['enum_consts'] || []).each do |enumConst|
|
166
|
+
caseName = enumConst['name']
|
167
|
+
caseValue = enumConst['value']
|
168
|
+
result.cases << EnumCase.new(name: caseName, value: caseValue, summary: enumConst['summary'], description: enumConst['description'])
|
169
|
+
end
|
170
|
+
|
171
|
+
return result
|
172
|
+
end
|
173
|
+
|
174
|
+
def convert_fucking_enum_of_types(enum)
|
175
|
+
result = [
|
176
|
+
TypeEnum.new(name: generate_enum_name(enum['name']), parents: [], cases: []),
|
177
|
+
TypeStruct.new(name: generate_struct_name(enum['name']), parents: [], fields: [], functions: [], summary: enum['summary'], description: enum['description'])
|
178
|
+
]
|
179
|
+
properties_name_set = Set.new
|
180
|
+
properties = []
|
181
|
+
(enum['enum_types'] || []).each do |enum_type|
|
182
|
+
result[0].cases << EnumCase.new(name: enum_type['name'], value: enum_type['name'])
|
183
|
+
(enum_type['struct_fields'] || []).each do |field|
|
184
|
+
if !properties_name_set.include?(field['name'])
|
185
|
+
properties << field
|
186
|
+
end
|
187
|
+
properties_name_set << field['name']
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
result[1].fields << StructField.new(name: "type", type: generate_enum_name(enum['name']))
|
192
|
+
properties.each do |property|
|
193
|
+
type = generateType(property)
|
194
|
+
if property['name'][/^dictionary$/]
|
195
|
+
type = "#{lib_prefix}MnemonicDictionary"
|
196
|
+
end
|
197
|
+
result[1].fields << StructField.new(name: property['name'], type: type, summary: property['summary'], description: property['description'])
|
198
|
+
end
|
199
|
+
result
|
200
|
+
end
|
201
|
+
|
202
|
+
private def generateSimpleType(type)
|
203
|
+
tempType = ""
|
204
|
+
|
205
|
+
if type['type'] == "Ref"
|
206
|
+
if type['ref_name'] == "Value" || type['ref_name'] == "API"
|
207
|
+
tempType = "Value"
|
208
|
+
else
|
209
|
+
return type['optional'] ? "#{generateRefType(type['ref_name'] || "nil")}<Optional>" : generateRefType(type['ref_name'] || "nil")
|
210
|
+
end
|
211
|
+
else
|
212
|
+
tempType = type['type']
|
213
|
+
end
|
214
|
+
tempType = "#{tempType}<Optional>" if type['optional']
|
215
|
+
|
216
|
+
tempType
|
217
|
+
end
|
218
|
+
|
219
|
+
private def generateRefType(type)
|
220
|
+
result = ""
|
221
|
+
|
222
|
+
if type[/(.+)\.(.+)/]
|
223
|
+
mod = $1
|
224
|
+
typeName = $2
|
225
|
+
result = "#{lib_prefix}#{typeName}"
|
226
|
+
else
|
227
|
+
result = "#{lib_prefix}#{type}"
|
228
|
+
end
|
229
|
+
|
230
|
+
result
|
231
|
+
end
|
232
|
+
|
233
|
+
private def generateType(type)
|
234
|
+
if type['type'] == "Optional" && type['optional_inner']
|
235
|
+
type['optional'] = true
|
236
|
+
type['optional_inner']['optional'] = true
|
237
|
+
if type['optional_inner']['type'] == "Optional"
|
238
|
+
return generateType(type['optional_inner'])
|
239
|
+
else
|
240
|
+
return generateSimpleType(type['optional_inner'])
|
241
|
+
end
|
242
|
+
else
|
243
|
+
return generateSimpleType(type)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
private def generate_enum_name(name)
|
248
|
+
"#{lib_prefix}#{name}#{lib_enum_postfix}"
|
249
|
+
end
|
250
|
+
|
251
|
+
private def generate_struct_name(name)
|
252
|
+
"#{lib_prefix}#{name}"
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
|
257
|
+
class ApiRubyTypes
|
258
|
+
attr_accessor :version
|
259
|
+
attr_accessor :modules
|
260
|
+
attr_accessor :all_types
|
261
|
+
|
262
|
+
def initialize(params)
|
263
|
+
@all_types = {}
|
264
|
+
params.each do |k, v|
|
265
|
+
if self.respond_to?(k.to_sym)
|
266
|
+
instance_variable_set("@#{k}".to_sym, v)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
class Module
|
273
|
+
attr_accessor :name
|
274
|
+
attr_accessor :summary
|
275
|
+
attr_accessor :description
|
276
|
+
attr_accessor :alias
|
277
|
+
attr_accessor :enums
|
278
|
+
attr_accessor :types
|
279
|
+
attr_accessor :types_hash
|
280
|
+
attr_accessor :functions
|
281
|
+
attr_accessor :summary
|
282
|
+
attr_accessor :description
|
283
|
+
|
284
|
+
def initialize(params)
|
285
|
+
@types_hash = {}
|
286
|
+
params.each do |k, v|
|
287
|
+
if self.respond_to?(k.to_sym)
|
288
|
+
instance_variable_set("@#{k}".to_sym, v)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
class TypeAlias
|
295
|
+
attr_accessor :name
|
296
|
+
attr_accessor :type
|
297
|
+
attr_accessor :summary
|
298
|
+
attr_accessor :description
|
299
|
+
|
300
|
+
def initialize(params)
|
301
|
+
params.each do |k, v|
|
302
|
+
if self.respond_to?(k.to_sym)
|
303
|
+
instance_variable_set("@#{k}".to_sym, v)
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
class TypeEnum
|
310
|
+
attr_accessor :name
|
311
|
+
attr_accessor :parents
|
312
|
+
attr_accessor :cases
|
313
|
+
attr_accessor :summary
|
314
|
+
attr_accessor :description
|
315
|
+
|
316
|
+
def initialize(params)
|
317
|
+
params.each do |k, v|
|
318
|
+
if self.respond_to?(k.to_sym)
|
319
|
+
instance_variable_set("@#{k}".to_sym, v)
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
class EnumCase
|
326
|
+
attr_accessor :name
|
327
|
+
attr_accessor :value
|
328
|
+
attr_accessor :summary
|
329
|
+
attr_accessor :description
|
330
|
+
|
331
|
+
def initialize(params)
|
332
|
+
params.each do |k, v|
|
333
|
+
if self.respond_to?(k)
|
334
|
+
instance_variable_set("@#{k}".to_sym, v)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
class TypeStruct
|
341
|
+
attr_accessor :name
|
342
|
+
attr_accessor :parents
|
343
|
+
attr_accessor :fields
|
344
|
+
attr_accessor :functions
|
345
|
+
attr_accessor :summary
|
346
|
+
attr_accessor :description
|
347
|
+
|
348
|
+
def initialize(params)
|
349
|
+
params.each do |k, v|
|
350
|
+
if self.respond_to?(k.to_sym)
|
351
|
+
instance_variable_set("@#{k}".to_sym, v)
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
class StructField
|
358
|
+
attr_accessor :name
|
359
|
+
attr_accessor :type
|
360
|
+
attr_accessor :summary
|
361
|
+
attr_accessor :description
|
362
|
+
|
363
|
+
def initialize(params)
|
364
|
+
params.each do |k, v|
|
365
|
+
if self.respond_to?(k.to_sym)
|
366
|
+
instance_variable_set("@#{k}".to_sym, v)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
class StructFunction
|
373
|
+
attr_accessor :name
|
374
|
+
attr_accessor :arguments
|
375
|
+
attr_accessor :result
|
376
|
+
attr_accessor :summary
|
377
|
+
attr_accessor :description
|
378
|
+
|
379
|
+
def initialize(params)
|
380
|
+
params.each do |k, v|
|
381
|
+
if self.respond_to?(k.to_sym)
|
382
|
+
instance_variable_set("@#{k}".to_sym, v)
|
383
|
+
end
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
class FunctionArgument
|
389
|
+
attr_accessor :name
|
390
|
+
attr_accessor :type
|
391
|
+
|
392
|
+
def initialize(params)
|
393
|
+
params.each do |k, v|
|
394
|
+
if self.respond_to?(k.to_sym)
|
395
|
+
instance_variable_set("@#{k}".to_sym, v)
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|