ton_sdk_client 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,466 @@
1
+ module TonSdk
2
+
3
+ # NOTE
4
+ # as of 3 feb 2021, in the main repository this module is still unstable
5
+ module Debot
6
+
7
+ #
8
+ # types
9
+ #
10
+
11
+ module ErrorCode
12
+ START_FAILED = 801
13
+ FETCH_FAILED = 802
14
+ EXECUTION_FAILED = 803
15
+ INVALID_HANDLE = 804
16
+ INVALID_JSON_PARAMS = 805
17
+ INVALID_FUNCTION_ID = 806
18
+ INVALID_ABI = 807
19
+ GET_METHOD_FAILED = 808
20
+ INVALID_MSG = 809
21
+ EXTERNAL_CALL_FAILED = 810
22
+ end
23
+
24
+ class DebotAction
25
+ attr_reader :description, :name, :action_type, :to, :attributes, :misc
26
+
27
+ def initialize(description:, name:, action_type:, to:, attributes:, misc:)
28
+ @description = description
29
+ @name = name
30
+ @action_type = action_type
31
+ @to = to
32
+ @attributes = attributes
33
+ @misc = misc
34
+ end
35
+
36
+ def to_h
37
+ {
38
+ description: @description,
39
+ name: @name,
40
+ action_type: @action_type,
41
+ to: @to,
42
+ attributes: @attributes,
43
+ misc: @misc
44
+ }
45
+ end
46
+
47
+ def self.from_json(j)
48
+ return nil if j.nil?
49
+
50
+ self.new(
51
+ description: j["description"],
52
+ name: j["name"],
53
+ action_type: j["action_type"],
54
+ to: j["to"],
55
+ attributes: j["attributes"],
56
+ misc: j["misc"]
57
+ )
58
+ end
59
+ end
60
+
61
+ class ParamsOfStart
62
+ attr_reader :address
63
+
64
+ def initialize(a)
65
+ @address = a
66
+ end
67
+
68
+ def to_h = { address: @address }
69
+ end
70
+
71
+ class RegisteredDebot
72
+ attr_reader :debot_handle
73
+
74
+ def initialize(a)
75
+ @debot_handle = a
76
+ end
77
+
78
+ def to_h = { debot_handle: @debot_handle }
79
+ end
80
+
81
+ class ParamsOfAppDebotBrowser
82
+
83
+ # todo remove?
84
+ TYPE_VALUES = [
85
+ :log,
86
+ :switch,
87
+ :switch_completed,
88
+ :show_action,
89
+ :input,
90
+ :get_signing_box,
91
+ :invoke_debot,
92
+ :send
93
+ ]
94
+
95
+ attr_reader :type_, :msg, :context_id, :action, :prompt, :debot_addr, :message
96
+
97
+ def new_with_type_log(msg)
98
+ @type_ = :log
99
+ @msg = msg
100
+ end
101
+
102
+ def new_with_type_switch(context_id)
103
+ @type_ = :switch
104
+ @context_id = context_id
105
+ end
106
+
107
+ def new_with_type_switch_completed
108
+ @type_ = :switch_completed
109
+ end
110
+
111
+ def new_with_type_show_action(action)
112
+ @type_ = :show_action
113
+ @action = action
114
+ end
115
+
116
+ def new_with_type_input(prompt)
117
+ @type_ = :input
118
+ @prompt = prompt
119
+ end
120
+
121
+ def new_with_type_get_signing_box
122
+ @type_ = :get_signing_box
123
+ end
124
+
125
+ def new_with_type_invoke_debot(debot_addr, action)
126
+ @type_ = :invoke_debot
127
+ @debot_addr = debot_addr
128
+ @action = action
129
+ end
130
+
131
+ def new_with_type_send(message)
132
+ @type_ = :send
133
+ @message = message
134
+ end
135
+
136
+ def to_h
137
+ {
138
+ type: Helper.sym_to_capitalized_case_str(@type_),
139
+ msg: @msg,
140
+ context_id: @context_id,
141
+ action: @action,
142
+ prompt: @prompt,
143
+ debot_addr: @debot_addr,
144
+ message: @message
145
+ }
146
+ end
147
+
148
+ def self.from_json(j)
149
+ return nil if j.nil?
150
+
151
+ self.new(
152
+ type_: self.parse_type(j["type"]),
153
+ msg: j["msg"],
154
+ context_id: j["context_id"],
155
+ action: DebotAction.from_json(j["action"]),
156
+ prompt: j["prompt"],
157
+ debot_addr: j["debot_addr"]
158
+ )
159
+ end
160
+
161
+ private
162
+
163
+ def self.parse_type(type_str)
164
+ types_str = TYPE_VALUES.map(Helper.capitalized_case_str_to_snake_case_sym)
165
+ unless types_str.include?(type_str)
166
+ raise ArgumentError.new("type #{type_str} is unknown; known types: #{types_str}")
167
+ end
168
+
169
+ Helper.capitalized_case_str_to_snake_case_sym(type_str)
170
+ end
171
+ end
172
+
173
+ class ResultOfAppDebotBrowser
174
+ TYPE_VALUES = [
175
+ :input,
176
+ :get_signing_box,
177
+ :invoke_debot
178
+ ]
179
+
180
+ attr_reader :type_, :value, :signing_box
181
+
182
+ def initialize(type_:, value: nil, signing_box: nil)
183
+ unless TYPE_VALUES.include?(type_)
184
+ raise ArgumentError.new("type #{type_} is unknown; known types: #{TYPE_VALUES}")
185
+ end
186
+ @type_ = type_
187
+ @value = value
188
+ @signing_box = signing_box
189
+ end
190
+ end
191
+
192
+ class ParamsOfFetch
193
+ attr_reader :address
194
+
195
+ def initialize(a)
196
+ @address = a
197
+ end
198
+
199
+ def to_h = { address: @address }
200
+ end
201
+
202
+ class ParamsOfExecute
203
+ attr_reader :debot_handle, :action
204
+
205
+ def initialize(debot_handle:, action:)
206
+ @debot_handle = debot_handle
207
+ @action = action
208
+ end
209
+
210
+ def to_h
211
+ {
212
+ debot_handle: @debot_handle,
213
+ action: @action.to_h
214
+ }
215
+ end
216
+ end
217
+
218
+ class ParamsOfSend
219
+ attr_reader :debot_handle, :message
220
+
221
+ def initialize(debot_handle:, message:)
222
+ @debot_handle = debot_handle
223
+ @message = message
224
+ end
225
+
226
+ def to_h
227
+ {
228
+ debot_handle: @debot_handle,
229
+ message: @message
230
+ }
231
+ end
232
+ end
233
+
234
+ #
235
+ # functions
236
+ #
237
+
238
+ def self.start(ctx, params, app_browser_obj)
239
+ # TODO
240
+ # 1) the handlers in 'start' and 'fetch' are identical
241
+ # verify that it works and get rid of repetition
242
+
243
+ # 2) this all can be replaced with 'app_browser_obj.request(...)' and
244
+ # 'app_browser_obj.notify(...)' calls, possibly
245
+
246
+ app_resp_handler = Proc.new do |data|
247
+ req_data = data["request_data"]
248
+ case data["type"]
249
+ when "Log"
250
+ new_obj = ParamsOfAppDebotBrowser.from_json(data)
251
+ app_browser_obj.log(new_obj.msg)
252
+
253
+ when "Switch"
254
+ new_obj = ParamsOfAppDebotBrowser.from_json(data)
255
+ app_browser_obj.switch_to(new_obj.context_id)
256
+
257
+ when "SwitchCompleted"
258
+ app_browser_obj.switch_completed()
259
+
260
+ when "ShowAction"
261
+ new_obj = ParamsOfAppDebotBrowser.from_json(data)
262
+ app_browser_obj.show_action(new_obj.action)
263
+
264
+ when "Input"
265
+ new_obj = ParamsOfAppDebotBrowser.from_json(data)
266
+ # TODO possibly in a new thread or fiber
267
+ app_req_res = begin
268
+ res = app_browser_obj.input(new_obj.prompt)
269
+ Client::AppRequestResult(type_: :ok, result: ResultOfAppDebotBrowser.new(type_: :input, value: res))
270
+ rescue Exception => e
271
+ Client::AppRequestResult(type_: :error, text: e.message)
272
+ end
273
+
274
+ params = Client::ParamsOfResolveAppRequest.new(
275
+ app_request_id: data["app_request_id"],
276
+ result: app_req_res
277
+ )
278
+ TonSdk::Client.resolve_app_request(c_ctx, params)
279
+
280
+ when "GetSigningBox"
281
+ new_obj = ParamsOfAppDebotBrowser.from_json(data)
282
+ # TODO possibly in a new thread or fiber
283
+ app_req_res = begin
284
+ res = app_browser_obj.get_signing_box()
285
+ Client::AppRequestResult(type_: :ok, result: ResultOfAppDebotBrowser.new(type_: :get_signing_box, signing_box: res))
286
+ rescue Exception => e
287
+ Client::AppRequestResult(type_: :error, text: e.message)
288
+ end
289
+
290
+ params = Client::ParamsOfResolveAppRequest.new(
291
+ app_request_id: data["app_request_id"],
292
+ result: app_req_res
293
+ )
294
+ TonSdk::Client.resolve_app_request(c_ctx, params)
295
+
296
+ when "InvokeDebot"
297
+ new_obj = ParamsOfAppDebotBrowser.from_json(data)
298
+ # TODO possibly in a new thread or fiber
299
+ app_req_res = begin
300
+ res = app_browser_obj.invoke_debot(new_obj.debot_addr, new_obj.action)
301
+ Client::AppRequestResult(type_: :ok, result: ResultOfAppDebotBrowser.new(type_: :invoke_debot))
302
+ rescue Exception => e
303
+ Client::AppRequestResult(type_: :error, text: e.message)
304
+ end
305
+
306
+ params = Client::ParamsOfResolveAppRequest.new(
307
+ app_request_id: data["app_request_id"],
308
+ result: app_req_res
309
+ )
310
+ TonSdk::Client.resolve_app_request(c_ctx, params)
311
+
312
+ else
313
+ # TODO log 'unknown option'
314
+ end
315
+ end
316
+
317
+ Interop::request_to_native_lib(
318
+ ctx,
319
+ "debot.start",
320
+ params.to_h.to_json,
321
+ debot_app_response_handler: app_resp_handler,
322
+ is_single_thread_only: false
323
+ ) do |resp|
324
+ if resp.success?
325
+ yield NativeLibResponsetResult.new(
326
+ result: RegisteredDebot.new(resp.result["debot_handle"])
327
+ )
328
+ else
329
+ yield resp
330
+ end
331
+ end
332
+ end
333
+
334
+ def self.fetch(ctx, params, app_browser_obj)
335
+ # TODO
336
+ # 1) the handlers in 'start' and 'fetch' are identical
337
+ # verify that it works and get rid of repetition
338
+
339
+ # 2) this all can be replaced with 'app_browser_obj.request(...)' and
340
+ # 'app_browser_obj.notify(...)' calls, possibly
341
+
342
+ app_resp_handler = Proc.new do |data|
343
+ req_data = data["request_data"]
344
+ case data["type"]
345
+ when "Log"
346
+ new_obj = ParamsOfAppDebotBrowser.from_json(data)
347
+ app_browser_obj.log(new_obj.msg)
348
+
349
+ when "Switch"
350
+ new_obj = ParamsOfAppDebotBrowser.from_json(data)
351
+ app_browser_obj.switch_to(new_obj.context_id)
352
+
353
+ when "SwitchCompleted"
354
+ app_browser_obj.switch_completed()
355
+
356
+ when "ShowAction"
357
+ new_obj = ParamsOfAppDebotBrowser.from_json(data)
358
+ app_browser_obj.show_action(new_obj.action)
359
+
360
+ when "Input"
361
+ new_obj = ParamsOfAppDebotBrowser.from_json(data)
362
+ # TODO possibly in a new thread or fiber
363
+ app_req_res = begin
364
+ res = app_browser_obj.input(new_obj.prompt)
365
+ Client::AppRequestResult(type_: :ok, result: ResultOfAppDebotBrowser.new(type_: :input, value: res))
366
+ rescue Exception => e
367
+ Client::AppRequestResult(type_: :error, text: e.message)
368
+ end
369
+
370
+ params = Client::ParamsOfResolveAppRequest.new(
371
+ app_request_id: data["app_request_id"],
372
+ result: app_req_res
373
+ )
374
+ TonSdk::Client.resolve_app_request(c_ctx, params)
375
+
376
+ when "GetSigningBox"
377
+ new_obj = ParamsOfAppDebotBrowser.from_json(data)
378
+ # TODO possibly in a new thread or fiber
379
+ app_req_res = begin
380
+ res = app_browser_obj.get_signing_box()
381
+ Client::AppRequestResult(type_: :ok, result: ResultOfAppDebotBrowser.new(type_: :get_signing_box, signing_box: res))
382
+ rescue Exception => e
383
+ Client::AppRequestResult(type_: :error, text: e.message)
384
+ end
385
+
386
+ params = Client::ParamsOfResolveAppRequest.new(
387
+ app_request_id: data["app_request_id"],
388
+ result: app_req_res
389
+ )
390
+ TonSdk::Client.resolve_app_request(c_ctx, params)
391
+
392
+ when "InvokeDebot"
393
+ new_obj = ParamsOfAppDebotBrowser.from_json(data)
394
+ # TODO possibly in a new thread or fiber
395
+ app_req_res = begin
396
+ res = app_browser_obj.invoke_debot(new_obj.debot_addr, new_obj.action)
397
+ Client::AppRequestResult(type_: :ok, result: ResultOfAppDebotBrowser.new(type_: :invoke_debot))
398
+ rescue Exception => e
399
+ Client::AppRequestResult(type_: :error, text: e.message)
400
+ end
401
+
402
+ params = Client::ParamsOfResolveAppRequest.new(
403
+ app_request_id: data["app_request_id"],
404
+ result: app_req_res
405
+ )
406
+ TonSdk::Client.resolve_app_request(c_ctx, params)
407
+
408
+ else
409
+ # TODO log 'unknown option'
410
+ end
411
+ end
412
+
413
+ Interop::request_to_native_lib(
414
+ ctx,
415
+ "debot.fetch",
416
+ params.to_h.to_json,
417
+ debot_app_response_handler: app_resp_handler,
418
+ is_single_thread_only: false
419
+ ) do |resp|
420
+ if resp.success?
421
+ yield NativeLibResponsetResult.new(
422
+ result: RegisteredDebot.new(resp.result["debot_handle"])
423
+ )
424
+ else
425
+ yield resp
426
+ end
427
+ end
428
+ end
429
+
430
+ def self.execute(ctx, params)
431
+ Interop::request_to_native_lib(ctx, "debot.execute", params.to_h.to_json) do |resp|
432
+ if resp.success?
433
+ yield NativeLibResponsetResult.new(
434
+ result: nil
435
+ )
436
+ else
437
+ yield resp
438
+ end
439
+ end
440
+ end
441
+
442
+ def self.remove(ctx, params)
443
+ Interop::request_to_native_lib(ctx, "debot.remove", params.to_h.to_json) do |resp|
444
+ if resp.success?
445
+ yield NativeLibResponsetResult.new(
446
+ result: nil
447
+ )
448
+ else
449
+ yield resp
450
+ end
451
+ end
452
+ end
453
+
454
+ def self.send(ctx, params)
455
+ Interop::request_to_native_lib(ctx, "debot.send", params.to_h.to_json) do |resp|
456
+ if resp.success?
457
+ yield NativeLibResponsetResult.new(
458
+ result: nil
459
+ )
460
+ else
461
+ yield resp
462
+ end
463
+ end
464
+ end
465
+ end
466
+ end