From a0d3d797477fd0b3a59e41939ee82ac0de4b8203 Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Mon, 26 Oct 2026 17:14:17 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20invite=20links=20(/i/INV-=E2=80=A6)=20sk?= =?UTF-8?q?ip=20the=20crawler=20script=20challenge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An invite is a person's first visit, often opened from a chat whose link preview cannot run the challenge script; it is not an item page and nothing links to it. Item pages (/i/) are still challenged. Co-Authored-By: Claude Opus 5.5 --- apps/web/src/lib/pricing.js | 7 ++++++- test/pricing.test.js | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/web/src/lib/pricing.js b/apps/web/src/lib/pricing.js index a9466a6..c9965d6 100644 --- a/apps/web/src/lib/pricing.js +++ b/apps/web/src/lib/pricing.js @@ -162,7 +162,12 @@ export function gatewayOptions(priceCents) { work: 17, css: true, paths: ['/i/', '/feeds/', '/tlds', '/tlds/'], - when: (_request, url) => url.pathname.startsWith('/i/') || url.search.length > 1, + // An invite link (/i/INV-…) is a person's first visit, often opened from a + // chat whose link preview cannot run the script; it is not an item page + // and nothing links to it, so the swarm never walks it. + when: (_request, url) => + (url.pathname.startsWith('/i/') && !/^\/i\/inv-/i.test(url.pathname)) || + url.search.length > 1, }, onSale: async (sale) => { console.log('[x402] sold a pass', { diff --git a/test/pricing.test.js b/test/pricing.test.js index 17bfcb4..f831d95 100644 --- a/test/pricing.test.js +++ b/test/pricing.test.js @@ -178,4 +178,10 @@ describe('the script challenge (faceted listings, item pages)', async () => { expect(on('/feeds/new')).toBe(false); expect(on('/feeds/new?')).toBe(false); }); + + test('an invite link is a first visit, not an item page', () => { + expect(on('/i/INV-7K3M-QX9D-2F8H')).toBe(false); + expect(on('/i/inv-7k3m-qx9d-2f8h')).toBe(false); + expect(on('/i/INV-7K3M-QX9D-2F8H?x=1')).toBe(true); + }); });