|
| 1 | +# x402 Testing Plan |
| 2 | + |
| 3 | +## Goal |
| 4 | + |
| 5 | +Validate the end-to-end x402 payment flow used by the Vue demo against the local x402 test server. |
| 6 | + |
| 7 | +Success means: |
| 8 | + |
| 9 | +- protected endpoints return a payment challenge when no payment is attached |
| 10 | +- a funded Base Sepolia wallet can complete the paid retry successfully |
| 11 | +- `X402Tester` writes results and errors to the shared dashboard UI console |
| 12 | +- common failure modes are easy to reproduce and diagnose |
| 13 | + |
| 14 | +## Scope |
| 15 | + |
| 16 | +This plan covers the main x402 demo path across: |
| 17 | + |
| 18 | +- `demo/vue-app-new/src/components/X402Tester.vue` |
| 19 | +- `demo/vue-app-new/src/components/AppDashboard.vue` |
| 20 | +- `demo/x402-test-server/src/index.ts` |
| 21 | +- the `useX402Fetch` flow exposed through `@web3auth/modal/x402/vue` |
| 22 | + |
| 23 | +It does not try to fully validate every wallet provider or every facilitator implementation. |
| 24 | + |
| 25 | +## Test Environment |
| 26 | + |
| 27 | +### Backend |
| 28 | + |
| 29 | +Start the local x402 server: |
| 30 | + |
| 31 | +```bash |
| 32 | +cd demo/x402-test-server |
| 33 | +cp .env.example .env |
| 34 | +# Set EVM_ADDRESS and SVM_ADDRESS |
| 35 | +npm install |
| 36 | +npm run dev |
| 37 | +``` |
| 38 | + |
| 39 | +Expected default server URL: |
| 40 | + |
| 41 | +```text |
| 42 | +http://localhost:4021 |
| 43 | +``` |
| 44 | + |
| 45 | +### Frontend |
| 46 | + |
| 47 | +Start the Vue demo and point it at the local server: |
| 48 | + |
| 49 | +```bash |
| 50 | +cd demo/vue-app-new |
| 51 | +cp .env.sample .env |
| 52 | +``` |
| 53 | + |
| 54 | +Set at least: |
| 55 | + |
| 56 | +```bash |
| 57 | +VITE_APP_X402_TEST_CONTENT_URL=http://localhost:4021/weather |
| 58 | +``` |
| 59 | + |
| 60 | +Then run: |
| 61 | + |
| 62 | +```bash |
| 63 | +npm install |
| 64 | +npm run dev |
| 65 | +``` |
| 66 | + |
| 67 | +## Preconditions |
| 68 | + |
| 69 | +- Web3Auth login is working in the Vue demo |
| 70 | +- an EVM wallet is connected |
| 71 | +- the wallet can switch to Base Sepolia (`0x14a34`) |
| 72 | +- the wallet has enough Base Sepolia gas |
| 73 | +- the wallet has enough Base Sepolia USDC for micro-payments |
| 74 | + |
| 75 | +## Endpoints Under Test |
| 76 | + |
| 77 | +| Method | Path | Expected behavior | |
| 78 | +| ------ | ---- | ----------------- | |
| 79 | +| `GET` | `/health` | Free health check | |
| 80 | +| `GET` | `/weather` | Standard paid x402 route | |
| 81 | +| `GET` | `/premium-data` | Paid route with higher price | |
| 82 | +| `GET` | `/weather-plain` | Debug-friendly route that returns payment requirements in the body when unpaid | |
| 83 | + |
| 84 | +## Manual Test Cases |
| 85 | + |
| 86 | +| ID | Scenario | Steps | Expected result | |
| 87 | +| -- | -------- | ----- | --------------- | |
| 88 | +| `X402-01` | Server health | Call `GET /health` in a browser or with `curl` | `200 OK` with JSON status payload | |
| 89 | +| `X402-02` | Unpaid challenge for `/weather` | Call `GET /weather` without payment headers | `402 Payment Required` and x402 payment requirements | |
| 90 | +| `X402-03` | Successful paid fetch for `/weather` in Vue UI | Log in, connect wallet, switch to Base Sepolia, keep the tester URL on `/weather`, and press `Fetch with Payment` | shared UI console shows `x402 response`, `status: 200`, and a weather payload in `body` | |
| 91 | +| `X402-04` | Successful paid fetch for `/premium-data` in Vue UI | Change the tester URL to `/premium-data` and press `Fetch with Payment` | shared UI console shows `x402 response`, `status: 200`, and premium dataset JSON | |
| 92 | +| `X402-05` | Debug route without payment | Call `GET /weather-plain` without payment headers | `402` body includes `accepts` array and resource metadata | |
| 93 | +| `X402-06` | Debug route through Vue UI | Set the tester URL to `/weather-plain` and press `Fetch with Payment` | shared UI console shows `x402 response`, `status: 200`, and the weather payload | |
| 94 | +| `X402-07` | Wrong-network recovery | Open the Vue demo while connected to an EVM chain other than Base Sepolia | tester shows `Not on Base Sepolia`; after pressing `Switch to Base Sepolia`, the badge updates and fetch can be retried | |
| 95 | +| `X402-08` | Insufficient balance failure | Use a wallet without enough USDC or gas and attempt `Fetch with Payment` | fetch fails cleanly; UI console shows an actionable error or a 402-style response that can be inspected | |
| 96 | + |
| 97 | +## Focus Areas During Testing |
| 98 | + |
| 99 | +### UI behavior |
| 100 | + |
| 101 | +- the `Fetch with Payment` button is disabled when no wallet is connected |
| 102 | +- loading state is shown while the request is in flight |
| 103 | +- results are printed in the dashboard console, not inline inside `X402Tester` |
| 104 | +- errors are also routed to the dashboard console |
| 105 | + |
| 106 | +### Payment behavior |
| 107 | + |
| 108 | +- unpaid requests are challenged instead of silently failing |
| 109 | +- paid retries use the connected wallet on Base Sepolia |
| 110 | +- the same URL can be retested multiple times without refreshing the page |
| 111 | +- successful payments return the protected resource body |
| 112 | + |
| 113 | +### Debuggability |
| 114 | + |
| 115 | +- `/weather-plain` remains available as a browser-friendly inspection route |
| 116 | +- server logs are sufficient to distinguish challenge, retry, and settlement failures |
| 117 | +- console output includes enough context to see which URL was tested and whether the response was successful |
| 118 | + |
| 119 | +## Suggested cURL Checks |
| 120 | + |
| 121 | +Use these checks before testing the Vue flow: |
| 122 | + |
| 123 | +```bash |
| 124 | +curl -i http://localhost:4021/health |
| 125 | +curl -i http://localhost:4021/weather |
| 126 | +curl -i http://localhost:4021/weather-plain |
| 127 | +curl -i http://localhost:4021/premium-data |
| 128 | +``` |
| 129 | + |
| 130 | +Expected outcomes: |
| 131 | + |
| 132 | +- `/health` returns `200` |
| 133 | +- paid routes return `402` when no payment is attached |
| 134 | +- `/weather-plain` returns a readable JSON challenge body |
| 135 | + |
| 136 | +## Failure Cases To Watch |
| 137 | + |
| 138 | +Common issues worth validating explicitly: |
| 139 | + |
| 140 | +- wallet is connected, but not on Base Sepolia |
| 141 | +- wallet has insufficient USDC for the requested payment |
| 142 | +- wallet has insufficient gas to complete the transaction |
| 143 | +- a stale or expired payment proof is retried |
| 144 | +- the configured tester URL points to the wrong server or port |
| 145 | +- the frontend shows no result because console output wiring regressed |
| 146 | + |
| 147 | +## Exit Criteria |
| 148 | + |
| 149 | +The testing cycle is complete when: |
| 150 | + |
| 151 | +- `X402-01` through `X402-06` pass |
| 152 | +- at least one negative case from `X402-07` or `X402-08` is exercised |
| 153 | +- success and failure states are both visible in the dashboard console |
| 154 | +- no inline result panel is required to inspect x402 responses |
0 commit comments