mixin_bot 0.6.0 → 0.6.1
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/lib/mixin_bot/api/collectible.rb +38 -3
- data/lib/mixin_bot/api/multisig.rb +9 -18
- data/lib/mixin_bot/api.rb +15 -0
- data/lib/mixin_bot/utils.rb +206 -6
- data/lib/mixin_bot/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fea4c2a8e738f32bcadb126f775042eb9c0a57d9fcfd168948127e8332e58a9a
|
4
|
+
data.tar.gz: 9f0699d3a105c499530230b565b6c22a8cd74dcda857a220fb6de73a899f1ffe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 774bf51ca38c7e507e4e6da343e139500715d7c150fb04083f4418e9a3a8fe6627383230953807f7463cc041391e8649c01290e634783b6e04b47f150eb01fe6
|
7
|
+
data.tar.gz: 69732a0f23244b8c62aa4fd553af66239df418427c9f7b0afd1437cd8821a9d05df3ac8c1ad4d60c66559b613fce5dc4268e67b5122bae7d7aeff20273a301ce
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module MixinBot
|
4
4
|
class API
|
5
5
|
module Collectible
|
6
|
+
NFT_ASSET_MIXIN_ID = '1700941284a95f31b25ec8c546008f208f88eee4419ccdcdbe6e3195e60128ca'
|
7
|
+
|
6
8
|
def collectible(id, access_token: nil)
|
7
9
|
path = "/collectibles/tokens/#{id}"
|
8
10
|
access_token ||= access_token('GET', path, '')
|
@@ -35,7 +37,7 @@ module MixinBot
|
|
35
37
|
|
36
38
|
COLLECTABLE_REQUEST_ACTIONS = %i[sign unlock].freeze
|
37
39
|
def create_collectible_request(action, raw, access_token: nil)
|
38
|
-
raise ArgumentError, "request action is limited in #{COLLECTABLE_REQUEST_ACTIONS.join(', ')}" unless action.to_sym
|
40
|
+
raise ArgumentError, "request action is limited in #{COLLECTABLE_REQUEST_ACTIONS.join(', ')}" unless COLLECTABLE_REQUEST_ACTIONS.include? action.to_sym
|
39
41
|
path = '/collectibles/requests'
|
40
42
|
payload = {
|
41
43
|
action: action,
|
@@ -47,11 +49,11 @@ module MixinBot
|
|
47
49
|
end
|
48
50
|
|
49
51
|
def create_sign_collectible_request(raw, access_token: nil)
|
50
|
-
|
52
|
+
create_collectible_request 'sign', raw, access_token: access_token
|
51
53
|
end
|
52
54
|
|
53
55
|
def create_unlock_collectible_request(raw, access_token: nil)
|
54
|
-
|
56
|
+
create_collectible_request 'unlock', raw, access_token: access_token
|
55
57
|
end
|
56
58
|
|
57
59
|
def sign_collectible_request(request_id, pin)
|
@@ -85,6 +87,39 @@ module MixinBot
|
|
85
87
|
end
|
86
88
|
end
|
87
89
|
|
90
|
+
# collectible = {
|
91
|
+
# type: 'non_fungible_output',
|
92
|
+
# user_id: '',
|
93
|
+
# output_id: '',
|
94
|
+
# token_id: '',
|
95
|
+
# transaction_hash: '',
|
96
|
+
# output_index: '',
|
97
|
+
# amount: 1,
|
98
|
+
# senders: [],
|
99
|
+
# sender_threshold: 1,
|
100
|
+
# receivers: [],
|
101
|
+
# receivers_threshold: 1,
|
102
|
+
# state: 'unspent'
|
103
|
+
# }
|
104
|
+
COLLECTIBLE_TRANSACTION_ARGUMENTS = %i[collectible nfo receivers threshold].freeze
|
105
|
+
def build_collectible_transaction(**kwargs)
|
106
|
+
raise ArgumentError, "#{COLLECTIBLE_TRANSACTION_ARGUMENTS.join(', ')} are needed for build collectible transaction" unless COLLECTIBLE_TRANSACTION_ARGUMENTS.all? { |param| kwargs.keys.include? param }
|
107
|
+
|
108
|
+
kwargs = kwargs.with_indifferent_access
|
109
|
+
collectible = kwargs['collectible']
|
110
|
+
raise "collectible is #{collectible['state']}" unless collectible['state'] == 'unspent'
|
111
|
+
|
112
|
+
build_raw_transaction(
|
113
|
+
utxos: [collectible],
|
114
|
+
senders: collectible['receivers'],
|
115
|
+
receivers: kwargs['receivers'],
|
116
|
+
threshold: kwargs['threshold'],
|
117
|
+
extra: kwargs["nfo"],
|
118
|
+
amount: 1,
|
119
|
+
asset_mixin_id: NFT_ASSET_MIXIN_ID
|
120
|
+
)
|
121
|
+
end
|
122
|
+
|
88
123
|
def nft_memo(collection, token_id, meta)
|
89
124
|
MixinBot::Utils.nft_memo collection, token_id, meta
|
90
125
|
end
|
@@ -40,7 +40,7 @@ module MixinBot
|
|
40
40
|
|
41
41
|
MULTISIG_REQUEST_ACTIONS = %i[sign unlock].freeze
|
42
42
|
def create_multisig_request(action, raw, access_token: nil)
|
43
|
-
raise ArgumentError, "request action is limited in #{MULTISIG_REQUEST_ACTIONS.join(', ')}" unless action.to_sym
|
43
|
+
raise ArgumentError, "request action is limited in #{MULTISIG_REQUEST_ACTIONS.join(', ')}" unless MULTISIG_REQUEST_ACTIONS.include? action.to_sym
|
44
44
|
|
45
45
|
path = '/multisigs/requests'
|
46
46
|
payload = {
|
@@ -54,13 +54,13 @@ module MixinBot
|
|
54
54
|
|
55
55
|
# transfer from the multisig address
|
56
56
|
def create_sign_multisig_request(raw, access_token: nil)
|
57
|
-
create_multisig_request 'sign', raw, access_token
|
57
|
+
create_multisig_request 'sign', raw, access_token: access_token
|
58
58
|
end
|
59
59
|
|
60
60
|
# transfer from the multisig address
|
61
61
|
# create a request for unlock a multi-sign
|
62
62
|
def create_unlock_multisig_request(raw, access_token: nil)
|
63
|
-
create_multisig_request 'unlock', raw, access_token
|
63
|
+
create_multisig_request 'unlock', raw, access_token: access_token
|
64
64
|
end
|
65
65
|
|
66
66
|
def sign_multisig_request(request_id, pin)
|
@@ -151,7 +151,7 @@ module MixinBot
|
|
151
151
|
# amount: string / float,
|
152
152
|
# memo: string,
|
153
153
|
# }
|
154
|
-
RAW_TRANSACTION_ARGUMENTS = %i[senders receivers amount threshold
|
154
|
+
RAW_TRANSACTION_ARGUMENTS = %i[utxos senders receivers amount threshold].freeze
|
155
155
|
def build_raw_transaction(**kwargs)
|
156
156
|
raise ArgumentError, "#{RAW_TRANSACTION_ARGUMENTS.join(', ')} are needed for build raw transaction" unless RAW_TRANSACTION_ARGUMENTS.all? { |param| kwargs.keys.include? param }
|
157
157
|
|
@@ -160,24 +160,14 @@ module MixinBot
|
|
160
160
|
amount = kwargs[:amount]
|
161
161
|
threshold = kwargs[:threshold]
|
162
162
|
asset_id = kwargs[:asset_id]
|
163
|
+
asset_mixin_id = kwargs[:asset_mixin_id]
|
163
164
|
utxos = kwargs[:utxos]
|
164
165
|
memo = kwargs[:memo]
|
166
|
+
extra = kwargs[:extra]
|
165
167
|
access_token = kwargs[:access_token]
|
166
168
|
|
167
169
|
raise 'access_token required!' if access_token.nil? && !senders.include?(client_id)
|
168
170
|
|
169
|
-
# default to use all(first 100) unspent utxo
|
170
|
-
utxos ||= multisigs(
|
171
|
-
members: senders,
|
172
|
-
threshold: threshold,
|
173
|
-
state: 'unspent',
|
174
|
-
access_token: access_token
|
175
|
-
)['data'].filter(
|
176
|
-
&lambda { |utxo|
|
177
|
-
utxo['asset_id'] == kwargs[:asset_id]
|
178
|
-
}
|
179
|
-
)
|
180
|
-
|
181
171
|
amount = amount.to_f.round(8)
|
182
172
|
input_amount = utxos.map(
|
183
173
|
&lambda { |utxo|
|
@@ -221,10 +211,11 @@ module MixinBot
|
|
221
211
|
}
|
222
212
|
end
|
223
213
|
|
224
|
-
extra = Digest.hexencode
|
214
|
+
extra = extra || Digest.hexencode(memo.to_s.slice(0, 140))
|
215
|
+
asset = asset_mixin_id || SHA3::Digest::SHA256.hexdigest(asset_id)
|
225
216
|
tx = {
|
226
217
|
version: 2,
|
227
|
-
asset:
|
218
|
+
asset: asset,
|
228
219
|
inputs: inputs,
|
229
220
|
outputs: outputs,
|
230
221
|
extra: extra
|
data/lib/mixin_bot/api.rb
CHANGED
@@ -48,6 +48,10 @@ module MixinBot
|
|
48
48
|
MixinBot::Utils.sign_raw_transaction tx
|
49
49
|
end
|
50
50
|
|
51
|
+
def decode_raw_transaction(raw)
|
52
|
+
MixinBot::Utils.decode_raw_transaction raw
|
53
|
+
end
|
54
|
+
|
51
55
|
# Use a mixin software to implement transaction build
|
52
56
|
def sign_raw_transaction_native(json)
|
53
57
|
ensure_mixin_command_exist
|
@@ -59,6 +63,17 @@ module MixinBot
|
|
59
63
|
output.chomp
|
60
64
|
end
|
61
65
|
|
66
|
+
# Use a mixin software to implement transaction build
|
67
|
+
def decode_raw_transaction_native(raw)
|
68
|
+
ensure_mixin_command_exist
|
69
|
+
command = format("mixin decoderawtransaction --raw '%<arg>s'", arg: raw)
|
70
|
+
|
71
|
+
output, error = Open3.capture3(command)
|
72
|
+
raise error unless error.empty?
|
73
|
+
|
74
|
+
JSON.parse output.chomp
|
75
|
+
end
|
76
|
+
|
62
77
|
include MixinBot::API::App
|
63
78
|
include MixinBot::API::Asset
|
64
79
|
include MixinBot::API::Attachment
|
data/lib/mixin_bot/utils.rb
CHANGED
@@ -58,6 +58,7 @@ module MixinBot
|
|
58
58
|
if tx.is_a? String
|
59
59
|
tx = JSON.parse tx
|
60
60
|
end
|
61
|
+
raise "#{tx} is not a valid json" unless tx.is_a? Hash
|
61
62
|
|
62
63
|
tx = tx.with_indifferent_access
|
63
64
|
bytes = []
|
@@ -67,6 +68,8 @@ module MixinBot
|
|
67
68
|
|
68
69
|
# version
|
69
70
|
bytes += [0, tx['version']]
|
71
|
+
|
72
|
+
# asset
|
70
73
|
bytes += [tx['asset']].pack('H*').bytes
|
71
74
|
|
72
75
|
# inputs
|
@@ -92,6 +95,72 @@ module MixinBot
|
|
92
95
|
bytes.pack('C*').unpack1('H*')
|
93
96
|
end
|
94
97
|
|
98
|
+
def decode_raw_transaction(raw)
|
99
|
+
bytes = [raw].pack('H*').bytes
|
100
|
+
tx = {}
|
101
|
+
|
102
|
+
magic = bytes.shift(2)
|
103
|
+
raise 'Not valid raw' unless magic == MAGIC
|
104
|
+
|
105
|
+
version = bytes.shift(2)
|
106
|
+
tx['version'] = bytes_to_int version
|
107
|
+
|
108
|
+
asset = bytes.shift(32)
|
109
|
+
tx['asset'] = asset.pack('C*').unpack1('H*')
|
110
|
+
|
111
|
+
# read inputs
|
112
|
+
bytes, tx = decode_inputs bytes, tx
|
113
|
+
|
114
|
+
# read outputs
|
115
|
+
bytes, tx = decode_outputs bytes, tx
|
116
|
+
|
117
|
+
extra_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
118
|
+
tx['extra'] = bytes.shift(extra_size).pack('C*').unpack1('H*')
|
119
|
+
|
120
|
+
num = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
121
|
+
if num == MAX_ENCODE_INT
|
122
|
+
# aggregated
|
123
|
+
aggregated = {}
|
124
|
+
|
125
|
+
raise 'invalid aggregated' unless bytes.shift(2).reverse.pack('C*').unpack1('S*') == AGGREGATED_SIGNATURE_PREFIX
|
126
|
+
|
127
|
+
aggregated['signature'] = bytes.shift(64).pack('C*').unpack1('H*')
|
128
|
+
|
129
|
+
byte = bytes.shift
|
130
|
+
case byte
|
131
|
+
when AGGREGATED_SIGNATURE_ORDINAY_MASK.first
|
132
|
+
aggregated['signers'] = []
|
133
|
+
masks_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
134
|
+
masks = bytes.shift(masks_size)
|
135
|
+
masks = [masks] unless masks.is_a? Array
|
136
|
+
|
137
|
+
masks.each_with_index do |mask, i|
|
138
|
+
8.times do |j|
|
139
|
+
k = 1 << j
|
140
|
+
aggregated['signers'].push(i * 8 + j) if mask & k == k
|
141
|
+
end
|
142
|
+
end
|
143
|
+
when AGGREGATED_SIGNATURE_SPARSE_MASK.first
|
144
|
+
signers_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
145
|
+
return if signers_size == 0
|
146
|
+
|
147
|
+
aggregated['signers'] = []
|
148
|
+
signers_size.times do
|
149
|
+
aggregated['signers'].push bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
tx['aggregated'] = aggregated
|
154
|
+
else
|
155
|
+
if !bytes.empty? && bytes[...2] != NULL_BYTES
|
156
|
+
signatures_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
157
|
+
tx['signatures'] = bytes.shift(signatures_size).pack('C*').unpack1('H*')
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
tx
|
162
|
+
end
|
163
|
+
|
95
164
|
def nft_memo_hash(collection, token_id, meta)
|
96
165
|
collection = NULL_UUID if collection.empty?
|
97
166
|
meta = meta.to_json if meta.is_a?(Hash)
|
@@ -225,9 +294,9 @@ module MixinBot
|
|
225
294
|
# genesis
|
226
295
|
genesis = input['genesis'] || ''
|
227
296
|
if genesis.empty?
|
228
|
-
bytes +=
|
297
|
+
bytes += NULL_BYTES
|
229
298
|
else
|
230
|
-
genesis_bytes = [genesis].pack('H*')
|
299
|
+
genesis_bytes = [genesis].pack('H*').bytes
|
231
300
|
bytes += encode_int genesis_bytes.size
|
232
301
|
bytes += genesis_bytes
|
233
302
|
end
|
@@ -265,7 +334,7 @@ module MixinBot
|
|
265
334
|
# group
|
266
335
|
group = mint['group'] || ''
|
267
336
|
if group.empty?
|
268
|
-
bytes += encode_int
|
337
|
+
bytes += encode_int NULL_BYTES
|
269
338
|
else
|
270
339
|
group_bytes = [group].pack('H*')
|
271
340
|
bytes += encode_int group_bytes.size
|
@@ -349,14 +418,14 @@ module MixinBot
|
|
349
418
|
end
|
350
419
|
|
351
420
|
def encode_aggregated_signature(aggregated, bytes = [])
|
352
|
-
bytes += MAX_ENCODE_INT
|
421
|
+
bytes += encode_int MAX_ENCODE_INT
|
353
422
|
bytes += encode_int AGGREGATED_SIGNATURE_PREFIX
|
354
423
|
bytes += [aggregated['signature']].pack('H*').bytes
|
355
424
|
|
356
425
|
signers = aggregated['signers']
|
357
426
|
if signers.size == 0
|
358
427
|
bytes += AGGREGATED_SIGNATURE_ORDINAY_MASK
|
359
|
-
bytes +=
|
428
|
+
bytes += NULL_BYTES
|
360
429
|
else
|
361
430
|
signers.each do |sig, i|
|
362
431
|
raise 'signers not sorted' if i > 0 && sig <= signers[i - 1]
|
@@ -366,7 +435,7 @@ module MixinBot
|
|
366
435
|
max = signers.last
|
367
436
|
if (((max / 8 | 0) + 1 | 0) > aggregated['signature'].size * 2)
|
368
437
|
bytes += AGGREGATED_SIGNATURE_SPARSE_MASK
|
369
|
-
bytes += encode_int aggregated['
|
438
|
+
bytes += encode_int aggregated['signers'].size
|
370
439
|
signers.map(&->(signer) { bytes += encode_int(signer) })
|
371
440
|
end
|
372
441
|
|
@@ -403,6 +472,137 @@ module MixinBot
|
|
403
472
|
|
404
473
|
bytes
|
405
474
|
end
|
475
|
+
|
476
|
+
def decode_inputs(bytes, tx)
|
477
|
+
inputs_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
478
|
+
tx['inputs'] = []
|
479
|
+
inputs_size.times do
|
480
|
+
input = {}
|
481
|
+
hash = bytes.shift(32)
|
482
|
+
input['hash'] = hash.pack('C*').unpack1('H*')
|
483
|
+
|
484
|
+
index = bytes.shift(2)
|
485
|
+
input['index'] = index.reverse.pack('C*').unpack1('S*')
|
486
|
+
|
487
|
+
if bytes[...2] != NULL_BYTES
|
488
|
+
genesis_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
489
|
+
genesis = bytes.shift(genesis_size)
|
490
|
+
input['genesis'] = genesis.pack('C*').unpack1('H*')
|
491
|
+
else
|
492
|
+
bytes.shift 2
|
493
|
+
end
|
494
|
+
|
495
|
+
if bytes[...2] != NULL_BYTES
|
496
|
+
magic = bytes.shift(2)
|
497
|
+
raise 'Not valid input' unless magic == MAGIC
|
498
|
+
|
499
|
+
deposit = {}
|
500
|
+
deposit['chain'] = bytes.shift(32).pack('C*').unpack1('H*')
|
501
|
+
|
502
|
+
asset_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
503
|
+
deposit['asset'] = bytes.shift(asset_size).unpack1('H*')
|
504
|
+
|
505
|
+
transaction_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
506
|
+
deposit['transaction'] = bytes.shift(transaction_size).unpack1('H*')
|
507
|
+
|
508
|
+
deposit['index'] = bytes.shift(8).reverse.pack('C*').unpack1('Q*')
|
509
|
+
|
510
|
+
amount_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
511
|
+
deposit['amount'] = bytes_to_int bytes.shift(amount_size)
|
512
|
+
|
513
|
+
input['deposit'] = deposit
|
514
|
+
else
|
515
|
+
bytes.shift 2
|
516
|
+
end
|
517
|
+
|
518
|
+
if bytes[...2] != NULL_BYTES
|
519
|
+
magic = bytes.shift(2)
|
520
|
+
raise 'Not valid input' unless magic == MAGIC
|
521
|
+
|
522
|
+
mint = {}
|
523
|
+
if bytes[...2] != NULL_BYTES
|
524
|
+
group_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
525
|
+
mint['group'] = bytes.shift(group_size).unpack1('H*')
|
526
|
+
else
|
527
|
+
bytes.shift 2
|
528
|
+
end
|
529
|
+
|
530
|
+
mint['batch'] = bytes.shift(8).reverse.pack('C*').unpack1('Q*')
|
531
|
+
_amount_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
532
|
+
mint['amount'] = bytes_to_int bytes.shift(_amount_size)
|
533
|
+
|
534
|
+
input['mint'] = mint
|
535
|
+
else
|
536
|
+
bytes.shift 2
|
537
|
+
end
|
538
|
+
|
539
|
+
tx['inputs'].push input
|
540
|
+
end
|
541
|
+
|
542
|
+
[bytes, tx]
|
543
|
+
end
|
544
|
+
|
545
|
+
def decode_outputs(bytes, tx)
|
546
|
+
outputs_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
547
|
+
tx['outputs'] = []
|
548
|
+
outputs_size.times do
|
549
|
+
output = {}
|
550
|
+
|
551
|
+
bytes.shift
|
552
|
+
type = bytes.shift
|
553
|
+
output['type'] = type
|
554
|
+
|
555
|
+
amount_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
556
|
+
output['amount'] = format('%.8f', bytes_to_int(bytes.shift(amount_size)).to_f / 1e8)
|
557
|
+
|
558
|
+
output['keys'] = []
|
559
|
+
keys_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
560
|
+
keys_size.times do
|
561
|
+
output['keys'].push bytes.shift(32).pack('C*').unpack1('H*')
|
562
|
+
end
|
563
|
+
|
564
|
+
output['mask'] = bytes.shift(32).pack('C*').unpack1('H*')
|
565
|
+
|
566
|
+
script_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
567
|
+
output['script'] = bytes.shift(script_size).pack('C*').unpack1('H*')
|
568
|
+
|
569
|
+
if bytes[...2] != NULL_BYTES
|
570
|
+
magic = bytes.shift(2)
|
571
|
+
raise 'Not valid output' unless magic == MAGIC
|
572
|
+
|
573
|
+
withdraw = {}
|
574
|
+
|
575
|
+
output['chain'] = bytes.shift(32).pack('C*').unpack1('H*')
|
576
|
+
|
577
|
+
asset_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
578
|
+
output['asset'] = bytes.shift(asset_size).unpack1('H*')
|
579
|
+
|
580
|
+
if bytes[...2] != NULL_BYTES
|
581
|
+
address = {}
|
582
|
+
|
583
|
+
adderss_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
584
|
+
output['adderss'] = bytes.shift(adderss_size).pack('C*').unpack1('H*')
|
585
|
+
else
|
586
|
+
bytes.shift 2
|
587
|
+
end
|
588
|
+
|
589
|
+
if bytes[...2] != NULL_BYTES
|
590
|
+
tag = {}
|
591
|
+
|
592
|
+
tag_size = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
593
|
+
output['tag'] = bytes.shift(tag_size).pack('C*').unpack1('H*')
|
594
|
+
else
|
595
|
+
bytes.shift 2
|
596
|
+
end
|
597
|
+
else
|
598
|
+
bytes.shift 2
|
599
|
+
end
|
600
|
+
|
601
|
+
tx['outputs'].push output
|
602
|
+
end
|
603
|
+
|
604
|
+
[bytes, tx]
|
605
|
+
end
|
406
606
|
end
|
407
607
|
end
|
408
608
|
end
|
data/lib/mixin_bot/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mixin_bot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- an-lee
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-10-
|
11
|
+
date: 2021-10-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|