mixin_bot 2.6.0 → 3.0.2

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +3 -3
  3. data/API_COVERAGE.md +1 -0
  4. data/CHANGELOG.md +22 -1
  5. data/README.md +116 -5
  6. data/docs/agent/cookbook.md +49 -0
  7. data/examples/blaze_async.rb +6 -4
  8. data/lib/generators/mixin_bot/authentication/USAGE +29 -0
  9. data/lib/generators/mixin_bot/authentication/authentication_generator.rb +82 -0
  10. data/lib/generators/mixin_bot/authentication/templates/app/controllers/concerns/authentication.rb.tt +52 -0
  11. data/lib/generators/mixin_bot/authentication/templates/app/controllers/sessions_controller.rb.tt +24 -0
  12. data/lib/generators/mixin_bot/authentication/templates/app/models/current.rb.tt +4 -0
  13. data/lib/generators/mixin_bot/authentication/templates/app/models/session.rb.tt +3 -0
  14. data/lib/generators/mixin_bot/authentication/templates/app/models/user.rb.tt +12 -0
  15. data/lib/generators/mixin_bot/authentication/templates/app/views/sessions/new.html.erb.tt +3 -0
  16. data/lib/generators/mixin_bot/authentication/templates/config/initializers/omniauth.rb.tt +21 -0
  17. data/lib/generators/mixin_bot/blaze/USAGE +19 -0
  18. data/lib/generators/mixin_bot/blaze/blaze_generator.rb +43 -0
  19. data/lib/generators/mixin_bot/blaze/templates/app/mixin/handlers/text_handler.rb +14 -0
  20. data/lib/generators/mixin_bot/blaze/templates/config/initializers/mixin_bot_blaze.rb +23 -0
  21. data/lib/generators/mixin_bot/install/USAGE +24 -0
  22. data/lib/generators/mixin_bot/install/install_generator.rb +50 -0
  23. data/lib/generators/mixin_bot/notifications/USAGE +13 -0
  24. data/lib/generators/mixin_bot/notifications/notifications_generator.rb +49 -0
  25. data/lib/generators/mixin_bot/notifications/templates/app/notifications/payment_received_notification.rb +24 -0
  26. data/lib/generators/mixin_bot/outputs/USAGE +29 -0
  27. data/lib/generators/mixin_bot/outputs/outputs_generator.rb +50 -0
  28. data/lib/generators/mixin_bot/outputs/templates/app/mixin/processors/deposit_processor.rb +21 -0
  29. data/lib/generators/mixin_bot/outputs/templates/app/models/mixin_output.rb +8 -0
  30. data/lib/generators/mixin_bot/outputs/templates/db/migrate/create_mixin_outputs.rb.tt +26 -0
  31. data/lib/generators/mixin_bot/transfers/USAGE +37 -0
  32. data/lib/generators/mixin_bot/transfers/templates/app/jobs/mixin_transfers/perform_job.rb +13 -0
  33. data/lib/generators/mixin_bot/transfers/templates/app/jobs/mixin_transfers/reconcile_job.rb +14 -0
  34. data/lib/generators/mixin_bot/transfers/templates/app/models/mixin_transfer.rb +11 -0
  35. data/lib/generators/mixin_bot/transfers/templates/db/migrate/create_mixin_transfers.rb.tt +23 -0
  36. data/lib/generators/mixin_bot/transfers/transfers_generator.rb +67 -0
  37. data/lib/generators/mixin_bot.rb +10 -0
  38. data/lib/mixin_bot/api/app.rb +20 -0
  39. data/lib/mixin_bot/api/blaze_async.rb +5 -1
  40. data/lib/mixin_bot/api/snapshot.rb +5 -0
  41. data/lib/mixin_bot/blaze/reactor.rb +249 -0
  42. data/lib/mixin_bot/blaze/router.rb +333 -0
  43. data/lib/mixin_bot/cache_store_adapter.rb +3 -1
  44. data/lib/mixin_bot/client.rb +2 -1
  45. data/lib/mixin_bot/computer.rb +3 -1
  46. data/lib/mixin_bot/configuration.rb +52 -0
  47. data/lib/mixin_bot/json_decoder.rb +14 -0
  48. data/lib/mixin_bot/notifications/mixin_channel.rb +80 -0
  49. data/lib/mixin_bot/outputs/cursor_model.rb +33 -0
  50. data/lib/mixin_bot/outputs/envelope.rb +160 -0
  51. data/lib/mixin_bot/outputs/memory_stores.rb +97 -0
  52. data/lib/mixin_bot/outputs/poller.rb +178 -0
  53. data/lib/mixin_bot/outputs/processing_job.rb +54 -0
  54. data/lib/mixin_bot/outputs/processors.rb +124 -0
  55. data/lib/mixin_bot/outputs/receipt_model.rb +86 -0
  56. data/lib/mixin_bot/outputs.rb +42 -0
  57. data/lib/mixin_bot/rails/railtie.rb +44 -0
  58. data/lib/mixin_bot/rails/tasks/poller.rake +33 -0
  59. data/lib/mixin_bot/rails.rb +34 -0
  60. data/lib/mixin_bot/registry.rb +79 -0
  61. data/lib/mixin_bot/transfers/model.rb +112 -0
  62. data/lib/mixin_bot/transfers/performer.rb +64 -0
  63. data/lib/mixin_bot/transfers/reconcile.rb +53 -0
  64. data/lib/mixin_bot/transfers.rb +23 -0
  65. data/lib/mixin_bot/version.rb +1 -1
  66. data/lib/mixin_bot.rb +4 -0
  67. data/lib/puma/plugin/mixin_blaze.rb +263 -0
  68. data/llms.txt +1 -1
  69. metadata +69 -7
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MixinBot
4
+ ##
5
+ # Outbound transfer pipeline: a persisted transfer record enqueues a job
6
+ # that executes the Safe transaction pipeline exactly once per trace id,
7
+ # records the outcome on the record's state, and reconciles unknown
8
+ # outcomes (timeout after submission) against the snapshot API before any
9
+ # retry — the network's trace deduplication makes retries safe.
10
+ #
11
+ module Transfers
12
+ class << self
13
+ # Shared logger for the transfers integration; called with (level, detail).
14
+ attr_accessor :logger
15
+ end
16
+
17
+ self.logger = ->(level, detail) { warn "[mixin_transfers] #{level}: #{detail}" }
18
+ end
19
+ end
20
+
21
+ require_relative 'transfers/model'
22
+ require_relative 'transfers/performer'
23
+ require_relative 'transfers/reconcile'
@@ -11,5 +11,5 @@ module MixinBot
11
11
  #
