Files
bitvid/tests/zap-receipt-pool.test.mjs
T
thePR0M3TH3ANandClaude Opus 4.8 0ec9db70e8 fix(zap): receipt validation works with nostr-tools 2.x SimplePool
After a successful split zap, validation errored: "Unable to initialize a relay
pool for receipt validation." The validator built a fresh `new SimplePool()` and
required `pool.list()`, but nostr-tools 2.x removed SimplePool.list() (the rest of
the app only has it because js/nostr/toolkit.js shims it). So validation always
failed even though the payment went through.

Fix: resolveReceiptListPool() applies the app's legacy .list shim
(shimLegacySimplePoolMethods) to the freshly created pool, and the gate now
accepts a listEvents override instead of hard-requiring pool.list.

tests/zap-receipt-pool.test.mjs: 2.x pool gets .list shimmed; createPool override
shimmed; listEvents override leaves the pool as-is; null when neither available.
Mutation-verified (removing the shim fails it).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-21 22:11:46 -04:00

62 lines
2.3 KiB
JavaScript

// Regression: after a successful zap, receipt validation failed with "Unable to
// initialize a relay pool for receipt validation." nostr-tools 2.x SimplePool no
// longer has .list(), and the validator constructed a fresh raw pool and required
// pool.list. resolveReceiptListPool must apply the app's legacy .list shim so a
// 2.x pool can query — and honor a listEvents override without needing .list.
import "./test-helpers/setup-localstorage.mjs";
import assert from "node:assert/strict";
import test from "node:test";
import { resolveReceiptListPool } from "../js/payments/zapReceiptValidator.js";
// Mimics a nostr-tools 2.x SimplePool: instances have subscribeMany/close but NO
// .list() (the method was removed in 2.x).
function makeV2Tools() {
function SimplePool() {
this.subscribeMany = () => ({ close() {} });
this.querySync = async () => [];
this.close = () => {};
}
return { SimplePool };
}
test("a freshly constructed 2.x pool (no .list) gets the legacy .list shim", () => {
const tools = makeV2Tools();
const bare = new tools.SimplePool();
assert.equal(typeof bare.list, "undefined", "2.x pool starts without .list");
const pool = resolveReceiptListPool(tools, {});
assert.ok(pool, "a pool must be returned");
assert.equal(
typeof pool.list,
"function",
"the shim must add .list so receipt validation can query relays",
);
});
test("createPool override is respected and shimmed when it lacks .list", () => {
const created = { subscribeMany: () => ({ close() {} }), close: () => {} };
const pool = resolveReceiptListPool({}, { createPool: () => created });
assert.equal(pool, created, "must use the override-created pool");
assert.equal(typeof pool.list, "function", "and shim it with .list");
});
test("a listEvents override means the pool is left as-is (no shim required)", () => {
const created = { close: () => {} }; // no list, no subscribeMany
const pool = resolveReceiptListPool(
{},
{ createPool: () => created, listEvents: async () => [] },
);
assert.equal(pool, created);
assert.equal(
typeof pool.list,
"undefined",
"with a listEvents override the validator uses it, so .list isn't forced",
);
});
test("returns null when there is no SimplePool and no override", () => {
const pool = resolveReceiptListPool({}, {});
assert.equal(pool, null);
});