@goplausible/openclaw-algorand-plugin 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +112 -0
  3. package/index.ts +361 -0
  4. package/lib/mcp-servers.ts +14 -0
  5. package/lib/x402-fetch.ts +213 -0
  6. package/memory/algorand-plugin.md +82 -0
  7. package/openclaw.plugin.json +30 -0
  8. package/package.json +41 -0
  9. package/setup.ts +80 -0
  10. package/skills/algorand-development/SKILL.md +90 -0
  11. package/skills/algorand-development/references/build-smart-contracts-reference.md +79 -0
  12. package/skills/algorand-development/references/build-smart-contracts.md +52 -0
  13. package/skills/algorand-development/references/create-project-reference.md +86 -0
  14. package/skills/algorand-development/references/create-project.md +89 -0
  15. package/skills/algorand-development/references/implement-arc-standards-arc32-arc56.md +396 -0
  16. package/skills/algorand-development/references/implement-arc-standards-arc4.md +265 -0
  17. package/skills/algorand-development/references/implement-arc-standards.md +92 -0
  18. package/skills/algorand-development/references/search-algorand-examples-reference.md +119 -0
  19. package/skills/algorand-development/references/search-algorand-examples.md +89 -0
  20. package/skills/algorand-development/references/troubleshoot-errors-contract.md +373 -0
  21. package/skills/algorand-development/references/troubleshoot-errors-transaction.md +599 -0
  22. package/skills/algorand-development/references/troubleshoot-errors.md +105 -0
  23. package/skills/algorand-development/references/use-algokit-cli-reference.md +228 -0
  24. package/skills/algorand-development/references/use-algokit-cli.md +64 -0
  25. package/skills/algorand-interaction/SKILL.md +223 -0
  26. package/skills/algorand-interaction/references/algorand-mcp.md +743 -0
  27. package/skills/algorand-interaction/references/examples-algorand-mcp.md +647 -0
  28. package/skills/algorand-python/SKILL.md +95 -0
  29. package/skills/algorand-python/references/build-smart-contracts-decorators.md +413 -0
  30. package/skills/algorand-python/references/build-smart-contracts-reference.md +55 -0
  31. package/skills/algorand-python/references/build-smart-contracts-storage.md +452 -0
  32. package/skills/algorand-python/references/build-smart-contracts-transactions.md +445 -0
  33. package/skills/algorand-python/references/build-smart-contracts-types.md +438 -0
  34. package/skills/algorand-python/references/build-smart-contracts.md +82 -0
  35. package/skills/algorand-python/references/create-project-reference.md +55 -0
  36. package/skills/algorand-python/references/create-project.md +75 -0
  37. package/skills/algorand-python/references/implement-arc-standards-arc32-arc56.md +101 -0
  38. package/skills/algorand-python/references/implement-arc-standards-arc4.md +154 -0
  39. package/skills/algorand-python/references/implement-arc-standards.md +39 -0
  40. package/skills/algorand-python/references/troubleshoot-errors-contract.md +355 -0
  41. package/skills/algorand-python/references/troubleshoot-errors-transaction.md +430 -0
  42. package/skills/algorand-python/references/troubleshoot-errors.md +46 -0
  43. package/skills/algorand-python/references/use-algokit-utils-reference.md +350 -0
  44. package/skills/algorand-python/references/use-algokit-utils.md +76 -0
  45. package/skills/algorand-typescript/SKILL.md +131 -0
  46. package/skills/algorand-typescript/references/algorand-ts-migration-from-beta.md +448 -0
  47. package/skills/algorand-typescript/references/algorand-ts-migration-from-tealscript.md +487 -0
  48. package/skills/algorand-typescript/references/algorand-ts-migration.md +102 -0
  49. package/skills/algorand-typescript/references/algorand-typescript-syntax-methods-and-abi.md +134 -0
  50. package/skills/algorand-typescript/references/algorand-typescript-syntax-reference.md +58 -0
  51. package/skills/algorand-typescript/references/algorand-typescript-syntax-storage.md +154 -0
  52. package/skills/algorand-typescript/references/algorand-typescript-syntax-transactions.md +187 -0
  53. package/skills/algorand-typescript/references/algorand-typescript-syntax-types-and-values.md +150 -0
  54. package/skills/algorand-typescript/references/algorand-typescript-syntax.md +84 -0
  55. package/skills/algorand-typescript/references/build-smart-contracts-reference.md +52 -0
  56. package/skills/algorand-typescript/references/build-smart-contracts.md +74 -0
  57. package/skills/algorand-typescript/references/call-smart-contracts-reference.md +237 -0
  58. package/skills/algorand-typescript/references/call-smart-contracts.md +183 -0
  59. package/skills/algorand-typescript/references/create-project-reference.md +53 -0
  60. package/skills/algorand-typescript/references/create-project.md +86 -0
  61. package/skills/algorand-typescript/references/deploy-react-frontend-examples.md +527 -0
  62. package/skills/algorand-typescript/references/deploy-react-frontend-reference.md +412 -0
  63. package/skills/algorand-typescript/references/deploy-react-frontend.md +239 -0
  64. package/skills/algorand-typescript/references/implement-arc-standards-arc32-arc56.md +73 -0
  65. package/skills/algorand-typescript/references/implement-arc-standards-arc4.md +126 -0
  66. package/skills/algorand-typescript/references/implement-arc-standards.md +44 -0
  67. package/skills/algorand-typescript/references/test-smart-contracts-examples.md +245 -0
  68. package/skills/algorand-typescript/references/test-smart-contracts-unit-tests.md +147 -0
  69. package/skills/algorand-typescript/references/test-smart-contracts.md +127 -0
  70. package/skills/algorand-typescript/references/troubleshoot-errors-contract.md +296 -0
  71. package/skills/algorand-typescript/references/troubleshoot-errors-transaction.md +438 -0
  72. package/skills/algorand-typescript/references/troubleshoot-errors.md +56 -0
  73. package/skills/algorand-typescript/references/use-algokit-utils-reference.md +342 -0
  74. package/skills/algorand-typescript/references/use-algokit-utils.md +74 -0
  75. package/skills/algorand-x402-python/SKILL.md +113 -0
  76. package/skills/algorand-x402-python/references/create-python-x402-client-examples.md +469 -0
  77. package/skills/algorand-x402-python/references/create-python-x402-client-reference.md +313 -0
  78. package/skills/algorand-x402-python/references/create-python-x402-client.md +207 -0
  79. package/skills/algorand-x402-python/references/create-python-x402-facilitator-examples.md +924 -0
  80. package/skills/algorand-x402-python/references/create-python-x402-facilitator-reference.md +629 -0
  81. package/skills/algorand-x402-python/references/create-python-x402-facilitator.md +408 -0
  82. package/skills/algorand-x402-python/references/create-python-x402-server-examples.md +703 -0
  83. package/skills/algorand-x402-python/references/create-python-x402-server-reference.md +303 -0
  84. package/skills/algorand-x402-python/references/create-python-x402-server.md +221 -0
  85. package/skills/algorand-x402-python/references/explain-algorand-x402-python-examples.md +605 -0
  86. package/skills/algorand-x402-python/references/explain-algorand-x402-python-reference.md +315 -0
  87. package/skills/algorand-x402-python/references/explain-algorand-x402-python.md +167 -0
  88. package/skills/algorand-x402-python/references/use-python-x402-core-avm-examples.md +554 -0
  89. package/skills/algorand-x402-python/references/use-python-x402-core-avm-reference.md +278 -0
  90. package/skills/algorand-x402-python/references/use-python-x402-core-avm.md +166 -0
  91. package/skills/algorand-x402-typescript/SKILL.md +129 -0
  92. package/skills/algorand-x402-typescript/references/create-typescript-x402-client-examples.md +879 -0
  93. package/skills/algorand-x402-typescript/references/create-typescript-x402-client-reference.md +371 -0
  94. package/skills/algorand-x402-typescript/references/create-typescript-x402-client.md +236 -0
  95. package/skills/algorand-x402-typescript/references/create-typescript-x402-facilitator-examples.md +875 -0
  96. package/skills/algorand-x402-typescript/references/create-typescript-x402-facilitator-reference.md +461 -0
  97. package/skills/algorand-x402-typescript/references/create-typescript-x402-facilitator.md +270 -0
  98. package/skills/algorand-x402-typescript/references/create-typescript-x402-nextjs-examples.md +1181 -0
  99. package/skills/algorand-x402-typescript/references/create-typescript-x402-nextjs-reference.md +360 -0
  100. package/skills/algorand-x402-typescript/references/create-typescript-x402-nextjs.md +251 -0
  101. package/skills/algorand-x402-typescript/references/create-typescript-x402-paywall-examples.md +870 -0
  102. package/skills/algorand-x402-typescript/references/create-typescript-x402-paywall-reference.md +323 -0
  103. package/skills/algorand-x402-typescript/references/create-typescript-x402-paywall.md +281 -0
  104. package/skills/algorand-x402-typescript/references/create-typescript-x402-server-examples.md +1135 -0
  105. package/skills/algorand-x402-typescript/references/create-typescript-x402-server-reference.md +382 -0
  106. package/skills/algorand-x402-typescript/references/create-typescript-x402-server.md +216 -0
  107. package/skills/algorand-x402-typescript/references/explain-algorand-x402-typescript-examples.md +616 -0
  108. package/skills/algorand-x402-typescript/references/explain-algorand-x402-typescript-reference.md +323 -0
  109. package/skills/algorand-x402-typescript/references/explain-algorand-x402-typescript.md +232 -0
  110. package/skills/algorand-x402-typescript/references/use-typescript-x402-core-avm-examples.md +1417 -0
  111. package/skills/algorand-x402-typescript/references/use-typescript-x402-core-avm-reference.md +504 -0
  112. package/skills/algorand-x402-typescript/references/use-typescript-x402-core-avm.md +158 -0