12
12
  # @see https://semver.org/
13
13
  #
14
- VERSION = '2.6.0'
14
+ VERSION = '3.0.2'
15
15
  end
data/lib/mixin_bot.rb CHANGED
@@ -26,11 +26,13 @@ require_relative 'mixin_bot/models'
26
26
  require_relative 'mixin_bot/session_store'
27
27
  require_relative 'mixin_bot/cache_store_adapter'
28
28
  require_relative 'mixin_bot/api'
29
+ require_relative 'mixin_bot/blaze/reactor'
29
30
  require_relative 'mixin_bot/bot_auth'
30
31
  require_relative 'mixin_bot/cli'
31
32
  require_relative 'mixin_bot/computer'
32
33
  require_relative 'mixin_bot/invoice'
33
34
  require_relative 'mixin_bot/monitor'
35
+ require_relative 'mixin_bot/registry'
34
36
  require_relative 'mixin_bot/url_scheme'
35
37
  require_relative 'mixin_bot/utils'
36
38
  require_relative 'mixin_bot/nfo'
@@ -229,4 +231,6 @@ module MixinBot
229
231
  @deprecator ||= ActiveSupport::Deprecation.new('2.0', 'MixinBot')
230
232
  end
231
233
  end
234
+
235
+ extend Registry
232
236
  end
