openzoo 0.50.13 → 0.50.14
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/lib/pay.js +35 -1
- package/package.json +1 -1
package/lib/pay.js
CHANGED
|
@@ -339,10 +339,44 @@ export class PayClient {
|
|
|
339
339
|
});
|
|
340
340
|
}
|
|
341
341
|
onStage?.('paying');
|
|
342
|
-
|
|
342
|
+
let response = await fetchHeaders(url, {
|
|
343
343
|
...init,
|
|
344
344
|
headers: { ...stripAuthorization(init.headers || {}), ...paymentHeaders(payment.header) },
|
|
345
345
|
});
|
|
346
|
+
|
|
347
|
+
// A REFUSED ATOMIC ROW MUST NOT TAKE THE WHOLE CALL DOWN.
|
|
348
|
+
//
|
|
349
|
+
// The candidate loop above only recovers from UnderfundedError; a payment
|
|
350
|
+
// the SERVER refuses happens out here, and used to surface as
|
|
351
|
+
// "zoo returned HTTP 402" with no second attempt. That is survivable for a
|
|
352
|
+
// row every client has always paid, and not survivable for the AtomicSettle
|
|
353
|
+
// row, which is newer, opt-in, and asks for a different signature — one
|
|
354
|
+
// gateway-side disagreement and every Base caller is dead in the water.
|
|
355
|
+
//
|
|
356
|
+
// So: if the row we chose was the atomic one and the server would not take
|
|
357
|
+
// it, drop back to the ordinary rows and pay again. We lose the
|
|
358
|
+
// response-bound receipt for this call and keep the call. Only the atomic
|
|
359
|
+
// row gets this treatment — a plain row being refused is a real failure and
|
|
360
|
+
// still surfaces.
|
|
361
|
+
if (response.status === 402 && accept?.extra?.settlement === 'atomic') {
|
|
362
|
+
const plain = candidates.filter((c) => c?.extra?.settlement !== 'atomic');
|
|
363
|
+
for (const cand of plain) {
|
|
364
|
+
try {
|
|
365
|
+
const retry = await this.buildPaymentFor(cand, onStage, quote);
|
|
366
|
+
const again = await fetchHeaders(url, {
|
|
367
|
+
...init,
|
|
368
|
+
headers: { ...stripAuthorization(init.headers || {}), ...paymentHeaders(retry.header) },
|
|
369
|
+
});
|
|
370
|
+
if (again.status !== 402) {
|
|
371
|
+
accept = cand; payment = retry; response = again;
|
|
372
|
+
lastGoodAsset = memoKey(cand);
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
} catch (e) {
|
|
376
|
+
if (!(e instanceof UnderfundedError)) throw e;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
346
380
|
// NEVER PRESENT OUR OWN SIGNATURE AS THE TRANSACTION.
|
|
347
381
|
//
|
|
348
382
|
// This fell back to `{ signature: payment.ownerSignature }`, and on Solana
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openzoo",
|
|
3
|
-
"version": "0.50.
|
|
3
|
+
"version": "0.50.14",
|
|
4
4
|
"description": "Local x402-paying proxy + MCP server for openzoo.fun — point any OpenAI-compatible harness (Cursor, Claude Code, aider, SDKs) at localhost and it pays per call from a local burner wallet. Solana and Base rails live; Robinhood experimental.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|