From 9ebb9a86b2cb3f7eb86f417fa3143ea570c57710 Mon Sep 17 00:00:00 2001 From: martbost Date: Thu, 10 Sep 2026 07:43:24 -0500 Subject: [PATCH] Ledger/earnings rows show when; Earn credits: never your own ads; burner sets Polygon fees + rotates RPCs on node errors Co-Authored-By: Claude Fable 5.1 --- burner.js | 14 +++++++++++--- public/admin.html | 4 ++-- public/assets/common.js | 3 ++- public/assets/site.css | 1 + public/contract.html | 4 ++-- public/disclaimer.html | 4 ++-- public/index.html | 4 ++-- public/join.html | 4 ++-- public/ledger.html | 4 ++-- public/my.html | 5 +++-- public/plays.html | 4 ++-- public/privacy.html | 4 ++-- public/shorts.html | 2 +- public/terms.html | 4 ++-- public/tx.html | 4 ++-- public/view.html | 2 +- public/wall.html | 4 ++-- 17 files changed, 41 insertions(+), 30 deletions(-) diff --git a/burner.js b/burner.js index ff2d789..94bb514 100644 --- a/burner.js +++ b/burner.js @@ -17,11 +17,13 @@ function keyHex() { if (!k.startsWith('0x')) k = '0x' + k; return /^0x[0-9a-fA-F]{64}$/.test(k) ? k : null; } +let rpcIdx = 0; function provider() { const c = chain.getConfig(); - const url = (c.rpcs && c.rpcs[0]) || c.rpc; - return new ethers.JsonRpcProvider(url, Number(c.chainId)); + const urls = (c.rpcs && c.rpcs.length) ? c.rpcs : [c.rpc]; + return new ethers.JsonRpcProvider(urls[rpcIdx % urls.length], Number(c.chainId), { staticNetwork: true }); } +function rotateRpc() { const c = chain.getConfig(); const n = (c.rpcs && c.rpcs.length) || 1; rpcIdx = (rpcIdx + 1) % n; } async function setup() { const k = keyHex(); if (!k || !ethers) { state.enabled = false; return; } @@ -49,14 +51,20 @@ async function tick() { if (BigInt(state.balanceWei) < ethers.parseEther('0.05')) { state.lastError = 'engine wallet low on POL for gas'; return { burned: 0 }; } for (const b of pending.slice(0, 20)) { try { - const tx = await ctr.consume(Number(b.memberId), 0, BigInt(b.amount), refToBytes32(b.ref)); + // Polygon nodes reject low priority fees and some public RPCs answer fee + // queries with 500s: set the fees ourselves from the server's estimate + const g = await chain.suggestedFees(); + const overrides = { gasLimit: 120000n, maxPriorityFeePerGas: BigInt(g.maxPriorityFeePerGas), maxFeePerGas: BigInt(g.maxFeePerGas) }; + const tx = await ctr.consume(Number(b.memberId), 0, BigInt(b.amount), refToBytes32(b.ref), overrides); const rc = await tx.wait(1); if (rc && rc.status === 1) { await ads.markBurned(b.id, tx.hash); burned += 1; state.burned += 1; state.lastTx = tx.hash; state.lastError = null; } else { state.lastError = 'consume reverted for burn ' + b.id; break; } } catch (e) { state.lastError = 'burn ' + b.id + ': ' + String(e.shortMessage || e.message).slice(0, 160); + // a node error (500, timeout, rate limit): move to the next RPC for the next tick. // an "Insufficient credits" revert means the member's on-chain balance is // already lower than the engine thinks; leave it pending for the admin to review + if (/server response|timeout|rate|429|503|502|500/i.test(String(e.message))) rotateRpc(); break; } } diff --git a/public/admin.html b/public/admin.html index 620100e..a9c69ff 100644 --- a/public/admin.html +++ b/public/admin.html @@ -6,7 +6,7 @@ Admin | InstantAdPay - +