Class: Mpp::Server::MppHandler
- Inherits:
-
Object
- Object
- Mpp::Server::MppHandler
- Extended by:
- T::Sig
- Defined in:
- lib/mpp/server/mpp_handler.rb
Constant Summary collapse
- REQUEST_OPTION_KEYS =
[:body, :url, :payment_signature, :accept_payment, :http_method].freeze
Instance Attribute Summary collapse
-
#defaults ⇒ Object
readonly
Returns the value of attribute defaults.
-
#method ⇒ Object
readonly
Returns the value of attribute method.
-
#methods ⇒ Object
readonly
Returns the value of attribute methods.
-
#realm ⇒ Object
readonly
Returns the value of attribute realm.
-
#secret_key ⇒ Object
readonly
Returns the value of attribute secret_key.
Class Method Summary collapse
Instance Method Summary collapse
- #build_charge_request(method, amount, **kwargs) ⇒ Object
- #challenge_response(challenge, url: nil, http_method: nil) ⇒ Object
- #charge(authorization, amount, **kwargs) ⇒ Object
- #charge_one(method, authorization, amount, **kwargs) ⇒ Object
- #compose(*entries) ⇒ Object
-
#initialize(realm:, secret_key:, method: nil, methods: nil, defaults: nil, events: nil) ⇒ MppHandler
constructor
A new instance of MppHandler.
- #on(name, handler = nil, &block) ⇒ Object
- #on_challenge_created(handler = nil, &block) ⇒ Object
- #on_payment_failed(handler = nil, &block) ⇒ Object
- #on_payment_success(handler = nil, &block) ⇒ Object
- #resolve_method(method_ref) ⇒ Object
Constructor Details
#initialize(realm:, secret_key:, method: nil, methods: nil, defaults: nil, events: nil) ⇒ MppHandler
Returns a new instance of MppHandler.
40 41 42 43 44 45 46 47 |
# File 'lib/mpp/server/mpp_handler.rb', line 40 def initialize(realm:, secret_key:, method: nil, methods: nil, defaults: nil, events: nil) @methods = T.let(normalize_methods(method, methods), T::Array[T.untyped]) @method = T.let(@methods.first, T.untyped) @realm = T.let(realm, String) @secret_key = T.let(secret_key, String) @defaults = T.let(defaults || {}, T::Hash[String, T.untyped]) @events = T.let(events || Mpp::Events.server_dispatcher, Mpp::Events::Dispatcher) end |
Instance Attribute Details
#defaults ⇒ Object (readonly)
Returns the value of attribute defaults.
28 29 30 |
# File 'lib/mpp/server/mpp_handler.rb', line 28 def defaults @defaults end |
#method ⇒ Object (readonly)
Returns the value of attribute method.
16 17 18 |
# File 'lib/mpp/server/mpp_handler.rb', line 16 def method @method end |
#methods ⇒ Object (readonly)
Returns the value of attribute methods.
19 20 21 |
# File 'lib/mpp/server/mpp_handler.rb', line 19 def methods @methods end |
#realm ⇒ Object (readonly)
Returns the value of attribute realm.
22 23 24 |
# File 'lib/mpp/server/mpp_handler.rb', line 22 def realm @realm end |
#secret_key ⇒ Object (readonly)
Returns the value of attribute secret_key.
25 26 27 |
# File 'lib/mpp/server/mpp_handler.rb', line 25 def secret_key @secret_key end |
Class Method Details
.create(method: nil, methods: nil, realm: nil, secret_key: nil, events: nil) ⇒ Object
59 60 61 62 63 64 65 66 67 |
# File 'lib/mpp/server/mpp_handler.rb', line 59 def self.create(method: nil, methods: nil, realm: nil, secret_key: nil, events: nil) new( method: method, methods: methods, realm: realm || Defaults.detect_realm, secret_key: secret_key || Defaults.detect_secret_key, events: events ) end |
Instance Method Details
#build_charge_request(method, amount, **kwargs) ⇒ Object
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/mpp/server/mpp_handler.rb', line 186 def build_charge_request(method, amount, **kwargs) currency = kwargs[:currency] recipient = kwargs[:recipient] external_id = kwargs[:external_id] memo = kwargs[:memo] fee_payer = if kwargs.key?(:fee_payer) kwargs[:fee_payer] else method.respond_to?(:fee_payer) && method.fee_payer end chain_id = kwargs[:chain_id] extra = kwargs[:extra] mppx_scope = kwargs[:mppx_scope] resolved_currency = currency || (method.respond_to?(:currency) ? method.currency : nil) resolved_recipient = recipient || (method.respond_to?(:recipient) ? method.recipient : nil) raise ArgumentError, "currency must be set on the method or passed to charge()" unless resolved_currency raise ArgumentError, "recipient must be set on the method or passed to charge()" unless resolved_recipient decimals = method.respond_to?(:decimals) ? method.decimals : DEFAULT_DECIMALS base_amount = Mpp::Units.parse_units(amount, decimals).to_s request = { "amount" => base_amount, "currency" => resolved_currency, "recipient" => resolved_recipient } request["externalId"] = external_id unless external_id.nil? if extra extra.each do |key, value| raise ArgumentError, "extra must be a dict[str, str]" unless key.is_a?(String) && value.is_a?(String) end request["extra"] = extra end if mppx_scope mppx_scope.each do |key, value| raise ArgumentError, "mppx_scope must be a dict[str, str]" unless key.is_a?(String) && value.is_a?(String) end request["_mppx_scope"] = mppx_scope end resolved_chain_id = chain_id resolved_chain_id ||= method.chain_id if method.respond_to?(:chain_id) if memo || fee_payer || !resolved_chain_id.nil? method_details = {} method_details["chainId"] = resolved_chain_id unless resolved_chain_id.nil? method_details["memo"] = memo if memo method_details["feePayer"] = true if fee_payer request["methodDetails"] = method_details end Mpp::Server::MethodHelper.transform_request(method, request, nil) end |
#challenge_response(challenge, url: nil, http_method: nil) ⇒ Object
244 245 246 247 248 249 250 251 |
# File 'lib/mpp/server/mpp_handler.rb', line 244 def challenge_response(challenge, url: nil, http_method: nil) challenges = challenge.is_a?(Array) ? challenge : [challenge] extra = {} if @methods.length == 1 && @method.respond_to?(:decorate_challenge) @method.decorate_challenge(extra, challenges.first, url: url, http_method: http_method) end Decorator.make_challenge_response(challenges, @realm, extra_headers: extra) end |
#charge(authorization, amount, **kwargs) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/mpp/server/mpp_handler.rb', line 116 def charge(, amount, **kwargs) charge_methods = @methods.select { |candidate| candidate.intents.key?("charge") } raise ArgumentError, "No registered method supports charge intent" if charge_methods.empty? request_opts = kwargs.slice(*REQUEST_OPTION_KEYS) offer_opts = kwargs.except(*REQUEST_OPTION_KEYS) if charge_methods.length == 1 return charge_one( charge_methods.first, , amount, **request_opts, **offer_opts ) end entries = charge_methods.map { |candidate| [candidate, offer_opts.merge(amount: amount)] } ComposedHandler.from_entries(self, entries).call( authorization: , payment_signature: request_opts[:payment_signature], body: request_opts[:body], url: request_opts[:url], accept_payment: request_opts[:accept_payment], http_method: request_opts[:http_method] ) end |
#charge_one(method, authorization, amount, **kwargs) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/mpp/server/mpp_handler.rb', line 146 def charge_one(method, , amount, **kwargs) intent = method.intents["charge"] raise ArgumentError, "Method #{method.name} does not support charge intent" unless intent body = kwargs[:body] url = kwargs[:url] payment_signature = kwargs[:payment_signature] offer_opts = kwargs.except(*REQUEST_OPTION_KEYS) request = build_charge_request(method, amount, **offer_opts) if payment_signature && method.respond_to?(:bind_x402_credential) return verify_x402( method, intent, request, payment_signature: payment_signature, url: url, body: body, description: offer_opts[:description], expires: offer_opts[:expires], http_method: kwargs[:http_method] ) end Verify.verify_or_challenge( authorization: , intent: intent, request: request, realm: @realm, secret_key: @secret_key, method: method.name, description: offer_opts[:description], expires: offer_opts[:expires], events: @events, body: body ) end |
#compose(*entries) ⇒ Object
91 92 93 |
# File 'lib/mpp/server/mpp_handler.rb', line 91 def compose(*entries) ComposedHandler.from_entries(self, entries) end |
#on(name, handler = nil, &block) ⇒ Object
70 71 72 |
# File 'lib/mpp/server/mpp_handler.rb', line 70 def on(name, handler = nil, &block) @events.on(name, handler, &block) end |
#on_challenge_created(handler = nil, &block) ⇒ Object
75 76 77 |
# File 'lib/mpp/server/mpp_handler.rb', line 75 def on_challenge_created(handler = nil, &block) on(Mpp::Events::CHALLENGE_CREATED, handler, &block) end |
#on_payment_failed(handler = nil, &block) ⇒ Object
80 81 82 |
# File 'lib/mpp/server/mpp_handler.rb', line 80 def on_payment_failed(handler = nil, &block) on(Mpp::Events::PAYMENT_FAILED, handler, &block) end |
#on_payment_success(handler = nil, &block) ⇒ Object
85 86 87 |
# File 'lib/mpp/server/mpp_handler.rb', line 85 def on_payment_success(handler = nil, &block) on(Mpp::Events::PAYMENT_SUCCESS, handler, &block) end |
#resolve_method(method_ref) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/mpp/server/mpp_handler.rb', line 97 def resolve_method(method_ref) case method_ref when String resolve_method_key(method_ref) else found = @methods.find { |candidate| candidate.equal?(method_ref) } || @methods.find { |candidate| candidate.name == method_ref.name } return found if found raise ArgumentError, "No handler for #{method_ref.inspect}. Is this method in your methods array?" end end |