@@ -0,0 +1,263 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Puma plugin hosting the Blaze connection inside the web process tree —
4
+ # the Solid Queue plugin architecture:
5
+ #
6
+ # # config/puma.rb
7
+ # plugin :mixin_blaze
8
+ # mixin_blaze_mode :fork # default; :async hosts the loop in-process
9
+ #
10
+ # # config/initializers/mixin_bot.rb
11
+ # MixinBot.configure do
12
+ # self.blaze_handler = ->(envelope) { MyBot.process! envelope }
13
+ # end
14
+ #
15
+ # Modes:
16
+ # - *fork* (default): after boot a dedicated child process runs
17
+ # {MixinBot::Blaze::Reactor}; a background thread supervises it and stops
18
+ # Puma if the child dies (fail fast — silent non-reception is worse than a
19
+ # visible restart). The child stops with Puma and monitors the master.
20
+ # - *async*: the reactor runs in a Puma background thread inside this very
21
+ # process. In cluster mode that process is the master.
22
+ #
23
+ # Requires `preload_app!` in cluster mode: plugins run in the launcher
24
+ # process, and without preloading it holds no application code to resolve
25
+ # the handler.
26
+ require 'English'
27
+ require 'mixin_bot'
28
+ require 'puma/plugin'
29
+
30
+ module Puma
31
+ class DSL
32
+ # Selects where the Blaze connection lives (see file comment).
33
+ #
34
+ # @param mode [Symbol] +:fork+ (default) or +:async+
35
+ def mixin_blaze_mode(mode = :fork)
36
+ @options[:mixin_blaze_mode] = mode.to_sym
37
+ end
38
+ end
39
+ end
40
+
41
+ Puma::Plugin.create do
42
+ def start(launcher)
43
+ @launcher = launcher
44
+ @log_writer = launcher.log_writer
45
+ @puma_pid = $PROCESS_ID
46
+ @mode = launcher.options[:mixin_blaze_mode] || :fork
47
+
48
+ unless %i[fork async].include?(@mode)
49
+ @log_writer.error "mixin_blaze: mixin_blaze_mode must be fork or async, got #{@mode.inspect}; plugin not started"
50
+ return
51
+ end
52
+
53
+ if launcher.options[:workers].to_i.positive? && !launcher.options[:preload_app]
54
+ @log_writer.error 'mixin_blaze: Puma cluster mode requires preload_app! (the launcher process hosts the Blaze handler); ' \
55
+ 'enable preload_app! or drop to single mode; plugin not started'
56
+ return
57
+ end
58
+
59
+ @mode == :async ? start_async_mode : start_fork_mode
60
+ end
61
+
62
+ private
63
+
64
+ def start_fork_mode
65
+ in_background { monitor_blaze_fork }
66
+
67
+ register_lifecycle(
68
+ booted: -> { fork_blaze },
69
+ stopped: -> { stop_blaze_fork },
70
+ restart: -> { stop_blaze_fork }
71
+ )
72
+ end
73
+
74
+ def start_async_mode
75
+ register_lifecycle(
76
+ booted: -> { start_blaze_async },
77
+ stopped: -> { stop_blaze_async },
78
+ restart: lambda {
79
+ stop_blaze_async
80
+ start_blaze_async
81
+ }
82
+ )
83
+ end
84
+
85
+ # Puma 7 renamed the lifecycle hooks; the old names remain as deprecated
86
+ # aliases (same branching as Solid Queue's plugin).
87
+ def register_lifecycle(booted:, stopped:, restart:)
88
+ if Gem::Version.new(Puma::Const::VERSION) < Gem::Version.new('7')
89
+ @launcher.events.on_booted { booted.call }
90
+ @launcher.events.on_stopped { stopped.call }
91
+ @launcher.events.on_restart { restart.call }
92
+ else
93
+ @launcher.events.after_booted { booted.call }
94
+ @launcher.events.after_stopped { stopped.call }
95
+ @launcher.events.before_restart { restart.call }
96
+ end
97
+ end
98
+
99
+ # ---- fork mode ----
100
+
101
+ def fork_blaze
102
+ reactor = build_reactor
103
+ return if reactor.nil?
104
+
105
+ @blaze_pid = fork do
106
+ @blaze_pid = nil
107
+ # the master's INT trap must not run here; raise Interrupt on the main
108
+ # thread instead, so the reactor unwinds and closes the connection
109
+ Signal.trap(:INT) { raise Interrupt }
110
+ Signal.trap(:TERM) { exit!(0) }
111
+ Thread.new { monitor_puma_master }
112
+
113
+ begin
114
+ reactor.run
115
+ ensure
116
+ # skip at-exit finalization, which can deadlock on inherited
117
+ # database handles (same rationale as Solid Queue's plugin)
118
+ exit!(0)
119
+ end
120
+ end
121
+
122
+ log "mixin_blaze: forked Blaze child (pid #{@blaze_pid})"
123
+ rescue NotImplementedError
124
+ @log_writer.error 'mixin_blaze: fork is unavailable on this platform; use mixin_blaze_mode :async'
125
+ end
126
+
127
+ def stop_blaze_fork
128
+ return unless @blaze_pid
129
+
130
+ @shutting_down = true
131
+
132
+ begin
133
+ Process.waitpid(@blaze_pid, Process::WNOHANG)
134
+ rescue Errno::ECHILD, Errno::ESRCH
135
+ # already gone; the reap loop below handles it
136
+ end
137
+ log 'mixin_blaze: stopping Blaze child...'
138
+ begin
139
+ Process.kill(:INT, @blaze_pid)
140
+ rescue Errno::ESRCH
141
+ @blaze_pid = nil
142
+ return
143
+ end
144
+
145
+ # bounded reap: never let a stuck child hold up Puma's shutdown
146
+ deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + 10.0
147
+ reaped = false
148
+ while Process.clock_gettime(Process::CLOCK_MONOTONIC) < deadline
149
+ begin
150
+ reaped = true if Process.waitpid(@blaze_pid, Process::WNOHANG)
151
+ break if reaped
152
+ rescue Errno::ECHILD, Errno::ESRCH
153
+ reaped = true
154
+ break
155
+ end
156
+ sleep 0.05
157
+ end
158
+
159
+ unless reaped
160
+ log "mixin_blaze: Blaze child #{@blaze_pid} did not stop within 10s; killing"
161
+ begin
162
+ Process.kill(:KILL, @blaze_pid)
163
+ rescue Errno::ESRCH
164
+ nil
165
+ end
166
+ begin
167
+ Process.waitpid(@blaze_pid) # KILL is fatal; reap the zombie
168
+ rescue Errno::ECHILD, Errno::ESRCH
169
+ nil
170
+ end
171
+ end
172
+ @blaze_pid = nil
173
+ rescue Errno::ECHILD, Errno::ESRCH
174
+ @blaze_pid = nil
175
+ end
176
+
177
+ def monitor_blaze_fork
178
+ loop do
179
+ if blaze_fork_dead?
180
+ log 'mixin_blaze: Blaze child has gone away, stopping Puma...'
181
+ stop_puma!
182
+ break
183
+ end
184
+ sleep 2
185
+ end
186
+ rescue StandardError => e
187
+ log "mixin_blaze: monitor thread ended (#{e.class}: #{e.message})"
188
+ end
189
+
190
+ def blaze_fork_dead?
191
+ return false if @shutting_down
192
+ return false unless @blaze_pid
193
+
194
+ Process.waitpid(@blaze_pid, Process::WNOHANG)
195
+ false
196
+ rescue Errno::ECHILD, Errno::ESRCH
197
+ true
198
+ end
199
+
200
+ def monitor_puma_master
201
+ loop do
202
+ if Process.ppid != @puma_pid
203
+ Process.kill(:INT, $PROCESS_ID)
204
+ break
205
+ end
206
+ sleep 2
207
+ end
208
+ end
209
+
210
+ # ---- async mode ----
211
+
212
+ def start_blaze_async
213
+ reactor = build_reactor
214
+ return if reactor.nil?
215
+
216
+ @reactor = reactor
217
+ @blaze_thread = Thread.new do
218
+ Thread.current.name = 'puma plugin mixin_blaze' if Thread.current.respond_to?(:name=)
219
+ reactor.run
220
+ end
221
+
222
+ log "mixin_blaze: Blaze reactor running in-process (pid #{Process.pid})"
223
+ end
224
+
225
+ def stop_blaze_async(join_limit: 1)
226
+ reactor = @reactor
227
+ thread = @blaze_thread
228
+ @reactor = nil
229
+ @blaze_thread = nil
230
+
231
+ return unless reactor
232
+
233
+ reactor.stop
234
+ thread&.join(join_limit)
235
+ log 'mixin_blaze: in-process Blaze reactor stopped'
236
+ end
237
+
238
+ # ---- shared ----
239
+
240
+ # Handler resolution happens at boot time (after the application has
241
+ # loaded — Puma starts plugin background work after load_and_bind).
242
+ def build_reactor
243
+ handler = MixinBot.config.blaze_handler
244
+ if handler.nil?
245
+ @log_writer.error 'mixin_blaze: no handler configured — set MixinBot.configure { self.blaze_handler = ->(envelope) { ... } }; ' \
246
+ 'plugin not started'
247
+ return nil
248
+ end
249
+
250
+ MixinBot::Blaze::Reactor.new(handler: handler, logger: ->(level, detail) { log("mixin_blaze #{level}: #{detail}") })
251
+ end
252
+
253
+ def stop_puma!
254
+ Process.kill(:INT, $PROCESS_ID)
255
+ end
256
+
257
+ def log(message)
258
+ @log_writer.log(message)
259
+ rescue Errno::EIO, Errno::EPIPE, Errno::EBADF
260
+ # the controlling terminal can disappear mid-shutdown; keep going
261
+ nil
262
+ end
263
+ end
data/llms.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # MixinBot
2
2
 
