@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,870 @@
1
+ # x402 Paywall Examples
2
+
3
+ ## AVM-Only Paywall
4
+
5
+ ```typescript
6
+ import { createPaywall, avmPaywall } from "@x402-avm/paywall";
7
+
8
+ const paywall = createPaywall()
9
+ .withNetwork(avmPaywall)
10
+ .withConfig({
11
+ appName: "My DApp",
12
+ appLogo: "https://example.com/logo.png",
13
+ testnet: true,
14
+ })
15
+ .build();
16
+ ```
17
+
18
+ ---
19
+
20
+ ## EVM-Only Paywall
21
+
22
+ ```typescript
23
+ import { createPaywall, evmPaywall } from "@x402-avm/paywall";
24
+
25
+ const paywall = createPaywall()
26
+ .withNetwork(evmPaywall)
27
+ .withConfig({
28
+ appName: "EVM DApp",
29
+ testnet: true,
30
+ })
31
+ .build();
32
+ ```
33
+
34
+ ---
35
+
36
+ ## Multi-Network Paywall (AVM + EVM)
37
+
38
+ ```typescript
39
+ import { createPaywall, avmPaywall, evmPaywall } from "@x402-avm/paywall";
40
+
41
+ const paywall = createPaywall()
42
+ .withNetwork(avmPaywall)
43
+ .withNetwork(evmPaywall)
44
+ .withConfig({
45
+ appName: "Multi-Chain Premium",
46
+ testnet: true,
47
+ })
48
+ .build();
49
+ ```
50
+
51
+ ---
52
+
53
+ ## Universal Paywall (AVM + EVM + SVM)
54
+
55
+ ```typescript
56
+ import { createPaywall, avmPaywall, evmPaywall, svmPaywall } from "@x402-avm/paywall";
57
+
58
+ const paywall = createPaywall()
59
+ .withNetwork(avmPaywall)
60
+ .withNetwork(evmPaywall)
61
+ .withNetwork(svmPaywall)
62
+ .withConfig({
63
+ appName: "Universal Paywall",
64
+ testnet: true,
65
+ })
66
+ .build();
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Express.js Basic Integration
72
+
73
+ ```typescript
74
+ import express from "express";
75
+ import {
76
+ paymentMiddleware,
77
+ x402ResourceServer,
78
+ } from "@x402-avm/express";
79
+ import { createPaywall, avmPaywall } from "@x402-avm/paywall";
80
+
81
+ const app = express();
82
+
83
+ const routes = {
84
+ "/api/premium-content": {
85
+ accepts: {
86
+ scheme: "exact",
87
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
88
+ asset: "10458941",
89
+ payTo: "YOUR_ALGORAND_ADDRESS_HERE",
90
+ price: "$0.01",
91
+ maxTimeoutSeconds: 300,
92
+ },
93
+ description: "Access to premium content",
94
+ mimeType: "application/json",
95
+ },
96
+ };
97
+
98
+ const paywall = createPaywall()
99
+ .withNetwork(avmPaywall)
100
+ .withConfig({
101
+ appName: "Premium API",
102
+ appLogo: "https://example.com/logo.png",
103
+ testnet: true,
104
+ })
105
+ .build();
106
+
107
+ const facilitatorUrl = process.env.FACILITATOR_URL || "https://facilitator.example.com";
108
+ const server = new x402ResourceServer({ url: facilitatorUrl });
109
+
110
+ app.use(paymentMiddleware(routes, server, { testnet: true }, paywall));
111
+
112
+ app.get("/api/premium-content", (req, res) => {
113
+ res.json({
114
+ title: "Premium Article",
115
+ content: "This is the paid content that was unlocked by your USDC payment.",
116
+ timestamp: new Date().toISOString(),
117
+ });
118
+ });
119
+
120
+ app.get("/api/free-content", (req, res) => {
121
+ res.json({ message: "This content is free!" });
122
+ });
123
+
124
+ app.listen(3000, () => {
125
+ console.log("Server running on http://localhost:3000");
126
+ });
127
+ ```
128
+
129
+ ---
130
+
131
+ ## Express.js with HTTP Resource Server and Hooks
132
+
133
+ ```typescript
134
+ import {
135
+ paymentMiddlewareFromHTTPServer,
136
+ x402ResourceServer,
137
+ x402HTTPResourceServer,
138
+ } from "@x402-avm/express";
139
+ import { createPaywall, avmPaywall } from "@x402-avm/paywall";
140
+
141
+ const resourceServer = new x402ResourceServer({ url: facilitatorUrl });
142
+
143
+ const httpServer = new x402HTTPResourceServer(resourceServer, routes)
144
+ .onProtectedRequest(async (context) => {
145
+ console.log(`[x402] Protected request: ${context.path}`);
146
+ });
147
+
148
+ const paywall = createPaywall()
149
+ .withNetwork(avmPaywall)
150
+ .withConfig({ appName: "My App", testnet: true })
151
+ .build();
152
+
153
+ app.use(paymentMiddlewareFromHTTPServer(httpServer, { testnet: true }, paywall));
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Express.js Multiple Protected Routes
159
+
160
+ ```typescript
161
+ const routes = {
162
+ "/api/weather": {
163
+ accepts: {
164
+ scheme: "exact",
165
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
166
+ asset: "10458941",
167
+ payTo: "YOUR_ADDRESS",
168
+ price: "$0.001",
169
+ maxTimeoutSeconds: 60,
170
+ },
171
+ description: "Real-time weather data",
172
+ mimeType: "application/json",
173
+ },
174
+ "/api/analytics": {
175
+ accepts: {
176
+ scheme: "exact",
177
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
178
+ asset: "10458941",
179
+ payTo: "YOUR_ADDRESS",
180
+ price: "$0.05",
181
+ maxTimeoutSeconds: 300,
182
+ },
183
+ description: "Detailed analytics report",
184
+ mimeType: "application/json",
185
+ },
186
+ "/api/ai-summary": {
187
+ accepts: {
188
+ scheme: "exact",
189
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
190
+ asset: "10458941",
191
+ payTo: "YOUR_ADDRESS",
192
+ price: "$0.10",
193
+ maxTimeoutSeconds: 600,
194
+ },
195
+ description: "AI-powered content summary",
196
+ mimeType: "application/json",
197
+ },
198
+ };
199
+ ```
200
+
201
+ ---
202
+
203
+ ## Hono Basic Integration
204
+
205
+ ```typescript
206
+ import { Hono } from "hono";
207
+ import { paymentMiddleware, x402ResourceServer } from "@x402-avm/hono";
208
+ import { createPaywall, avmPaywall } from "@x402-avm/paywall";
209
+
210
+ const app = new Hono();
211
+
212
+ const routes = {
213
+ "/api/premium": {
214
+ accepts: {
215
+ scheme: "exact",
216
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
217
+ asset: "10458941",
218
+ payTo: "YOUR_ALGORAND_ADDRESS",
219
+ price: "$0.01",
220
+ maxTimeoutSeconds: 300,
221
+ },
222
+ description: "Premium content access",
223
+ mimeType: "application/json",
224
+ },
225
+ };
226
+
227
+ const paywall = createPaywall()
228
+ .withNetwork(avmPaywall)
229
+ .withConfig({ appName: "Hono API", testnet: true })
230
+ .build();
231
+
232
+ const server = new x402ResourceServer({ url: process.env.FACILITATOR_URL! });
233
+
234
+ app.use("*", paymentMiddleware(routes, server, { testnet: true }, paywall));
235
+
236
+ app.get("/api/premium", (c) => {
237
+ return c.json({
238
+ content: "This is premium content, paid with USDC on Algorand!",
239
+ });
240
+ });
241
+
242
+ app.get("/", (c) => c.text("Welcome to the Hono API"));
243
+
244
+ export default app;
245
+ ```
246
+
247
+ ---
248
+
249
+ ## Hono with Cloudflare Workers
250
+
251
+ ```typescript
252
+ import { Hono } from "hono";
253
+ import { paymentMiddlewareFromConfig, x402ResourceServer } from "@x402-avm/hono";
254
+ import { createPaywall, avmPaywall } from "@x402-avm/paywall";
255
+
256
+ type Env = {
257
+ FACILITATOR_URL: string;
258
+ PAYTO_ADDRESS: string;
259
+ };
260
+
261
+ const app = new Hono<{ Bindings: Env }>();
262
+
263
+ app.use("*", async (c, next) => {
264
+ const routes = {
265
+ "/api/data": {
266
+ accepts: {
267
+ scheme: "exact",
268
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
269
+ asset: "10458941",
270
+ payTo: c.env.PAYTO_ADDRESS,
271
+ price: "$0.01",
272
+ maxTimeoutSeconds: 300,
273
+ },
274
+ description: "Paid API data",
275
+ mimeType: "application/json",
276
+ },
277
+ };
278
+
279
+ const paywall = createPaywall()
280
+ .withNetwork(avmPaywall)
281
+ .withConfig({ appName: "Worker API", testnet: true })
282
+ .build();
283
+
284
+ const server = new x402ResourceServer({ url: c.env.FACILITATOR_URL });
285
+
286
+ const middleware = paymentMiddleware(routes, server, { testnet: true }, paywall);
287
+ return middleware(c, next);
288
+ });
289
+
290
+ app.get("/api/data", (c) => {
291
+ return c.json({ data: "Premium data from Cloudflare Worker" });
292
+ });
293
+
294
+ export default app;
295
+ ```
296
+
297
+ ---
298
+
299
+ ## Next.js Middleware Approach
300
+
301
+ ```typescript
302
+ // middleware.ts
303
+ import { paymentProxy, x402ResourceServer } from "@x402-avm/next";
304
+ import { createPaywall, avmPaywall } from "@x402-avm/paywall";
305
+ import { NextRequest, NextResponse } from "next/server";
306
+
307
+ const routes = {
308
+ "/api/premium": {
309
+ accepts: {
310
+ scheme: "exact",
311
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
312
+ asset: "10458941",
313
+ payTo: process.env.PAYTO_ADDRESS!,
314
+ price: "$0.01",
315
+ maxTimeoutSeconds: 300,
316
+ },
317
+ description: "Premium API endpoint",
318
+ mimeType: "application/json",
319
+ },
320
+ };
321
+
322
+ const paywall = createPaywall()
323
+ .withNetwork(avmPaywall)
324
+ .withConfig({
325
+ appName: "Next.js App",
326
+ appLogo: "/logo.png",
327
+ testnet: true,
328
+ })
329
+ .build();
330
+
331
+ const server = new x402ResourceServer({ url: process.env.FACILITATOR_URL! });
332
+
333
+ const proxy = paymentProxy(routes, server, { testnet: true }, paywall);
334
+
335
+ export async function middleware(request: NextRequest) {
336
+ if (request.nextUrl.pathname.startsWith("/api/premium")) {
337
+ return proxy(request);
338
+ }
339
+ return NextResponse.next();
340
+ }
341
+
342
+ export const config = {
343
+ matcher: ["/api/premium/:path*"],
344
+ };
345
+ ```
346
+
347
+ ---
348
+
349
+ ## Next.js Route Handler (withX402)
350
+
351
+ ```typescript
352
+ // app/api/premium/route.ts
353
+ import { NextRequest, NextResponse } from "next/server";
354
+ import { withX402, x402ResourceServer } from "@x402-avm/next";
355
+ import { createPaywall, avmPaywall } from "@x402-avm/paywall";
356
+
357
+ const server = new x402ResourceServer({
358
+ url: process.env.FACILITATOR_URL!,
359
+ });
360
+
361
+ const paywall = createPaywall()
362
+ .withNetwork(avmPaywall)
363
+ .withConfig({ appName: "Next.js App", testnet: true })
364
+ .build();
365
+
366
+ const routeConfig = {
367
+ accepts: {
368
+ scheme: "exact",
369
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
370
+ asset: "10458941",
371
+ payTo: process.env.PAYTO_ADDRESS!,
372
+ price: "$0.01",
373
+ maxTimeoutSeconds: 300,
374
+ },
375
+ description: "Premium content",
376
+ mimeType: "application/json",
377
+ };
378
+
379
+ async function handler(request: NextRequest) {
380
+ return NextResponse.json({
381
+ content: "Premium content unlocked with Algorand USDC payment!",
382
+ timestamp: new Date().toISOString(),
383
+ });
384
+ }
385
+
386
+ export const GET = withX402(handler, routeConfig, server, { testnet: true }, paywall);
387
+ ```
388
+
389
+ ---
390
+
391
+ ## Multi-Network Server Routes
392
+
393
+ ```typescript
394
+ const routes = {
395
+ "/api/premium": {
396
+ accepts: [
397
+ {
398
+ scheme: "exact",
399
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
400
+ asset: "10458941",
401
+ payTo: "ALGO_ADDRESS_HERE",
402
+ price: "$0.01",
403
+ maxTimeoutSeconds: 300,
404
+ },
405
+ {
406
+ scheme: "exact",
407
+ network: "eip155:84532",
408
+ asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
409
+ payTo: "0xEVM_ADDRESS_HERE",
410
+ price: "$0.01",
411
+ maxTimeoutSeconds: 30,
412
+ },
413
+ ],
414
+ description: "Premium content - pay with USDC on Algorand or Base",
415
+ mimeType: "application/json",
416
+ },
417
+ };
418
+ ```
419
+
420
+ ---
421
+
422
+ ## Custom Paywall Handler
423
+
424
+ ```typescript
425
+ import type { PaywallNetworkHandler, PaymentRequirements, PaymentRequired, PaywallConfig } from "@x402-avm/paywall";
426
+
427
+ const customAvmPaywall: PaywallNetworkHandler = {
428
+ supports(requirement: PaymentRequirements): boolean {
429
+ return requirement.network.startsWith("algorand:");
430
+ },
431
+
432
+ generateHtml(
433
+ requirement: PaymentRequirements,
434
+ paymentRequired: PaymentRequired,
435
+ config: PaywallConfig,
436
+ ): string {
437
+ const amount = requirement.amount
438
+ ? parseFloat(requirement.amount) / 1_000_000
439
+ : 0;
440
+
441
+ return `
442
+ <!DOCTYPE html>
443
+ <html>
444
+ <head>
445
+ <title>${config.appName || "Payment Required"}</title>
446
+ <meta charset="utf-8" />
447
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
448
+ <style>
449
+ body {
450
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
451
+ max-width: 600px;
452
+ margin: 40px auto;
453
+ padding: 20px;
454
+ text-align: center;
455
+ }
456
+ .amount { font-size: 2em; font-weight: bold; color: #1a1a2e; }
457
+ .pay-btn {
458
+ background: #6c63ff;
459
+ color: white;
460
+ border: none;
461
+ padding: 16px 48px;
462
+ font-size: 1.1em;
463
+ border-radius: 12px;
464
+ cursor: pointer;
465
+ margin-top: 24px;
466
+ }
467
+ </style>
468
+ <script>
469
+ window.x402 = {
470
+ amount: ${amount},
471
+ paymentRequired: ${JSON.stringify(paymentRequired)},
472
+ testnet: ${config.testnet ?? true},
473
+ currentUrl: "${paymentRequired.resource?.url || config.currentUrl || ""}",
474
+ config: { chainConfig: {} },
475
+ appName: "${config.appName || ""}",
476
+ appLogo: "${config.appLogo || ""}",
477
+ };
478
+ </script>
479
+ </head>
480
+ <body>
481
+ ${config.appLogo ? `<img src="${config.appLogo}" style="width:64px;height:64px;border-radius:12px" />` : ""}
482
+ <h1>Payment Required</h1>
483
+ <p>${paymentRequired.resource?.description || "Access to premium content"}</p>
484
+ <div class="amount">$${amount.toFixed(2)} USDC</div>
485
+ <p>on Algorand ${config.testnet ? "Testnet" : "Mainnet"}</p>
486
+ <button class="pay-btn" id="payBtn">Connect Wallet & Pay</button>
487
+ </body>
488
+ </html>
489
+ `;
490
+ },
491
+ };
492
+
493
+ const paywall = createPaywall()
494
+ .withNetwork(customAvmPaywall)
495
+ .withConfig({ appName: "Custom Paywall" })
496
+ .build();
497
+ ```
498
+
499
+ ---
500
+
501
+ ## Wallet Configuration
502
+
503
+ ```typescript
504
+ import { getWallets } from "@wallet-standard/app";
505
+
506
+ const walletsApi = getWallets();
507
+ const algorandWallets = walletsApi.get().filter((wallet) => {
508
+ return "algorand:signTransaction" in wallet.features;
509
+ });
510
+ ```
511
+
512
+ ---
513
+
514
+ ## Custom Wallet Integration (Outside Paywall)
515
+
516
+ ```typescript
517
+ import { useWallet } from "@txnlab/use-wallet-react";
518
+ import { wrapFetchWithPayment, x402Client } from "@x402-avm/fetch";
519
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
520
+ import type { ClientAvmSigner } from "@x402-avm/avm";
521
+
522
+ function CustomPaymentUI() {
523
+ const { activeAccount, signTransactions } = useWallet();
524
+
525
+ async function payAndFetch(url: string) {
526
+ if (!activeAccount) throw new Error("Connect wallet first");
527
+
528
+ const signer: ClientAvmSigner = {
529
+ address: activeAccount.address,
530
+ signTransactions: async (txns, indexes) => signTransactions(txns, indexes),
531
+ };
532
+
533
+ const client = new x402Client();
534
+ registerExactAvmScheme(client, { signer });
535
+ const fetchWithPay = wrapFetchWithPayment(fetch, client);
536
+
537
+ const response = await fetchWithPay(url);
538
+ return response;
539
+ }
540
+ }
541
+ ```
542
+
543
+ ---
544
+
545
+ ## Paywall Config Override at Runtime
546
+
547
+ ```typescript
548
+ app.use(paymentMiddleware(
549
+ routes,
550
+ server,
551
+ {
552
+ testnet: process.env.NODE_ENV !== "production",
553
+ appName: process.env.APP_NAME || "My App",
554
+ },
555
+ paywall,
556
+ ));
557
+ ```
558
+
559
+ ---
560
+
561
+ ## Complete Express.js Server with AVM Paywall
562
+
563
+ ```typescript
564
+ import express from "express";
565
+ import cors from "cors";
566
+ import {
567
+ paymentMiddleware,
568
+ x402ResourceServer,
569
+ } from "@x402-avm/express";
570
+ import { createPaywall, avmPaywall } from "@x402-avm/paywall";
571
+
572
+ const app = express();
573
+ app.use(cors());
574
+ app.use(express.json());
575
+
576
+ const FACILITATOR_URL = process.env.FACILITATOR_URL || "https://facilitator.example.com";
577
+ const PAYTO_ADDRESS = process.env.PAYTO_ADDRESS || "YOUR_ALGORAND_ADDRESS";
578
+ const PORT = parseInt(process.env.PORT || "3000");
579
+ const IS_TESTNET = process.env.NODE_ENV !== "production";
580
+
581
+ const ALGORAND_TESTNET_NETWORK = "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=";
582
+ const ALGORAND_MAINNET_NETWORK = "algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=";
583
+ const USDC_TESTNET_ASA = "10458941";
584
+ const USDC_MAINNET_ASA = "31566704";
585
+
586
+ const network = IS_TESTNET ? ALGORAND_TESTNET_NETWORK : ALGORAND_MAINNET_NETWORK;
587
+ const usdcAsset = IS_TESTNET ? USDC_TESTNET_ASA : USDC_MAINNET_ASA;
588
+
589
+ const routes = {
590
+ "/api/weather": {
591
+ accepts: {
592
+ scheme: "exact",
593
+ network,
594
+ asset: usdcAsset,
595
+ payTo: PAYTO_ADDRESS,
596
+ price: "$0.001",
597
+ maxTimeoutSeconds: 60,
598
+ },
599
+ description: "Real-time weather data for any city",
600
+ mimeType: "application/json",
601
+ },
602
+ "/api/article/:id": {
603
+ accepts: {
604
+ scheme: "exact",
605
+ network,
606
+ asset: usdcAsset,
607
+ payTo: PAYTO_ADDRESS,
608
+ price: "$0.05",
609
+ maxTimeoutSeconds: 300,
610
+ },
611
+ description: "Full premium article access",
612
+ mimeType: "application/json",
613
+ },
614
+ "/api/report": {
615
+ accepts: {
616
+ scheme: "exact",
617
+ network,
618
+ asset: usdcAsset,
619
+ payTo: PAYTO_ADDRESS,
620
+ price: "$1.00",
621
+ maxTimeoutSeconds: 600,
622
+ },
623
+ description: "Comprehensive analytics report",
624
+ mimeType: "application/json",
625
+ },
626
+ };
627
+
628
+ const paywall = createPaywall()
629
+ .withNetwork(avmPaywall)
630
+ .withConfig({
631
+ appName: "Premium Data API",
632
+ appLogo: "https://example.com/api-logo.png",
633
+ testnet: IS_TESTNET,
634
+ })
635
+ .build();
636
+
637
+ const server = new x402ResourceServer({ url: FACILITATOR_URL });
638
+ app.use(paymentMiddleware(routes, server, { testnet: IS_TESTNET }, paywall));
639
+
640
+ app.get("/", (req, res) => {
641
+ res.json({
642
+ name: "Premium Data API",
643
+ endpoints: {
644
+ "/api/weather?city=London": "$0.001 USDC - Weather data",
645
+ "/api/article/:id": "$0.05 USDC - Premium articles",
646
+ "/api/report": "$1.00 USDC - Full analytics report",
647
+ },
648
+ network: IS_TESTNET ? "Algorand Testnet" : "Algorand Mainnet",
649
+ payTo: PAYTO_ADDRESS,
650
+ });
651
+ });
652
+
653
+ app.get("/api/weather", (req, res) => {
654
+ const city = req.query.city || "London";
655
+ res.json({
656
+ city,
657
+ temperature: Math.round(15 + Math.random() * 20),
658
+ humidity: Math.round(40 + Math.random() * 40),
659
+ conditions: ["Sunny", "Cloudy", "Rainy", "Windy"][Math.floor(Math.random() * 4)],
660
+ timestamp: new Date().toISOString(),
661
+ });
662
+ });
663
+
664
+ app.get("/api/article/:id", (req, res) => {
665
+ res.json({
666
+ id: req.params.id,
667
+ title: "Premium Article: Advanced Algorand Development",
668
+ content: "This is the full premium article content...",
669
+ author: "x402-avm Team",
670
+ publishedAt: new Date().toISOString(),
671
+ });
672
+ });
673
+
674
+ app.get("/api/report", (req, res) => {
675
+ res.json({
676
+ title: "Comprehensive Analytics Report",
677
+ generatedAt: new Date().toISOString(),
678
+ metrics: {
679
+ totalUsers: 15420,
680
+ activeUsers: 8932,
681
+ revenue: "$42,150",
682
+ growth: "+15.3%",
683
+ },
684
+ });
685
+ });
686
+
687
+ app.listen(PORT, () => {
688
+ console.log(`Server running on http://localhost:${PORT}`);
689
+ console.log(`Network: ${IS_TESTNET ? "Algorand Testnet" : "Algorand Mainnet"}`);
690
+ console.log(`Facilitator: ${FACILITATOR_URL}`);
691
+ });
692
+ ```
693
+
694
+ ---
695
+
696
+ ## Complete Hono Multi-Network API
697
+
698
+ ```typescript
699
+ import { Hono } from "hono";
700
+ import { cors } from "hono/cors";
701
+ import { paymentMiddleware, x402ResourceServer } from "@x402-avm/hono";
702
+ import { createPaywall, avmPaywall, evmPaywall } from "@x402-avm/paywall";
703
+
704
+ const app = new Hono();
705
+ app.use("*", cors());
706
+
707
+ const routes = {
708
+ "/api/data": {
709
+ accepts: [
710
+ {
711
+ scheme: "exact",
712
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
713
+ asset: "10458941",
714
+ payTo: process.env.ALGO_PAYTO!,
715
+ price: "$0.01",
716
+ maxTimeoutSeconds: 300,
717
+ },
718
+ {
719
+ scheme: "exact",
720
+ network: "eip155:84532",
721
+ asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
722
+ payTo: process.env.EVM_PAYTO!,
723
+ price: "$0.01",
724
+ maxTimeoutSeconds: 30,
725
+ },
726
+ ],
727
+ description: "Premium data - pay with USDC on Algorand or Base",
728
+ mimeType: "application/json",
729
+ },
730
+ };
731
+
732
+ const paywall = createPaywall()
733
+ .withNetwork(avmPaywall)
734
+ .withNetwork(evmPaywall)
735
+ .withConfig({
736
+ appName: "Multi-Chain API",
737
+ testnet: true,
738
+ })
739
+ .build();
740
+
741
+ const server = new x402ResourceServer({ url: process.env.FACILITATOR_URL! });
742
+
743
+ app.use("*", paymentMiddleware(routes, server, { testnet: true }, paywall));
744
+
745
+ app.get("/", (c) => {
746
+ return c.json({
747
+ name: "Multi-Chain Premium API",
748
+ endpoints: { "/api/data": "$0.01 USDC (Algorand or Base)" },
749
+ });
750
+ });
751
+
752
+ app.get("/api/data", (c) => {
753
+ return c.json({
754
+ message: "This content was unlocked with USDC payment!",
755
+ timestamp: new Date().toISOString(),
756
+ });
757
+ });
758
+
759
+ export default {
760
+ port: 3000,
761
+ fetch: app.fetch,
762
+ };
763
+ ```
764
+
765
+ ---
766
+
767
+ ## Complete Next.js App with withX402
768
+
769
+ ### app/api/premium/route.ts
770
+
771
+ ```typescript
772
+ import { NextRequest, NextResponse } from "next/server";
773
+ import { withX402, x402ResourceServer } from "@x402-avm/next";
774
+ import { createPaywall, avmPaywall } from "@x402-avm/paywall";
775
+
776
+ const server = new x402ResourceServer({
777
+ url: process.env.FACILITATOR_URL!,
778
+ });
779
+
780
+ const paywall = createPaywall()
781
+ .withNetwork(avmPaywall)
782
+ .withConfig({
783
+ appName: "Next.js Premium",
784
+ appLogo: "/logo.svg",
785
+ testnet: process.env.NODE_ENV !== "production",
786
+ })
787
+ .build();
788
+
789
+ const routeConfig = {
790
+ accepts: {
791
+ scheme: "exact",
792
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
793
+ asset: "10458941",
794
+ payTo: process.env.PAYTO_ADDRESS!,
795
+ price: "$0.01",
796
+ maxTimeoutSeconds: 300,
797
+ },
798
+ description: "Premium AI-generated content",
799
+ mimeType: "application/json",
800
+ };
801
+
802
+ async function handler(request: NextRequest) {
803
+ const searchParams = request.nextUrl.searchParams;
804
+ const topic = searchParams.get("topic") || "Algorand";
805
+
806
+ return NextResponse.json({
807
+ topic,
808
+ content: `Premium AI analysis of "${topic}"...`,
809
+ generatedAt: new Date().toISOString(),
810
+ model: "premium-v2",
811
+ });
812
+ }
813
+
814
+ export const GET = withX402(
815
+ handler,
816
+ routeConfig,
817
+ server,
818
+ { testnet: process.env.NODE_ENV !== "production" },
819
+ paywall,
820
+ );
821
+ ```
822
+
823
+ ### app/page.tsx
824
+
825
+ ```tsx
826
+ "use client";
827
+
828
+ import { useState } from "react";
829
+
830
+ export default function Home() {
831
+ const [result, setResult] = useState<string>("");
832
+ const [loading, setLoading] = useState(false);
833
+
834
+ async function fetchPremium() {
835
+ setLoading(true);
836
+ try {
837
+ const res = await fetch("/api/premium?topic=DeFi");
838
+ if (res.ok) {
839
+ const data = await res.json();
840
+ setResult(JSON.stringify(data, null, 2));
841
+ } else if (res.status === 402) {
842
+ setResult("Payment required -- navigate to /api/premium in browser to see paywall");
843
+ }
844
+ } catch (err) {
845
+ setResult(`Error: ${err}`);
846
+ } finally {
847
+ setLoading(false);
848
+ }
849
+ }
850
+
851
+ return (
852
+ <main style={{ padding: "40px", maxWidth: "600px", margin: "auto" }}>
853
+ <h1>x402-avm Next.js Demo</h1>
854
+ <p>
855
+ Visit{" "}
856
+ <a href="/api/premium?topic=Algorand">/api/premium</a>{" "}
857
+ in your browser to see the paywall.
858
+ </p>
859
+ <button onClick={fetchPremium} disabled={loading}>
860
+ {loading ? "Loading..." : "Fetch Premium (programmatic)"}
861
+ </button>
862
+ {result && (
863
+ <pre style={{ background: "#f0f0f0", padding: "16px", marginTop: "16px" }}>
864
+ {result}
865
+ </pre>
866
+ )}
867
+ </main>
868
+ );
869
+ }
870
+ ```