coinbase / coinbase/agentkit

awal x402 pay: after GET returns 402, settle with POST (do not submit payment on GET)

Open
#1,494 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
1.3k
Forks
815
Avg merge
13h 31m
Merged PRs (30d)
2

Description

### Summary
`npx awal x402 pay ` defaults to GET. When a resource correctly returns **402 on GET for discovery** but only **settles on POST**, awal authorizes payment then resubmits on GET. Servers that refuse to settle money on GET (correct security posture) reject with errors like `Payment was authorized but rejected by server`. No funds move; the agent path still looks broken unless the caller passes `-X POST -d '{}'`.

Resource owners should **not** settle on GET (logs, prefetch, intermediary retries on money routes). The missing behavior is in awal: after a GET 402, use the bazaar/extensions method (POST) for the paid retry.

### Environment
- `awal` 2.12.1 (`npx awal`)
- Base mainnet USDC
- Endpoint pattern: `POST /api/x402/scout-credits/{topup_id}` (intent-bound pay URL; no session headers required)
- Host used in dogfood: `https://flint.network`

### Repro
1. Create an intent-bound pay URL that:
- Answers **GET** with HTTP 402 + `PAYMENT-REQUIRED` + bazaar extensions saying method **POST**
- Settles **only** on **POST** with a valid payment payload
2. Run bare stock:
```bash
npx awal x402 pay "https://example.com/api/x402/scout-credits/" --max-amount 1000000 --json
```
3. Observe failure after authorization:
```text
X402 submission failed: Payment was authorized but rejected by server
```
4. Run recipe form (works):
```bash
npx awal x402 pay -X POST -d '{}' "https://example.com/api/x402/scout-credits/" --max-amount 1000000 --json
```
5. `awal x402 details ` already auto-detects method POST and shows bazaar `input.method: "POST"`.

### Expected
Bare `awal x402 pay ` should discover via GET, read accepted method from 402/bazaar, then authorize and **settle on POST**. Never attach a payment payload to a discovery-only GET.

### Actual
Discovery works. Settlement still uses the discovery verb (GET). Payment authorized, then rejected. Wallet balance unchanged.

### Ask
Teach `awal x402 pax` (default GET) to honor bazaar/extensions method for the paid attempt after a 402, matching what `awal x402 details` already detects.

### Workaround
```bash
awal x402 pay -X POST -d '{}'
```

### Provenance
FLINT Network / Firstmate dogfood, 2026-09-11 PT. Example settled recipe receipt: `fsr_01M29Y5K7HGEN1S1NJJXXVMY4V`.

Contributor guide

Open the contributing guide

Research direction

Start with the `awal x402 pay` command and reproduce the bare-GET failure against an endpoint that returns 402 with a bazaar extension declaring POST. Compare its paid retry with `awal x402 details`, which already detects `input.method: "POST"`. Done means discovery still uses GET, while the authorized payment is submitted with the advertised method and never attached to the discovery GET.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, cli, payments
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.