Skip to content

Phase 3.9: ATXPAccountHandler, settle-at-start, X402 fixes#149

Merged
badjer merged 3 commits intomainfrom
feature/phase3.9-sdk
Apr 7, 2026
Merged

Phase 3.9: ATXPAccountHandler, settle-at-start, X402 fixes#149
badjer merged 3 commits intomainfrom
feature/phase3.9-sdk

Conversation

@badjer
Copy link
Copy Markdown
Contributor

@badjer badjer commented Apr 7, 2026

Rollout

No feature flags needed. SDK changes only take effect when developers upgrade to this version.

Breaking change for ATXPAccount users: ATXPAccount now uses ATXPAccountHandler exclusively (delegates to /authorize/auto). Requires the server SDK to also be upgraded (settle-at-start middleware). Old server + new client = payment failure for ATXPAccount. Upgrade both together.

Non-ATXPAccount users (BaseAccount, SolanaAccount): No breaking changes. X402/MPP handlers + push-mode fallback work as before.

Summary

Client (@atxp/client):

  • ATXPAccountHandler: exclusive handler for ATXPAccount, delegates ALL protocol decisions to accounts /authorize/auto
  • Account.usesAccountsAuthorize interface property replaces brittle instanceof ATXPAccount check
  • ATXPAccount never falls back to push mode (errors instead of silently using a different account path)
  • Handler guard: tryProtocolHandlers only runs on HTTP 402 (fixes MPP handler intercepting raw MCP 200s)
  • X402ProtocolHandler: static import, enriches requirements with USDC contract address
  • buildPaymentHeaders supports atxp protocol → X-ATXP-PAYMENT header
  • checkForATXPResponse preserves original -32042 omni-challenge data
  • 7 unit tests for ATXPAccountHandler

Server (@atxp/server, @atxp/express):

  • detectProtocol: detects X-ATXP-PAYMENT header for ATXP pull mode
  • Express middleware: settle-at-start (validates + credits ledger before MCP handler runs)
  • Settle-at-start tradeoff documented: payment committed before handler runs (inverse of old serve-before-settle problem)
  • buildX402Requirements: filters to X402-compatible networks (base/base_sepolia), warns on empty accepts
  • destinationAccountId passed in X402/MPP settle bodies
  • Lazy-init race fix in getSettlement() (promise caching)

Build fixes:

  • Rollup dist/node_modules cleanup in client and base package build scripts
  • x402 static imports (fixes module resolution in workspaces)

Test plan

  • ATXPAccountHandler unit tests (7 tests: canHandle, authorize delegation, error paths, param extraction)
  • ATXPAccount pull mode E2E: /authorize/auto → one-time token → settle-at-start → ledger credit
  • BaseAccount X402 E2E: Permit2 signed locally → X-PAYMENT header → settle-at-start
  • Non-ATXPAccount push-mode fallback still works
  • Build: npm run build succeeds, no dist/node_modules issues

🤖 Generated with Claude Code

badjer and others added 3 commits April 7, 2026 09:29
Phase 3.9 SDK changes:

Client:
- ATXPAccountHandler: exclusive handler for ATXPAccount, delegates to /authorize/auto
- ATXPAccount never falls back to push mode (errors instead)
- Handler guard: tryProtocolHandlers only runs on HTTP 402 (not raw MCP 200s)
- X402ProtocolHandler: static import, enriches requirements with asset/mimeType
- buildPaymentHeaders supports 'atxp' protocol (X-ATXP-PAYMENT header)
- checkForATXPResponse preserves original -32042 error data

Server:
- detectProtocol: detects X-ATXP-PAYMENT header for ATXP pull mode
- Express middleware: settle-at-start (credits ledger before MCP handler runs)
- buildX402Requirements: filters to X402-compatible networks (base/base_sepolia)
- destinationAccountId in X402/MPP settle bodies

Build fix:
- Rollup dist/node_modules cleanup in client and base package build scripts
- x402 static imports (fixes module resolution in workspaces)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…start docs

- 7 unit tests for ATXPAccountHandler (canHandle, authorize delegation, error paths)
- Replace instanceof ATXPAccount with Account.usesAccountsAuthorize interface property
- Fix lazy-init race in getSettlement() (promise caching)
- USDC address source comment (Circle docs link)
- Remove cli-base.ts (dev test utility, doesn't belong in PR)
- buildAuthorizeParams: error log with challenge keys on missing amount
- Settle-at-start tradeoff documented (pay-before-serve vs serve-before-pay)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…mpty accepts warning

- Fix buildSyntheticResponseFromMcpError spread order (x402 fields win over errorData)
- 10 settle-at-start Express middleware tests (settle→proceed, settle-fail→402, identity)
- resolveIdentity ATXP: handle both base64 and raw JSON (matches MPP pattern)
- buildOmniError: warn when X402 accepts is empty after filtering
- Remove CLAUDE.local.md, add to .gitignore
- Update PR description with usesAccountsAuthorize, tests, settle-at-start docs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@badjer badjer merged commit 0c585e6 into main Apr 7, 2026
1 check passed
@badjer badjer deleted the feature/phase3.9-sdk branch April 7, 2026 17:45
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