mixin_bot 0.12.1 → 1.0.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/lib/mixin_bot/api/address.rb +21 -0
- data/lib/mixin_bot/api/app.rb +5 -11
- data/lib/mixin_bot/api/asset.rb +9 -16
- data/lib/mixin_bot/api/attachment.rb +27 -22
- data/lib/mixin_bot/api/auth.rb +29 -51
- data/lib/mixin_bot/api/blaze.rb +4 -3
- data/lib/mixin_bot/api/collectible.rb +60 -58
- data/lib/mixin_bot/api/conversation.rb +29 -49
- data/lib/mixin_bot/api/encrypted_message.rb +17 -17
- data/lib/mixin_bot/api/legacy_multisig.rb +87 -0
- data/lib/mixin_bot/api/legacy_output.rb +50 -0
- data/lib/mixin_bot/api/legacy_payment.rb +31 -0
- data/lib/mixin_bot/api/legacy_snapshot.rb +39 -0
- data/lib/mixin_bot/api/legacy_transaction.rb +173 -0
- data/lib/mixin_bot/api/legacy_transfer.rb +42 -0
- data/lib/mixin_bot/api/me.rb +13 -17
- data/lib/mixin_bot/api/message.rb +13 -10
- data/lib/mixin_bot/api/multisig.rb +16 -221
- data/lib/mixin_bot/api/output.rb +46 -0
- data/lib/mixin_bot/api/payment.rb +9 -20
- data/lib/mixin_bot/api/pin.rb +57 -65
- data/lib/mixin_bot/api/rpc.rb +9 -11
- data/lib/mixin_bot/api/snapshot.rb +15 -29
- data/lib/mixin_bot/api/tip.rb +43 -0
- data/lib/mixin_bot/api/transaction.rb +184 -60
- data/lib/mixin_bot/api/transfer.rb +64 -32
- data/lib/mixin_bot/api/user.rb +83 -53
- data/lib/mixin_bot/api/withdraw.rb +52 -53
- data/lib/mixin_bot/api.rb +78 -45
- data/lib/mixin_bot/cli/api.rb +149 -5
- data/lib/mixin_bot/cli/utils.rb +14 -4
- data/lib/mixin_bot/cli.rb +13 -10
- data/lib/mixin_bot/client.rb +76 -127
- data/lib/mixin_bot/configuration.rb +98 -0
- data/lib/mixin_bot/nfo.rb +174 -0
- data/lib/mixin_bot/transaction.rb +505 -0
- data/lib/mixin_bot/utils/address.rb +108 -0
- data/lib/mixin_bot/utils/crypto.rb +182 -0
- data/lib/mixin_bot/utils/decoder.rb +58 -0
- data/lib/mixin_bot/utils/encoder.rb +63 -0
- data/lib/mixin_bot/utils.rb +8 -109
- data/lib/mixin_bot/uuid.rb +41 -0
- data/lib/mixin_bot/version.rb +1 -1
- data/lib/mixin_bot.rb +39 -14
- data/lib/mvm/bridge.rb +2 -19
- data/lib/mvm/client.rb +11 -33
- data/lib/mvm/nft.rb +4 -4
- data/lib/mvm/registry.rb +9 -9
- data/lib/mvm/scan.rb +3 -5
- data/lib/mvm.rb +5 -6
- metadata +101 -44
- data/lib/mixin_bot/utils/nfo.rb +0 -176
- data/lib/mixin_bot/utils/transaction.rb +0 -478
- data/lib/mixin_bot/utils/uuid.rb +0 -43
data/lib/mvm/registry.rb
CHANGED
@@ -6,12 +6,12 @@ module MVM
|
|
6
6
|
|
7
7
|
def initialize(rpc_url: MVM::RPC_URL, registry_address: MVM::REGISTRY_ADDRESS)
|
8
8
|
@rpc = Eth::Client.create rpc_url
|
9
|
-
@registry = Eth::Contract.from_abi name: 'Registry', address: registry_address, abi: File.
|
9
|
+
@registry = Eth::Contract.from_abi name: 'Registry', address: registry_address, abi: File.read(File.expand_path('./abis/registry.json', __dir__))
|
10
10
|
end
|
11
11
|
|
12
12
|
def pid
|
13
13
|
hex = @rpc.call(@registry, 'PID').to_s(16)
|
14
|
-
MixinBot::
|
14
|
+
MixinBot::UUID.new(hex:).unpacked
|
15
15
|
end
|
16
16
|
|
17
17
|
def version
|
@@ -20,7 +20,7 @@ module MVM
|
|
20
20
|
|
21
21
|
def asset_from_contract(contract)
|
22
22
|
hex = @rpc.call(@registry, 'assets', contract).to_s(16)
|
23
|
-
MixinBot::
|
23
|
+
MixinBot::UUID.new(hex:).unpacked
|
24
24
|
end
|
25
25
|
|
26
26
|
def users_from_contract(contract)
|
@@ -28,12 +28,12 @@ module MVM
|
|
28
28
|
members = []
|
29
29
|
length = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
30
30
|
length.times do
|
31
|
-
members << MixinBot::
|
31
|
+
members << MixinBot::UUID.new(raw: bytes.shift(16).pack('C*')).unpacked
|
32
32
|
end
|
33
33
|
threshold = bytes.shift(2).reverse.pack('C*').unpack1('S*')
|
34
34
|
{
|
35
|
-
members
|
36
|
-
threshold:
|
35
|
+
members:,
|
36
|
+
threshold:
|
37
37
|
}.with_indifferent_access
|
38
38
|
end
|
39
39
|
|
@@ -52,9 +52,9 @@ module MVM
|
|
52
52
|
|
53
53
|
def contract_from_multisig(user_ids, threshold)
|
54
54
|
bytes = []
|
55
|
-
bytes += MixinBot
|
56
|
-
bytes += [user_ids.sort.join
|
57
|
-
bytes += MixinBot
|
55
|
+
bytes += MixinBot.utils.encode_uint_16(user_ids.length)
|
56
|
+
bytes += [user_ids.sort.join.gsub('-', '')].pack('H*').bytes
|
57
|
+
bytes += MixinBot.utils.encode_uint_16(threshold)
|
58
58
|
|
59
59
|
hash = Eth::Util.bin_to_prefixed_hex(Eth::Util.keccak256(bytes.pack('C*')))
|
60
60
|
@rpc.call @registry, 'contracts', hash.to_i(16)
|
data/lib/mvm/scan.rb
CHANGED
@@ -12,11 +12,9 @@ module MVM
|
|
12
12
|
path = '/api'
|
13
13
|
r = client.get(
|
14
14
|
path,
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
module: 'account'
|
19
|
-
}
|
15
|
+
address:,
|
16
|
+
action: 'tokenlist',
|
17
|
+
module: 'account'
|
20
18
|
)['result']
|
21
19
|
|
22
20
|
r = r.filter(&->(token) { token['type'] == type }) if type.present?
|
data/lib/mvm.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'active_support/all'
|
4
|
-
require 'http'
|
5
4
|
require 'eth'
|
6
5
|
|
7
|
-
require_relative '
|
8
|
-
require_relative '
|
9
|
-
require_relative '
|
10
|
-
require_relative '
|
11
|
-
require_relative '
|
6
|
+
require_relative 'mvm/bridge'
|
7
|
+
require_relative 'mvm/client'
|
8
|
+
require_relative 'mvm/nft'
|
9
|
+
require_relative 'mvm/registry'
|
10
|
+
require_relative 'mvm/scan'
|
12
11
|
|
13
12
|
module MVM
|
14
13
|
RPC_URL = 'https://geth.mvm.dev'
|
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.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- an-lee
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.8'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: base58
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.2'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.2'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bcrypt
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,20 +66,34 @@ dependencies:
|
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '3.1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: blake3-rb
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.5'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.5'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: cli-ui
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
58
86
|
requirements:
|
59
87
|
- - "~>"
|
60
88
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
89
|
+
version: '2.2'
|
62
90
|
type: :runtime
|
63
91
|
prerelease: false
|
64
92
|
version_requirements: !ruby/object:Gem::Requirement
|
65
93
|
requirements:
|
66
94
|
- - "~>"
|
67
95
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
96
|
+
version: '2.2'
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: eth
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,33 +109,61 @@ dependencies:
|
|
81
109
|
- !ruby/object:Gem::Version
|
82
110
|
version: '0.5'
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
112
|
+
name: faraday
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
86
114
|
requirements:
|
87
115
|
- - ">="
|
88
116
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
117
|
+
version: '2'
|
90
118
|
type: :runtime
|
91
119
|
prerelease: false
|
92
120
|
version_requirements: !ruby/object:Gem::Requirement
|
93
121
|
requirements:
|
94
122
|
- - ">="
|
95
123
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
124
|
+
version: '2'
|
97
125
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
126
|
+
name: faraday-multipart
|
99
127
|
requirement: !ruby/object:Gem::Requirement
|
100
128
|
requirements:
|
101
|
-
- - "
|
129
|
+
- - ">="
|
102
130
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
131
|
+
version: '1'
|
104
132
|
type: :runtime
|
105
133
|
prerelease: false
|
106
134
|
version_requirements: !ruby/object:Gem::Requirement
|
107
135
|
requirements:
|
108
|
-
- - "
|
136
|
+
- - ">="
|
109
137
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
138
|
+
version: '1'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: faraday-retry
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '2'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '2'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: faye-websocket
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0.11'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0.11'
|
111
167
|
- !ruby/object:Gem::Dependency
|
112
168
|
name: jose
|
113
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -193,89 +249,75 @@ dependencies:
|
|
193
249
|
- !ruby/object:Gem::Version
|
194
250
|
version: 2.2.5
|
195
251
|
- !ruby/object:Gem::Dependency
|
196
|
-
name:
|
252
|
+
name: minitest-reporters
|
197
253
|
requirement: !ruby/object:Gem::Requirement
|
198
254
|
requirements:
|
199
255
|
- - "~>"
|
200
256
|
- !ruby/object:Gem::Version
|
201
|
-
version:
|
257
|
+
version: '1.6'
|
202
258
|
type: :development
|
203
259
|
prerelease: false
|
204
260
|
version_requirements: !ruby/object:Gem::Requirement
|
205
261
|
requirements:
|
206
262
|
- - "~>"
|
207
263
|
- !ruby/object:Gem::Version
|
208
|
-
version:
|
264
|
+
version: '1.6'
|
209
265
|
- !ruby/object:Gem::Dependency
|
210
|
-
name:
|
266
|
+
name: pry
|
211
267
|
requirement: !ruby/object:Gem::Requirement
|
212
268
|
requirements:
|
213
269
|
- - "~>"
|
214
270
|
- !ruby/object:Gem::Version
|
215
|
-
version: '
|
271
|
+
version: '0.14'
|
216
272
|
type: :development
|
217
273
|
prerelease: false
|
218
274
|
version_requirements: !ruby/object:Gem::Requirement
|
219
275
|
requirements:
|
220
276
|
- - "~>"
|
221
277
|
- !ruby/object:Gem::Version
|
222
|
-
version: '
|
278
|
+
version: '0.14'
|
223
279
|
- !ruby/object:Gem::Dependency
|
224
|
-
name:
|
280
|
+
name: rake
|
225
281
|
requirement: !ruby/object:Gem::Requirement
|
226
282
|
requirements:
|
227
283
|
- - "~>"
|
228
284
|
- !ruby/object:Gem::Version
|
229
|
-
version: '
|
285
|
+
version: '13.0'
|
230
286
|
type: :development
|
231
287
|
prerelease: false
|
232
288
|
version_requirements: !ruby/object:Gem::Requirement
|
233
289
|
requirements:
|
234
290
|
- - "~>"
|
235
291
|
- !ruby/object:Gem::Version
|
236
|
-
version: '
|
292
|
+
version: '13.0'
|
237
293
|
- !ruby/object:Gem::Dependency
|
238
294
|
name: rubocop
|
239
295
|
requirement: !ruby/object:Gem::Requirement
|
240
296
|
requirements:
|
241
297
|
- - "~>"
|
242
298
|
- !ruby/object:Gem::Version
|
243
|
-
version: '
|
244
|
-
type: :development
|
245
|
-
prerelease: false
|
246
|
-
version_requirements: !ruby/object:Gem::Requirement
|
247
|
-
requirements:
|
248
|
-
- - "~>"
|
249
|
-
- !ruby/object:Gem::Version
|
250
|
-
version: '0.72'
|
251
|
-
- !ruby/object:Gem::Dependency
|
252
|
-
name: rubocop-rspec
|
253
|
-
requirement: !ruby/object:Gem::Requirement
|
254
|
-
requirements:
|
255
|
-
- - "~>"
|
256
|
-
- !ruby/object:Gem::Version
|
257
|
-
version: '1.33'
|
299
|
+
version: '1'
|
258
300
|
type: :development
|
259
301
|
prerelease: false
|
260
302
|
version_requirements: !ruby/object:Gem::Requirement
|
261
303
|
requirements:
|
262
304
|
- - "~>"
|
263
305
|
- !ruby/object:Gem::Version
|
264
|
-
version: '1
|
306
|
+
version: '1'
|
265
307
|
- !ruby/object:Gem::Dependency
|
266
308
|
name: simplecov
|
267
309
|
requirement: !ruby/object:Gem::Requirement
|
268
310
|
requirements:
|
269
311
|
- - "~>"
|
270
312
|
- !ruby/object:Gem::Version
|
271
|
-
version: 0.
|
313
|
+
version: '0.22'
|
272
314
|
type: :development
|
273
315
|
prerelease: false
|
274
316
|
version_requirements: !ruby/object:Gem::Requirement
|
275
317
|
requirements:
|
276
318
|
- - "~>"
|
277
319
|
- !ruby/object:Gem::Version
|
278
|
-
version: 0.
|
320
|
+
version: '0.22'
|
279
321
|
description: An API wrapper for Mixin Nexwork
|
280
322
|
email:
|
281
323
|
- an.lee.work@gmail.com
|
@@ -288,6 +330,7 @@ files:
|
|
288
330
|
- bin/mixinbot
|
289
331
|
- lib/mixin_bot.rb
|
290
332
|
- lib/mixin_bot/api.rb
|
333
|
+
- lib/mixin_bot/api/address.rb
|
291
334
|
- lib/mixin_bot/api/app.rb
|
292
335
|
- lib/mixin_bot/api/asset.rb
|
293
336
|
- lib/mixin_bot/api/attachment.rb
|
@@ -296,13 +339,21 @@ files:
|
|
296
339
|
- lib/mixin_bot/api/collectible.rb
|
297
340
|
- lib/mixin_bot/api/conversation.rb
|
298
341
|
- lib/mixin_bot/api/encrypted_message.rb
|
342
|
+
- lib/mixin_bot/api/legacy_multisig.rb
|
343
|
+
- lib/mixin_bot/api/legacy_output.rb
|
344
|
+
- lib/mixin_bot/api/legacy_payment.rb
|
345
|
+
- lib/mixin_bot/api/legacy_snapshot.rb
|
346
|
+
- lib/mixin_bot/api/legacy_transaction.rb
|
347
|
+
- lib/mixin_bot/api/legacy_transfer.rb
|
299
348
|
- lib/mixin_bot/api/me.rb
|
300
349
|
- lib/mixin_bot/api/message.rb
|
301
350
|
- lib/mixin_bot/api/multisig.rb
|
351
|
+
- lib/mixin_bot/api/output.rb
|
302
352
|
- lib/mixin_bot/api/payment.rb
|
303
353
|
- lib/mixin_bot/api/pin.rb
|
304
354
|
- lib/mixin_bot/api/rpc.rb
|
305
355
|
- lib/mixin_bot/api/snapshot.rb
|
356
|
+
- lib/mixin_bot/api/tip.rb
|
306
357
|
- lib/mixin_bot/api/transaction.rb
|
307
358
|
- lib/mixin_bot/api/transfer.rb
|
308
359
|
- lib/mixin_bot/api/user.rb
|
@@ -312,10 +363,15 @@ files:
|
|
312
363
|
- lib/mixin_bot/cli/node.rb
|
313
364
|
- lib/mixin_bot/cli/utils.rb
|
314
365
|
- lib/mixin_bot/client.rb
|
366
|
+
- lib/mixin_bot/configuration.rb
|
367
|
+
- lib/mixin_bot/nfo.rb
|
368
|
+
- lib/mixin_bot/transaction.rb
|
315
369
|
- lib/mixin_bot/utils.rb
|
316
|
-
- lib/mixin_bot/utils/
|
317
|
-
- lib/mixin_bot/utils/
|
318
|
-
- lib/mixin_bot/utils/
|
370
|
+
- lib/mixin_bot/utils/address.rb
|
371
|
+
- lib/mixin_bot/utils/crypto.rb
|
372
|
+
- lib/mixin_bot/utils/decoder.rb
|
373
|
+
- lib/mixin_bot/utils/encoder.rb
|
374
|
+
- lib/mixin_bot/uuid.rb
|
319
375
|
- lib/mixin_bot/version.rb
|
320
376
|
- lib/mvm.rb
|
321
377
|
- lib/mvm/abis/bridge.json
|
@@ -331,7 +387,8 @@ files:
|
|
331
387
|
homepage: https://github.com/an-lee/mixin_bot
|
332
388
|
licenses:
|
333
389
|
- MIT
|
334
|
-
metadata:
|
390
|
+
metadata:
|
391
|
+
rubygems_mfa_required: 'true'
|
335
392
|
post_install_message:
|
336
393
|
rdoc_options: []
|
337
394
|
require_paths:
|
@@ -347,7 +404,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
347
404
|
- !ruby/object:Gem::Version
|
348
405
|
version: '0'
|
349
406
|
requirements: []
|
350
|
-
rubygems_version: 3.4.
|
407
|
+
rubygems_version: 3.4.21
|
351
408
|
signing_key:
|
352
409
|
specification_version: 4
|
353
410
|
summary: An API wrapper for Mixin Nexwork
|
data/lib/mixin_bot/utils/nfo.rb
DELETED
@@ -1,176 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module MixinBot
|
4
|
-
module Utils
|
5
|
-
class Nfo
|
6
|
-
NFT_MEMO_PREFIX = 'NFO'
|
7
|
-
NFT_MEMO_VERSION = 0x00
|
8
|
-
NFT_MEMO_DEFAULT_CHAIN = '43d61dcd-e413-450d-80b8-101d5e903357'
|
9
|
-
NFT_MEMO_DEFAULT_CLASS = '3c8c161a18ae2c8b14fda1216fff7da88c419b5d'
|
10
|
-
NULL_UUID = '00000000-0000-0000-0000-000000000000'
|
11
|
-
|
12
|
-
attr_reader :prefix, :version, :raw
|
13
|
-
attr_accessor :mask, :chain, :nm_class, :collection, :token, :extra, :memo, :hex
|
14
|
-
|
15
|
-
def initialize(**kwargs)
|
16
|
-
@prefix = NFT_MEMO_PREFIX
|
17
|
-
@version = NFT_MEMO_VERSION
|
18
|
-
@mask = kwargs[:mask] || 0
|
19
|
-
@chain = kwargs[:chain] || NFT_MEMO_DEFAULT_CHAIN
|
20
|
-
@nm_class = kwargs[:nm_class] || NFT_MEMO_DEFAULT_CLASS
|
21
|
-
@collection = kwargs[:collection] || NULL_UUID
|
22
|
-
@token = kwargs[:token].presence&.to_i
|
23
|
-
@extra = kwargs[:extra]
|
24
|
-
@memo = kwargs[:memo]
|
25
|
-
@hex = kwargs[:hex]
|
26
|
-
end
|
27
|
-
|
28
|
-
def mint_memo
|
29
|
-
raise MixinBot::InvalidNfoFormatError, 'token is required' if token.blank?
|
30
|
-
raise MixinBot::InvalidNfoFormatError, 'extra must be 256-bit string' if extra.blank? || extra.size != 64
|
31
|
-
|
32
|
-
@collection = NULL_UUID if collection.blank?
|
33
|
-
@chain = NFT_MEMO_DEFAULT_CHAIN
|
34
|
-
@nm_class = NFT_MEMO_DEFAULT_CLASS
|
35
|
-
mark 0
|
36
|
-
encode
|
37
|
-
|
38
|
-
memo
|
39
|
-
end
|
40
|
-
|
41
|
-
def unique_token_id
|
42
|
-
bytes = []
|
43
|
-
bytes += MixinBot::Utils::UUID.new(hex: chain).packed.bytes
|
44
|
-
bytes += [nm_class].pack('H*').bytes
|
45
|
-
bytes += MixinBot::Utils::UUID.new(hex: collection).packed.bytes
|
46
|
-
bytes += MixinBot::Utils.bytes_of token
|
47
|
-
|
48
|
-
md5 = Digest::MD5.new
|
49
|
-
md5.update bytes.pack('c*')
|
50
|
-
digest = [md5.hexdigest].pack('H*').bytes
|
51
|
-
|
52
|
-
digest[6] = (digest[6] & 0x0f) | 0x30
|
53
|
-
digest[8] = (digest[8] & 0x3f) | 0x80
|
54
|
-
|
55
|
-
hex = digest.pack('c*').unpack1('H*')
|
56
|
-
|
57
|
-
MixinBot::Utils::UUID.new(hex: hex).unpacked
|
58
|
-
end
|
59
|
-
|
60
|
-
def mark(*indexes)
|
61
|
-
indexes.map do |index|
|
62
|
-
raise ArgumentError, "invalid NFO memo index #{index}" if index >= 64 || index.negative?
|
63
|
-
|
64
|
-
@mask = mask ^ (1 << index)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def encode
|
69
|
-
bytes = []
|
70
|
-
|
71
|
-
bytes += prefix.bytes
|
72
|
-
bytes += [version]
|
73
|
-
|
74
|
-
if mask != 0
|
75
|
-
bytes += [1]
|
76
|
-
bytes += MixinBot::Utils.encode_unit_64 mask
|
77
|
-
bytes += MixinBot::Utils::UUID.new(hex: chain).packed.bytes
|
78
|
-
|
79
|
-
class_bytes = [nm_class].pack('H*').bytes
|
80
|
-
bytes += MixinBot::Utils.bytes_of class_bytes.size
|
81
|
-
bytes += class_bytes
|
82
|
-
|
83
|
-
collection_bytes = collection.split('-').pack('H* H* H* H* H*').bytes
|
84
|
-
bytes += MixinBot::Utils.bytes_of collection_bytes.size
|
85
|
-
bytes += collection_bytes
|
86
|
-
|
87
|
-
# token_bytes = memo[:token].split('-').pack('H* H* H* H* H*').bytes
|
88
|
-
token_bytes = MixinBot::Utils.bytes_of token
|
89
|
-
bytes += MixinBot::Utils.bytes_of token_bytes.size
|
90
|
-
bytes += token_bytes
|
91
|
-
else
|
92
|
-
bytes += [0]
|
93
|
-
end
|
94
|
-
|
95
|
-
extra_bytes = [extra].pack('H*').bytes
|
96
|
-
bytes += MixinBot::Utils.bytes_of extra_bytes.size
|
97
|
-
bytes += extra_bytes
|
98
|
-
|
99
|
-
@raw = bytes.pack('C*')
|
100
|
-
@hex = raw.unpack1('H*')
|
101
|
-
@memo = Base64.urlsafe_encode64 raw, padding: false
|
102
|
-
|
103
|
-
self
|
104
|
-
end
|
105
|
-
|
106
|
-
def decode
|
107
|
-
@raw =
|
108
|
-
if memo.present?
|
109
|
-
Base64.urlsafe_decode64 memo
|
110
|
-
elsif hex.present?
|
111
|
-
[hex].pack('H*')
|
112
|
-
else
|
113
|
-
raise InvalidNfoFormatError, 'memo or hex is required'
|
114
|
-
end
|
115
|
-
|
116
|
-
@hex = raw.unpack1('H*') if hex.blank?
|
117
|
-
@memo = Base64.urlsafe_encode64 raw, padding: false if memo.blank?
|
118
|
-
|
119
|
-
decode_bytes
|
120
|
-
self
|
121
|
-
end
|
122
|
-
|
123
|
-
def decode_bytes
|
124
|
-
bytes = raw.bytes
|
125
|
-
|
126
|
-
_prefix = bytes.shift(3).pack('C*')
|
127
|
-
raise MixinBot::InvalidNfoFormatError, "NFO prefix #{_prefix}" if _prefix != prefix
|
128
|
-
|
129
|
-
_version = bytes.shift
|
130
|
-
raise MixinBot::InvalidNfoFormatError, "NFO version #{prefix}" if _version != version
|
131
|
-
|
132
|
-
hint = bytes.shift
|
133
|
-
if hint == 1
|
134
|
-
@mask = bytes.shift(8).reverse.pack('C*').unpack1('Q*')
|
135
|
-
|
136
|
-
@chain = MixinBot::Utils::UUID.new(hex: bytes.shift(16).pack('C*').unpack1('H*')).unpacked
|
137
|
-
|
138
|
-
class_length = bytes.shift
|
139
|
-
@nm_class = bytes.shift(class_length).pack('C*').unpack1('H*')
|
140
|
-
|
141
|
-
collection_length = bytes.shift
|
142
|
-
@collection = MixinBot::Utils::UUID.new(hex: bytes.shift(collection_length).pack('C*').unpack1('H*')).unpacked
|
143
|
-
|
144
|
-
token_length = bytes.shift
|
145
|
-
@token = MixinBot::Utils.bytes_to_int bytes.shift(token_length)
|
146
|
-
end
|
147
|
-
|
148
|
-
extra_length = bytes.shift
|
149
|
-
@extra = bytes.shift(extra_length).pack('C*').unpack1('H*')
|
150
|
-
|
151
|
-
self
|
152
|
-
end
|
153
|
-
|
154
|
-
def to_h
|
155
|
-
hash = {
|
156
|
-
prefix: prefix,
|
157
|
-
version: version,
|
158
|
-
mask: mask,
|
159
|
-
chain: chain,
|
160
|
-
class: nm_class,
|
161
|
-
collection: collection,
|
162
|
-
token: token,
|
163
|
-
extra: extra,
|
164
|
-
memo: memo,
|
165
|
-
hex: hex
|
166
|
-
}
|
167
|
-
|
168
|
-
hash.each do |key, value|
|
169
|
-
hash.delete key if value.blank?
|
170
|
-
end
|
171
|
-
|
172
|
-
hash
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|