Conversation
beforeVerify and beforeSettle are payment gates. A throw was logged and treated as a pass, so an extension that could not finish its check still authorized the payment. Those phases now abort with extension_hook_error. Advisory hooks still log and continue. Fixes x402-foundation#3689. Majority-AI disclosure: drafted and reviewed with AI assistance; tests run locally.
|
@Bartok9 is attempting to deploy a commit to the Coinbase Team on Vercel. A member of the Team first needs to authorize it. |
|
Thanks for picking this up so quickly, @Bartok9. This is pretty much the direction I was hoping for in #3689, and @StratedgeWorkflowSystems's cross-SDK check makes the case clearly. I checked it at One small thing I'd consider: when the hook throws, the error message ends up in Maybe we should return a fixed message such as Also, one thing worth keeping in mind for the merge: #3151 currently wraps the TS facilitator's |
A gate-hook throw still fails closed, but invalidMessage and errorMessage now use a fixed "extension hook failed". The thrown detail stays in the existing warning log so an RPC URL or path is not sent to the client.
|
Good catch on the client-facing text. Pushed On #3151: agreed that wrapping the TS facilitator's gate loops in log-and-continue would reopen fail-open on that path while this PR closes it on the resource server. This change does not touch the facilitator. Happy to follow that up separately so the two do not land in opposite directions. |
Summary
Fixes #3689.
beforeVerifyandbeforeSettleare payment gates. A hook can return{ abort: true }to stop the payment, but a throw was only logged and the loop continued. An extension that could not finish its check (decode, signature, commitment) therefore failed open.A throw in those two phases now stops the payment with reason
extension_hook_errorand the thrown message. The warning log stays. Advisory phases (after*,on*Failure, enrichment) still log and continue.Test plan
pnpm exec vitest run test/unit/server/x402ResourceServer.test.ts --coverage.enabled=falseintypescript/packages/core— 162 passedbeforeVerifyreturnsisValid: falseand does not call the facilitatorbeforeSettlethrowsSettleErrorwitherrorReason: extension_hook_errorand does not settleabortresults are unchangedMajority-AI disclosure: drafted and reviewed with AI assistance.
The Vercel preview gate may ask the Coinbase Team to authorize a first contribution from this fork. That is not a code failure.