Repository navigation
fix(batch): sign deposits with a finalized blockhash when the 402 names none - #95
Merged
Merged
Conversation
…es none
@x402/svm 2.28 resolveBlockhash() uses the 402's extra.recentBlockhash, else
@solana/kit getLatestBlockhash at its default confirmed commitment (traced by
agent-money-bench: params [{commitment: confirmed}]). PayAI's verifier lags
the tip and rejects such a blockhash as BlockhashNotFound, so the deposit is
refused and the call pays exact.
createPayload() now passes the scheme a copy of the 402 whose batch accepts
lacking recentBlockhash carry a finalized one (getLatestBlockhash finalized,
cached 10 s per RPC URL), when the payment will likely carry a deposit (no
usable record for the trusted accept's key, or a top-up prepareTopUp sized).
Additive only; @x402/core matches the echoed accept as a superset; a failed
read leaves the 402 as is. Tests: open, top-up, authorization reads nothing,
402-named blockhash kept, failed read falls back (3 fail on main).
VickyXAI
force-pushed
the
fix/batch-finalized-blockhash
branch
from
October 27, 2026 16:11
5ea3384 to
131925b
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.
Problem
A batch deposit (open or top-up) is a Solana transaction. In
@x402/svm2.28,resolveBlockhash()takes its blockhash from the 402'sextra.recentBlockhash. If the 402 has none, it calls@solana/kit'sgetLatestBlockhash()at kit's default commitment, which isconfirmed. The agent-money-bench session traced the request ("params":[{"commitment":"confirmed"}]), and the new fallback test shows the same thing. PayAI's verifier runs behind the chain tip and rejects a blockhash it hasn't seen yet withinvalid_exact_svm_transaction_simulation_failed: "BlockhashNotFound", the same failure the bench saw on @x402/svm exact payments. The SDK then classifies the refused deposit asdeposit_refused: the call pays exact and the deposit is re-read from chain. Nothing is lost, but each refusal costs a full exact payment.The SDK's own exact path (
src/x402.ts) already gets afinalizedblockhash: web3.js sends no commitment, and the RPC's default is finalized.Change
createPayload()now builds the payment from a copy of the 402. In that copy, batch accepts with norecentBlockhashget afinalizedblockhash plus itslastValidBlockHeight, read from the configured RPC (withrpcHeaders) and cached 10 s per RPC URL, like the exact path'sBLOCKHASH_TTL_MS.prepareTopUpjust sized a top-up. Authorizations sign no transaction and read nothing.@x402/core'spaymentRequirementsMatchAcceptedmatches the echoedaccepted.extraas a superset of the gateway's requirements, and blockrun-sol's batch handler only comparespayTo/asset/network(src/lib/batch/payment.ts:260).lastValidBlockHeightitself; in-doubt logic still uses only the SDK's own anchor.Tests
New, in
test/unit/solana-batch.test.ts:accepted.extracarries it.confirmedread.The first two and the fallback test fail on main; the other two guard behaviour that should not change.
npm test: 1074 passed, 12 skipped. Build, lint and typecheck are clean.Docs:
docs/solana-batch.md(RPC section), CLAUDE.md batch section, CHANGELOG (Unreleased). #94 also edits CHANGELOG[Unreleased], so whichever merges second needs a one-line rebase.