@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,1181 @@
1
+ # @x402-avm/next Examples
2
+
3
+ ## Installation
4
+
5
+ ```bash
6
+ npm install @x402-avm/next @x402-avm/avm @x402-avm/core
7
+ ```
8
+
9
+ For paywall UI support:
10
+
11
+ ```bash
12
+ npm install @x402-avm/next @x402-avm/avm @x402-avm/core @x402-avm/paywall
13
+ ```
14
+
15
+ ---
16
+
17
+ ## paymentProxyFromConfig
18
+
19
+ ### middleware.ts
20
+
21
+ ```typescript
22
+ import { NextRequest } from "next/server";
23
+ import { paymentProxyFromConfig } from "@x402-avm/next";
24
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
25
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
26
+
27
+ const PAY_TO = process.env.PAY_TO!;
28
+
29
+ const routes = {
30
+ "GET /api/weather": {
31
+ accepts: {
32
+ scheme: "exact",
33
+ network: ALGORAND_TESTNET_CAIP2,
34
+ payTo: PAY_TO,
35
+ price: "$0.01",
36
+ },
37
+ description: "Weather data",
38
+ },
39
+ "GET /api/premium/*": {
40
+ accepts: {
41
+ scheme: "exact",
42
+ network: ALGORAND_TESTNET_CAIP2,
43
+ payTo: PAY_TO,
44
+ price: "$0.10",
45
+ },
46
+ description: "Premium API endpoints",
47
+ },
48
+ };
49
+
50
+ const facilitatorClient = new HTTPFacilitatorClient();
51
+
52
+ const proxy = paymentProxyFromConfig(routes, facilitatorClient);
53
+
54
+ export async function middleware(request: NextRequest) {
55
+ return proxy(request);
56
+ }
57
+
58
+ export const config = {
59
+ matcher: "/api/:path*",
60
+ };
61
+ ```
62
+
63
+ ### app/api/weather/route.ts
64
+
65
+ ```typescript
66
+ import { NextResponse } from "next/server";
67
+
68
+ export async function GET() {
69
+ return NextResponse.json({
70
+ temperature: 72,
71
+ condition: "sunny",
72
+ city: "San Francisco",
73
+ });
74
+ }
75
+ ```
76
+
77
+ ### app/api/premium/data/route.ts
78
+
79
+ ```typescript
80
+ import { NextResponse } from "next/server";
81
+
82
+ export async function GET() {
83
+ return NextResponse.json({
84
+ data: "premium content",
85
+ tier: "gold",
86
+ });
87
+ }
88
+ ```
89
+
90
+ ---
91
+
92
+ ## paymentProxy
93
+
94
+ ### middleware.ts
95
+
96
+ ```typescript
97
+ import { NextRequest } from "next/server";
98
+ import { paymentProxy, x402ResourceServer } from "@x402-avm/next";
99
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
100
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
101
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
102
+
103
+ const PAY_TO = process.env.PAY_TO!;
104
+
105
+ const facilitatorClient = new HTTPFacilitatorClient({
106
+ url: process.env.FACILITATOR_URL || "https://x402.org/facilitator",
107
+ });
108
+
109
+ const server = new x402ResourceServer(facilitatorClient);
110
+ registerExactAvmScheme(server);
111
+
112
+ const routes = {
113
+ "GET /api/weather/:city": {
114
+ accepts: {
115
+ scheme: "exact",
116
+ network: ALGORAND_TESTNET_CAIP2,
117
+ payTo: PAY_TO,
118
+ price: "$0.01",
119
+ },
120
+ description: "City weather data",
121
+ },
122
+ "POST /api/generate": {
123
+ accepts: {
124
+ scheme: "exact",
125
+ network: ALGORAND_TESTNET_CAIP2,
126
+ payTo: PAY_TO,
127
+ price: "$1.00",
128
+ },
129
+ description: "AI content generation",
130
+ },
131
+ };
132
+
133
+ const proxy = paymentProxy(routes, server);
134
+
135
+ export async function middleware(request: NextRequest) {
136
+ return proxy(request);
137
+ }
138
+
139
+ export const config = {
140
+ matcher: "/api/:path*",
141
+ };
142
+ ```
143
+
144
+ ---
145
+
146
+ ## paymentProxyFromHTTPServer
147
+
148
+ ### middleware.ts
149
+
150
+ ```typescript
151
+ import { NextRequest } from "next/server";
152
+ import {
153
+ paymentProxyFromHTTPServer,
154
+ x402ResourceServer,
155
+ x402HTTPResourceServer,
156
+ } from "@x402-avm/next";
157
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
158
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
159
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
160
+
161
+ const PAY_TO = process.env.PAY_TO!;
162
+
163
+ const facilitatorClient = new HTTPFacilitatorClient();
164
+ const resourceServer = new x402ResourceServer(facilitatorClient);
165
+ registerExactAvmScheme(resourceServer);
166
+
167
+ const routes = {
168
+ "GET /api/data": {
169
+ accepts: {
170
+ scheme: "exact",
171
+ network: ALGORAND_TESTNET_CAIP2,
172
+ payTo: PAY_TO,
173
+ price: "$0.05",
174
+ },
175
+ description: "Protected data",
176
+ },
177
+ };
178
+
179
+ const httpServer = new x402HTTPResourceServer(resourceServer, routes);
180
+
181
+ httpServer.onProtectedRequest(async (context, routeConfig) => {
182
+ const authToken = context.adapter.getHeader("authorization");
183
+
184
+ if (authToken && await verifyToken(authToken)) {
185
+ return { grantAccess: true };
186
+ }
187
+
188
+ const clientIP = context.adapter.getHeader("x-forwarded-for");
189
+ if (clientIP && isRateLimited(clientIP)) {
190
+ return { abort: true, reason: "Rate limited" };
191
+ }
192
+
193
+ return undefined;
194
+ });
195
+
196
+ const proxy = paymentProxyFromHTTPServer(httpServer);
197
+
198
+ export async function middleware(request: NextRequest) {
199
+ return proxy(request);
200
+ }
201
+
202
+ export const config = {
203
+ matcher: "/api/:path*",
204
+ };
205
+
206
+ async function verifyToken(token: string): Promise<boolean> {
207
+ return token.startsWith("Bearer valid-");
208
+ }
209
+
210
+ function isRateLimited(ip: string): boolean {
211
+ return false;
212
+ }
213
+ ```
214
+
215
+ ---
216
+
217
+ ## withX402
218
+
219
+ ### app/api/weather/route.ts
220
+
221
+ ```typescript
222
+ import { NextRequest, NextResponse } from "next/server";
223
+ import { withX402, x402ResourceServer } from "@x402-avm/next";
224
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
225
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
226
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
227
+
228
+ const facilitatorClient = new HTTPFacilitatorClient();
229
+ const server = new x402ResourceServer(facilitatorClient);
230
+ registerExactAvmScheme(server);
231
+
232
+ const routeConfig = {
233
+ accepts: {
234
+ scheme: "exact",
235
+ network: ALGORAND_TESTNET_CAIP2,
236
+ payTo: process.env.PAY_TO!,
237
+ price: "$0.01",
238
+ },
239
+ description: "Weather data",
240
+ };
241
+
242
+ async function handler(request: NextRequest) {
243
+ return NextResponse.json({
244
+ temperature: 72,
245
+ condition: "sunny",
246
+ city: "San Francisco",
247
+ timestamp: new Date().toISOString(),
248
+ });
249
+ }
250
+
251
+ export const GET = withX402(handler, routeConfig, server);
252
+ ```
253
+
254
+ ---
255
+
256
+ ## Shared Config Module (lib/x402.ts)
257
+
258
+ ### lib/x402.ts
259
+
260
+ ```typescript
261
+ import { x402ResourceServer } from "@x402-avm/next";
262
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
263
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
264
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
265
+
266
+ const facilitatorClient = new HTTPFacilitatorClient({
267
+ url: process.env.FACILITATOR_URL || "https://x402.org/facilitator",
268
+ });
269
+
270
+ export const x402Server = new x402ResourceServer(facilitatorClient);
271
+ registerExactAvmScheme(x402Server);
272
+
273
+ export const PAY_TO = process.env.PAY_TO!;
274
+ export const NETWORK = ALGORAND_TESTNET_CAIP2;
275
+ ```
276
+
277
+ ### app/api/weather/route.ts
278
+
279
+ ```typescript
280
+ import { NextRequest, NextResponse } from "next/server";
281
+ import { withX402 } from "@x402-avm/next";
282
+ import { x402Server, PAY_TO, NETWORK } from "@/lib/x402";
283
+
284
+ const handler = async (request: NextRequest) => {
285
+ return NextResponse.json({
286
+ temperature: 72,
287
+ condition: "sunny",
288
+ });
289
+ };
290
+
291
+ export const GET = withX402(handler, {
292
+ accepts: {
293
+ scheme: "exact",
294
+ network: NETWORK,
295
+ payTo: PAY_TO,
296
+ price: "$0.01",
297
+ },
298
+ description: "Weather data",
299
+ }, x402Server);
300
+ ```
301
+
302
+ ### app/api/premium/route.ts
303
+
304
+ ```typescript
305
+ import { NextRequest, NextResponse } from "next/server";
306
+ import { withX402 } from "@x402-avm/next";
307
+ import { x402Server, PAY_TO, NETWORK } from "@/lib/x402";
308
+
309
+ const handler = async (request: NextRequest) => {
310
+ return NextResponse.json({
311
+ data: "premium content",
312
+ tier: "gold",
313
+ });
314
+ };
315
+
316
+ export const GET = withX402(handler, {
317
+ accepts: {
318
+ scheme: "exact",
319
+ network: NETWORK,
320
+ payTo: PAY_TO,
321
+ price: "$0.50",
322
+ },
323
+ description: "Premium content",
324
+ }, x402Server);
325
+ ```
326
+
327
+ ### app/api/generate/route.ts
328
+
329
+ ```typescript
330
+ import { NextRequest, NextResponse } from "next/server";
331
+ import { withX402 } from "@x402-avm/next";
332
+ import { x402Server, PAY_TO, NETWORK } from "@/lib/x402";
333
+
334
+ const handler = async (request: NextRequest) => {
335
+ const { prompt } = await request.json();
336
+
337
+ try {
338
+ const result = await generateContent(prompt);
339
+ return NextResponse.json({ prompt, result });
340
+ } catch (error) {
341
+ return NextResponse.json(
342
+ { error: "Generation failed" },
343
+ { status: 500 },
344
+ );
345
+ }
346
+ };
347
+
348
+ export const POST = withX402(handler, {
349
+ accepts: {
350
+ scheme: "exact",
351
+ network: NETWORK,
352
+ payTo: PAY_TO,
353
+ price: "$1.00",
354
+ },
355
+ description: "AI generation",
356
+ }, x402Server);
357
+
358
+ async function generateContent(prompt: string): Promise<string> {
359
+ return "Generated content...";
360
+ }
361
+ ```
362
+
363
+ ---
364
+
365
+ ## withX402FromHTTPServer
366
+
367
+ ### app/api/data/route.ts
368
+
369
+ ```typescript
370
+ import { NextRequest, NextResponse } from "next/server";
371
+ import {
372
+ withX402FromHTTPServer,
373
+ x402ResourceServer,
374
+ x402HTTPResourceServer,
375
+ } from "@x402-avm/next";
376
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
377
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
378
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
379
+
380
+ const facilitatorClient = new HTTPFacilitatorClient();
381
+ const resourceServer = new x402ResourceServer(facilitatorClient);
382
+ registerExactAvmScheme(resourceServer);
383
+
384
+ const routeConfig = {
385
+ accepts: {
386
+ scheme: "exact",
387
+ network: ALGORAND_TESTNET_CAIP2,
388
+ payTo: process.env.PAY_TO!,
389
+ price: "$0.05",
390
+ },
391
+ description: "Protected data",
392
+ };
393
+
394
+ const httpServer = new x402HTTPResourceServer(resourceServer, {
395
+ "*": routeConfig,
396
+ });
397
+
398
+ httpServer.onProtectedRequest(async (context, config) => {
399
+ console.log(`Payment request: ${context.method} ${context.path}`);
400
+ return undefined;
401
+ });
402
+
403
+ const handler = async (request: NextRequest) => {
404
+ return NextResponse.json({ data: "protected content" });
405
+ };
406
+
407
+ export const GET = withX402FromHTTPServer(handler, httpServer);
408
+ ```
409
+
410
+ ---
411
+
412
+ ## Protected Page Route (HTML)
413
+
414
+ ### middleware.ts
415
+
416
+ ```typescript
417
+ import { NextRequest } from "next/server";
418
+ import { paymentProxyFromConfig } from "@x402-avm/next";
419
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
420
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
421
+
422
+ const routes = {
423
+ "GET /premium-article": {
424
+ accepts: {
425
+ scheme: "exact",
426
+ network: ALGORAND_TESTNET_CAIP2,
427
+ payTo: process.env.PAY_TO!,
428
+ price: "$0.25",
429
+ },
430
+ description: "Premium article",
431
+ mimeType: "text/html",
432
+ },
433
+ "GET /api/data/*": {
434
+ accepts: {
435
+ scheme: "exact",
436
+ network: ALGORAND_TESTNET_CAIP2,
437
+ payTo: process.env.PAY_TO!,
438
+ price: "$0.01",
439
+ },
440
+ description: "Data API",
441
+ },
442
+ };
443
+
444
+ const proxy = paymentProxyFromConfig(routes, new HTTPFacilitatorClient());
445
+
446
+ export async function middleware(request: NextRequest) {
447
+ return proxy(request);
448
+ }
449
+
450
+ export const config = {
451
+ matcher: ["/premium-article", "/api/data/:path*"],
452
+ };
453
+ ```
454
+
455
+ ### app/premium-article/page.tsx
456
+
457
+ ```tsx
458
+ export default function PremiumArticlePage() {
459
+ return (
460
+ <article>
461
+ <h1>Premium Article</h1>
462
+ <p>This content is only accessible after payment.</p>
463
+ <p>Full article text here...</p>
464
+ </article>
465
+ );
466
+ }
467
+ ```
468
+
469
+ ---
470
+
471
+ ## Protecting Multiple HTTP Methods
472
+
473
+ ### app/api/resource/route.ts
474
+
475
+ ```typescript
476
+ import { NextRequest, NextResponse } from "next/server";
477
+ import { withX402 } from "@x402-avm/next";
478
+ import { x402Server, PAY_TO, NETWORK } from "@/lib/x402";
479
+
480
+ const routeConfig = {
481
+ accepts: {
482
+ scheme: "exact",
483
+ network: NETWORK,
484
+ payTo: PAY_TO,
485
+ price: "$0.05",
486
+ },
487
+ description: "Resource CRUD",
488
+ };
489
+
490
+ const getHandler = async (request: NextRequest) => {
491
+ return NextResponse.json({ resource: "data", method: "GET" });
492
+ };
493
+
494
+ const postHandler = async (request: NextRequest) => {
495
+ const body = await request.json();
496
+ return NextResponse.json({ created: true, resource: body });
497
+ };
498
+
499
+ const putHandler = async (request: NextRequest) => {
500
+ const body = await request.json();
501
+ return NextResponse.json({ updated: true, resource: body });
502
+ };
503
+
504
+ export const GET = withX402(getHandler, routeConfig, x402Server);
505
+ export const POST = withX402(postHandler, routeConfig, x402Server);
506
+ export const PUT = withX402(putHandler, {
507
+ accepts: {
508
+ scheme: "exact",
509
+ network: NETWORK,
510
+ payTo: PAY_TO,
511
+ price: "$0.10",
512
+ },
513
+ description: "Resource update",
514
+ }, x402Server);
515
+ ```
516
+
517
+ ---
518
+
519
+ ## Conditional Payment (Free Tier + Paid Tier)
520
+
521
+ ### app/api/search/route.ts
522
+
523
+ ```typescript
524
+ import { NextRequest, NextResponse } from "next/server";
525
+ import {
526
+ withX402FromHTTPServer,
527
+ x402ResourceServer,
528
+ x402HTTPResourceServer,
529
+ } from "@x402-avm/next";
530
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
531
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
532
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
533
+
534
+ const facilitatorClient = new HTTPFacilitatorClient();
535
+ const resourceServer = new x402ResourceServer(facilitatorClient);
536
+ registerExactAvmScheme(resourceServer);
537
+
538
+ const httpServer = new x402HTTPResourceServer(resourceServer, {
539
+ "*": {
540
+ accepts: {
541
+ scheme: "exact",
542
+ network: ALGORAND_TESTNET_CAIP2,
543
+ payTo: process.env.PAY_TO!,
544
+ price: "$0.05",
545
+ },
546
+ description: "Search API",
547
+ },
548
+ });
549
+
550
+ httpServer.onProtectedRequest(async (context) => {
551
+ const limit = context.adapter.getQueryParam("limit");
552
+ if (limit && parseInt(limit) <= 10) {
553
+ return { grantAccess: true };
554
+ }
555
+ return undefined;
556
+ });
557
+
558
+ const handler = async (request: NextRequest) => {
559
+ const { searchParams } = new URL(request.url);
560
+ const query = searchParams.get("q") || "";
561
+ const limit = parseInt(searchParams.get("limit") || "100");
562
+
563
+ const results = await performSearch(query, limit);
564
+ return NextResponse.json({ query, results, count: results.length });
565
+ };
566
+
567
+ export const GET = withX402FromHTTPServer(handler, httpServer);
568
+
569
+ async function performSearch(query: string, limit: number) {
570
+ return Array.from({ length: Math.min(limit, 50) }, (_, i) => ({
571
+ id: i,
572
+ title: `Result ${i + 1} for "${query}"`,
573
+ }));
574
+ }
575
+ ```
576
+
577
+ ---
578
+
579
+ ## Dynamic Routes with Payment
580
+
581
+ ### middleware.ts
582
+
583
+ ```typescript
584
+ import { NextRequest } from "next/server";
585
+ import { paymentProxyFromConfig } from "@x402-avm/next";
586
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
587
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
588
+
589
+ const PAY_TO = process.env.PAY_TO!;
590
+
591
+ const routes = {
592
+ "GET /api/users/*": {
593
+ accepts: {
594
+ scheme: "exact",
595
+ network: ALGORAND_TESTNET_CAIP2,
596
+ payTo: PAY_TO,
597
+ price: "$0.01",
598
+ },
599
+ description: "User profile data",
600
+ },
601
+ "GET /api/reports/*": {
602
+ accepts: {
603
+ scheme: "exact",
604
+ network: ALGORAND_TESTNET_CAIP2,
605
+ payTo: PAY_TO,
606
+ price: "$0.25",
607
+ },
608
+ description: "Monthly report",
609
+ },
610
+ };
611
+
612
+ const proxy = paymentProxyFromConfig(routes, new HTTPFacilitatorClient());
613
+
614
+ export async function middleware(request: NextRequest) {
615
+ return proxy(request);
616
+ }
617
+
618
+ export const config = {
619
+ matcher: ["/api/users/:path*", "/api/reports/:path*"],
620
+ };
621
+ ```
622
+
623
+ ### app/api/users/[id]/route.ts
624
+
625
+ ```typescript
626
+ import { NextResponse } from "next/server";
627
+
628
+ export async function GET(
629
+ request: Request,
630
+ { params }: { params: { id: string } },
631
+ ) {
632
+ const user = await fetchUser(params.id);
633
+ if (!user) {
634
+ return NextResponse.json({ error: "User not found" }, { status: 404 });
635
+ }
636
+ return NextResponse.json(user);
637
+ }
638
+
639
+ async function fetchUser(id: string) {
640
+ return { id, name: "Alice", email: "alice@example.com" };
641
+ }
642
+ ```
643
+
644
+ ### app/api/reports/[year]/[month]/route.ts
645
+
646
+ ```typescript
647
+ import { NextResponse } from "next/server";
648
+
649
+ export async function GET(
650
+ request: Request,
651
+ { params }: { params: { year: string; month: string } },
652
+ ) {
653
+ return NextResponse.json({
654
+ year: params.year,
655
+ month: params.month,
656
+ data: "Monthly report data...",
657
+ });
658
+ }
659
+ ```
660
+
661
+ ---
662
+
663
+ ## Paywall with Proxy Pattern
664
+
665
+ ### middleware.ts
666
+
667
+ ```typescript
668
+ import { NextRequest } from "next/server";
669
+ import { paymentProxy, x402ResourceServer } from "@x402-avm/next";
670
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
671
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
672
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
673
+
674
+ const facilitatorClient = new HTTPFacilitatorClient();
675
+ const server = new x402ResourceServer(facilitatorClient);
676
+ registerExactAvmScheme(server);
677
+
678
+ const routes = {
679
+ "GET /premium/*": {
680
+ accepts: {
681
+ scheme: "exact",
682
+ network: ALGORAND_TESTNET_CAIP2,
683
+ payTo: process.env.PAY_TO!,
684
+ price: "$0.25",
685
+ },
686
+ description: "Premium content",
687
+ mimeType: "text/html",
688
+ },
689
+ };
690
+
691
+ const paywallConfig = {
692
+ title: "Premium Content",
693
+ description: "Pay with Algorand to unlock this content",
694
+ logoUrl: "/logo.png",
695
+ };
696
+
697
+ const proxy = paymentProxy(routes, server, paywallConfig);
698
+
699
+ export async function middleware(request: NextRequest) {
700
+ return proxy(request);
701
+ }
702
+
703
+ export const config = {
704
+ matcher: "/premium/:path*",
705
+ };
706
+ ```
707
+
708
+ ---
709
+
710
+ ## Custom Paywall HTML
711
+
712
+ ```typescript
713
+ const routes = {
714
+ "GET /premium/article": {
715
+ accepts: {
716
+ scheme: "exact",
717
+ network: ALGORAND_TESTNET_CAIP2,
718
+ payTo: process.env.PAY_TO!,
719
+ price: "$0.25",
720
+ },
721
+ description: "Premium article",
722
+ customPaywallHtml: `
723
+ <!DOCTYPE html>
724
+ <html>
725
+ <head>
726
+ <title>Payment Required</title>
727
+ <style>
728
+ body { font-family: sans-serif; max-width: 600px; margin: 50px auto; }
729
+ .price { font-size: 2em; color: #6366f1; }
730
+ </style>
731
+ </head>
732
+ <body>
733
+ <h1>Premium Article</h1>
734
+ <p class="price">$0.25</p>
735
+ <p>Pay with your Algorand wallet to read this article.</p>
736
+ <p>Supported wallets: Pera, Defly, Kibisis</p>
737
+ </body>
738
+ </html>
739
+ `,
740
+ },
741
+ };
742
+ ```
743
+
744
+ ---
745
+
746
+ ## Unpaid Response Body (for API Clients)
747
+
748
+ ```typescript
749
+ const routes = {
750
+ "GET /api/article/:id": {
751
+ accepts: {
752
+ scheme: "exact",
753
+ network: ALGORAND_TESTNET_CAIP2,
754
+ payTo: process.env.PAY_TO!,
755
+ price: "$0.10",
756
+ },
757
+ description: "Full article",
758
+ unpaidResponseBody: (context) => ({
759
+ contentType: "application/json",
760
+ body: {
761
+ title: "Article Preview",
762
+ preview: "First paragraph of the article...",
763
+ fullArticle: false,
764
+ paymentRequired: {
765
+ price: "$0.10",
766
+ network: "Algorand Testnet",
767
+ },
768
+ },
769
+ }),
770
+ },
771
+ };
772
+ ```
773
+
774
+ ---
775
+
776
+ ## Multiple Networks (Testnet and Mainnet)
777
+
778
+ ```typescript
779
+ import {
780
+ ALGORAND_TESTNET_CAIP2,
781
+ ALGORAND_MAINNET_CAIP2,
782
+ } from "@x402-avm/avm";
783
+
784
+ const routes = {
785
+ "GET /api/data": {
786
+ accepts: [
787
+ {
788
+ scheme: "exact",
789
+ network: ALGORAND_TESTNET_CAIP2,
790
+ payTo: "YOUR_TESTNET_ADDRESS",
791
+ price: "$0.01",
792
+ },
793
+ {
794
+ scheme: "exact",
795
+ network: ALGORAND_MAINNET_CAIP2,
796
+ payTo: "YOUR_MAINNET_ADDRESS",
797
+ price: "$0.01",
798
+ },
799
+ ],
800
+ description: "Data endpoint (testnet or mainnet)",
801
+ },
802
+ };
803
+ ```
804
+
805
+ ---
806
+
807
+ ## Cross-Chain: Algorand + EVM
808
+
809
+ ```typescript
810
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
811
+
812
+ const routes = {
813
+ "GET /api/data": {
814
+ accepts: [
815
+ {
816
+ scheme: "exact",
817
+ network: ALGORAND_TESTNET_CAIP2,
818
+ payTo: "YOUR_ALGORAND_ADDRESS",
819
+ price: "$0.01",
820
+ },
821
+ {
822
+ scheme: "exact",
823
+ network: "eip155:84532",
824
+ payTo: "0xYourEvmAddress",
825
+ price: "$0.01",
826
+ },
827
+ ],
828
+ description: "Cross-chain: ALGO or ETH",
829
+ },
830
+ };
831
+ ```
832
+
833
+ ---
834
+
835
+ ## USDC Payments
836
+
837
+ ```typescript
838
+ import {
839
+ ALGORAND_TESTNET_CAIP2,
840
+ USDC_TESTNET_ASA_ID,
841
+ } from "@x402-avm/avm";
842
+
843
+ const routes = {
844
+ "GET /api/premium": {
845
+ accepts: {
846
+ scheme: "exact",
847
+ network: ALGORAND_TESTNET_CAIP2,
848
+ payTo: "YOUR_ALGORAND_ADDRESS",
849
+ price: "$5.00",
850
+ extra: {
851
+ asset: USDC_TESTNET_ASA_ID,
852
+ },
853
+ },
854
+ description: "Premium (USDC only)",
855
+ },
856
+ };
857
+ ```
858
+
859
+ ---
860
+
861
+ ## Complete App: Proxy Pattern
862
+
863
+ ### Project Structure
864
+
865
+ ```
866
+ my-x402-app/
867
+ .env.local
868
+ middleware.ts
869
+ app/
870
+ page.tsx
871
+ api/
872
+ health/route.ts
873
+ weather/[city]/route.ts
874
+ premium/data/route.ts
875
+ generate/route.ts
876
+ lib/
877
+ x402.ts
878
+ ```
879
+
880
+ ### .env.local
881
+
882
+ ```bash
883
+ PAY_TO=ALGORAND_ADDRESS_HERE_58_CHARS
884
+ FACILITATOR_URL=https://x402.org/facilitator
885
+ ```
886
+
887
+ ### lib/x402.ts
888
+
889
+ ```typescript
890
+ import { x402ResourceServer } from "@x402-avm/next";
891
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
892
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
893
+
894
+ export const PAY_TO = process.env.PAY_TO!;
895
+
896
+ const facilitatorClient = new HTTPFacilitatorClient({
897
+ url: process.env.FACILITATOR_URL || "https://x402.org/facilitator",
898
+ });
899
+
900
+ export const x402Server = new x402ResourceServer(facilitatorClient);
901
+ registerExactAvmScheme(x402Server);
902
+ ```
903
+
904
+ ### middleware.ts
905
+
906
+ ```typescript
907
+ import { NextRequest } from "next/server";
908
+ import { paymentProxy } from "@x402-avm/next";
909
+ import { x402Server, PAY_TO } from "@/lib/x402";
910
+ import {
911
+ ALGORAND_TESTNET_CAIP2,
912
+ USDC_TESTNET_ASA_ID,
913
+ } from "@x402-avm/avm";
914
+
915
+ const routes = {
916
+ "GET /api/weather/*": {
917
+ accepts: {
918
+ scheme: "exact",
919
+ network: ALGORAND_TESTNET_CAIP2,
920
+ payTo: PAY_TO,
921
+ price: "$0.01",
922
+ },
923
+ description: "Weather data",
924
+ unpaidResponseBody: () => ({
925
+ contentType: "application/json",
926
+ body: { message: "Pay $0.01 for weather data" },
927
+ }),
928
+ },
929
+ "GET /api/premium/*": {
930
+ accepts: {
931
+ scheme: "exact",
932
+ network: ALGORAND_TESTNET_CAIP2,
933
+ payTo: PAY_TO,
934
+ price: "$0.50",
935
+ extra: { asset: USDC_TESTNET_ASA_ID },
936
+ },
937
+ description: "Premium content (USDC)",
938
+ },
939
+ "POST /api/generate": {
940
+ accepts: {
941
+ scheme: "exact",
942
+ network: ALGORAND_TESTNET_CAIP2,
943
+ payTo: PAY_TO,
944
+ price: "$1.00",
945
+ },
946
+ description: "AI generation",
947
+ },
948
+ };
949
+
950
+ const paywallConfig = {
951
+ title: "x402-avm Demo",
952
+ description: "Pay with Algorand to access premium features",
953
+ };
954
+
955
+ const proxy = paymentProxy(routes, x402Server, paywallConfig);
956
+
957
+ export async function middleware(request: NextRequest) {
958
+ return proxy(request);
959
+ }
960
+
961
+ export const config = {
962
+ matcher: "/api/:path*",
963
+ };
964
+ ```
965
+
966
+ ### app/api/weather/[city]/route.ts
967
+
968
+ ```typescript
969
+ import { NextResponse } from "next/server";
970
+
971
+ export async function GET(
972
+ request: Request,
973
+ { params }: { params: { city: string } },
974
+ ) {
975
+ return NextResponse.json({
976
+ city: params.city,
977
+ temperature: Math.floor(Math.random() * 40) + 50,
978
+ condition: ["sunny", "cloudy", "rainy"][Math.floor(Math.random() * 3)],
979
+ humidity: Math.floor(Math.random() * 60) + 30,
980
+ });
981
+ }
982
+ ```
983
+
984
+ ### app/api/premium/data/route.ts
985
+
986
+ ```typescript
987
+ import { NextResponse } from "next/server";
988
+
989
+ export async function GET() {
990
+ return NextResponse.json({
991
+ analytics: {
992
+ pageViews: 15420,
993
+ uniqueVisitors: 8734,
994
+ bounceRate: 0.32,
995
+ },
996
+ });
997
+ }
998
+ ```
999
+
1000
+ ### app/api/generate/route.ts
1001
+
1002
+ ```typescript
1003
+ import { NextRequest, NextResponse } from "next/server";
1004
+
1005
+ export async function POST(request: NextRequest) {
1006
+ const { prompt } = await request.json();
1007
+ return NextResponse.json({
1008
+ prompt,
1009
+ generated: "AI-generated content...",
1010
+ model: "gpt-4",
1011
+ tokens: 256,
1012
+ });
1013
+ }
1014
+ ```
1015
+
1016
+ ### app/api/health/route.ts
1017
+
1018
+ ```typescript
1019
+ import { NextResponse } from "next/server";
1020
+
1021
+ export async function GET() {
1022
+ return NextResponse.json({ status: "healthy" });
1023
+ }
1024
+ ```
1025
+
1026
+ ### app/page.tsx
1027
+
1028
+ ```tsx
1029
+ export default function Home() {
1030
+ return (
1031
+ <main>
1032
+ <h1>x402-avm Next.js Demo</h1>
1033
+ <p>API Endpoints:</p>
1034
+ <ul>
1035
+ <li>GET /api/weather/:city -- $0.01 ALGO</li>
1036
+ <li>GET /api/premium/data -- $0.50 USDC</li>
1037
+ <li>POST /api/generate -- $1.00 ALGO</li>
1038
+ <li>GET /api/health -- Free</li>
1039
+ </ul>
1040
+ </main>
1041
+ );
1042
+ }
1043
+ ```
1044
+
1045
+ ---
1046
+
1047
+ ## Complete App: Route Handler Pattern
1048
+
1049
+ ### Project Structure
1050
+
1051
+ ```
1052
+ my-x402-app/
1053
+ .env.local
1054
+ app/
1055
+ page.tsx
1056
+ api/
1057
+ health/route.ts
1058
+ weather/route.ts
1059
+ premium/route.ts
1060
+ generate/route.ts
1061
+ lib/
1062
+ x402.ts
1063
+ ```
1064
+
1065
+ ### lib/x402.ts
1066
+
1067
+ ```typescript
1068
+ import { x402ResourceServer } from "@x402-avm/next";
1069
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
1070
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
1071
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
1072
+
1073
+ export const PAY_TO = process.env.PAY_TO!;
1074
+ export const NETWORK = ALGORAND_TESTNET_CAIP2;
1075
+
1076
+ const facilitatorClient = new HTTPFacilitatorClient({
1077
+ url: process.env.FACILITATOR_URL || "https://x402.org/facilitator",
1078
+ });
1079
+
1080
+ export const x402Server = new x402ResourceServer(facilitatorClient);
1081
+ registerExactAvmScheme(x402Server);
1082
+ ```
1083
+
1084
+ ### app/api/weather/route.ts
1085
+
1086
+ ```typescript
1087
+ import { NextRequest, NextResponse } from "next/server";
1088
+ import { withX402 } from "@x402-avm/next";
1089
+ import { x402Server, PAY_TO, NETWORK } from "@/lib/x402";
1090
+
1091
+ const handler = async (request: NextRequest) => {
1092
+ const city = request.nextUrl.searchParams.get("city") || "san-francisco";
1093
+ return NextResponse.json({
1094
+ city,
1095
+ temperature: 72,
1096
+ condition: "sunny",
1097
+ });
1098
+ };
1099
+
1100
+ export const GET = withX402(handler, {
1101
+ accepts: {
1102
+ scheme: "exact",
1103
+ network: NETWORK,
1104
+ payTo: PAY_TO,
1105
+ price: "$0.01",
1106
+ },
1107
+ description: "Weather data",
1108
+ }, x402Server);
1109
+ ```
1110
+
1111
+ ### app/api/premium/route.ts
1112
+
1113
+ ```typescript
1114
+ import { NextRequest, NextResponse } from "next/server";
1115
+ import { withX402 } from "@x402-avm/next";
1116
+ import { x402Server, PAY_TO, NETWORK } from "@/lib/x402";
1117
+ import { USDC_TESTNET_ASA_ID } from "@x402-avm/avm";
1118
+
1119
+ const handler = async (request: NextRequest) => {
1120
+ return NextResponse.json({
1121
+ data: "premium content",
1122
+ analytics: { views: 15000, revenue: "$1234.56" },
1123
+ });
1124
+ };
1125
+
1126
+ export const GET = withX402(handler, {
1127
+ accepts: {
1128
+ scheme: "exact",
1129
+ network: NETWORK,
1130
+ payTo: PAY_TO,
1131
+ price: "$0.50",
1132
+ extra: { asset: USDC_TESTNET_ASA_ID },
1133
+ },
1134
+ description: "Premium analytics (USDC)",
1135
+ }, x402Server);
1136
+ ```
1137
+
1138
+ ### app/api/generate/route.ts
1139
+
1140
+ ```typescript
1141
+ import { NextRequest, NextResponse } from "next/server";
1142
+ import { withX402 } from "@x402-avm/next";
1143
+ import { x402Server, PAY_TO, NETWORK } from "@/lib/x402";
1144
+
1145
+ const handler = async (request: NextRequest) => {
1146
+ try {
1147
+ const { prompt } = await request.json();
1148
+ const result = await generateContent(prompt);
1149
+ return NextResponse.json({ prompt, result });
1150
+ } catch (error) {
1151
+ return NextResponse.json(
1152
+ { error: "Generation failed" },
1153
+ { status: 500 },
1154
+ );
1155
+ }
1156
+ };
1157
+
1158
+ export const POST = withX402(handler, {
1159
+ accepts: {
1160
+ scheme: "exact",
1161
+ network: NETWORK,
1162
+ payTo: PAY_TO,
1163
+ price: "$1.00",
1164
+ },
1165
+ description: "AI generation",
1166
+ }, x402Server);
1167
+
1168
+ async function generateContent(prompt: string): Promise<string> {
1169
+ return "Generated content based on: " + prompt;
1170
+ }
1171
+ ```
1172
+
1173
+ ### app/api/health/route.ts
1174
+
1175
+ ```typescript
1176
+ import { NextResponse } from "next/server";
1177
+
1178
+ export async function GET() {
1179
+ return NextResponse.json({ status: "healthy" });
1180
+ }
1181
+ ```