mpp-rb 0.1.8 → 0.1.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5d5c20207eb5f09b4f077cea8bdd1fb1f2acc15d12c5d00928cc7e8eddcf627
4
- data.tar.gz: 1f080945c2a322985b47d184ccaf00b543931bcb6f4623c070175d03efab5cd8
3
+ metadata.gz: 9b15406ee08abfa67c30c458ceb33ba59d0af4873350e5d0976521f6fd9409e1
4
+ data.tar.gz: 7ed79eafc950f4fb78253c7b0e93003498597bb5d87ffeda2f6e147004e4f858
5
5
  SHA512:
6
- metadata.gz: 7044c78ebef4814fce755614c194a6723c39df930071762aab94e19e944bb241f33bfd554fdc18ed0ef5f7b3f9cdc9d219923ab4a9aac6278e94896069b2634c
7
- data.tar.gz: d71d6869c20d1a569a0425cde39dd39938688735d0360db47fe82f80ac454f3d4ec015624f942c1bf1760c271e9297ca848300ac63d5d0366496b57a2475efc6
6
+ metadata.gz: 0bd1c63ff9e43759b05f7f3c4114368679407b04856c38d620e1b85d02c856028a9b740f80c50f848ebd238c2bbab2a0ae02e53197b9e6034951956a3251a4a2
7
+ data.tar.gz: 2c0e2ffd65f60ad41b4fe2ce25006491b7fea6c76c5f0edac0672e738e64c53d9b23f0e3216b477dd638474957f54be6c9f04c5005af173e6c83fdf51103bb7a
@@ -136,7 +136,7 @@ module Mpp
136
136
  end
137
137
 
138
138
  def x402_credential?(credential)
139
- credential.payload.is_a?(Hash) && credential.payload["_x402"] == true
139
+ credential.is_a?(X402Credential)
140
140
  end
141
141
 
142
142
  def addresses_equal?(left, right)
@@ -99,9 +99,9 @@ module Mpp
99
99
  http_method: http_method
100
100
  )
101
101
  echo = challenge.to_echo
102
- Mpp::Credential.new(
102
+ X402Credential.new(
103
103
  challenge: echo,
104
- payload: authorization.merge("_x402" => true),
104
+ payload: authorization,
105
105
  source: source_for(authorization["from"])
106
106
  )
107
107
  end
@@ -0,0 +1,12 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Mpp
5
+ module Methods
6
+ module Evm
7
+ # Credential bound server-side from an x402 PAYMENT-SIGNATURE header.
8
+ class X402Credential < Mpp::Credential
9
+ end
10
+ end
11
+ end
12
+ end
@@ -8,6 +8,7 @@ module Mpp
8
8
  autoload :Authorization, "mpp/methods/evm/authorization"
9
9
  autoload :ChargeIntent, "mpp/methods/evm/charge_intent"
10
10
  autoload :EvmMethod, "mpp/methods/evm/evm_method"
11
+ autoload :X402Credential, "mpp/methods/evm/x402_credential"
11
12
 
12
13
  # Factory for a server-side EVM charge method with inline x402 exact support.
13
14
  def self.charge(currency:, recipient:, x402:, authorization: nil, chain_id: nil, decimals: nil,
@@ -221,6 +221,7 @@ module Mpp
221
221
 
222
222
  receipt_data = fetch_transaction_receipt(rpc_url, reserved_tx_hash)
223
223
  verify_transaction_receipt!(receipt_data, request, credential: credential)
224
+ claim_settlement!(reserved_tx_hash)
224
225
  @store.put(store_key, TRANSACTION_VERIFIED)
225
226
  return Mpp::Receipt.success(reserved_tx_hash)
226
227
  end
@@ -241,6 +242,7 @@ module Mpp
241
242
  if transaction_submission_may_have_succeeded?(e)
242
243
  receipt_data = fetch_transaction_receipt(rpc_url, reserved_tx_hash)
243
244
  verify_transaction_receipt!(receipt_data, request, credential: credential)
245
+ claim_settlement!(reserved_tx_hash)
244
246
  @store.put(store_key, TRANSACTION_VERIFIED)
245
247
  return Mpp::Receipt.success(reserved_tx_hash)
246
248
  end
@@ -260,16 +262,26 @@ module Mpp
260
262
  # claim until verification finishes so a concurrent retry cannot
261
263
  # rebroadcast the same payload.
262
264
  raw_store_key = store_key
265
+ raw_tx_hash = reserved_tx_hash
263
266
  store_key, reserved_tx_hash = rebase_reservation_to_chain_hash(store_key, reserved_tx_hash, tx_hash)
264
267
 
265
268
  receipt_data = fetch_transaction_receipt(rpc_url, reserved_tx_hash)
266
269
  verify_transaction_receipt!(receipt_data, request, credential: credential)
270
+ claim_settlement!(raw_tx_hash, reserved_tx_hash)
267
271
  @store.put(store_key, TRANSACTION_VERIFIED)
268
272
  @store.put(raw_store_key, TRANSACTION_VERIFIED) if raw_store_key != store_key
269
273
 
270
274
  Mpp::Receipt.success(reserved_tx_hash)
271
275
  end
272
276
 
277
+ def claim_settlement!(*tx_hashes)
278
+ tx_hashes.map(&:downcase).uniq.each do |tx_hash|
279
+ unless @store.put_if_absent("mpp:charge:settled:#{tx_hash}", true)
280
+ raise Mpp::VerificationError, "Transaction hash already used"
281
+ end
282
+ end
283
+ end
284
+
273
285
  def transaction_submission_may_have_succeeded?(error)
274
286
  message = "#{error.class}: #{error.message}".downcase
275
287
 
data/lib/mpp/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Mpp
5
- VERSION = "0.1.8"
5
+ VERSION = "0.1.9"
6
6
  end
@@ -150,7 +150,7 @@ module Mpp
150
150
  route_bound = !client_nonce.nil?
151
151
  route_requires_binding = !challenge.digest.nil? || !challenge.opaque.nil?
152
152
 
153
- if route_requires_binding && !route_bound && route_binding == :required
153
+ if !route_bound && route_binding == :required
154
154
  Kernel.raise Mpp::VerificationFailedError.new(reason: "x402 payment payload does not bind required route metadata")
155
155
  end
156
156
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mpp-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stripe
@@ -86,6 +86,7 @@ files:
86
86
  - lib/mpp/methods/evm/authorization.rb
87
87
  - lib/mpp/methods/evm/charge_intent.rb
88
88
  - lib/mpp/methods/evm/evm_method.rb
89
+ - lib/mpp/methods/evm/x402_credential.rb
89
90
  - lib/mpp/methods/stripe.rb
90
91
  - lib/mpp/methods/stripe/analytics_metadata.rb
91
92
  - lib/mpp/methods/stripe/charge_intent.rb