@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,323 @@
1
+ # x402 Paywall Reference
2
+
3
+ Detailed API reference for `@x402-avm/paywall` and framework middleware packages.
4
+
5
+ ## Package: @x402-avm/paywall
6
+
7
+ ### Installation
8
+
9
+ ```bash
10
+ npm install @x402-avm/paywall @x402-avm/avm @x402-avm/core
11
+ ```
12
+
13
+ ### Exports from @x402-avm/paywall
14
+
15
+ | Export | Type | Description |
16
+ |--------|------|-------------|
17
+ | `createPaywall` | Function | Creates a new `PaywallBuilder` instance |
18
+ | `PaywallBuilder` | Class | Builder for configuring and building paywall providers |
19
+ | `avmPaywall` | Object | AVM network handler (algorand:*) |
20
+ | `evmPaywall` | Object | EVM network handler (eip155:*) |
21
+ | `svmPaywall` | Object | SVM network handler (solana:*) |
22
+ | `PaywallProvider` | Type | Interface for paywall HTML generation |
23
+ | `PaywallConfig` | Type | Configuration options for paywall branding |
24
+ | `PaywallNetworkHandler` | Type | Interface for network-specific handlers |
25
+ | `PaymentRequired` | Type | 402 response structure |
26
+ | `PaymentRequirements` | Type | Individual payment requirement |
27
+
28
+ ### Exports from @x402-avm/paywall/avm
29
+
30
+ | Export | Type | Description |
31
+ |--------|------|-------------|
32
+ | `avmPaywall` | Object | AVM paywall handler (same as main export) |
33
+
34
+ ---
35
+
36
+ ## PaywallBuilder
37
+
38
+ ### createPaywall()
39
+
40
+ Factory function that creates a new `PaywallBuilder` instance.
41
+
42
+ ```typescript
43
+ function createPaywall(): PaywallBuilder;
44
+ ```
45
+
46
+ ### PaywallBuilder Methods
47
+
48
+ | Method | Signature | Description |
49
+ |--------|-----------|-------------|
50
+ | `.withNetwork(handler)` | `(handler: PaywallNetworkHandler) => PaywallBuilder` | Register a network-specific paywall handler. Order matters -- first match wins. |
51
+ | `.withConfig(config)` | `(config: PaywallConfig) => PaywallBuilder` | Set default paywall configuration. |
52
+ | `.build()` | `() => PaywallProvider` | Build and return a `PaywallProvider`. |
53
+
54
+ ### PaywallProvider
55
+
56
+ ```typescript
57
+ interface PaywallProvider {
58
+ /**
59
+ * Generate an HTML paywall page for the given payment requirements.
60
+ * @param paymentRequired - The full 402 response from the server
61
+ * @param config - Optional runtime config override
62
+ * @returns Full HTML page as a string
63
+ */
64
+ generateHtml(paymentRequired: PaymentRequired, config?: PaywallConfig): string;
65
+ }
66
+ ```
67
+
68
+ ### PaywallConfig
69
+
70
+ ```typescript
71
+ interface PaywallConfig {
72
+ /** App name shown in wallet connection modal title */
73
+ appName?: string;
74
+ /** App logo URL shown in the paywall header */
75
+ appLogo?: string;
76
+ /** URL of the content being accessed (used for retry after payment) */
77
+ currentUrl?: string;
78
+ /** Whether to use testnet (default: true) */
79
+ testnet?: boolean;
80
+ }
81
+ ```
82
+
83
+ ---
84
+
85
+ ## PaywallNetworkHandler
86
+
87
+ Interface for creating custom network-specific paywall handlers.
88
+
89
+ ```typescript
90
+ interface PaywallNetworkHandler {
91
+ /**
92
+ * Check if this handler supports the given payment requirement.
93
+ * @param requirement - A single payment requirement from the 402 response
94
+ * @returns true if this handler can generate HTML for this requirement
95
+ */
96
+ supports(requirement: PaymentRequirements): boolean;
97
+
98
+ /**
99
+ * Generate the full HTML paywall page.
100
+ * @param requirement - The matched payment requirement
101
+ * @param paymentRequired - The full PaymentRequired response
102
+ * @param config - Paywall configuration
103
+ * @returns Full HTML page as a string
104
+ */
105
+ generateHtml(
106
+ requirement: PaymentRequirements,
107
+ paymentRequired: PaymentRequired,
108
+ config: PaywallConfig,
109
+ ): string;
110
+ }
111
+ ```
112
+
113
+ ### Built-in Handlers
114
+
115
+ | Handler | Supports | Networks |
116
+ |---------|----------|----------|
117
+ | `avmPaywall` | `network.startsWith("algorand:")` | Algorand Testnet, Algorand Mainnet |
118
+ | `evmPaywall` | `network.startsWith("eip155:")` | Base, Ethereum, etc. |
119
+ | `svmPaywall` | `network.startsWith("solana:")` | Solana |
120
+
121
+ ### Handler Selection
122
+
123
+ When `PaywallProvider.generateHtml()` is called, it iterates through registered handlers in order. The first handler whose `supports()` returns true for any of the `accepts` requirements is used to generate the HTML.
124
+
125
+ ---
126
+
127
+ ## avmPaywall Handler
128
+
129
+ The `avmPaywall` handler generates a full React-based HTML page with:
130
+
131
+ 1. **window.x402 global** -- Embeds payment configuration for the client-side app
132
+ 2. **Wallet discovery** -- Uses `@wallet-standard/app` to find Algorand wallets
133
+ 3. **Wallet selection UI** -- Dropdown with icons for detected wallets
134
+ 4. **Balance checking** -- Reads USDC ASA balance for the connected account
135
+ 5. **Transaction signing** -- Uses `algorand:signTransaction` wallet-standard feature
136
+ 6. **Payment submission** -- Retries original request with `PAYMENT-SIGNATURE` header
137
+ 7. **Automatic redirect** -- Redirects to paid content after successful payment
138
+
139
+ ### Supported Wallets
140
+
141
+ | Wallet | Type | Feature |
142
+ |--------|------|---------|
143
+ | Pera Wallet | Mobile + WalletConnect | `algorand:signTransaction` |
144
+ | Defly Wallet | Mobile + WalletConnect | `algorand:signTransaction` |
145
+ | Lute Wallet | Browser Extension | `algorand:signTransaction` |
146
+
147
+ ### window.x402 Configuration Object
148
+
149
+ The generated HTML page injects this configuration:
150
+
151
+ ```javascript
152
+ window.x402 = {
153
+ amount: 0.01, // Amount in USDC (human-readable)
154
+ paymentRequired: {...}, // Full PaymentRequired response
155
+ testnet: true, // Network mode
156
+ currentUrl: "...", // URL to retry after payment
157
+ config: { chainConfig: {} },
158
+ appName: "My App",
159
+ appLogo: "https://...",
160
+ };
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Framework Middleware
166
+
167
+ ### @x402-avm/express
168
+
169
+ | Function | Signature | Description |
170
+ |----------|-----------|-------------|
171
+ | `paymentMiddleware` | `(routes, server, config?, paywall?)` | Express middleware |
172
+ | `paymentMiddlewareFromHTTPServer` | `(httpServer, config?, paywall?)` | Express middleware from HTTP server |
173
+ | `paymentMiddlewareFromConfig` | `(routes, facilitator?, schemes?, config?, paywall?)` | Express middleware from config |
174
+ | `x402ResourceServer` | Class | Resource server for facilitator communication |
175
+ | `x402HTTPResourceServer` | Class | HTTP-aware resource server with route config |
176
+
177
+ ### @x402-avm/hono
178
+
179
+ | Function | Signature | Description |
180
+ |----------|-----------|-------------|
181
+ | `paymentMiddleware` | `(routes, server, config?, paywall?)` | Hono middleware |
182
+ | `paymentMiddlewareFromHTTPServer` | `(httpServer, config?, paywall?)` | Hono middleware from HTTP server |
183
+ | `paymentMiddlewareFromConfig` | `(routes, facilitator?, schemes?, config?, paywall?)` | Hono middleware from config |
184
+ | `x402ResourceServer` | Class | Resource server for facilitator communication |
185
+
186
+ ### @x402-avm/next
187
+
188
+ | Function | Signature | Description |
189
+ |----------|-----------|-------------|
190
+ | `paymentProxy` | `(routes, server, config?, paywall?)` | Next.js middleware proxy |
191
+ | `withX402` | `(handler, routeConfig, server, config?, paywall?)` | Next.js route wrapper |
192
+ | `paymentProxyFromHTTPServer` | `(httpServer, config?, paywall?)` | Next.js proxy from HTTP server |
193
+ | `paymentProxyFromConfig` | `(routes, facilitator?, schemes?, config?, paywall?)` | Next.js proxy from config |
194
+ | `x402ResourceServer` | Class | Resource server for facilitator communication |
195
+
196
+ ---
197
+
198
+ ## Route Configuration
199
+
200
+ ```typescript
201
+ interface RouteConfig {
202
+ [path: string]: {
203
+ /** Payment requirements -- single object or array for multi-network */
204
+ accepts: PaymentAccepts | PaymentAccepts[];
205
+ /** Human-readable description of the resource */
206
+ description: string;
207
+ /** MIME type of the response */
208
+ mimeType: string;
209
+ };
210
+ }
211
+
212
+ interface PaymentAccepts {
213
+ /** Payment scheme (currently "exact") */
214
+ scheme: string;
215
+ /** CAIP-2 network identifier */
216
+ network: string;
217
+ /** Asset identifier (ASA ID for Algorand, contract address for EVM) */
218
+ asset: string;
219
+ /** Receiver address */
220
+ payTo: string;
221
+ /** Price string (e.g., "$0.01") */
222
+ price: string;
223
+ /** Maximum timeout in seconds for payment validity */
224
+ maxTimeoutSeconds: number;
225
+ }
226
+ ```
227
+
228
+ ---
229
+
230
+ ## Bundle Sizes
231
+
232
+ The paywall system is designed for tree-shaking. Import only the network handlers you need:
233
+
234
+ ```typescript
235
+ // AVM only -- smallest bundle
236
+ import { avmPaywall } from "@x402-avm/paywall/avm";
237
+
238
+ // AVM + EVM
239
+ import { avmPaywall, evmPaywall } from "@x402-avm/paywall";
240
+
241
+ // All networks
242
+ import { avmPaywall, evmPaywall, svmPaywall } from "@x402-avm/paywall";
243
+ ```
244
+
245
+ ---
246
+
247
+ ## USDC Asset IDs
248
+
249
+ | Network | ASA ID | CAIP-2 |
250
+ |---------|--------|--------|
251
+ | Algorand Testnet | `10458941` | `algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=` |
252
+ | Algorand Mainnet | `31566704` | `algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=` |
253
+
254
+ ---
255
+
256
+ ## Testing
257
+
258
+ ### Testing the Paywall HTML Generation
259
+
260
+ ```typescript
261
+ import { createPaywall, avmPaywall } from "@x402-avm/paywall";
262
+
263
+ const paywall = createPaywall()
264
+ .withNetwork(avmPaywall)
265
+ .withConfig({ appName: "Test App", testnet: true })
266
+ .build();
267
+
268
+ const html = paywall.generateHtml({
269
+ x402Version: 2,
270
+ accepts: [{
271
+ scheme: "exact",
272
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
273
+ asset: "10458941",
274
+ payTo: "TEST_ADDRESS",
275
+ amount: "10000",
276
+ maxTimeoutSeconds: 300,
277
+ }],
278
+ resource: {
279
+ url: "https://test.example.com/premium",
280
+ description: "Test content",
281
+ mimeType: "application/json",
282
+ },
283
+ });
284
+
285
+ // Verify the HTML contains expected elements
286
+ console.assert(html.includes("window.x402"));
287
+ console.assert(html.includes("Test App"));
288
+ ```
289
+
290
+ ### Testing Middleware Integration
291
+
292
+ ```bash
293
+ # Start server
294
+ npm start
295
+
296
+ # Test JSON 402 response (API client)
297
+ curl -H "Accept: application/json" http://localhost:3000/api/premium
298
+
299
+ # Test HTML paywall (browser-like)
300
+ curl -H "Accept: text/html" http://localhost:3000/api/premium
301
+
302
+ # Test with payment header (after obtaining one)
303
+ curl -H "PAYMENT-SIGNATURE: <base64-payload>" http://localhost:3000/api/premium
304
+ ```
305
+
306
+ ---
307
+
308
+ ## Important Notes
309
+
310
+ - The paywall HTML page is a self-contained React application served inline. No additional static files or CDN dependencies are required.
311
+ - `withNetwork()` order determines handler priority. Register your preferred network first.
312
+ - The `testnet` flag in `PaywallConfig` affects which Algod endpoint the paywall page connects to (AlgoNode testnet vs mainnet).
313
+ - Route paths support Express-style patterns (`:param`, `*` wildcards).
314
+ - The `price` field in route config accepts human-readable strings like `"$0.01"` which are converted to microunits internally.
315
+
316
+ ---
317
+
318
+ ## External Resources
319
+
320
+ - [x402-avm Examples Repository](https://github.com/GoPlausible/x402-avm/tree/branch-v2-algorand-publish/examples/)
321
+ - [x402-avm Documentation](https://github.com/GoPlausible/.github/blob/main/profile/algorand-x402-documentation/)
322
+ - [@wallet-standard/app](https://github.com/wallet-standard/wallet-standard)
323
+ - [@txnlab/use-wallet](https://txnlab.gitbook.io/use-wallet)
@@ -0,0 +1,281 @@
1
+ # Creating Paywall UIs for x402-Protected Endpoints
2
+
3
+ Build server-side middleware that serves payment HTML pages to browsers and JSON 402 responses to API clients, with automatic wallet integration for Algorand (Pera, Defly, Lute).
4
+
5
+ ## Prerequisites
6
+
7
+ Before using this skill, ensure:
8
+
9
+ 1. **A backend framework** (Express.js, Hono, or Next.js)
10
+ 2. **A facilitator service** running and accessible via URL
11
+ 3. **An Algorand address** to receive payments (payTo address)
12
+
13
+ ## Core Workflow: Server-Side Paywall Architecture
14
+
15
+ The paywall system has two sides. The server middleware detects missing payments and serves either a JSON 402 or an HTML paywall page. The HTML page handles wallet connection, signing, and retry:
16
+
17
+ ```
18
+ Browser Request
19
+ |
20
+ v
21
+ [Server Middleware]
22
+ |
23
+ +-- Has PAYMENT-SIGNATURE header?
24
+ | |
25
+ | +-- Yes: Verify payment, settle transaction, return content
26
+ | +-- No: Is this a browser request (Accept: text/html)?
27
+ | |
28
+ | +-- Yes: Return paywall HTML page (402)
29
+ | +-- No: Return JSON 402 response
30
+ |
31
+ v
32
+ [Paywall HTML Page]
33
+ |
34
+ +-- Reads window.x402 config
35
+ +-- Shows wallet connection UI (Pera/Defly/Lute)
36
+ +-- User connects wallet and approves payment
37
+ +-- Retries request with PAYMENT-SIGNATURE header
38
+ +-- Redirects to paid content
39
+ ```
40
+
41
+ ## How to Proceed
42
+
43
+ ### Step 1: Install Dependencies
44
+
45
+ Server-side packages:
46
+ ```bash
47
+ npm install @x402-avm/paywall @x402-avm/avm @x402-avm/core
48
+ ```
49
+
50
+ Plus your framework middleware:
51
+ ```bash
52
+ # Express.js
53
+ npm install @x402-avm/express
54
+
55
+ # Hono
56
+ npm install @x402-avm/hono
57
+
58
+ # Next.js
59
+ npm install @x402-avm/next
60
+ ```
61
+
62
+ ### Step 2: Create the Paywall with PaywallBuilder
63
+
64
+ The `PaywallBuilder` creates a `PaywallProvider` that generates HTML paywall pages. Register network handlers in priority order -- first match wins:
65
+
66
+ ```typescript
67
+ import { createPaywall, avmPaywall } from "@x402-avm/paywall";
68
+
69
+ const paywall = createPaywall()
70
+ .withNetwork(avmPaywall) // Supports algorand:* networks
71
+ .withConfig({
72
+ appName: "My Premium API",
73
+ appLogo: "https://example.com/logo.png",
74
+ testnet: true,
75
+ })
76
+ .build();
77
+ ```
78
+
79
+ For multi-network support, register multiple handlers:
80
+
81
+ ```typescript
82
+ import { createPaywall, avmPaywall, evmPaywall, svmPaywall } from "@x402-avm/paywall";
83
+
84
+ const paywall = createPaywall()
85
+ .withNetwork(avmPaywall) // algorand:*
86
+ .withNetwork(evmPaywall) // eip155:*
87
+ .withNetwork(svmPaywall) // solana:*
88
+ .withConfig({ appName: "Universal Paywall", testnet: true })
89
+ .build();
90
+ ```
91
+
92
+ ### Step 3: Define Protected Routes
93
+
94
+ Routes specify what payment is required for each endpoint:
95
+
96
+ ```typescript
97
+ const routes = {
98
+ "/api/premium-content": {
99
+ accepts: {
100
+ scheme: "exact",
101
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
102
+ asset: "10458941", // USDC ASA ID on testnet
103
+ payTo: "YOUR_ALGORAND_ADDRESS_HERE",
104
+ price: "$0.01", // 0.01 USDC
105
+ maxTimeoutSeconds: 300,
106
+ },
107
+ description: "Access to premium content",
108
+ mimeType: "application/json",
109
+ },
110
+ };
111
+ ```
112
+
113
+ ### Step 4: Apply Middleware (Express.js)
114
+
115
+ ```typescript
116
+ import express from "express";
117
+ import { paymentMiddleware, x402ResourceServer } from "@x402-avm/express";
118
+
119
+ const app = express();
120
+ const server = new x402ResourceServer({ url: process.env.FACILITATOR_URL! });
121
+
122
+ app.use(paymentMiddleware(routes, server, { testnet: true }, paywall));
123
+
124
+ app.get("/api/premium-content", (req, res) => {
125
+ res.json({ content: "This is the paid content." });
126
+ });
127
+
128
+ app.listen(3000);
129
+ ```
130
+
131
+ ### Step 4 (Alt): Apply Middleware (Hono)
132
+
133
+ ```typescript
134
+ import { Hono } from "hono";
135
+ import { paymentMiddleware, x402ResourceServer } from "@x402-avm/hono";
136
+
137
+ const app = new Hono();
138
+ const server = new x402ResourceServer({ url: process.env.FACILITATOR_URL! });
139
+
140
+ app.use("*", paymentMiddleware(routes, server, { testnet: true }, paywall));
141
+
142
+ app.get("/api/premium-content", (c) => {
143
+ return c.json({ content: "Premium content unlocked!" });
144
+ });
145
+
146
+ export default app;
147
+ ```
148
+
149
+ ### Step 4 (Alt): Apply Middleware (Next.js)
150
+
151
+ **Middleware approach:**
152
+ ```typescript
153
+ // middleware.ts
154
+ import { paymentProxy, x402ResourceServer } from "@x402-avm/next";
155
+
156
+ const server = new x402ResourceServer({ url: process.env.FACILITATOR_URL! });
157
+ const proxy = paymentProxy(routes, server, { testnet: true }, paywall);
158
+
159
+ export async function middleware(request: NextRequest) {
160
+ if (request.nextUrl.pathname.startsWith("/api/premium")) {
161
+ return proxy(request);
162
+ }
163
+ return NextResponse.next();
164
+ }
165
+ ```
166
+
167
+ **Route handler approach (withX402):**
168
+ ```typescript
169
+ // app/api/premium/route.ts
170
+ import { withX402, x402ResourceServer } from "@x402-avm/next";
171
+
172
+ const server = new x402ResourceServer({ url: process.env.FACILITATOR_URL! });
173
+
174
+ async function handler(request: NextRequest) {
175
+ return NextResponse.json({ content: "Premium content!" });
176
+ }
177
+
178
+ export const GET = withX402(handler, routeConfig, server, { testnet: true }, paywall);
179
+ ```
180
+
181
+ ## Important Rules / Guidelines
182
+
183
+ 1. **Handler order matters** -- `withNetwork()` calls determine priority. The first handler whose `supports()` returns true for a payment requirement is used
184
+ 2. **avmPaywall supports `algorand:*`** -- Any network starting with `algorand:` is matched
185
+ 3. **Testnet vs Mainnet** -- Set `testnet: true/false` in both `PaywallConfig` and middleware config
186
+ 4. **USDC ASA IDs** -- Testnet: `10458941`, Mainnet: `31566704`
187
+ 5. **Facilitator URL is required** -- The middleware needs a running facilitator to verify and settle payments
188
+ 6. **Tree-shaking** -- Import only the network handlers you need. `avmPaywall` can be imported from `@x402-avm/paywall` or `@x402-avm/paywall/avm`
189
+ 7. **Multiple routes** -- Define multiple entries in the routes object, each with its own price, description, and asset
190
+
191
+ ## Wallet Integration
192
+
193
+ The AVM paywall HTML page uses `@wallet-standard/app` to discover Algorand wallets:
194
+
195
+ | Wallet | Type | Feature |
196
+ |--------|------|---------|
197
+ | Pera Wallet | Mobile + WalletConnect | `algorand:signTransaction` |
198
+ | Defly Wallet | Mobile + WalletConnect | `algorand:signTransaction` |
199
+ | Lute Wallet | Browser Extension | `algorand:signTransaction` |
200
+
201
+ The paywall page automatically:
202
+ - Discovers available wallets via wallet-standard
203
+ - Shows a wallet selection UI
204
+ - Checks USDC balance for the connected account
205
+ - Handles transaction signing
206
+ - Retries the original request with the payment header
207
+ - Redirects to the paid content on success
208
+
209
+ ## Multi-Network Paywalls
210
+
211
+ Accept payments on multiple chains by specifying an array in `accepts`:
212
+
213
+ ```typescript
214
+ const routes = {
215
+ "/api/premium": {
216
+ accepts: [
217
+ {
218
+ scheme: "exact",
219
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
220
+ asset: "10458941",
221
+ payTo: "ALGO_ADDRESS_HERE",
222
+ price: "$0.01",
223
+ maxTimeoutSeconds: 300,
224
+ },
225
+ {
226
+ scheme: "exact",
227
+ network: "eip155:84532",
228
+ asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
229
+ payTo: "0xEVM_ADDRESS_HERE",
230
+ price: "$0.01",
231
+ maxTimeoutSeconds: 30,
232
+ },
233
+ ],
234
+ description: "Premium content - pay with USDC on Algorand or Base",
235
+ mimeType: "application/json",
236
+ },
237
+ };
238
+ ```
239
+
240
+ ## Custom Paywall Handler
241
+
242
+ If the built-in paywall does not meet your needs, implement a custom `PaywallNetworkHandler`:
243
+
244
+ ```typescript
245
+ import type { PaywallNetworkHandler } from "@x402-avm/paywall";
246
+
247
+ const customHandler: PaywallNetworkHandler = {
248
+ supports(requirement) {
249
+ return requirement.network.startsWith("algorand:");
250
+ },
251
+ generateHtml(requirement, paymentRequired, config) {
252
+ return `<!DOCTYPE html>
253
+ <html><body>
254
+ <h1>Pay ${requirement.amount} to access</h1>
255
+ <script>window.x402 = ${JSON.stringify({ paymentRequired, ...config })};</script>
256
+ </body></html>`;
257
+ },
258
+ };
259
+
260
+ const paywall = createPaywall()
261
+ .withNetwork(customHandler)
262
+ .build();
263
+ ```
264
+
265
+ ## Common Errors / Troubleshooting
266
+
267
+ | Error | Cause | Solution |
268
+ |-------|-------|----------|
269
+ | Paywall not shown in browser | Middleware not applied or route not matched | Check route patterns match request paths |
270
+ | JSON 402 returned to browser | Browser not sending `Accept: text/html` | Ensure direct browser navigation, not programmatic fetch |
271
+ | Wallet not detected | Wallet extension not installed | Install Pera, Defly, or Lute wallet |
272
+ | "Insufficient balance" | Account has no USDC | Fund the wallet with USDC on the correct network |
273
+ | Facilitator unreachable | Wrong URL or service down | Verify `FACILITATOR_URL` environment variable |
274
+ | Payment not settling | Facilitator signer not funded | Ensure the facilitator address has ALGO for fees |
275
+
276
+ ## References / Further Reading
277
+
278
+ - [create-typescript-x402-paywall-reference.md](./create-typescript-x402-paywall-reference.md) - Detailed API reference
279
+ - [create-typescript-x402-paywall-examples.md](./create-typescript-x402-paywall-examples.md) - Complete code examples
280
+ - [x402-avm Examples Repository](https://github.com/GoPlausible/x402-avm/tree/branch-v2-algorand-publish/examples/)
281
+ - [x402-avm Documentation](https://github.com/GoPlausible/.github/blob/main/profile/algorand-x402-documentation/)