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.
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