3
- > Ruby SDK and CLI for Mixin Network: Safe UTXO transfers, REST API, Blaze messaging, transaction crypto, optional MVM helpers. Ruby >= 3.2. Gem version 2.3.0.
3
+ > Ruby SDK and CLI for Mixin Network: Safe UTXO transfers, REST API, Blaze messaging, transaction crypto, optional MVM helpers. Ruby >= 4.0. Gem version 3.0.2.
4
4
 
5
5
  Important notes:
6
6
 
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixin_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.0
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - an-lee
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-09-07 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activesupport
@@ -24,6 +23,20 @@ dependencies:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
25
  version: '7'
26
+ - !ruby/object:Gem::Dependency
27
+ name: async
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2.0'
27
40
  - !ruby/object:Gem::Dependency
28
41
  name: async-websocket
29
42
  requirement: !ruby/object:Gem::Requirement
@@ -287,6 +300,36 @@ files:
287
300
  - examples/blaze.rb
288
301
  - examples/blaze_async.rb
289
302
  - examples/config.yml.example
303
+ - lib/generators/mixin_bot.rb
304
+ - lib/generators/mixin_bot/authentication/USAGE
305
+ - lib/generators/mixin_bot/authentication/authentication_generator.rb
306
+ - lib/generators/mixin_bot/authentication/templates/app/controllers/concerns/authentication.rb.tt
307
+ - lib/generators/mixin_bot/authentication/templates/app/controllers/sessions_controller.rb.tt
308
+ - lib/generators/mixin_bot/authentication/templates/app/models/current.rb.tt
309
+ - lib/generators/mixin_bot/authentication/templates/app/models/session.rb.tt
310
+ - lib/generators/mixin_bot/authentication/templates/app/models/user.rb.tt
311
+ - lib/generators/mixin_bot/authentication/templates/app/views/sessions/new.html.erb.tt
312
+ - lib/generators/mixin_bot/authentication/templates/config/initializers/omniauth.rb.tt
313
+ - lib/generators/mixin_bot/blaze/USAGE
314
+ - lib/generators/mixin_bot/blaze/blaze_generator.rb
315
+ - lib/generators/mixin_bot/blaze/templates/app/mixin/handlers/text_handler.rb
316
+ - lib/generators/mixin_bot/blaze/templates/config/initializers/mixin_bot_blaze.rb
317
+ - lib/generators/mixin_bot/install/USAGE
318
+ - lib/generators/mixin_bot/install/install_generator.rb
319
+ - lib/generators/mixin_bot/notifications/USAGE
320
+ - lib/generators/mixin_bot/notifications/notifications_generator.rb
321
+ - lib/generators/mixin_bot/notifications/templates/app/notifications/payment_received_notification.rb
322
+ - lib/generators/mixin_bot/outputs/USAGE
323
+ - lib/generators/mixin_bot/outputs/outputs_generator.rb
324
+ - lib/generators/mixin_bot/outputs/templates/app/mixin/processors/deposit_processor.rb
325
+ - lib/generators/mixin_bot/outputs/templates/app/models/mixin_output.rb
326
+ - lib/generators/mixin_bot/outputs/templates/db/migrate/create_mixin_outputs.rb.tt
327
+ - lib/generators/mixin_bot/transfers/USAGE
328
+ - lib/generators/mixin_bot/transfers/templates/app/jobs/mixin_transfers/perform_job.rb
329
+ - lib/generators/mixin_bot/transfers/templates/app/jobs/mixin_transfers/reconcile_job.rb
330
+ - lib/generators/mixin_bot/transfers/templates/app/models/mixin_transfer.rb
331
+ - lib/generators/mixin_bot/transfers/templates/db/migrate/create_mixin_transfers.rb.tt
332
+ - lib/generators/mixin_bot/transfers/transfers_generator.rb
290
333
  - lib/mixin_bot.rb
