Production-ready multi-chain batch sender: Base Account + EIP-5792, testable core modules, security & UI polish - #1
Open
arena-ai-coding-agent[bot] wants to merge 2 commits into
Open
arena-ai-coding-agent[bot] wants to merge 2 commits into
arena-ai-coding-agent[bot] wants to merge 2 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…and docs - Stateless BatchSender.sol (disperseEther/disperseToken) — reviewed version of the contract uploaded to main: identical code, plus NatSpec documenting that it has no owner, no upgrade path, and no withdraw function - Multi-chain registry in public/chains.json (Base, Ethereum, Optimism, Arbitrum, BSC, Avalanche, Polygon PoS, LitVM LiteForge) with per-chain fallback RPC URLs; ABI sanity-checked against the contract - Extract pure logic from main.js into src/core/ (parse, validate, distribute, debounce, errors, rpc, sendCalls) with 62 Vitest unit tests - npm run check:chains drift guard keeps chains.json in sync with the AppKit network list - AUDIT.md (security review) and ARCHITECTURE.md (design notes) - Rename gitignore -> .gitignore; drop dead public/indexold.html - Vite code-splitting + host allowlist for the preview proxy; package-lock.json re-synced so npm ci works (it failed against the previously committed lock file) Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
…zy Reown, UI polish Base Account (Base App passkey smart wallet) support: - Dedicated 'Sign in with Base Account' connect button; Base Account featured first in the Reown wallet modal (official wallet ID from docs.base.org) - EIP-5792 dispatch: when the connected wallet advertises wallet_sendCalls (detected via wallet_getCapabilities), the batch is submitted atomically to the smart wallet and tracked via wallet_getCallsStatus to a terminal state; standard gas-estimated signer path remains as fallback - ERC20 dispersements send value=0x0 in the smart-wallet batch (disperseToken is non-payable); only ETH batches attach the ETH value Architecture & robustness: - Reown AppKit lazy-loaded after first paint (requestIdleCallback) — main bundle ~36 kB raw / ~11 kB gzip; the ~400 kB-gzip Reown chunk is deferred - Centralized error handling with ABI revert-reason decoding (src/core/errors.js); read-only RPC fallback provider for balance/allowance reads — signing always uses the connected wallet - Debounce + generation-token on the async summary/allowance path so switching chains/tokens can no longer apply stale results - Gas-estimation failure is fatal (no more manual-gas broadcast that would guarantee a revert); MAX_RECIPIENTS=500 safety cap - Burn/dead-address (zero + ...dead) confirmation gate: dispatch stays disabled until the user explicitly acknowledges UI/UX: - Consistent SVG icon system for notifications, section headers, and stepper checks (emojis removed); ARIA live region for notifications - vercel.json: single redirects array — the Farcaster /.well-known/farcaster.json manifest redirect was silently dropped by a duplicate JSON key Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
arena-ai-coding-agent
Bot
force-pushed
the
arena/01a019cb-farsend
branch
from
September 20, 2026 18:41
c33d2a3 to
ddf67dd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Turns FarSend into a production-grade, multi-chain batch sender that works with regular EOAs, Farcaster Mini App context, and Base Account (the passkey ERC-4337 smart wallet powering the Base App) — all through the same deployed, immutable
BatchSendercontracts, so no existing contracts need redeploying.Commits
Key changes
Base Account / Base App smart wallet support
wallet_sendCalls(checked viawallet_getCapabilities), the batch is submitted atomically to the smart wallet — which can bundle and sponsor gas — and tracked viawallet_getCallsStatusto a terminal stateACTION_REJECTED) are always surfaced, never swallowedvalue=0x0in the smart-wallet batch (non-payabledisperseToken); only ETH batches attach the ETH valueArchitecture (pure core modules, all unit-tested)
src/core/:parse,validate(burn/dead-address detection),distribute,debounce,errors(revert decoding),rpc(fallback read providers),sendCalls(EIP-5792)public/chains.jsonin sync with the AppKit network list (npm run check:chains)requestIdleCallback) — main bundle ~36 kB raw / ~11 kB gzip; the ~400 kB-gzip Reown chunk deferred to idle timeSecurity & safety
BatchSender.sol(stateless: no owner, no upgrade path, no withdraw) — same code as the contract uploaded to main, with NatSpec documenting its safety properties; ABI mirrored inpublic/chains.json...dead) confirmation gate: dispatch disabled until explicitly acknowledgedMAX_RECIPIENTS = 500safety capAUDIT.md(active doc) +ARCHITECTURE.mddesign notesMulti-chain config
BatchSender.sol+ one entry inchains.json; old deployments untouchedUI/UX & infra polish
vercel.jsonduplicateredirectskey — the Farcaster/.well-known/farcaster.jsonmanifest redirect was being silently droppedpackage-lock.jsonre-synced:npm cinow verified clean on a fresh checkoutVerification
node --checkclean on all modulesnpm test→ 62/62 passingnpm run check:chains→ OK (8 chains, ABI present)npm run build→ clean (only the expected large-chunk warning for the lazy-loaded Reown bundle)npm civerified clean on a fresh checkoutNotes / follow-ups (intentionally out of scope)
.github/workflows/ci.ymlis ready but held locally: the GitHub App used for this session lacks theworkflowspermission, so pushing it is rejected. Once granted it can be added (also addnode --checkfordebounce.js,errors.js,rpc.js,sendCalls.js).capabilities.paymasterServicecan be passed towallet_sendCallslater).webhookUrlin the Farcaster manifest left as-is per request.