steem-ruby 0.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.
@@ -0,0 +1,1056 @@
1
+ require 'bitcoin'
2
+ require 'digest'
3
+ require 'time'
4
+
5
+ module Steem
6
+
7
+ # These class methods make it simple to do things like broacast a {Broadcast#vote}
8
+ # or {Broadcast#comment} operation. They accept all of the fields expected by
9
+ # the blockchain plus the following additional options:
10
+ #
11
+ # * wif
12
+ # * url (optional)
13
+ # * database_api (optional)
14
+ # * block_api (optional)
15
+ # * network_broadcast_api (optional)
16
+ # * pretend (optional)
17
+ #
18
+ # These options are not sent in the broadcast. The `wif` authorities can be
19
+ # posting, active, and owner.
20
+ #
21
+ # Setting `url` will allow you to specify a different node instead of taking
22
+ # the default: ({ChainConfig::NETWORKS_STEEM_DEFAULT_NODE}).
23
+ #
24
+ # Setting `database_api`, `block_api`, and `network_broadcast_api` is
25
+ # optional, doing so will allow you to override the default node and/or the
26
+ # RPC Client.
27
+ #
28
+ # When passing the `pretend` field, if it is set to {::True}, nothing is
29
+ # broadcasted, but the `wif` is checked for the proper authority.
30
+ #
31
+ # For details on what to pass to these methods, check out the {https://developers.steem.io/apidefinitions/broadcast-ops Steem Developer Portal Broadcast Operations} page.
32
+ class Broadcast
33
+ extend Retriable
34
+
35
+ DEFAULT_MAX_ACCEPTED_PAYOUT = Type::Amount.new(["1000000000", 3, "@@000000013"])
36
+
37
+ # This operation is used to cast a vote on a post/comment.
38
+ #
39
+ # options = {
40
+ # wif: wif,
41
+ # params: {
42
+ # voter: voter,
43
+ # author: author,
44
+ # permlink: permlink,
45
+ # weight: weight
46
+ # }
47
+ # }
48
+ #
49
+ # Steem::Broadcast.vote(options) do |result|
50
+ # puts result
51
+ # end
52
+ #
53
+ # @param options [Hash] options
54
+ # @option options [String] :wif Posting wif
55
+ # @option options [Hash] :params
56
+ # * :voter (String)
57
+ # * :author (String)
58
+ # * :permlink (String)
59
+ # * :weight (Number)
60
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
61
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_vote
62
+ def self.vote(options, &block)
63
+ required_fields = %i(voter author permlink weight)
64
+ params = options[:params]
65
+ check_required_fields(params, *required_fields)
66
+
67
+ ops = [[:vote, params]]
68
+
69
+ process(options.merge(ops: ops), &block)
70
+ end
71
+
72
+ # Creates a post/comment. This method simplifies content creation by
73
+ # combining `comment` and `comment_options` into one transaction.
74
+ #
75
+ # options = {
76
+ # wif: wif,
77
+ # params: {
78
+ # author: author,
79
+ # title: 'This is my fancy post title.',
80
+ # body: 'This is my fancy post body.',
81
+ # metadata: {
82
+ # tags: %w(these are my fancy tags)
83
+ # }
84
+ # }
85
+ # }
86
+ #
87
+ # Steem::Broadcast.comment(options)
88
+ #
89
+ # options = {
90
+ # wif: wif,
91
+ # params: {
92
+ # author: author,
93
+ # title: 'This is my fancy post title.',
94
+ # body: 'This is my fancy post body.',
95
+ # metadata: {
96
+ # tags: %w(these are my fancy tags)
97
+ # },
98
+ # beneficiaries: [
99
+ # {account: "david", weight: 500},
100
+ # {account: "erin", weight: 500},
101
+ # {account: "faythe", weight: 1000},
102
+ # {account: "frank", weight: 500}
103
+ # ]
104
+ # }
105
+ # }
106
+ #
107
+ # Steem::Broadcast.comment(options)
108
+ #
109
+ # @param options [Hash] options
110
+ # @option options [String] :wif Posting wif
111
+ # @option options [Hash] :params
112
+ # * :author (String)
113
+ # * :title (String) Title of the content.
114
+ # * :body (String) Body of the content.
115
+ # * :metadata (Hash) Metadata of the content, becomes `json_metadata`.
116
+ # * :permlink (String) (automatic) Permlink of the content, defaults to formatted title.
117
+ # * :parent_permlink (String) (automatic) Parent permlink of the content, defaults to first tag.
118
+ # * :parent_author (String) (optional) Parent author of the content (only used if reply).
119
+ # * :max_accepted_payout (String) (1000000.000 SBD) Maximum accepted payout, set to '0.000 SBD' to deline payout
120
+ # * :percent_steem_dollars (Numeric) (5000) Percent STEEM Dollars is used to set 50/50 or 100% STEEM Power
121
+ # * :allow_votes (Numeric) (true) Allow votes for this content.
122
+ # * :allow_curation_rewards (Numeric) (true) Allow curation rewards for this content.
123
+ # * :beneficiaries (Array<Hash>) Sets the beneficiaries of this content.
124
+ # * :pretend (Boolean) Just validate, do not broadcast.
125
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_comment
126
+ def self.comment(options, &block)
127
+ required_fields = %i(author body permlink parent_permlink)
128
+ params = options[:params]
129
+ metadata = (params[:metadata] rescue nil) || {}
130
+ metadata['app'] ||= Steem::AGENT_ID
131
+ tags = metadata['tags'] || []
132
+ params[:parent_permlink] ||= tags.first
133
+
134
+ if !!params[:title]
135
+ params[:permlink] ||= params[:title].downcase.gsub(/[^a-z0-9\-]+/, '-')
136
+ end
137
+
138
+ check_required_fields(params, *required_fields)
139
+
140
+ ops = [[:comment, {
141
+ parent_author: params[:parent_author] || '',
142
+ parent_permlink: params[:parent_permlink],
143
+ author: params[:author],
144
+ permlink: params[:permlink],
145
+ title: params[:title] || '',
146
+ body: params[:body],
147
+ json_metadata: metadata.to_json
148
+ }]]
149
+
150
+ max_accepted_payout = if params.keys.include? :max_accepted_payout
151
+ Type::Amount.to_nia(params[:max_accepted_payout])
152
+ else
153
+ DEFAULT_MAX_ACCEPTED_PAYOUT.to_nia
154
+ end
155
+
156
+ allow_votes = if params.keys.include? :allow_votes
157
+ !!params[:allow_votes]
158
+ else
159
+ true
160
+ end
161
+
162
+ allow_curation_rewards = if params.keys.include? :allow_curation_rewards
163
+ !!params[:allow_curation_rewards]
164
+ else
165
+ true
166
+ end
167
+
168
+ comment_options = {
169
+ author: params[:author],
170
+ permlink: params[:permlink],
171
+ max_accepted_payout: max_accepted_payout,
172
+ percent_steem_dollars: params[:percent_steem_dollars] || 10000,
173
+ allow_votes: allow_votes,
174
+ allow_curation_rewards: allow_curation_rewards,
175
+ extensions: []
176
+ }
177
+
178
+ if !!params[:beneficiaries]
179
+ comment_options[:extensions] << [0, {beneficiaries: params[:beneficiaries]}]
180
+ end
181
+
182
+ ops << [:comment_options, comment_options]
183
+
184
+ process(options.merge(ops: ops), &block)
185
+ end
186
+
187
+ # Deletes a post/comment.
188
+ #
189
+ # Steem::Broadcast.delete_comment(wif: wif, params: {author: author, permlink: permlink}) do |result|
190
+ # puts result
191
+ # end
192
+ #
193
+ # @param options [Hash] options
194
+ # @option options [String] :wif Posting wif
195
+ # @option options [Hash] :params
196
+ # * :author (String)
197
+ # * :permlink (String)
198
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
199
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_delete_comment
200
+ def self.delete_comment(options, &block)
201
+ required_fields = %i(author permlink)
202
+ params = options[:params]
203
+ check_required_fields(params, *required_fields)
204
+
205
+ ops = [[:delete_comment, params]]
206
+
207
+ process(options.merge(ops: ops), &block)
208
+ end
209
+
210
+ # Transfers asset from one account to another.
211
+ #
212
+ # options = {
213
+ # wif: wif,
214
+ # params: {
215
+ # from: from,
216
+ # to: to,
217
+ # amount: amount,
218
+ # memo: memo
219
+ # }
220
+ # }
221
+ #
222
+ # Steem::Broadcast.transfer(options) do |result|
223
+ # puts result
224
+ # end
225
+ #
226
+ # @param options [Hash] options
227
+ # @option options [String] :wif Active wif
228
+ # @option options [Hash] :params
229
+ # * :from (String)
230
+ # * :to (String)
231
+ # * :amount (String)
232
+ # * :memo (String)
233
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
234
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_transfer
235
+ def self.transfer(options, &block)
236
+ required_fields = %i(from to amount memo)
237
+ params = options[:params]
238
+ check_required_fields(params, *required_fields)
239
+
240
+ params[:amount] = Type::Amount.to_nia(params[:amount])
241
+
242
+ ops = [[:transfer, params]]
243
+
244
+ process(options.merge(ops: ops), &block)
245
+ end
246
+
247
+ # This operation converts STEEM into VFS (Vesting Fund Shares) at the
248
+ # current exchange rate.
249
+ #
250
+ # options = {
251
+ # wif: wif,
252
+ # params: {
253
+ # from: from,
254
+ # to: to,
255
+ # amount: amount,
256
+ # }
257
+ # }
258
+ #
259
+ # Steem::Broadcast.transfer_to_vesting(options) do |result|
260
+ # puts result
261
+ # end
262
+ #
263
+ # @param options [Hash] options
264
+ # @option options [String] :wif Active wif
265
+ # @option options [Hash] :params
266
+ # * :from (String)
267
+ # * :to (String)
268
+ # * :amount (String)
269
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
270
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_transfer_to_vesting
271
+ def self.transfer_to_vesting(options, &block)
272
+ required_fields = %i(from to amount)
273
+ params = options[:params]
274
+ check_required_fields(params, *required_fields)
275
+
276
+ params[:amount] = Type::Amount.to_nia(params[:amount])
277
+
278
+ ops = [[:transfer_to_vesting, params]]
279
+
280
+ process(options.merge(ops: ops), &block)
281
+ end
282
+
283
+ # At any given point in time an account can be withdrawing from their
284
+ # vesting shares.
285
+ #
286
+ # Steem::Broadcast.withdraw_vesting(wif: wif, params: {account: account, vesting_shares: vesting_shares}) do |result|
287
+ # puts result
288
+ # end
289
+ #
290
+ # @param options [Hash] options
291
+ # @option options [String] :wif Active wif
292
+ # @option options [Hash] :params
293
+ # * :account (String)
294
+ # * :vesting_shares (String)
295
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
296
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_withdraw_vesting
297
+ def self.withdraw_vesting(options, &block)
298
+ required_fields = %i(account vesting_shares)
299
+ params = options[:params]
300
+ check_required_fields(params, *required_fields)
301
+
302
+ params[:vesting_shares] = Type::Amount.to_nia(params[:vesting_shares])
303
+
304
+ ops = [[:withdraw_vesting, params]]
305
+
306
+ process(options.merge(ops: ops), &block)
307
+ end
308
+
309
+ # This operation creates a limit order and matches it against existing open
310
+ # orders.
311
+ #
312
+ # @param options [Hash] options
313
+ # @option options [String] :wif Active wif
314
+ # @option options [Hash] :params
315
+ # * :owner (String)
316
+ # * :orderid (String)
317
+ # * :amount_to_sell (String)
318
+ # * :min_to_receive (String)
319
+ # * :fill_or_kill (Boolean)
320
+ # * :expiration (String)
321
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
322
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_limit_order_create
323
+ def self.limit_order_create(options, &block)
324
+ required_fields = %i(owner orderid amount_to_sell min_to_receive
325
+ fill_or_kill)
326
+ params = options[:params]
327
+ check_required_fields(params, *required_fields)
328
+
329
+ params[:amount_to_sell] = Type::Amount.to_nia(params[:amount_to_sell])
330
+ params[:min_to_receive] = Type::Amount.to_nia(params[:min_to_receive])
331
+
332
+ if !!params[:expiration]
333
+ params[:expiration] = Time.parse(params[:expiration].to_s)
334
+ params[:expiration] = params[:expiration].strftime('%Y-%m-%dT%H:%M:%S')
335
+ end
336
+
337
+ ops = [[:limit_order_create, params]]
338
+
339
+ process(options.merge(ops: ops), &block)
340
+ end
341
+
342
+ # Cancels an order and returns the balance to owner.
343
+ #
344
+ # @param options [Hash] options
345
+ # @option options [String] :wif Active wif
346
+ # @option options [Hash] :params
347
+ # * :owner (String)
348
+ # * :orderid (String)
349
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
350
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_limit_order_cancel
351
+ def self.limit_order_cancel(options, &block)
352
+ required_fields = %i(owner orderid)
353
+ params = options[:params]
354
+ check_required_fields(params, *required_fields)
355
+
356
+ ops = [[:limit_order_cancel, params]]
357
+
358
+ process(options.merge(ops: ops), &block)
359
+ end
360
+
361
+ # Feeds can only be published by the top N witnesses which are included in
362
+ # every round and are used to define the exchange rate between steem and the
363
+ # dollar.
364
+ #
365
+ # @param options [Hash] options
366
+ # @option options [String] :wif Active wif
367
+ # @option options [Hash] :params
368
+ # * :publisher (String)
369
+ # * :exchange_rate (Hash)
370
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
371
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_feed_publish
372
+ def self.feed_publish(options, &block)
373
+ required_fields = %i(publisher exchange_rate)
374
+ params = options[:params]
375
+ check_required_fields(params, *required_fields)
376
+
377
+ exchange_rate = params[:exchange_rate] rescue {}
378
+ base = exchange_rate[:base]
379
+ quote = exchange_rate[:quote]
380
+ params[:exchange_rate][:base] = Type::Amount.to_nia(base)
381
+ params[:exchange_rate][:quote] = Type::Amount.to_nia(quote)
382
+
383
+ ops = [[:feed_publish, params]]
384
+
385
+ process(options.merge(ops: ops), &block)
386
+ end
387
+
388
+ # This operation instructs the blockchain to start a conversion between
389
+ # STEEM and SBD, the funds are deposited after 3.5 days.
390
+ #
391
+ # @param options [Hash] options
392
+ # @option options [String] :wif Active wif
393
+ # @option options [Hash] :params
394
+ # * :owner (String)
395
+ # * :requestid (String)
396
+ # * :amount (String)
397
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
398
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_convert
399
+ def self.convert(options, &block)
400
+ required_fields = %i(owner requestid amount)
401
+ params = options[:params]
402
+ check_required_fields(params, *required_fields)
403
+
404
+ params[:amount] = Type::Amount.to_nia(params[:amount])
405
+
406
+ ops = [[:convert, params]]
407
+
408
+ process(options.merge(ops: ops), &block)
409
+ end
410
+
411
+ # Create an account.
412
+ # options = {
413
+ # wif: wif,
414
+ # params: {
415
+ # fee: '1.000 STEEM',
416
+ # creator: creator_account_name,
417
+ # new_account_name: new_account_name,
418
+ # owner: {
419
+ # weight_threshold: 1,
420
+ # account_auths: [],
421
+ # key_auths: [[owner_public_key, 1]],
422
+ # },
423
+ # active: {
424
+ # weight_threshold: 1,
425
+ # account_auths: [],
426
+ # key_auths: [[active_public_key, 1]],
427
+ # },
428
+ # posting: {
429
+ # weight_threshold: 1,
430
+ # account_auths: [],
431
+ # key_auths: [[posting_public_key, 1]],
432
+ # },
433
+ # memo_key: memo_public_key,
434
+ # json_metadata: '{}'
435
+ # }
436
+ # }
437
+ #
438
+ # Steem::Broadcast.account_create(options)
439
+ #
440
+ # @param options [Hash] options
441
+ # @option options [String] :wif Active wif
442
+ # @option options [Hash] :params
443
+ # * :fee (String)
444
+ # * :creator (String)
445
+ # * :new_account_name (String)
446
+ # * :owner (Hash)
447
+ # * :active (Hash)
448
+ # * :posting (Hash)
449
+ # * :memo_key (String)
450
+ # * :json_metadata (String)
451
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
452
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_account_create
453
+ def self.account_create(options, &block)
454
+ required_fields = %i(fee creator new_account_name owner active posting memo_key json_metadata)
455
+ params = options[:params]
456
+ check_required_fields(params, *required_fields)
457
+
458
+ params[:fee] = Type::Amount.to_nia(params[:fee])
459
+
460
+ ops = [[:account_create, params]]
461
+
462
+ process(options.merge(ops: ops), &block)
463
+ end
464
+
465
+ # Update an account.
466
+ # options = {
467
+ # wif: wif,
468
+ # params: {
469
+ # account: new_account_name,
470
+ # owner: {
471
+ # weight_threshold: 1,
472
+ # account_auths: [],
473
+ # key_auths: [[owner_public_key, 1]],
474
+ # },
475
+ # active: {
476
+ # weight_threshold: 1,
477
+ # account_auths: [],
478
+ # key_auths: [[active_public_key, 1]],
479
+ # },
480
+ # posting: {
481
+ # weight_threshold: 1,
482
+ # account_auths: [],
483
+ # key_auths: [[posting_public_key, 1]],
484
+ # },
485
+ # memo_key: memo_public_key,
486
+ # json_metadata: '{}'
487
+ # }
488
+ # }
489
+ #
490
+ # Steem::Broadcast.account_update(options)
491
+ #
492
+ # @param options [Hash] options
493
+ # @option options [String] :wif Active wif
494
+ # @option options [Hash] :params
495
+ # * :account (String)
496
+ # * :owner (Hash) (optional)
497
+ # * :active (Hash) (optional)
498
+ # * :posting (Hash) (optional)
499
+ # * :memo_key (String) (optional)
500
+ # @option options [String] :json_metadata (optional)
501
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
502
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_account_update
503
+ def self.account_update(options, &block)
504
+ required_fields = %i(account)
505
+ params = options[:params]
506
+ check_required_fields(params, *required_fields)
507
+
508
+ ops = [[:account_update, params]]
509
+
510
+ process(options.merge(ops: ops), &block)
511
+ end
512
+
513
+ # Users who wish to become a witness must pay a fee acceptable to the
514
+ # current witnesses to apply for the position and allow voting to begin.
515
+ #
516
+ # options = {
517
+ # wif: wif,
518
+ # params: {
519
+ # owner: witness_account_name,
520
+ # url: '',
521
+ # block_signing_key: 'STM8ZSyzjPm48GmUuMSRufkVYkwYbZzbxeMysAVp7KFQwbTf98TcG',
522
+ # props: {
523
+ # account_creation_fee: '0.000 STEEM',
524
+ # maximum_block_size: 131072,
525
+ # sbd_interest_rate:1000
526
+ # },
527
+ # fee: '0.000 STEEM',
528
+ # }
529
+ # }
530
+ #
531
+ # Steem::Broadcast.witness_update(options)
532
+ #
533
+ # @param options [Hash] options
534
+ # @option options [String] :wif Active wif
535
+ # @option options [Hash] :params
536
+ # * :owner (String)
537
+ # * :url (String) (optional)
538
+ # * :block_signing_key (String)
539
+ # * :props (String)
540
+ # * :fee (String)
541
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
542
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_witness_update
543
+ def self.witness_update(options, &block)
544
+ required_fields = %i(owner block_signing_key props fee)
545
+ params = options[:params]
546
+ check_required_fields(params, *required_fields)
547
+
548
+ account_creation_fee = params[:props][:account_creation_fee] rescue nil
549
+ params[:props][:account_creation_fee] = Type::Amount.to_nia(account_creation_fee)
550
+ params[:fee] = Type::Amount.to_nia(params[:fee])
551
+
552
+ ops = [[:witness_update, params]]
553
+
554
+ process(options.merge(ops: ops), &block)
555
+ end
556
+
557
+ # All accounts with a VFS (Vesting Fund Shares) can vote for or against any
558
+ # witness.
559
+ #
560
+ # @param options [Hash] options
561
+ # @option options [String] :wif Active wif
562
+ # @option options [Hash] :params
563
+ # * :account (String)
564
+ # * :witness (String)
565
+ # * :approve (Boolean)
566
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
567
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_account_witness_vote
568
+ def self.account_witness_vote(options, &block)
569
+ required_fields = %i(account witness approve)
570
+ params = options[:params]
571
+ check_required_fields(params, *required_fields)
572
+
573
+ ops = [[:account_witness_vote, params]]
574
+
575
+ process(options.merge(ops: ops), &block)
576
+ end
577
+
578
+ # @param options [Hash] options
579
+ # @option options [String] :wif Active wif
580
+ # @option options [Hash] :params
581
+ # * :account (String)
582
+ # * :proxy (String)
583
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
584
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_account_witness_proxy
585
+ def self.account_witness_proxy(options, &block)
586
+ required_fields = %i(account proxy)
587
+ params = options[:params]
588
+ check_required_fields(params, *required_fields)
589
+
590
+ ops = [[:account_witness_proxy, params]]
591
+
592
+ process(options.merge(ops: ops), &block)
593
+ end
594
+
595
+ # Provides a generic way to add higher level protocols on top of witness
596
+ # consensus.
597
+ #
598
+ # @param options [Hash] options
599
+ # @option options [String] :wif Active wif
600
+ # @option options [Hash] :params
601
+ # * :required_auths (Array<String>)
602
+ # * :id (String)
603
+ # * :data (String)
604
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
605
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_custom
606
+ def self.custom(options, &block)
607
+ required_fields = %i(required_auths id data)
608
+ params = options[:params]
609
+ check_required_fields(params, *required_fields)
610
+
611
+ ops = [[:custom, params]]
612
+
613
+ process(options.merge(ops: ops), &block)
614
+ end
615
+
616
+ # The semmantics for this operation are the same as the {Broadcast#custom_json}
617
+ # operation, but with a binary payload.
618
+ #
619
+ # @param options [Hash] options
620
+ # @option options [String] :wif Posting wif
621
+ # @option options [Hash] :params
622
+ # * :id (String)
623
+ # * :data (String)
624
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
625
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_custom_binary
626
+ def self.custom_binary(options, &block)
627
+ required_fields = %i(id data)
628
+ params = options[:params]
629
+ check_required_fields(params, *required_fields)
630
+
631
+ ops = [[:custom_binary, params]]
632
+
633
+ process(options.merge(ops: ops), &block)
634
+ end
635
+
636
+ # Serves the same purpose as {Broadcast#custom} but also supports required
637
+ # posting authorities.
638
+ #
639
+ # @param options [Hash] options
640
+ # @option options [String] :wif Posting wif
641
+ # @option options [Hash] :params
642
+ # * :required_auths (Array<String>)
643
+ # * :required_posting_auths (Arrat<String>)
644
+ # * :id (String)
645
+ # * :json (String)
646
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
647
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_custom_json
648
+ def self.custom_json(options, &block)
649
+ required_fields = %i(id json)
650
+ params = options[:params]
651
+ check_required_fields(params, *required_fields)
652
+
653
+ params[:required_auths] ||= []
654
+ params[:required_posting_auths] ||= []
655
+ ops = [[:custom_json, params]]
656
+
657
+ process(options.merge(ops: ops), &block)
658
+ end
659
+
660
+ # Allows an account to setup a vesting withdraw but with the additional
661
+ # request for the funds to be transferred directly to another account’s
662
+ # balance rather than the withdrawing account.
663
+ #
664
+ # @param options [Hash] options
665
+ # @option options [String] :wif Active wif
666
+ # @option options [Hash] :params
667
+ # * :from_account (String)
668
+ # * :to_account (String)
669
+ # * :percent (Numeric)
670
+ # * :auto_vest (Boolean)
671
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
672
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_set_withdraw_vesting_route
673
+ def self.set_withdraw_vesting_route(options, &block)
674
+ required_fields = %i(from_account to_account percent auto_vest)
675
+ params = options[:params]
676
+ check_required_fields(params, *required_fields)
677
+
678
+ ops = [[:set_withdraw_vesting_route, params]]
679
+
680
+ process(options.merge(ops: ops), &block)
681
+ end
682
+
683
+ # All account recovery requests come from a listed recovery account.
684
+ #
685
+ # @param options [Hash] options
686
+ # @option options [String] :wif Active wif
687
+ # @option options [Hash] :params
688
+ # * :recovery_account (String)
689
+ # * :account_to_recover (String)
690
+ # * :new_owner_authority (Hash)
691
+ # * :extensions (Array) (optional)
692
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
693
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_request_account_recovery
694
+ def self.request_account_recovery(options, &block)
695
+ required_fields = %i(recovery_account account_to_recover new_owner_authority)
696
+ params = options[:params]
697
+ check_required_fields(params, *required_fields)
698
+
699
+ params[:extensions] ||= []
700
+ ops = [[:request_account_recovery, params]]
701
+
702
+ process(options.merge(ops: ops), &block)
703
+ end
704
+
705
+ # @param options [Hash] options
706
+ # @option options [String] :wif Active wif
707
+ # @option options [Hash] :params
708
+ # * :account_to_recover (String)
709
+ # * :new_owner_authority (Hash)
710
+ # * :recent_owner_authority (Hash)
711
+ # * :extensions (Array) (optional)
712
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
713
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_recover_account
714
+ def self.recover_account(options, &block)
715
+ required_fields = %i(account_to_recover new_owner_authority recent_owner_authority)
716
+ params = options[:params]
717
+ check_required_fields(params, *required_fields)
718
+
719
+ params[:extensions] ||= []
720
+ ops = [[:recover_account, params]]
721
+
722
+ process(options.merge(ops: ops), &block)
723
+ end
724
+
725
+ # Each account lists another account as their recovery account.
726
+ #
727
+ # @param options [Hash] options
728
+ # @option options [String] :wif Posting wif
729
+ # @option options [Hash] :params
730
+ # * :account_to_recover (String)
731
+ # * :new_recovery_account (String)
732
+ # * :extensions (Array) (optional)
733
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
734
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_change_recovery_account
735
+ def self.change_recovery_account(options, &block)
736
+ required_fields = %i(account_to_recover)
737
+ params = options[:params]
738
+ check_required_fields(params, *required_fields)
739
+
740
+ params[:new_recovery_account] ||= ''
741
+ params[:extensions] ||= []
742
+ ops = [[:change_recovery_account, params]]
743
+
744
+ process(options.merge(ops: ops), &block)
745
+ end
746
+
747
+ # The purpose of this operation is to enable someone to send money
748
+ # contingently to another individual.
749
+ #
750
+ # @param options [Hash] options
751
+ # @option options [String] :wif Active wif
752
+ # @option options [Hash] :params
753
+ # * :from (String)
754
+ # * :to (String)
755
+ # * :agent (String)
756
+ # * :escrow_id (String)
757
+ # * :sbd_amount (String)
758
+ # * :steem_amount (String)
759
+ # * :fee (String)
760
+ # * :ratification_deadline (String)
761
+ # * :escrow_expiration (String)
762
+ # * :json_meta (String)
763
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
764
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_escrow_transfer
765
+ def self.escrow_transfer(options, &block)
766
+ required_fields = %i(from to agent escrow_id fee ratification_deadline json_meta)
767
+ params = options[:params]
768
+ check_required_fields(params, *required_fields)
769
+
770
+ params[:sbd_amount] = Type::Amount.to_nia(params[:sbd_amount])
771
+ params[:steem_amount] = Type::Amount.to_nia(params[:steem_amount])
772
+ params[:fee] = Type::Amount.to_nia(params[:fee])
773
+
774
+ params[:ratification_deadline] = Time.parse(params[:ratification_deadline].to_s)
775
+ params[:ratification_deadline] = params[:ratification_deadline].strftime('%Y-%m-%dT%H:%M:%S')
776
+
777
+ if !!params[:escrow_expiration]
778
+ params[:escrow_expiration] = Time.parse(params[:escrow_expiration].to_s)
779
+ params[:escrow_expiration] = params[:escrow_expiration].strftime('%Y-%m-%dT%H:%M:%S')
780
+ end
781
+
782
+ ops = [[:escrow_transfer, params]]
783
+
784
+ process(options.merge(ops: ops), &block)
785
+ end
786
+
787
+ # If either the sender or receiver of an escrow payment has an issue, they
788
+ # can raise it for dispute.
789
+ #
790
+ # @param options [Hash] options
791
+ # @option options [String] :wif Active wif
792
+ # @option options [Hash] :params
793
+ # * :from (String)
794
+ # * :to (String)
795
+ # * :agent (String)
796
+ # * :who (String)
797
+ # * :escrow_id (String)
798
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
799
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_escrow_dispute
800
+ def self.escrow_dispute(options, &block)
801
+ required_fields = %i(from to agent who escrow_id)
802
+ params = options[:params]
803
+ check_required_fields(params, *required_fields)
804
+
805
+ ops = [[:escrow_dispute, params]]
806
+
807
+ process(options.merge(ops: ops), &block)
808
+ end
809
+
810
+ # This operation can be used by anyone associated with the escrow transfer
811
+ # to release funds if they have permission.
812
+ #
813
+ # @param options [Hash] options
814
+ # @option options [String] :wif Active wif
815
+ # @option options [Hash] :params
816
+ # * :from (String)
817
+ # * :to (String)
818
+ # * :agent (String)
819
+ # * :who (String)
820
+ # * :receiver (String)
821
+ # * :escrow_id (String)
822
+ # * :sbd_amount (String)
823
+ # * :steem_amount (String)
824
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
825
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_escrow_release
826
+ def self.escrow_release(options, &block)
827
+ required_fields = %i(from to agent who receiver escrow_id)
828
+ params = options[:params]
829
+ check_required_fields(params, *required_fields)
830
+
831
+ params[:sbd_amount] = Type::Amount.to_nia(params[:sbd_amount])
832
+ params[:steem_amount] = Type::Amount.to_nia(params[:steem_amount])
833
+
834
+ ops = [[:escrow_release, params]]
835
+
836
+ process(options.merge(ops: ops), &block)
837
+ end
838
+
839
+ # The agent and to accounts must approve an escrow transaction for it to be
840
+ # valid on the blockchain.
841
+ #
842
+ # @param options [Hash] options
843
+ # @option options [String] :wif Active wif
844
+ # @option options [Hash] :params
845
+ # * :from (String)
846
+ # * :to (String)
847
+ # * :agent (String)
848
+ # * :who (String)
849
+ # * :escrow_id (String)
850
+ # * :approve (String)
851
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
852
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_escrow_approve
853
+ def self.escrow_approve(options, &block)
854
+ required_fields = %i(from to agent who escrow_id approve)
855
+ params = options[:params]
856
+ check_required_fields(params, *required_fields)
857
+
858
+ ops = [[:escrow_approve, params]]
859
+
860
+ process(options.merge(ops: ops), &block)
861
+ end
862
+
863
+ # For time locked savings accounts.
864
+ #
865
+ # @param options [Hash] options
866
+ # @option options [String] :wif Active wif
867
+ # @option options [Hash] :params
868
+ # * :from (String)
869
+ # * :to (String)
870
+ # * :amount (String)
871
+ # * :memo (String) (optional)
872
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
873
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_transfer_to_savings
874
+ def self.transfer_to_savings(options, &block)
875
+ required_fields = %i(from to amount)
876
+ params = options[:params]
877
+ check_required_fields(params, *required_fields)
878
+
879
+ params[:memo] ||= ''
880
+ params[:amount] = Type::Amount.to_nia(params[:amount])
881
+
882
+ ops = [[:transfer_to_savings, params]]
883
+
884
+ process(options.merge(ops: ops), &block)
885
+ end
886
+
887
+ # @param options [Hash] options
888
+ # @option options [String] :wif Active wif
889
+ # @option options [Hash] :params
890
+ # * :from (String)
891
+ # * :request_id (String)
892
+ # * :to (String)
893
+ # * :amount (String)
894
+ # * :memo (String) (optional)
895
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
896
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_transfer_from_savings
897
+ def self.transfer_from_savings(options, &block)
898
+ required_fields = %i(from request_id to amount)
899
+ params = options[:params]
900
+ check_required_fields(params, *required_fields)
901
+
902
+ params[:memo] ||= ''
903
+ params[:amount] = Type::Amount.to_nia(params[:amount])
904
+
905
+ ops = [[:transfer_from_savings, params]]
906
+
907
+ process(options.merge(ops: ops), &block)
908
+ end
909
+
910
+ # @param options [Hash] options
911
+ # @option options [String] :wif Active wif
912
+ # @option options [Hash] :params
913
+ # * :from (String)
914
+ # * :request_id (String)
915
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
916
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_cancel_transfer_from_savings
917
+ def self.cancel_transfer_from_savings(options, &block)
918
+ required_fields = %i(from request_id)
919
+ params = options[:params]
920
+ check_required_fields(params, *required_fields)
921
+
922
+ ops = [[:cancel_transfer_from_savings, params]]
923
+
924
+ process(options.merge(ops: ops), &block)
925
+ end
926
+
927
+ # An account can chose to decline their voting rights after a 30 day delay.
928
+ # This includes voting on content and witnesses. **The voting rights cannot
929
+ # be acquired again once they have been declined.** This is only to
930
+ # formalize a smart contract between certain accounts and the community that
931
+ # currently only exists as a social contract.
932
+ #
933
+ # @param options [Hash] options
934
+ # @option options [String] :wif Owner wif
935
+ # @option options [Hash] :params
936
+ # * :account (String)
937
+ # * :decline (String)
938
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
939
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_decline_voting_rights
940
+ def self.decline_voting_rights(options, &block)
941
+ required_fields = %i(account decline)
942
+ params = options[:params]
943
+ check_required_fields(params, *required_fields)
944
+
945
+ ops = [[:decline_voting_rights, params]]
946
+
947
+ process(options.merge(ops: ops), &block)
948
+ end
949
+
950
+ # Delegate vesting shares from one account to the other.
951
+ #
952
+ # @param options [Hash] options
953
+ # @option options [String] :wif Active wif
954
+ # @option options [Hash] :params
955
+ # * :delegator (String)
956
+ # * :delegatee (String)
957
+ # * :vesting_shares (String)
958
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
959
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_delegate_vesting_shares
960
+ def self.delegate_vesting_shares(options, &block)
961
+ required_fields = %i(delegator delegatee vesting_shares)
962
+ params = options[:params]
963
+ check_required_fields(params, *required_fields)
964
+
965
+ params[:vesting_shares] = Type::Amount.to_nia(params[:vesting_shares])
966
+ ops = [[:delegate_vesting_shares, params]]
967
+
968
+ process(options.merge(ops: ops), &block)
969
+ end
970
+
971
+ # @param options [Hash] options
972
+ # @option options [String] :wif Active wif
973
+ # @option options [Hash] :params
974
+ # * :fee (String)
975
+ # * :delegation (String)
976
+ # * :creator (String)
977
+ # * :new_account_name (String)
978
+ # * :owner (String)
979
+ # * :active (String)
980
+ # * :posting (String)
981
+ # * :memo_key (String)
982
+ # * :json_metadata (String)
983
+ # * :extensions (Array)
984
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
985
+ # @see https://developers.steem.io/apidefinitions/broadcast-ops#broadcast_ops_account_create_with_delegation
986
+ def self.account_create_with_delegation(options, &block)
987
+ required_fields = %i(fee delegation creator new_account_name owner active posting memo_key json_metadata)
988
+ params = options[:params]
989
+ check_required_fields(params, *required_fields)
990
+
991
+ params[:fee] = Type::Amount.to_nia(params[:fee])
992
+ params[:delegation] = Type::Amount.to_nia(params[:delegation])
993
+ params[:extensions] ||= []
994
+
995
+ ops = [[:account_create_with_delegation, params]]
996
+
997
+ process(options.merge(ops: ops), &block)
998
+ end
999
+
1000
+ # @param options [Hash] options
1001
+ # @option options [Array<Array<Hash>] :ops Operations to process.
1002
+ # @option options [Boolean] :pretend Just validate, do not broadcast.
1003
+ def self.process(options, &block)
1004
+ ops = options[:ops]
1005
+ tx = TransactionBuilder.new(options)
1006
+ response = nil
1007
+
1008
+ loop do; begin
1009
+ tx.operations = ops
1010
+ trx = tx.transaction
1011
+
1012
+ response = if !!options[:pretend]
1013
+ database_api(options).verify_authority(trx: trx)
1014
+ else
1015
+ network_broadcast_api(options).broadcast_transaction_synchronous(trx: trx)
1016
+ end
1017
+
1018
+ break
1019
+ rescue => e
1020
+ if can_retry? e
1021
+ tx.expiration = nil
1022
+ redo
1023
+ end
1024
+
1025
+ raise e
1026
+ end; end
1027
+
1028
+ if !!block
1029
+ block.call response.result
1030
+ else
1031
+ return response.result
1032
+ end
1033
+ end
1034
+ private
1035
+ def self.database_api(options)
1036
+ options[:database_api] ||= Steem::DatabaseApi.new(options)
1037
+ end
1038
+
1039
+ def self.network_broadcast_api(options)
1040
+ options[:network_broadcast_api] ||= Steem::NetworkBroadcastApi.new(options)
1041
+ end
1042
+
1043
+ def self.check_required_fields(hash, *fields)
1044
+ fields.each do |field|
1045
+ value = hash[field]
1046
+
1047
+ raise Steem::ArgumentError, "#{field}: required" if value.nil?
1048
+
1049
+ case value
1050
+ when String, Array, Hash
1051
+ raise Steem::ArgumentError, "#{field}: required" if value.empty?
1052
+ end
1053
+ end
1054
+ end
1055
+ end
1056
+ end