wolverine-ai 5.2.0 → 5.2.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wolverine-ai",
3
- "version": "5.2.0",
3
+ "version": "5.2.2",
4
4
  "description": "Self-healing Node.js server framework powered by AI. Catches crashes, diagnoses errors, generates fixes, verifies, and restarts — automatically.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -145,7 +145,8 @@ async function x402Plugin(fastify, opts) {
145
145
  return;
146
146
  }
147
147
 
148
- // Payment present — send to facilitator for verification + on-chain settlement
148
+ // Payment present — verify and settle on-chain
149
+ // Try facilitator first (standard x402 SDK clients), then self-settle (wallet-signed payments)
149
150
  const routeAccepts = [{
150
151
  scheme: "exact",
151
152
  price,
@@ -153,29 +154,26 @@ async function x402Plugin(fastify, opts) {
153
154
  payTo: _payTo,
154
155
  }];
155
156
 
157
+ // Step 1: Try facilitator (works with @x402/fetch, @x402/evm SDK clients)
156
158
  const verified = await _settleViaFacilitator(paymentSig, routeAccepts);
157
159
  if (verified.valid) {
158
160
  reply.header("Payment-Response", JSON.stringify(verified.receipt || {}));
159
161
  request.x402 = { paid: true, amount: price, receipt: verified.receipt, txHash: verified.txHash, from: verified.from };
160
- // Log payment for dashboard analytics
161
- _logPayment({ route: request.url, method: request.method, amount: price, from: verified.from, txHash: verified.txHash, verified: true, timestamp: Date.now() });
162
+ _logPayment({ route: request.url, method: request.method, amount: price, from: verified.from, txHash: verified.txHash, verified: true, settled: "facilitator", timestamp: Date.now() });
162
163
  return; // continue to route handler
163
164
  }
164
165
 
165
- // Facilitator rejected — try self-settlement as fallback
166
- if (verified.reason === "facilitator_unavailable") {
167
- const selfResult = await _selfSettle(paymentSig, price);
168
- if (selfResult.valid) {
169
- reply.header("Payment-Response", JSON.stringify(selfResult.receipt || {}));
170
- request.x402 = { paid: true, amount: price, receipt: selfResult.receipt, txHash: selfResult.txHash, from: selfResult.from };
171
- _logPayment({ route: request.url, method: request.method, amount: price, from: selfResult.from, txHash: selfResult.txHash, verified: true, settled: "self", timestamp: Date.now() });
172
- return;
173
- }
174
- reply.code(402).send({ error: "Payment settlement failed", reason: selfResult.reason, price, payTo: _payTo });
166
+ // Step 2: Facilitator failed or rejected — self-settle via vault wallet
167
+ // This handles wallet-signed EIP-3009 payments (our own frontend, custom clients)
168
+ const selfResult = await _selfSettle(paymentSig, price);
169
+ if (selfResult.valid) {
170
+ reply.header("Payment-Response", JSON.stringify(selfResult.receipt || {}));
171
+ request.x402 = { paid: true, amount: price, receipt: selfResult.receipt, txHash: selfResult.txHash, from: selfResult.from };
172
+ _logPayment({ route: request.url, method: request.method, amount: price, from: selfResult.from, txHash: selfResult.txHash, verified: true, settled: "self", timestamp: Date.now() });
175
173
  return;
176
174
  }
177
175
 
178
- reply.code(402).send({ error: "Payment verification failed", reason: verified.reason, price, payTo: _payTo });
176
+ reply.code(402).send({ error: "Payment settlement failed", reason: selfResult.reason, facilitatorReason: verified.reason, price, payTo: _payTo });
179
177
  });
180
178
 
181
179
  // ── Public pricing endpoint ──
@@ -270,7 +268,9 @@ async function _selfSettle(paymentSig, price) {
270
268
 
271
269
  // Verify amount
272
270
  const expectedUsdc = Math.round(parseFloat(price.replace("$", "")) * 1e6);
273
- const actualUsdc = parseInt(auth.value, 16) || parseInt(auth.value, 10) || 0;
271
+ // Value comes as decimal string (e.g. "1000000" for $1) or hex (legacy "0xf4240")
272
+ const valStr = String(auth.value);
273
+ const actualUsdc = valStr.startsWith("0x") ? parseInt(valStr, 16) : parseInt(valStr, 10) || 0;
274
274
  if (actualUsdc < expectedUsdc * 0.99) {
275
275
  return { valid: false, reason: "amount_mismatch" };
276
276
  }