291
334
  - lib/mixin_bot/address.rb
292
335
  - lib/mixin_bot/api.rb
@@ -333,6 +376,8 @@ files:
333
376
  - lib/mixin_bot/api/turn.rb
334
377
  - lib/mixin_bot/api/user.rb
335
378
  - lib/mixin_bot/api/withdraw.rb
379
+ - lib/mixin_bot/blaze/reactor.rb
380
+ - lib/mixin_bot/blaze/router.rb
336
381
  - lib/mixin_bot/bot_auth.rb
337
382
  - lib/mixin_bot/cache_store_adapter.rb
338
383
  - lib/mixin_bot/cli.rb
@@ -351,6 +396,7 @@ files:
351
396
  - lib/mixin_bot/configuration.rb
352
397
  - lib/mixin_bot/errors.rb
353
398
  - lib/mixin_bot/invoice.rb
399
+ - lib/mixin_bot/json_decoder.rb
354
400
  - lib/mixin_bot/models.rb
355
401
  - lib/mixin_bot/models/address.rb
356
402
  - lib/mixin_bot/models/api_envelope.rb
@@ -362,11 +408,28 @@ files:
362
408
  - lib/mixin_bot/models/user.rb
363
409
  - lib/mixin_bot/monitor.rb
364
410
  - lib/mixin_bot/nfo.rb
