mtok-verify 0.1.1 → 0.1.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/onchain.js +18 -10
- package/package.json +1 -1
package/onchain.js
CHANGED
|
@@ -272,20 +272,28 @@ export function createOnchainVerifier({ rpcUrl, rpcUrls, usdcAddress, expectedCh
|
|
|
272
272
|
|
|
273
273
|
// #580 draw-age guard: refuse a payment older than maxPaidAgeMs so a stale replay
|
|
274
274
|
// can't buy a fresh serve after the relay's local redemption record lapsed or was
|
|
275
|
-
// lost.
|
|
276
|
-
//
|
|
277
|
-
//
|
|
275
|
+
// lost. This is DEFENSE-IN-DEPTH on top of the relay's served.has() one-serve guard,
|
|
276
|
+
// so it only REJECTS when it actually reads an age past the bound. If the paid block
|
|
277
|
+
// can't be read (missing blockNumber, or a transient RPC failure even after retries),
|
|
278
|
+
// it SKIPS the freshness check rather than reject: the payment was already fully
|
|
279
|
+
// verified above, and rejecting would make the SDK auto-DISPUTE a good draw over an RPC
|
|
280
|
+
// blip, burning an honest buyer's USDC and busting an innocent seller's reputation.
|
|
281
|
+
// Opt-in: unset => no extra RPC, exact current behavior.
|
|
278
282
|
const maxAge = Number(maxPaidAgeMs);
|
|
279
283
|
if (Number.isFinite(maxAge) && maxAge > 0) {
|
|
280
284
|
const bn = matchedLog?.blockNumber;
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
try {
|
|
285
|
+
let paidAtMs = null;
|
|
286
|
+
if (bn != null) {
|
|
284
287
|
const blockTag = (typeof bn === 'string' && bn.startsWith('0x')) ? bn : '0x' + BigInt(bn).toString(16);
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
288
|
+
for (let i = 0; i <= receiptRetries; i++) {
|
|
289
|
+
try {
|
|
290
|
+
const block = await rpc('eth_getBlockByNumber', [blockTag, false]);
|
|
291
|
+
if (block?.timestamp != null) { paidAtMs = Number(BigInt(block.timestamp)) * 1000; break; }
|
|
292
|
+
} catch { /* transient: fall through to retry */ }
|
|
293
|
+
if (i < receiptRetries) await sleepImpl(receiptRetryMs);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if (paidAtMs != null && nowMs() - paidAtMs > maxAge) return { ok: false, reason: 'payment_too_old' };
|
|
289
297
|
}
|
|
290
298
|
|
|
291
299
|
// #(fable review): bind each leg's `from` to the pay-time buyer (event.buyer,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mtok-verify",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "The on-chain verify core for mtok.market sellers: decode + verify a MtokDripLedger DrawPaid receipt (and its USDC transfer legs) against a paid draw, with the canonical DrawPaid topic set. Dependency-free, runs anywhere fetch runs (node, a CF Worker). The SSOT the platform + reference relay + house seller all share.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|