@@ -0,0 +1,360 @@
1
+ # @x402-avm/next Reference
2
+
3
+ Detailed API reference for the x402-avm Next.js integration package.
4
+
5
+ ## Dependencies
6
+
7
+ ```json
8
+ {
9
+ "dependencies": {
10
+ "@x402-avm/next": "latest",
11
+ "@x402-avm/core": "latest",
12
+ "@x402-avm/avm": "latest",
13
+ "next": ">=14.0.0"
14
+ }
15
+ }
16
+ ```
17
+
18
+ For paywall UI:
19
+
20
+ ```json
21
+ {
22
+ "dependencies": {
23
+ "@x402-avm/paywall": "latest"
24
+ }
25
+ }
26
+ ```
27
+
28
+ ## Package Exports: @x402-avm/next
29
+
30
+ | Export | Description |
31
+ |--------|-------------|
32
+ | `paymentProxyFromConfig` | Create proxy with auto-configured resource server |
33
+ | `paymentProxy` | Create proxy with pre-configured resource server |
34
+ | `paymentProxyFromHTTPServer` | Create proxy from an `x402HTTPResourceServer` |
35
+ | `withX402` | Wrap a route handler with payment protection |
36
+ | `withX402FromHTTPServer` | Wrap a route handler using an `x402HTTPResourceServer` |
37
+ | `x402ResourceServer` | Re-export from `@x402-avm/core/server` |
38
+ | `x402HTTPResourceServer` | Re-export from `@x402-avm/core/server` |
39
+
40
+ ## paymentProxyFromConfig
41
+
42
+ The simplest proxy setup. Creates the `x402ResourceServer` internally.
43
+
44
+ ```typescript
45
+ function paymentProxyFromConfig(
46
+ routes: Record<string, RouteDefinition>,
47
+ facilitatorClient: HTTPFacilitatorClient,
48
+ paywallConfig?: PaywallConfig,
49
+ ): (request: NextRequest) => Promise<NextResponse>;
50
+ ```
51
+
52
+ ### Parameters
53
+
54
+ | Parameter | Type | Description |
55
+ |-----------|------|-------------|
56
+ | `routes` | `Record<string, RouteDefinition>` | Route pattern to payment config mapping |
57
+ | `facilitatorClient` | `HTTPFacilitatorClient` | Client for communicating with facilitator |
58
+ | `paywallConfig` | `PaywallConfig` (optional) | Configuration for browser paywall UI |
59
+
60
+ ### Route Pattern Format
61
+
62
+ Route patterns follow the format `"METHOD /path/pattern"`:
63
+
64
+ | Pattern | Matches |
65
+ |---------|---------|
66
+ | `"GET /api/weather"` | Exact match: `GET /api/weather` |
67
+ | `"GET /api/premium/*"` | Wildcard: `GET /api/premium/data`, `GET /api/premium/stats` |
68
+ | `"POST /api/generate"` | Exact match: `POST /api/generate` |
69
+ | `"GET /api/users/:id"` | Parameter: `GET /api/users/123` |
70
+
71
+ ## paymentProxy
72
+
73
+ Create proxy with a pre-configured `x402ResourceServer`.
74
+
75
+ ```typescript
76
+ function paymentProxy(
77
+ routes: Record<string, RouteDefinition>,
78
+ server: x402ResourceServer,
79
+ paywallConfig?: PaywallConfig,
80
+ ): (request: NextRequest) => Promise<NextResponse>;
81
+ ```
82
+
83
+ ### Parameters
84
+
85
+ | Parameter | Type | Description |
86
+ |-----------|------|-------------|
87
+ | `routes` | `Record<string, RouteDefinition>` | Route pattern to payment config mapping |
88
+ | `server` | `x402ResourceServer` | Pre-configured resource server with registered schemes |
89
+ | `paywallConfig` | `PaywallConfig` (optional) | Configuration for browser paywall UI |
90
+
91
+ ## paymentProxyFromHTTPServer
92
+
93
+ Most advanced proxy variant. Uses an `x402HTTPResourceServer` for HTTP-level hooks.
94
+
95
+ ```typescript
96
+ function paymentProxyFromHTTPServer(
97
+ httpServer: x402HTTPResourceServer,
98
+ ): (request: NextRequest) => Promise<NextResponse>;
99
+ ```
100
+
101
+ ### Parameters
102
+
103
+ | Parameter | Type | Description |
104
+ |-----------|------|-------------|
105
+ | `httpServer` | `x402HTTPResourceServer` | HTTP server with routes and hooks configured |
106
+
107
+ ## withX402
108
+
109
+ Wrap an individual route handler with payment protection.
110
+
111
+ ```typescript
112
+ function withX402(
113
+ handler: (request: NextRequest) => Promise<NextResponse>,
114
+ routeConfig: RouteDefinition,
115
+ server: x402ResourceServer,
116
+ ): (request: NextRequest) => Promise<NextResponse>;
117
+ ```
118
+
119
+ ### Parameters
120
+
121
+ | Parameter | Type | Description |
122
+ |-----------|------|-------------|
123
+ | `handler` | `(request: NextRequest) => Promise<NextResponse>` | The route handler to protect |
124
+ | `routeConfig` | `RouteDefinition` | Payment configuration for this route |
125
+ | `server` | `x402ResourceServer` | Pre-configured resource server |
126
+
127
+ ### Settlement Behavior
128
+
129
+ - Payment is verified **before** the handler executes
130
+ - Payment is settled **only if** the handler returns a response with status < 400
131
+ - If the handler returns 4xx or 5xx, payment is **not settled** (user is not charged)
132
+
133
+ ## withX402FromHTTPServer
134
+
135
+ Wrap a route handler using an `x402HTTPResourceServer` with hooks.
136
+
137
+ ```typescript
138
+ function withX402FromHTTPServer(
139
+ handler: (request: NextRequest) => Promise<NextResponse>,
140
+ httpServer: x402HTTPResourceServer,
141
+ ): (request: NextRequest) => Promise<NextResponse>;
142
+ ```
143
+
144
+ ### Parameters
145
+
146
+ | Parameter | Type | Description |
147
+ |-----------|------|-------------|
148
+ | `handler` | `(request: NextRequest) => Promise<NextResponse>` | The route handler to protect |
149
+ | `httpServer` | `x402HTTPResourceServer` | HTTP server with hooks configured |
150
+
151
+ ## RouteDefinition
152
+
153
+ ```typescript
154
+ interface RouteDefinition {
155
+ accepts: AcceptsConfig | AcceptsConfig[];
156
+ description?: string;
157
+ mimeType?: string;
158
+ customPaywallHtml?: string;
159
+ unpaidResponseBody?: (context: RequestContext) => {
160
+ contentType: string;
161
+ body: unknown;
162
+ };
163
+ }
164
+ ```
165
+
166
+ ### AcceptsConfig
167
+
168
+ ```typescript
169
+ interface AcceptsConfig {
170
+ scheme: "exact";
171
+ network: string; // CAIP-2 identifier
172
+ payTo: string; // Algorand address (58 chars)
173
+ price: string; // Dollar amount, e.g., "$0.01", "$1.00"
174
+ extra?: {
175
+ asset?: string; // ASA ID for token payments
176
+ };
177
+ }
178
+ ```
179
+
180
+ ### Price Format
181
+
182
+ The `price` field uses dollar notation:
183
+
184
+ | Price | Atomic Units (6 decimals) |
185
+ |-------|--------------------------|
186
+ | `"$0.01"` | `10000` |
187
+ | `"$0.10"` | `100000` |
188
+ | `"$1.00"` | `1000000` |
189
+ | `"$5.00"` | `5000000` |
190
+
191
+ ## PaywallConfig
192
+
193
+ ```typescript
194
+ interface PaywallConfig {
195
+ title?: string;
196
+ description?: string;
197
+ logoUrl?: string;
198
+ }
199
+ ```
200
+
201
+ Used by the proxy pattern to render a browser-friendly paywall page when the request's `Accept` header includes `text/html`.
202
+
203
+ ## x402HTTPResourceServer Hooks
204
+
205
+ ### onProtectedRequest
206
+
207
+ Register a hook that runs before payment processing.
208
+
209
+ ```typescript
210
+ httpServer.onProtectedRequest(async (context, routeConfig) => {
211
+ // Return { grantAccess: true } to skip payment
212
+ // Return { abort: true, reason: string } to reject the request
213
+ // Return undefined to continue to payment flow
214
+ });
215
+ ```
216
+
217
+ ### Hook Return Values
218
+
219
+ | Return | Effect |
220
+ |--------|--------|
221
+ | `{ grantAccess: true }` | Skip payment, forward request to handler |
222
+ | `{ abort: true, reason: string }` | Reject request immediately |
223
+ | `undefined` | Continue to standard payment flow |
224
+
225
+ ## Middleware Configuration
226
+
227
+ ### middleware.ts Placement
228
+
229
+ The `middleware.ts` file must be at the project root (next to `app/`):
230
+
231
+ ```
232
+ my-project/
233
+ middleware.ts <-- here
234
+ app/
235
+ page.tsx
236
+ api/
237
+ ...
238
+ ```
239
+
240
+ ### Matcher Configuration
241
+
242
+ Always specify which routes the middleware should intercept:
243
+
244
+ ```typescript
245
+ export const config = {
246
+ matcher: "/api/:path*", // All API routes
247
+ };
248
+
249
+ // Or specific routes:
250
+ export const config = {
251
+ matcher: [
252
+ "/api/weather/:path*",
253
+ "/api/premium/:path*",
254
+ "/premium-article",
255
+ ],
256
+ };
257
+ ```
258
+
259
+ ### Matcher Patterns
260
+
261
+ | Pattern | Matches |
262
+ |---------|---------|
263
+ | `"/api/:path*"` | All routes under `/api/` |
264
+ | `"/api/weather/:path*"` | All routes under `/api/weather/` |
265
+ | `"/premium-article"` | Exact path `/premium-article` |
266
+ | `["/api/*", "/premium/*"]` | Multiple patterns |
267
+
268
+ ## Proxy Pattern vs. withX402 Comparison
269
+
270
+ | Feature | Proxy (middleware.ts) | withX402 (route.ts) |
271
+ |---------|----------------------|---------------------|
272
+ | File location | `middleware.ts` at root | Each `route.ts` file |
273
+ | Route config | Centralized in one place | Per-route, distributed |
274
+ | Settlement timing | On proxy forward | After handler success (status < 400) |
275
+ | Error handling | Proxy-level | Handler-level (no charge on 5xx) |
276
+ | Handler modification | None required | Must wrap each exported function |
277
+ | Multi-method support | Via `"GET /path"`, `"POST /path"` | Wrap `GET`, `POST`, `PUT` individually |
278
+ | HTTP hooks | Via `paymentProxyFromHTTPServer` | Via `withX402FromHTTPServer` |
279
+ | Paywall support | Built-in with `paywallConfig` | Manual |
280
+ | Best for | Multiple routes, same config | Per-route control, safe settlement |
281
+
282
+ ## Proxy Pattern Variants
283
+
284
+ | Function | Server Creation | Hooks | Use Case |
285
+ |----------|----------------|-------|----------|
286
+ | `paymentProxyFromConfig` | Automatic | No | Simplest setup |
287
+ | `paymentProxy` | Manual | No | Custom server config |
288
+ | `paymentProxyFromHTTPServer` | Manual | Yes | Auth bypass, rate limiting |
289
+
290
+ ## withX402 Pattern Variants
291
+
292
+ | Function | Server Type | Hooks | Use Case |
293
+ |----------|-------------|-------|----------|
294
+ | `withX402` | `x402ResourceServer` | No | Simple per-route protection |
295
+ | `withX402FromHTTPServer` | `x402HTTPResourceServer` | Yes | Per-route with hooks |
296
+
297
+ ## Environment Variables
298
+
299
+ | Variable | Description | Default | Required |
300
+ |----------|-------------|---------|----------|
301
+ | `PAY_TO` | Algorand address to receive payments | None | Yes |
302
+ | `FACILITATOR_URL` | URL of the facilitator server | `https://x402.org/facilitator` | No |
303
+ | `ALGOD_SERVER` | Algorand node URL | `https://testnet-api.algonode.cloud` | No |
304
+ | `ALGOD_TOKEN` | Algorand node API token | `""` | No |
305
+
306
+ ## CAIP-2 Network Identifiers
307
+
308
+ | Network | Constant | Value |
309
+ |---------|----------|-------|
310
+ | Algorand Testnet | `ALGORAND_TESTNET_CAIP2` | `"algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI="` |
311
+ | Algorand Mainnet | `ALGORAND_MAINNET_CAIP2` | `"algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8="` |
312
+
313
+ ## USDC ASA IDs
314
+
315
+ | Network | Constant | Value |
316
+ |---------|----------|-------|
317
+ | Testnet | `USDC_TESTNET_ASA_ID` | `"10458941"` |
318
+ | Mainnet | `USDC_MAINNET_ASA_ID` | `"31566704"` |
319
+
320
+ ## Shared Config Pattern
321
+
322
+ For projects using the `withX402` pattern across multiple routes, create a shared config module:
323
+
324
+ ```
325
+ lib/
326
+ x402.ts <-- shared x402Server, PAY_TO, NETWORK
327
+ app/
328
+ api/
329
+ weather/route.ts <-- imports from @/lib/x402
330
+ premium/route.ts <-- imports from @/lib/x402
331
+ generate/route.ts <-- imports from @/lib/x402
332
+ ```
333
+
334
+ The shared module creates and configures the `x402ResourceServer` once, and exports it along with common constants.
335
+
336
+ ## Testing
337
+
338
+ 1. Start with Algorand TestNet (`ALGORAND_TESTNET_CAIP2`)
339
+ 2. Set `PAY_TO` to a testnet address
340
+ 3. Fund the test client address with testnet ALGO and USDC (ASA 10458941)
341
+ 4. Use the [Algorand Dispenser](https://bank.testnet.algorand.network/) for testnet ALGO
342
+ 5. Test 402 responses by hitting protected routes without the `PAYMENT-SIGNATURE` header
343
+ 6. Test payment flow using `x402Client` from `@x402-avm/core/client`
344
+
345
+ ## Key Considerations
346
+
347
+ - **Settlement safety**: Use `withX402` when you need guaranteed settlement only on success (e.g., AI generation that can fail)
348
+ - **Centralized config**: Use the proxy pattern when many routes share the same pricing structure
349
+ - **HTML pages**: Set `mimeType: "text/html"` for page routes to enable paywall rendering
350
+ - **Free routes**: Either exclude from the middleware matcher or do not wrap with `withX402`
351
+ - **Cross-chain**: Multiple `accepts` entries allow clients to pay on different networks
352
+ - **Dynamic pricing**: Route config can include callback functions for dynamic price computation
353
+
354
+ ## External Links
355
+
356
+ - [x402-avm Next.js Examples](https://github.com/GoPlausible/x402-avm/tree/branch-v2-algorand-publish/examples/)
357
+ - [x402-avm Documentation](https://github.com/GoPlausible/.github/blob/main/profile/algorand-x402-documentation/)
358
+ - [Next.js Middleware Documentation](https://nextjs.org/docs/app/building-your-application/routing/middleware)
359
+ - [Next.js App Router](https://nextjs.org/docs/app/building-your-application/routing)
360
+ - [@x402-avm/core Reference](./use-typescript-x402-core-avm-reference.md)
@@ -0,0 +1,251 @@
1
+ # Creating Next.js Apps with x402 Payment Protection
2
+
3
+ Build fullstack Next.js applications with HTTP 402 payment-gated routes using Algorand blockchain payments. Two patterns are available: the Proxy Pattern for middleware-level protection and the Route Handler Wrapper for per-endpoint control.
4
+
5
+ ## Prerequisites
6
+
7
+ Before using this skill, ensure:
8
+
9
+ 1. **Next.js 14+ App Router** project is set up
10
+ 2. **Node.js 18+** is installed
11
+ 3. **Algorand address** to receive payments (`PAY_TO`)
12
+ 4. **Facilitator URL** is available (default: `https://x402.org/facilitator`)
13
+
14
+ ## Core Workflow: Two Integration Patterns
15
+
16
+ ```
17
+ Pattern 1: Proxy (middleware.ts) Pattern 2: withX402 (route.ts)
18
+
19
+ Request Request
20
+ | |
21
+ v v
22
+ middleware.ts route.ts
23
+ | |
24
+ paymentProxy / paymentProxyFromConfig withX402(handler, config, server)
25
+ | |
26
+ Has PAYMENT-SIGNATURE? -No-> 402 Has PAYMENT-SIGNATURE? -No-> 402
27
+ | |
28
+ Yes Yes
29
+ | |
30
+ Verify via facilitator Verify via facilitator
31
+ | |
32
+ Forward to route handler Execute handler
33
+ | |
34
+ Return response If status < 400: settle payment
35
+ |
36
+ Return response
37
+ ```
38
+
39
+ ## How to Proceed
40
+
41
+ ### Step 1: Install Dependencies
42
+
43
+ ```bash
44
+ npm install @x402-avm/next @x402-avm/avm @x402-avm/core
45
+ ```
46
+
47
+ For paywall UI support:
48
+
49
+ ```bash
50
+ npm install @x402-avm/next @x402-avm/avm @x402-avm/core @x402-avm/paywall
51
+ ```
52
+
53
+ ### Step 2: Set Up Environment Variables
54
+
55
+ Create `.env.local`:
56
+
57
+ ```bash
58
+ PAY_TO=ALGORAND_ADDRESS_HERE_58_CHARS
59
+ FACILITATOR_URL=https://x402.org/facilitator
60
+ ```
61
+
62
+ ### Step 3: Choose Your Pattern
63
+
64
+ #### Option A: Proxy Pattern (Recommended for Multi-Route APIs)
65
+
66
+ Create `middleware.ts` at your project root:
67
+
68
+ ```typescript
69
+ import { NextRequest } from "next/server";
70
+ import { paymentProxyFromConfig } from "@x402-avm/next";
71
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
72
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
73
+
74
+ const PAY_TO = process.env.PAY_TO!;
75
+
76
+ const routes = {
77
+ "GET /api/weather": {
78
+ accepts: {
79
+ scheme: "exact",
80
+ network: ALGORAND_TESTNET_CAIP2,
81
+ payTo: PAY_TO,
82
+ price: "$0.01",
83
+ },
84
+ description: "Weather data",
85
+ },
86
+ "GET /api/premium/*": {
87
+ accepts: {
88
+ scheme: "exact",
89
+ network: ALGORAND_TESTNET_CAIP2,
90
+ payTo: PAY_TO,
91
+ price: "$0.10",
92
+ },
93
+ description: "Premium API endpoints",
94
+ },
95
+ };
96
+
97
+ const facilitatorClient = new HTTPFacilitatorClient();
98
+ const proxy = paymentProxyFromConfig(routes, facilitatorClient);
99
+
100
+ export async function middleware(request: NextRequest) {
101
+ return proxy(request);
102
+ }
103
+
104
+ export const config = {
105
+ matcher: "/api/:path*",
106
+ };
107
+ ```
108
+
109
+ Route handlers remain unchanged -- no wrapping needed:
110
+
111
+ ```typescript
112
+ // app/api/weather/route.ts
113
+ import { NextResponse } from "next/server";
114
+
115
+ export async function GET() {
116
+ return NextResponse.json({ temperature: 72, condition: "sunny" });
117
+ }
118
+ ```
119
+
120
+ #### Option B: Route Handler Wrapper (Recommended for Per-Endpoint Control)
121
+
122
+ Create a shared config module:
123
+
124
+ ```typescript
125
+ // lib/x402.ts
126
+ import { x402ResourceServer } from "@x402-avm/next";
127
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
128
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
129
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
130
+
131
+ export const PAY_TO = process.env.PAY_TO!;
132
+ export const NETWORK = ALGORAND_TESTNET_CAIP2;
133
+
134
+ const facilitatorClient = new HTTPFacilitatorClient({
135
+ url: process.env.FACILITATOR_URL || "https://x402.org/facilitator",
136
+ });
137
+
138
+ export const x402Server = new x402ResourceServer(facilitatorClient);
139
+ registerExactAvmScheme(x402Server);
140
+ ```
141
+
142
+ Wrap individual route handlers:
143
+
144
+ ```typescript
145
+ // app/api/weather/route.ts
146
+ import { NextRequest, NextResponse } from "next/server";
147
+ import { withX402 } from "@x402-avm/next";
148
+ import { x402Server, PAY_TO, NETWORK } from "@/lib/x402";
149
+
150
+ const handler = async (request: NextRequest) => {
151
+ return NextResponse.json({ temperature: 72, condition: "sunny" });
152
+ };
153
+
154
+ export const GET = withX402(handler, {
155
+ accepts: {
156
+ scheme: "exact",
157
+ network: NETWORK,
158
+ payTo: PAY_TO,
159
+ price: "$0.01",
160
+ },
161
+ description: "Weather data",
162
+ }, x402Server);
163
+ ```
164
+
165
+ ### Step 4: Add Free Routes (Optional)
166
+
167
+ Routes not matched by the middleware matcher or not wrapped with `withX402` are free:
168
+
169
+ ```typescript
170
+ // app/api/health/route.ts -- not wrapped, always free
171
+ import { NextResponse } from "next/server";
172
+
173
+ export async function GET() {
174
+ return NextResponse.json({ status: "healthy" });
175
+ }
176
+ ```
177
+
178
+ ### Step 5: Add Multi-Network Support (Optional)
179
+
180
+ Accept payments on both testnet and mainnet:
181
+
182
+ ```typescript
183
+ import {
184
+ ALGORAND_TESTNET_CAIP2,
185
+ ALGORAND_MAINNET_CAIP2,
186
+ } from "@x402-avm/avm";
187
+
188
+ const routes = {
189
+ "GET /api/data": {
190
+ accepts: [
191
+ {
192
+ scheme: "exact",
193
+ network: ALGORAND_TESTNET_CAIP2,
194
+ payTo: "YOUR_TESTNET_ADDRESS",
195
+ price: "$0.01",
196
+ },
197
+ {
198
+ scheme: "exact",
199
+ network: ALGORAND_MAINNET_CAIP2,
200
+ payTo: "YOUR_MAINNET_ADDRESS",
201
+ price: "$0.01",
202
+ },
203
+ ],
204
+ description: "Data endpoint (testnet or mainnet)",
205
+ },
206
+ };
207
+ ```
208
+
209
+ ## Important Rules / Guidelines
210
+
211
+ 1. **Proxy settles on forward, withX402 settles after success** -- The proxy pattern settles payment when forwarding the request. The `withX402` pattern only settles when the handler returns status < 400, protecting against paying for failed requests.
212
+ 2. **middleware.ts must be at the project root** -- Next.js only loads middleware from the root `middleware.ts` file
213
+ 3. **Use the `matcher` config** -- Always specify which routes the middleware should intercept to avoid processing static files and other non-API routes
214
+ 4. **Route patterns use `*` wildcard** -- `"GET /api/premium/*"` matches all sub-paths under `/api/premium/`
215
+ 5. **Share server instances** -- Create `lib/x402.ts` with shared `x402Server` and `PAY_TO` to avoid duplicating setup across route files
216
+ 6. **Register the AVM scheme** -- Call `registerExactAvmScheme()` on the server before use
217
+ 7. **Price uses dollar notation** -- Use `"$0.01"` format for human-readable pricing; the SDK converts to atomic units
218
+ 8. **Free routes** -- Either exclude them from the middleware matcher or do not wrap them with `withX402`
219
+
220
+ ## Pattern Comparison
221
+
222
+ | Criteria | Proxy (middleware.ts) | withX402 (route.ts) |
223
+ |----------|----------------------|---------------------|
224
+ | Setup complexity | Single file | Per-route setup |
225
+ | Route configuration | Centralized | Distributed |
226
+ | Settlement guarantee | Settles on proxy forward | Settles after handler success |
227
+ | Error handling | Proxy-level | Handler-level |
228
+ | Handler changes | None required | Wrap each export |
229
+ | Multiple methods | Via route patterns | Per-method wrapping |
230
+ | Best for | Multi-route APIs | Individual endpoints |
231
+
232
+ ## Common Errors / Troubleshooting
233
+
234
+ | Error | Cause | Solution |
235
+ |-------|-------|----------|
236
+ | Middleware not running | `middleware.ts` not at project root | Move to project root directory |
237
+ | Static files returning 402 | Matcher too broad | Restrict `matcher` to `/api/:path*` or specific paths |
238
+ | `PAY_TO` undefined | Missing env variable | Add `PAY_TO` to `.env.local` |
239
+ | `No scheme registered` | Missing AVM scheme registration | Call `registerExactAvmScheme(server)` |
240
+ | Payment settled on 500 error | Using proxy pattern | Switch to `withX402` for endpoints that can fail |
241
+ | Route not matched | Wrong route pattern | Verify pattern matches Next.js route structure |
242
+ | Cross-origin issues | CORS not configured | Add CORS headers in middleware or `next.config.js` |
243
+ | `FACILITATOR_URL` not set | Missing facilitator config | Set `FACILITATOR_URL` env variable or use default |
244
+
245
+ ## References / Further Reading
246
+
247
+ - [create-typescript-x402-nextjs-reference.md](./create-typescript-x402-nextjs-reference.md) - Full API reference for @x402-avm/next
248
+ - [create-typescript-x402-nextjs-examples.md](./create-typescript-x402-nextjs-examples.md) - Complete code examples
249
+ - [x402-avm Next.js Examples](https://github.com/GoPlausible/x402-avm/tree/branch-v2-algorand-publish/examples/)
250
+ - [x402-avm Documentation](https://github.com/GoPlausible/.github/blob/main/profile/algorand-x402-documentation/)
251
+ - [Next.js Middleware Documentation](https://nextjs.org/docs/app/building-your-application/routing/middleware)