411
+ - lib/mixin_bot/notifications/mixin_channel.rb
412
+ - lib/mixin_bot/outputs.rb
413
+ - lib/mixin_bot/outputs/cursor_model.rb
414
+ - lib/mixin_bot/outputs/envelope.rb
415
+ - lib/mixin_bot/outputs/memory_stores.rb
416
+ - lib/mixin_bot/outputs/poller.rb
417
+ - lib/mixin_bot/outputs/processing_job.rb
418
+ - lib/mixin_bot/outputs/processors.rb
419
+ - lib/mixin_bot/outputs/receipt_model.rb
420
+ - lib/mixin_bot/rails.rb
421
+ - lib/mixin_bot/rails/railtie.rb
422
+ - lib/mixin_bot/rails/tasks/poller.rake
423
+ - lib/mixin_bot/registry.rb
365
424
  - lib/mixin_bot/session_store.rb
366
425
  - lib/mixin_bot/transaction.rb
367
426
  - lib/mixin_bot/transaction/buffer.rb
368
427
  - lib/mixin_bot/transaction/decoder.rb
369
428
  - lib/mixin_bot/transaction/encoder.rb
429
+ - lib/mixin_bot/transfers.rb
430
+ - lib/mixin_bot/transfers/model.rb
431
+ - lib/mixin_bot/transfers/performer.rb
432
+ - lib/mixin_bot/transfers/reconcile.rb
370
433
  - lib/mixin_bot/url_scheme.rb
371
434
  - lib/mixin_bot/utils.rb
372
435
  - lib/mixin_bot/utils/address.rb
@@ -387,6 +450,7 @@ files:
387
450
  - lib/mvm/nft.rb
388
451
  - lib/mvm/registry.rb
389
452
  - lib/mvm/scan.rb
453
+ - lib/puma/plugin/mixin_blaze.rb
390
454
  - lib/tasks/api_coverage.rake
391
455
  - llms.txt
392
456
  homepage: https://github.com/an-lee/mixin_bot
@@ -394,7 +458,6 @@ licenses:
394
458
  - MIT
395
459
  metadata:
396
460
  rubygems_mfa_required: 'true'
397
- post_install_message:
398
461
  rdoc_options: []
399
462
  require_paths:
400
463
  - lib
@@ -402,15 +465,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
402
465
  requirements:
403
466
  - - ">="
404
467
  - !ruby/object:Gem::Version
405
- version: 3.2.0
468
+ version: 4.0.0
406
469
  required_rubygems_version: !ruby/object:Gem::Requirement
407
470
  requirements:
408
471
  - - ">="
409
472
  - !ruby/object:Gem::Version
410
473
  version: '0'
411
474
  requirements: []
412
- rubygems_version: 3.5.22
413
- signing_key:
475
+ rubygems_version: 4.0.20
414
476
  specification_version: 4
415
477
  summary: A Ruby SDK for Mixin Network
416
478
  test_files: []