mixin_bot 3.0.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.
- checksums.yaml +4 -4
- data/AGENTS.md +1 -1
- data/API_COVERAGE.md +1 -0
- data/CHANGELOG.md +11 -1
- data/README.md +75 -1
- data/docs/agent/cookbook.md +23 -0
- data/lib/generators/mixin_bot/authentication/USAGE +29 -0
- data/lib/generators/mixin_bot/authentication/authentication_generator.rb +82 -0
- data/lib/generators/mixin_bot/authentication/templates/app/controllers/concerns/authentication.rb.tt +52 -0
- data/lib/generators/mixin_bot/authentication/templates/app/controllers/sessions_controller.rb.tt +24 -0
- data/lib/generators/mixin_bot/authentication/templates/app/models/current.rb.tt +4 -0
- data/lib/generators/mixin_bot/authentication/templates/app/models/session.rb.tt +3 -0
- data/lib/generators/mixin_bot/authentication/templates/app/models/user.rb.tt +12 -0
- data/lib/generators/mixin_bot/authentication/templates/app/views/sessions/new.html.erb.tt +3 -0
- data/lib/generators/mixin_bot/authentication/templates/config/initializers/omniauth.rb.tt +21 -0
- data/lib/generators/mixin_bot/blaze/USAGE +19 -0
- data/lib/generators/mixin_bot/blaze/blaze_generator.rb +43 -0
- data/lib/generators/mixin_bot/blaze/templates/app/mixin/handlers/text_handler.rb +14 -0
- data/lib/generators/mixin_bot/blaze/templates/config/initializers/mixin_bot_blaze.rb +23 -0
- data/lib/generators/mixin_bot/install/USAGE +24 -0
- data/lib/generators/mixin_bot/install/install_generator.rb +50 -0
- data/lib/generators/mixin_bot/notifications/USAGE +13 -0
- data/lib/generators/mixin_bot/notifications/notifications_generator.rb +49 -0
- data/lib/generators/mixin_bot/notifications/templates/app/notifications/payment_received_notification.rb +24 -0
- data/lib/generators/mixin_bot/outputs/USAGE +29 -0
- data/lib/generators/mixin_bot/outputs/outputs_generator.rb +50 -0
- data/lib/generators/mixin_bot/outputs/templates/app/mixin/processors/deposit_processor.rb +21 -0
- data/lib/generators/mixin_bot/outputs/templates/app/models/mixin_output.rb +8 -0
- data/lib/generators/mixin_bot/outputs/templates/db/migrate/create_mixin_outputs.rb.tt +26 -0
- data/lib/generators/mixin_bot/transfers/USAGE +37 -0
- data/lib/generators/mixin_bot/transfers/templates/app/jobs/mixin_transfers/perform_job.rb +13 -0
- data/lib/generators/mixin_bot/transfers/templates/app/jobs/mixin_transfers/reconcile_job.rb +14 -0
- data/lib/generators/mixin_bot/transfers/templates/app/models/mixin_transfer.rb +11 -0
- data/lib/generators/mixin_bot/transfers/templates/db/migrate/create_mixin_transfers.rb.tt +23 -0
- data/lib/generators/mixin_bot/transfers/transfers_generator.rb +67 -0
- data/lib/generators/mixin_bot.rb +10 -0
- data/lib/mixin_bot/api/app.rb +20 -0
- data/lib/mixin_bot/api/snapshot.rb +5 -0
- data/lib/mixin_bot/blaze/reactor.rb +8 -3
- data/lib/mixin_bot/blaze/router.rb +333 -0
- data/lib/mixin_bot/cache_store_adapter.rb +3 -1
- data/lib/mixin_bot/client.rb +2 -1
- data/lib/mixin_bot/computer.rb +3 -1
- data/lib/mixin_bot/json_decoder.rb +14 -0
- data/lib/mixin_bot/notifications/mixin_channel.rb +80 -0
- data/lib/mixin_bot/outputs/cursor_model.rb +33 -0
- data/lib/mixin_bot/outputs/envelope.rb +160 -0
- data/lib/mixin_bot/outputs/memory_stores.rb +97 -0
- data/lib/mixin_bot/outputs/poller.rb +178 -0
- data/lib/mixin_bot/outputs/processing_job.rb +54 -0
- data/lib/mixin_bot/outputs/processors.rb +124 -0
- data/lib/mixin_bot/outputs/receipt_model.rb +86 -0
- data/lib/mixin_bot/outputs.rb +42 -0
- data/lib/mixin_bot/rails/railtie.rb +44 -0
- data/lib/mixin_bot/rails/tasks/poller.rake +33 -0
- data/lib/mixin_bot/rails.rb +34 -0
- data/lib/mixin_bot/registry.rb +79 -0
- data/lib/mixin_bot/transfers/model.rb +112 -0
- data/lib/mixin_bot/transfers/performer.rb +64 -0
- data/lib/mixin_bot/transfers/reconcile.rb +53 -0
- data/lib/mixin_bot/transfers.rb +23 -0
- data/lib/mixin_bot/version.rb +1 -1
- data/lib/mixin_bot.rb +3 -0
- data/llms.txt +1 -1
- metadata +51 -2
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Opt-in Rails integration layer: generators, railtie, and Rails glue.
|
|
4
|
+
#
|
|
5
|
+
# `require 'mixin_bot'` alone never loads any of this — the gem keeps no
|
|
6
|
+
# runtime dependency on Rails. Host applications opt in explicitly:
|
|
7
|
+
#
|
|
8
|
+
# # Gemfile
|
|
9
|
+
# gem 'mixin_bot'
|
|
10
|
+
# gem 'rails'
|
|
11
|
+
#
|
|
12
|
+
# # config/application.rb (after the bundler groups)
|
|
13
|
+
# require 'mixin_bot/rails'
|
|
14
|
+
#
|
|
15
|
+
# The railtie registers the mixin_bot rake tasks (e.g. `mixin_bot:poller`).
|
|
16
|
+
# Rails discovers the `lib/generators/mixin_bot/*` generators on its own.
|
|
17
|
+
|
|
18
|
+
require 'mixin_bot'
|
|
19
|
+
|
|
20
|
+
begin
|
|
21
|
+
require 'rails'
|
|
22
|
+
rescue LoadError => e
|
|
23
|
+
raise LoadError,
|
|
24
|
+
'mixin_bot/rails requires the rails gem, which is not a runtime ' \
|
|
25
|
+
"dependency of mixin_bot. Add `gem 'rails'` to your Gemfile, or " \
|
|
26
|
+
"drop `require 'mixin_bot/rails'` if you only need the SDK. " \
|
|
27
|
+
"(#{e.message})"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
require_relative 'blaze/router'
|
|
31
|
+
require_relative 'outputs'
|
|
32
|
+
require_relative 'transfers'
|
|
33
|
+
require_relative 'rails/railtie'
|
|
34
|
+
require_relative 'notifications/mixin_channel'
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MixinBot
|
|
4
|
+
##
|
|
5
|
+
# Named registry for running several bots (keystores) inside one process.
|
|
6
|
+
#
|
|
7
|
+
# The default bot stays on the global configuration (+MixinBot.configure+ /
|
|
8
|
+
# +MixinBot.api+). Additional bots register under a name and return a
|
|
9
|
+
# dedicated +MixinBot::API+ whose configuration is frozen after registration:
|
|
10
|
+
#
|
|
11
|
+
# MixinBot.register_bot :shop,
|
|
12
|
+
# app_id: '...',
|
|
13
|
+
# session_id: '...',
|
|
14
|
+
# session_private_key: '...',
|
|
15
|
+
# server_public_key: '...'
|
|
16
|
+
#
|
|
17
|
+
# MixinBot.bot(:shop).me
|
|
18
|
+
#
|
|
19
|
+
# Integration components built on top of the SDK (router, poller, transfers,
|
|
20
|
+
# notifications) accept the bot name and default to the global API client.
|
|
21
|
+
module Registry
|
|
22
|
+
##
|
|
23
|
+
# Registers a bot under +name+ with {MixinBot::API#initialize} kwargs and
|
|
24
|
+
# freezes the resulting client's configuration.
|
|
25
|
+
#
|
|
26
|
+
# @param name [Symbol, String] registry key
|
|
27
|
+
# @param kwargs [Hash] bot credentials (see {Configuration#initialize});
|
|
28
|
+
# empty kwargs would alias the global configuration and are rejected
|
|
29
|
+
# @return [MixinBot::API] the registered client
|
|
30
|
+
# @raise [MixinBot::ArgumentError] when the name is already registered or
|
|
31
|
+
# no credentials are given
|
|
32
|
+
#
|
|
33
|
+
def register_bot(name, **kwargs)
|
|
34
|
+
raise MixinBot::ArgumentError, 'register_bot requires bot credentials' if kwargs.empty?
|
|
35
|
+
raise MixinBot::ArgumentError, "bot #{name.inspect} is already registered" if bots.key?(name.to_sym)
|
|
36
|
+
|
|
37
|
+
api = MixinBot::API.new(**kwargs)
|
|
38
|
+
api.config.freeze
|
|
39
|
+
bots[name.to_sym] = api
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
##
|
|
43
|
+
# Returns the API client registered under +name+.
|
|
44
|
+
#
|
|
45
|
+
# MixinBot.bot(:shop).assets
|
|
46
|
+
#
|
|
47
|
+
# @param name [Symbol, String] registry key
|
|
48
|
+
# @return [MixinBot::API]
|
|
49
|
+
# @raise [KeyError] when nothing is registered under that name
|
|
50
|
+
#
|
|
51
|
+
def bot(name)
|
|
52
|
+
bots.fetch(name.to_sym)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
##
|
|
56
|
+
# Finds a bot client by its app id: the default API when the app id is
|
|
57
|
+
# the global configuration's, else the registered bot carrying it.
|
|
58
|
+
#
|
|
59
|
+
# @param app_id [String, nil]
|
|
60
|
+
# @return [MixinBot::API, nil] nil when no bot carries that app id
|
|
61
|
+
#
|
|
62
|
+
def bot_by_app_id(app_id)
|
|
63
|
+
return nil if app_id.nil?
|
|
64
|
+
return api if config.app_id == app_id
|
|
65
|
+
|
|
66
|
+
bots.each_value.find { |client| client.config.app_id == app_id }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
##
|
|
70
|
+
# Returns the registry contents (bot name => API client). The hash is
|
|
71
|
+
# exposed for introspection; mutate it only between registrations.
|
|
72
|
+
#
|
|
73
|
+
# @return [Hash{Symbol => MixinBot::API}]
|
|
74
|
+
#
|
|
75
|
+
def bots
|
|
76
|
+
@bots ||= {}
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/concern'
|
|
4
|
+
|
|
5
|
+
module MixinBot
|
|
6
|
+
module Transfers
|
|
7
|
+
##
|
|
8
|
+
# ActiveRecord concern for the generated +MixinTransfer+ model
|
|
9
|
+
# (mixin_bot:transfers generator): the transfer ledger's state machine and
|
|
10
|
+
# its execution entry points.
|
|
11
|
+
#
|
|
12
|
+
# class MixinTransfer < ApplicationRecord
|
|
13
|
+
# include MixinBot::Transfers::Model
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# transfer = MixinTransfer.create!(
|
|
17
|
+
# recipient_id: user_id, asset_id: ASSET, amount: '1.5',
|
|
18
|
+
# memo: 'payout', trace_id: SecureRandom.uuid
|
|
19
|
+
# )
|
|
20
|
+
# transfer.perform! # executes the Safe pipeline
|
|
21
|
+
# transfer.reconcile! # resolves unknown outcomes
|
|
22
|
+
# MixinTransfer.reconcile_pending! # recurring-job entry point
|
|
23
|
+
#
|
|
24
|
+
# Required columns (see the generated migration): recipient_id, asset_id,
|
|
25
|
+
# amount, memo, trace_id (unique), state (default 'pending'),
|
|
26
|
+
# previous_state, transaction_hash, error, transitioned_at, bot_app_id
|
|
27
|
+
# (nil = the default bot), plus Rails timestamps.
|
|
28
|
+
#
|
|
29
|
+
module Model
|
|
30
|
+
extend ActiveSupport::Concern
|
|
31
|
+
|
|
32
|
+
STATES = %w[pending broadcast confirmed failed reconciling].freeze
|
|
33
|
+
|
|
34
|
+
# The allowed state graph: pending is pre-submission; broadcast means
|
|
35
|
+
# the transaction was submitted; confirmed and failed are terminal;
|
|
36
|
+
# reconciling means a submission outcome was indeterminate.
|
|
37
|
+
TRANSITIONS = {
|
|
38
|
+
'pending' => %w[broadcast failed reconciling],
|
|
39
|
+
'broadcast' => %w[confirmed reconciling],
|
|
40
|
+
'reconciling' => %w[broadcast confirmed failed],
|
|
41
|
+
'confirmed' => [].freeze,
|
|
42
|
+
'failed' => [].freeze
|
|
43
|
+
}.freeze
|
|
44
|
+
|
|
45
|
+
included do
|
|
46
|
+
validates :trace_id, presence: true, uniqueness: true
|
|
47
|
+
validates :recipient_id, :asset_id, :amount, presence: true
|
|
48
|
+
validates :state, inclusion: { in: STATES }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
class_methods do
|
|
52
|
+
# Recurring-job entry point: resolve every transfer whose send attempt
|
|
53
|
+
# ended indeterminately (timeout after submission).
|
|
54
|
+
def reconcile_pending!
|
|
55
|
+
reconciling.find_each(&:reconcile!)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
##
|
|
60
|
+
# Audited state transition through the allowed graph. Never mutate
|
|
61
|
+
# #state directly. Same-state transitions are no-ops (idempotent
|
|
62
|
+
# retries); terminal states (confirmed, failed) never change.
|
|
63
|
+
#
|
|
64
|
+
# @param state [String] target state
|
|
65
|
+
# @param transaction_hash [String, nil] set when the network revealed it
|
|
66
|
+
# @param error [String, nil] set when the transition records a failure
|
|
67
|
+
# @raise [MixinBot::ArgumentError] when the transition is not allowed
|
|
68
|
+
#
|
|
69
|
+
def transition_to!(state, transaction_hash: nil, error: nil)
|
|
70
|
+
state = state.to_s
|
|
71
|
+
return self if state == self.state
|
|
72
|
+
|
|
73
|
+
unless TRANSITIONS.fetch(self.state, []).include?(state)
|
|
74
|
+
raise MixinBot::ArgumentError, "illegal transfer transition: #{self.state.inspect} → #{state.inspect}"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
update!(
|
|
78
|
+
previous_state: self.state,
|
|
79
|
+
state:,
|
|
80
|
+
transaction_hash: transaction_hash || self.transaction_hash,
|
|
81
|
+
error:,
|
|
82
|
+
transitioned_at: Time.now
|
|
83
|
+
)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
##
|
|
87
|
+
# Executes the Safe pipeline for this transfer (idempotent per trace
|
|
88
|
+
# id). Definitive rejections mark the transfer failed; indeterminate
|
|
89
|
+
# network outcomes mark it reconciling. {Reconcile} resolves those.
|
|
90
|
+
#
|
|
91
|
+
def perform!
|
|
92
|
+
return self if state == 'confirmed'
|
|
93
|
+
raise MixinBot::ArgumentError, "transfer #{trace_id} is failed and will not be retried" if state == 'failed'
|
|
94
|
+
|
|
95
|
+
Performer.new(self, api: bot_api).perform
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
##
|
|
99
|
+
# Resolves an indeterminate outcome: confirm from the trace's snapshot,
|
|
100
|
+
# or re-send with the same trace id (safe — the network deduplicates).
|
|
101
|
+
#
|
|
102
|
+
def reconcile!
|
|
103
|
+
Reconcile.new(self, api: bot_api).call
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# The API client bound to this transfer's bot (bot_app_id or default).
|
|
107
|
+
def bot_api
|
|
108
|
+
MixinBot.bot_by_app_id(bot_app_id) || MixinBot.api
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MixinBot
|
|
4
|
+
module Transfers
|
|
5
|
+
##
|
|
6
|
+
# Executes the Safe pipeline for one transfer record:
|
|
7
|
+
# build_utxos → build_safe_transaction → verify → sign → send, with the
|
|
8
|
+
# transfer's trace id as the request id, so network-side deduplication
|
|
9
|
+
# makes every retry safe.
|
|
10
|
+
#
|
|
11
|
+
# Outcome mapping:
|
|
12
|
+
# - success → broadcast (transaction hash stored), then confirmed when the
|
|
13
|
+
# submission response carries the hash (it normally does);
|
|
14
|
+
# - definitive API rejection (insufficient funds, invalid request, ...) →
|
|
15
|
+
# failed — never retried;
|
|
16
|
+
# - indeterminate network outcome (timeout/connection loss around the
|
|
17
|
+
# submission) → reconciling — {Reconcile} resolves it.
|
|
18
|
+
#
|
|
19
|
+
class Performer
|
|
20
|
+
# Indeterminate-outcome network errors: the submission may or may not
|
|
21
|
+
# have landed, so the transfer goes to reconciling rather than failed.
|
|
22
|
+
NETWORK_ERRORS = [Faraday::Error, SocketError, Errno::ETIMEDOUT, Timeout::Error].freeze
|
|
23
|
+
|
|
24
|
+
attr_reader :transfer, :api
|
|
25
|
+
|
|
26
|
+
def initialize(transfer, api:)
|
|
27
|
+
@transfer = transfer
|
|
28
|
+
@api = api
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# Runs the pipeline and records the outcome. Re-raises unexpected
|
|
33
|
+
# (non-API, non-network) errors — those are bugs, left to the job
|
|
34
|
+
# backend's retry policy, with the transfer still in its prior state.
|
|
35
|
+
#
|
|
36
|
+
# @return [MixinBot::Transfers::Performer]
|
|
37
|
+
#
|
|
38
|
+
def perform
|
|
39
|
+
response = api.create_safe_transfer(
|
|
40
|
+
asset_id: transfer.asset_id,
|
|
41
|
+
amount: transfer.amount.to_d,
|
|
42
|
+
members: [transfer.recipient_id],
|
|
43
|
+
memo: transfer.memo.to_s,
|
|
44
|
+
trace_id: transfer.trace_id
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
data = response['data']
|
|
48
|
+
data = data.first if data.is_a?(Array)
|
|
49
|
+
data ||= {}
|
|
50
|
+
|
|
51
|
+
transfer.transition_to!('broadcast', transaction_hash: data['transaction_hash'])
|
|
52
|
+
transfer.transition_to!('confirmed', transaction_hash: data['transaction_hash']) if data['transaction_hash']
|
|
53
|
+
self
|
|
54
|
+
rescue MixinBot::APIError => e
|
|
55
|
+
transfer.transition_to!('failed', error: "#{e.class}: #{e.message}")
|
|
56
|
+
self
|
|
57
|
+
rescue Faraday::Error, SocketError, Errno::ETIMEDOUT, Timeout::Error => e
|
|
58
|
+
Transfers.logger.call(:indeterminate, "#{e.class}: #{e.message} (trace #{transfer.trace_id})")
|
|
59
|
+
transfer.transition_to!('reconciling', error: "#{e.class}: #{e.message}")
|
|
60
|
+
self
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MixinBot
|
|
4
|
+
module Transfers
|
|
5
|
+
##
|
|
6
|
+
# Resolves a transfer whose send attempt ended indeterminately (timeout
|
|
7
|
+
# or connection loss around the submission):
|
|
8
|
+
#
|
|
9
|
+
# - a snapshot exists for the trace id → the transfer landed; confirm
|
|
10
|
+
# from the snapshot (no funds ever re-sent);
|
|
11
|
+
# - no snapshot exists → nothing landed; re-send with the same trace id —
|
|
12
|
+
# the network's trace deduplication makes that safe.
|
|
13
|
+
#
|
|
14
|
+
class Reconcile
|
|
15
|
+
attr_reader :transfer, :api
|
|
16
|
+
|
|
17
|
+
def initialize(transfer, api:)
|
|
18
|
+
@transfer = transfer
|
|
19
|
+
@api = api
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
##
|
|
23
|
+
# @return [Symbol] :confirmed (found in the network), :resent (nothing
|
|
24
|
+
# existed; re-sent successfully) or :failed (the re-send was
|
|
25
|
+
# definitively rejected)
|
|
26
|
+
#
|
|
27
|
+
def call
|
|
28
|
+
snapshot = fetch_snapshot_by_trace
|
|
29
|
+
|
|
30
|
+
if snapshot
|
|
31
|
+
transfer.transition_to!('confirmed',
|
|
32
|
+
transaction_hash: snapshot['transaction_hash'] || transfer.transaction_hash)
|
|
33
|
+
:confirmed
|
|
34
|
+
else
|
|
35
|
+
Performer.new(transfer, api:).perform
|
|
36
|
+
transfer.state == 'failed' ? :failed : :resent
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
# Returns the snapshot hash for the trace id, or nil when the network
|
|
43
|
+
# has none (the only outcome that justifies a re-send).
|
|
44
|
+
def fetch_snapshot_by_trace
|
|
45
|
+
response = api.safe_snapshot_by_trace(transfer.trace_id)
|
|
46
|
+
data = response['data']
|
|
47
|
+
data.is_a?(Hash) && data['snapshot_id'] ? data : nil
|
|
48
|
+
rescue MixinBot::NotFoundError
|
|
49
|
+
nil
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -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'
|
data/lib/mixin_bot/version.rb
CHANGED
data/lib/mixin_bot.rb
CHANGED
|
@@ -32,6 +32,7 @@ require_relative 'mixin_bot/cli'
|
|
|
32
32
|
require_relative 'mixin_bot/computer'
|
|
33
33
|
require_relative 'mixin_bot/invoice'
|
|
34
34
|
require_relative 'mixin_bot/monitor'
|
|
35
|
+
require_relative 'mixin_bot/registry'
|
|
35
36
|
require_relative 'mixin_bot/url_scheme'
|
|
36
37
|
require_relative 'mixin_bot/utils'
|
|
37
38
|
require_relative 'mixin_bot/nfo'
|
|
@@ -230,4 +231,6 @@ module MixinBot
|
|
|
230
231
|
@deprecator ||= ActiveSupport::Deprecation.new('2.0', 'MixinBot')
|
|
231
232
|
end
|
|
232
233
|
end
|
|
234
|
+
|
|
235
|
+
extend Registry
|
|
233
236
|
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 >= 4.0. Gem version 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,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mixin_bot
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0.
|
|
4
|
+
version: 3.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- an-lee
|
|
@@ -300,6 +300,36 @@ files:
|
|
|
300
300
|
- examples/blaze.rb
|
|
301
301
|
- examples/blaze_async.rb
|
|
302
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
|
|
303
333
|
- lib/mixin_bot.rb
|
|
304
334
|
- lib/mixin_bot/address.rb
|
|
305
335
|
- lib/mixin_bot/api.rb
|
|
@@ -347,6 +377,7 @@ files:
|
|
|
347
377
|
- lib/mixin_bot/api/user.rb
|
|
348
378
|
- lib/mixin_bot/api/withdraw.rb
|
|
349
379
|
- lib/mixin_bot/blaze/reactor.rb
|
|
380
|
+
- lib/mixin_bot/blaze/router.rb
|
|
350
381
|
- lib/mixin_bot/bot_auth.rb
|
|
351
382
|
- lib/mixin_bot/cache_store_adapter.rb
|
|
352
383
|
- lib/mixin_bot/cli.rb
|
|
@@ -365,6 +396,7 @@ files:
|
|
|
365
396
|
- lib/mixin_bot/configuration.rb
|
|
366
397
|
- lib/mixin_bot/errors.rb
|
|
367
398
|
- lib/mixin_bot/invoice.rb
|
|
399
|
+
- lib/mixin_bot/json_decoder.rb
|
|
368
400
|
- lib/mixin_bot/models.rb
|
|
369
401
|
- lib/mixin_bot/models/address.rb
|
|
370
402
|
- lib/mixin_bot/models/api_envelope.rb
|
|
@@ -376,11 +408,28 @@ files:
|
|
|
376
408
|
- lib/mixin_bot/models/user.rb
|
|
377
409
|
- lib/mixin_bot/monitor.rb
|
|
378
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
|
|
379
424
|
- lib/mixin_bot/session_store.rb
|
|
380
425
|
- lib/mixin_bot/transaction.rb
|
|
381
426
|
- lib/mixin_bot/transaction/buffer.rb
|
|
382
427
|
- lib/mixin_bot/transaction/decoder.rb
|
|
383
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
|
|
384
433
|
- lib/mixin_bot/url_scheme.rb
|
|
385
434
|
- lib/mixin_bot/utils.rb
|
|
386
435
|
- lib/mixin_bot/utils/address.rb
|
|
@@ -423,7 +472,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
423
472
|
- !ruby/object:Gem::Version
|
|
424
473
|
version: '0'
|
|
425
474
|
requirements: []
|
|
426
|
-
rubygems_version: 4.0.
|
|
475
|
+
rubygems_version: 4.0.20
|
|
427
476
|
specification_version: 4
|
|
428
477
|
summary: A Ruby SDK for Mixin Network
|
|
429
478
|
test_files: []
|