From 69dc0b99c2585dd27b6f98f9211c26271c30d23a Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Mon, 16 Mar 2026 14:28:26 +0000 Subject: [PATCH 1/2] [#170] Increase receipt retry backoff and add client-side delay - getReceiptWithRetry: 5 attempts with 2s multiplier (2/4/6/8/10s = 30s total) instead of 3 attempts with 1s (1/2/3s = 6s) - Add 5s client-side delay before indexer API calls in DonateWidget and usePublish hook to allow RPC propagation on Base Sepolia Fixes #170 Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/rpc.ts | 4 ++-- src/components/DonateWidget.tsx | 3 ++- src/hooks/usePublish.ts | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/rpc.ts b/lib/rpc.ts index 4a873171..1c3f2278 100644 --- a/lib/rpc.ts +++ b/lib/rpc.ts @@ -26,13 +26,13 @@ export const publicClient = createPublicClient({ * Load-balanced RPC nodes may not have the receipt immediately after * `waitForTransactionReceipt` completes on the client side. */ -export async function getReceiptWithRetry(hash: Hex, maxAttempts = 3) { +export async function getReceiptWithRetry(hash: Hex, maxAttempts = 5) { for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { return await publicClient.getTransactionReceipt({ hash }); } catch (err) { if (attempt === maxAttempts) throw err; - await new Promise((r) => setTimeout(r, attempt * 1000)); + await new Promise((r) => setTimeout(r, attempt * 2000)); } } throw new Error("unreachable"); diff --git a/src/components/DonateWidget.tsx b/src/components/DonateWidget.tsx index f091abcb..4cc1b28c 100644 --- a/src/components/DonateWidget.tsx +++ b/src/components/DonateWidget.tsx @@ -88,8 +88,9 @@ export function DonateWidget({ storylineId }: DonateWidgetProps) { setTxState("pending"); await publicClient.waitForTransactionReceipt({ hash }); - // Trigger donation indexer + // Trigger donation indexer (delay for RPC propagation on Base Sepolia) setTxState("indexing"); + await new Promise((r) => setTimeout(r, 5000)); const indexRes = await fetch("/api/index/donation", { method: "POST", headers: { "Content-Type": "application/json" }, diff --git a/src/hooks/usePublish.ts b/src/hooks/usePublish.ts index 003dea2c..1f805a2a 100644 --- a/src/hooks/usePublish.ts +++ b/src/hooks/usePublish.ts @@ -83,8 +83,9 @@ export function usePublish() { setState("pending"); await publicClient.waitForTransactionReceipt({ hash }); - // 4. Trigger indexer + // 4. Trigger indexer (delay for RPC propagation on Base Sepolia) setState("indexing"); + await new Promise((r) => setTimeout(r, 5000)); await fetch(opts.indexerRoute, { method: "POST", headers: { "Content-Type": "application/json" }, From 71c66b89a80e15a03518a41747e00913455d05a7 Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Mon, 16 Mar 2026 14:30:07 +0000 Subject: [PATCH 2/2] [#170] Scope client-side delay to donation path only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove 5s delay from usePublish (storyline/plot creation) — the server-side retry window (30s) is sufficient. Keep delay only in DonateWidget where the issue was observed. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/hooks/usePublish.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hooks/usePublish.ts b/src/hooks/usePublish.ts index 1f805a2a..003dea2c 100644 --- a/src/hooks/usePublish.ts +++ b/src/hooks/usePublish.ts @@ -83,9 +83,8 @@ export function usePublish() { setState("pending"); await publicClient.waitForTransactionReceipt({ hash }); - // 4. Trigger indexer (delay for RPC propagation on Base Sepolia) + // 4. Trigger indexer setState("indexing"); - await new Promise((r) => setTimeout(r, 5000)); await fetch(opts.indexerRoute, { method: "POST", headers: { "Content-Type": "application/json" },