mixin_bot 0.12.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mixin_bot/api/address.rb +21 -0
  3. data/lib/mixin_bot/api/app.rb +5 -11
  4. data/lib/mixin_bot/api/asset.rb +9 -16
  5. data/lib/mixin_bot/api/attachment.rb +27 -22
  6. data/lib/mixin_bot/api/auth.rb +29 -51
  7. data/lib/mixin_bot/api/blaze.rb +4 -3
  8. data/lib/mixin_bot/api/collectible.rb +60 -58
  9. data/lib/mixin_bot/api/conversation.rb +29 -49
  10. data/lib/mixin_bot/api/encrypted_message.rb +17 -17
  11. data/lib/mixin_bot/api/legacy_multisig.rb +87 -0
  12. data/lib/mixin_bot/api/legacy_output.rb +50 -0
  13. data/lib/mixin_bot/api/legacy_payment.rb +31 -0
  14. data/lib/mixin_bot/api/legacy_snapshot.rb +39 -0
  15. data/lib/mixin_bot/api/legacy_transaction.rb +173 -0
  16. data/lib/mixin_bot/api/legacy_transfer.rb +42 -0
  17. data/lib/mixin_bot/api/me.rb +13 -17
  18. data/lib/mixin_bot/api/message.rb +13 -10
  19. data/lib/mixin_bot/api/multisig.rb +16 -221
  20. data/lib/mixin_bot/api/output.rb +46 -0
  21. data/lib/mixin_bot/api/payment.rb +9 -20
  22. data/lib/mixin_bot/api/pin.rb +57 -65
  23. data/lib/mixin_bot/api/rpc.rb +9 -11
  24. data/lib/mixin_bot/api/snapshot.rb +15 -29
  25. data/lib/mixin_bot/api/tip.rb +43 -0
  26. data/lib/mixin_bot/api/transaction.rb +184 -60
  27. data/lib/mixin_bot/api/transfer.rb +64 -32
  28. data/lib/mixin_bot/api/user.rb +83 -53
  29. data/lib/mixin_bot/api/withdraw.rb +52 -53
  30. data/lib/mixin_bot/api.rb +78 -45
  31. data/lib/mixin_bot/cli/api.rb +149 -5
  32. data/lib/mixin_bot/cli/utils.rb +14 -4
  33. data/lib/mixin_bot/cli.rb +13 -10
  34. data/lib/mixin_bot/client.rb +76 -127
  35. data/lib/mixin_bot/configuration.rb +98 -0
  36. data/lib/mixin_bot/nfo.rb +174 -0
  37. data/lib/mixin_bot/transaction.rb +505 -0
  38. data/lib/mixin_bot/utils/address.rb +108 -0
  39. data/lib/mixin_bot/utils/crypto.rb +182 -0
  40. data/lib/mixin_bot/utils/decoder.rb +58 -0
  41. data/lib/mixin_bot/utils/encoder.rb +63 -0
  42. data/lib/mixin_bot/utils.rb +8 -109
  43. data/lib/mixin_bot/uuid.rb +41 -0
  44. data/lib/mixin_bot/version.rb +1 -1
  45. data/lib/mixin_bot.rb +39 -14
  46. data/lib/mvm/bridge.rb +2 -19
  47. data/lib/mvm/client.rb +11 -33
  48. data/lib/mvm/nft.rb +4 -4
  49. data/lib/mvm/registry.rb +9 -9
  50. data/lib/mvm/scan.rb +3 -5
  51. data/lib/mvm.rb +5 -6
  52. metadata +101 -44
  53. data/lib/mixin_bot/utils/nfo.rb +0 -176
  54. data/lib/mixin_bot/utils/transaction.rb +0 -478
  55. 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.open(File.expand_path('./abis/registry.json', __dir__)).read
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::Utils::UUID.new(hex: hex).unpacked
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::Utils::UUID.new(hex: hex).unpacked
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::Utils::UUID.new(raw: bytes.shift(16).pack('C*')).unpacked
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: members,
36
- threshold: 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::Utils.encode_int(user_ids.length)
56
- bytes += [user_ids.sort.join('').gsub('-', '')].pack('H*').bytes
57
- bytes += MixinBot::Utils.encode_int(threshold)
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
- params: {
16
- address: address,
17
- action: 'tokenlist',
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 './mvm/bridge'
8
- require_relative './mvm/client'
9
- require_relative './mvm/nft'
10
- require_relative './mvm/registry'
11
- require_relative './mvm/scan'
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.12.1
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-01-12 00:00:00.000000000 Z
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: '1.3'
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: '1.3'
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: faye-websocket
112
+ name: faraday
85
113
  requirement: !ruby/object:Gem::Requirement
86
114
  requirements:
87
115
  - - ">="
88
116
  - !ruby/object:Gem::Version
89
- version: '0.11'
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: '0.11'
124
+ version: '2'
97
125
  - !ruby/object:Gem::Dependency
98
- name: http
126
+ name: faraday-multipart
99
127
  requirement: !ruby/object:Gem::Requirement
100
128
  requirements:
101
- - - "~>"
129
+ - - ">="
102
130
  - !ruby/object:Gem::Version
103
- version: '4.1'
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: '4.1'
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: pry
252
+ name: minitest-reporters
197
253
  requirement: !ruby/object:Gem::Requirement
198
254
  requirements:
199
255
  - - "~>"
200
256
  - !ruby/object:Gem::Version
201
- version: 0.13.1
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: 0.13.1
264
+ version: '1.6'
209
265
  - !ruby/object:Gem::Dependency
210
- name: rake
266
+ name: pry
211
267
  requirement: !ruby/object:Gem::Requirement
212
268
  requirements:
213
269
  - - "~>"
214
270
  - !ruby/object:Gem::Version
215
- version: '13.0'
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: '13.0'
278
+ version: '0.14'
223
279
  - !ruby/object:Gem::Dependency
224
- name: rspec
280
+ name: rake
225
281
  requirement: !ruby/object:Gem::Requirement
226
282
  requirements:
227
283
  - - "~>"
228
284
  - !ruby/object:Gem::Version
229
- version: '3.8'
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: '3.8'
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: '0.72'
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.33'
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.18.2
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.18.2
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/nfo.rb
317
- - lib/mixin_bot/utils/transaction.rb
318
- - lib/mixin_bot/utils/uuid.rb
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.2
407
+ rubygems_version: 3.4.21
351
408
  signing_key:
352
409
  specification_version: 4
353
410
  summary: An API wrapper for Mixin Nexwork
@@ -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