Skip to content

feat: Use resource_url-based spend permissions#133

Merged
badjer merged 10 commits intomainfrom
feature/spend-permissions
Jan 14, 2026
Merged

feat: Use resource_url-based spend permissions#133
badjer merged 10 commits intomainfrom
feature/spend-permissions

Conversation

@badjer
Copy link
Contributor

@badjer badjer commented Jan 10, 2026

Summary

  • Updates SDK to use the new spend permissions flow
  • Replaces old scopedSpendConfig with resource_url-based permissions
  • Creates spend permissions via accounts /spend-permission endpoint

Changes

  • Replace scopedSpendConfig with mcpServer for resource URL tracking
  • Add createSpendPermission() method to create spend permissions
  • Pass spend_permission_token to auth during OAuth flow
  • Remove deprecated ScopedSpendConfig type

Test plan

  • Build passes
  • End-to-end flow tested with auth and accounts services
  • Unit tests for createSpendPermission

🤖 Generated with Claude Code

badjer and others added 2 commits January 13, 2026 11:22
Enables SDK clients to use scoped spend tokens during authorization,
allowing async charging instead of blocking on payment before each operation.

Changes:
- Add ScopedSpendConfig type with spendLimit field
- Add scopedSpendConfig option to ClientConfig
- Modify makeAuthRequestWithPaymentMaker to:
  1. Resolve destinationAccountId from auth server (new resolve_only endpoint)
  2. Call accounts /sign with destinationAccountId + spendLimit
  3. Pass scopedSpendToken to auth /authorize
- Add comprehensive tests for scoped spend flow

Usage:
```typescript
const client = await atxpClient({
  mcpServer: 'https://example.com/mcp',
  account: myAccount,
  scopedSpendConfig: { spendLimit: '50.00' }
});
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updates SDK to use the new spend permissions flow:

- Replace scopedSpendConfig with mcpServer for resource URL tracking
- Add createSpendPermission() to create spend permissions via accounts /spend-permission
- Pass spend_permission_token to auth during OAuth flow
- Remove old ScopedSpendConfig type

The new flow:
1. SDK calls accounts /spend-permission with resource_url to create permission
2. SDK passes spend_permission_token to auth during authorization
3. Auth stores token with OAuth token for charge strategy selection

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@badjer badjer force-pushed the feature/spend-permissions branch from 28edade to f39c3e4 Compare January 13, 2026 19:49
badjer and others added 8 commits January 13, 2026 12:29
The package-lock.json had nested node_modules entries for @atxp/common
that pointed to the npm registry version (0.10.3) instead of using the
local workspace version. This caused TypeScript to fail because the
published version doesn't have the new `iss` property on PaymentRequest.

Removed nested entries for:
- packages/atxp-client/node_modules/@atxp/common
- packages/atxp-base/node_modules/@atxp/common
- packages/atxp-express/node_modules/@atxp/common

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix tests to use mcpServer instead of scopedSpendConfig
- Test /spend-permission endpoint instead of /authorize?resolve_only
- Update error handling tests for graceful fallback behavior
- Add CLAUDE.md with testing instructions

The tests were testing an outdated design that used resolve_only and
/sign endpoints. Updated to test the actual implementation which uses
/spend-permission endpoint and graceful fallback on errors.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- PaymentServer now accepts oAuthDb to look up credentials
- Sends Basic auth header on /charge for resource_url validation
- serverConfig passes oAuthDb to PaymentServer constructor

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Keep src/dev/ files aligned with main branch - these are
for local development only and shouldn't be part of the PR.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…tials

- Remove mcpServer from ATXPFetcher config - resource URL now derived
  dynamically from OAuthAuthenticationRequiredError.resourceServerUrl
- Remove atxpAccountsServer from ClientConfig - derived from account.origin
- paymentServer: default oAuthDb to MemoryOAuthDb, hard error if
  credentials unavailable instead of silently dropping
- Update tests to reflect new behavior

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…entation detail

The security fix (Fix 1: validate resource_url on /charge) only requires changes
to ATXPPaymentServer to send client credentials. The atxp-client (atxpFetcher)
should not be creating spend permissions - that's an implementation detail of
ATXPAccounts, not something generic clients should handle.

This reverts all atxp-client changes, keeping only the atxp-server changes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ATXPAccount now creates spend permissions during the OAuth flow:

1. Added `createSpendPermission(resourceUrl)` method to ATXPAccount
   - Calls POST /spend-permission on accounts server
   - Returns spend permission token for authorization

2. Updated OAuthClient.makeAuthorizationUrl to accept optional spendPermissionToken
   - Adds spend_permission_token param to authorization URL
   - Also adds resource param for the MCP server URL

3. Updated ATXPFetcher.authToService to detect ATXPAccounts
   - Uses duck typing to check for createSpendPermission method
   - Creates spend permission before authorization if available
   - Continues auth flow even if spend permission creation fails

This is an ATXPAccount-specific feature - other account types (SolanaAccount,
BaseAccount, etc.) are unaffected as they don't have createSpendPermission.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Added createSpendPermission method to Account type in common
- Implemented in all account types (returns null for non-ATXP accounts)
- Removed type guard hasCreateSpendPermission from atxpFetcher
- Simplified OAuth flow to call createSpendPermission directly

This provides a clean interface for future account types to support
spend permissions without duck-typing.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@badjer badjer merged commit 23c5db3 into main Jan 14, 2026
1 check passed
@badjer badjer deleted the feature/spend-permissions branch January 14, 2026 18:02
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