Skip to content

perf(evm): poll waitForCallsStatus at 500ms — inclusion noticed ~3s sooner#32

Open
psmiratisu wants to merge 2 commits into
mainfrom
perf/callsstatus-polling
Open

perf(evm): poll waitForCallsStatus at 500ms — inclusion noticed ~3s sooner#32
psmiratisu wants to merge 2 commits into
mainfrom
perf/callsstatus-polling

Conversation

@psmiratisu

@psmiratisu psmiratisu commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Part of the trading-latency work (see internal-trading-bot #72/#73/#75). Measured from the acp-cli trade loop: a same-chain Base swap spent 7.4s between plan creation and the CLI reporting the confirmed tx — while the userOp itself landed in ~2s (one Base block).

Root cause

waitForTransactionHash calls client.waitForCallsStatus({ id }) with no pollingInterval, so viem falls back to the client default — 4s over http. The included userOp sits unnoticed until the next 4s tick. That dead wait dominates the user-perceived latency of every EVM send/batch in the trade loop.

Fix

Pass pollingInterval: 500 (env-overridable via ACP_CALLS_POLL_MS). Each tick is one light wallet_getCallsStatus read against the ACP RPC proxy, and the wait typically resolves in 4-6 ticks, so the added load is a handful of cheap reads per transaction in exchange for noticing inclusion within ~0.5s of reality.

Applies to both sendTransaction (ERC20-sponsored) and sendCalls (gasless) via the shared helper. timeout semantics unchanged (viem default).

Expected effect

acp-cli same-chain swaps: ~7.4s → ~4-5s for the send-to-confirmed segment. Combined with internal-trading-bot #75 (800ms settle skip), user-perceived swap time drops from ~10s to ~5-6s.

Typecheck clean against main's deps (tsc --noEmit — the repo has no test suite).

🤖 Generated with Claude Code


Note

Low Risk
Behavior change is limited to poll frequency and optional console telemetry; no auth or transaction semantics changes beyond noticing confirmation sooner.

Overview
Cuts user-perceived confirm latency on EVM smart-wallet sends by polling waitForCallsStatus every 500ms (override via ACP_CALLS_POLL_MS) instead of viem’s ~4s HTTP default, so inclusion is detected much sooner after the userOp lands—shared by sendTransaction and sendCalls through waitForTransactionHash.

Adds opt-in per-hop timing when ACP_TIMING is set: one [acp-timing] line per send breaking out prepare/sign/submit/confirm (or bundled submit + confirm for sendCalls) to separate API serial work from bundler inclusion.

Reviewed by Cursor Bugbot for commit cef3df8. Bugbot is set up for automated code reviews on this repo. Configure here.

psmiratisu and others added 2 commits July 8, 2026 16:40
…ooner

waitForCallsStatus was called without a pollingInterval, so viem fell back
to the client default (4s over http). A userOp included in ~2s (one Base
block) sat unnoticed until the next 4s tick — measured live from the acp-cli
trade loop: a same-chain swap spent ~7.4s between plan and confirmation
report, most of it this dead wait. 500ms notices inclusion within half a
second of reality; each tick is one light wallet_getCallsStatus read against
the ACP RPC proxy. Override with ACP_CALLS_POLL_MS.

Applies to both sendTransaction (ERC20-sponsored) and sendCalls (gasless)
via the shared waitForTransactionHash helper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
One log line per send splitting the pipeline into its serial hops —
sendTransaction: prepare/sign/submit/confirm; sendCalls: submit
(account-kit's internal prepare+sign+submit) and confirm (bundler
inclusion + detection). The polling fix in this PR removes dead wait
AFTER inclusion; these numbers show how much the bundler pipeline
itself costs, i.e. whether a direct-7702 (no-bundler) fast path is
worth building. Off by default; set ACP_TIMING=1 to enable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@psmiratisu

Copy link
Copy Markdown
Contributor Author

Added cef3df8: per-hop timing behind ACP_TIMING=1sendTransaction logs prepare/sign/submit/confirm ms, sendCalls logs submit (account-kit's internal prepare+sign+submit) and confirm (bundler inclusion + detection). The polling fix in this PR removes the dead wait after inclusion; these numbers quantify the userOp pipeline itself, to decide whether a direct-7702 (no-bundler) fast path is worth building. Off by default.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant