@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,382 @@
1
+ # x402-avm Server Reference
2
+
3
+ ## @x402-avm/express Package
4
+
5
+ ### Installation
6
+
7
+ ```bash
8
+ npm install @x402-avm/express @x402-avm/avm @x402-avm/core express
9
+ ```
10
+
11
+ With paywall:
12
+ ```bash
13
+ npm install @x402-avm/express @x402-avm/avm @x402-avm/core @x402-avm/paywall express
14
+ ```
15
+
16
+ ### Middleware Functions
17
+
18
+ #### paymentMiddlewareFromConfig
19
+
20
+ The simplest middleware variant. Creates and configures the x402ResourceServer internally.
21
+
22
+ ```typescript
23
+ function paymentMiddlewareFromConfig(
24
+ routes: RoutesConfig | RouteConfig,
25
+ facilitatorClient: HTTPFacilitatorClient,
26
+ schemes?: SchemeConfig[],
27
+ paywallConfig?: PaywallConfig,
28
+ paywall?: PaywallProvider,
29
+ ): RequestHandler
30
+ ```
31
+
32
+ | Parameter | Type | Required | Description |
33
+ |-----------|------|----------|-------------|
34
+ | `routes` | `RoutesConfig \| RouteConfig` | Yes | Route payment configuration |
35
+ | `facilitatorClient` | `HTTPFacilitatorClient` | Yes | Client to communicate with facilitator |
36
+ | `schemes` | `SchemeConfig[]` | No | Scheme configurations for network matching |
37
+ | `paywallConfig` | `PaywallConfig` | No | Paywall UI configuration |
38
+ | `paywall` | `PaywallProvider` | No | Custom paywall provider |
39
+
40
+ #### paymentMiddleware
41
+
42
+ Uses a pre-configured x402ResourceServer instance. Choose this when you need to register multiple schemes or reuse the server.
43
+
44
+ ```typescript
45
+ function paymentMiddleware(
46
+ routes: RoutesConfig | RouteConfig,
47
+ server: x402ResourceServer,
48
+ paywallConfig?: PaywallConfig,
49
+ paywall?: PaywallProvider,
50
+ ): RequestHandler
51
+ ```
52
+
53
+ | Parameter | Type | Required | Description |
54
+ |-----------|------|----------|-------------|
55
+ | `routes` | `RoutesConfig \| RouteConfig` | Yes | Route payment configuration |
56
+ | `server` | `x402ResourceServer` | Yes | Pre-configured resource server |
57
+ | `paywallConfig` | `PaywallConfig` | No | Paywall UI configuration |
58
+ | `paywall` | `PaywallProvider` | No | Custom paywall provider |
59
+
60
+ #### paymentMiddlewareFromHTTPServer
61
+
62
+ The most advanced variant. Uses x402HTTPResourceServer with hooks for custom access control.
63
+
64
+ ```typescript
65
+ function paymentMiddlewareFromHTTPServer(
66
+ httpServer: x402HTTPResourceServer,
67
+ ): RequestHandler
68
+ ```
69
+
70
+ | Parameter | Type | Required | Description |
71
+ |-----------|------|----------|-------------|
72
+ | `httpServer` | `x402HTTPResourceServer` | Yes | HTTP server with hooks configured |
73
+
74
+ ## @x402-avm/hono Package
75
+
76
+ ### Installation
77
+
78
+ ```bash
79
+ npm install @x402-avm/hono @x402-avm/avm @x402-avm/core hono
80
+ ```
81
+
82
+ Node.js server:
83
+ ```bash
84
+ npm install @x402-avm/hono @x402-avm/avm @x402-avm/core hono @hono/node-server
85
+ ```
86
+
87
+ ### Middleware Functions
88
+
89
+ The Hono package exports the same three middleware variants as Express, returning Hono `MiddlewareHandler` instead of Express `RequestHandler`.
90
+
91
+ #### paymentMiddlewareFromConfig
92
+
93
+ ```typescript
94
+ function paymentMiddlewareFromConfig(
95
+ routes: RoutesConfig | RouteConfig,
96
+ facilitatorClient: HTTPFacilitatorClient,
97
+ schemes?: SchemeConfig[],
98
+ paywallConfig?: PaywallConfig,
99
+ paywall?: PaywallProvider,
100
+ syncFacilitatorOnStart?: boolean, // default: true; set false for serverless
101
+ ): MiddlewareHandler
102
+ ```
103
+
104
+ The `syncFacilitatorOnStart` parameter is unique to Hono. Set it to `false` for Cloudflare Workers and other serverless environments to avoid cold-start delays.
105
+
106
+ #### paymentMiddleware
107
+
108
+ ```typescript
109
+ function paymentMiddleware(
110
+ routes: RoutesConfig | RouteConfig,
111
+ server: x402ResourceServer,
112
+ paywallConfig?: PaywallConfig,
113
+ paywall?: PaywallProvider,
114
+ ): MiddlewareHandler
115
+ ```
116
+
117
+ #### paymentMiddlewareFromHTTPServer
118
+
119
+ ```typescript
120
+ function paymentMiddlewareFromHTTPServer(
121
+ httpServer: x402HTTPResourceServer,
122
+ ): MiddlewareHandler
123
+ ```
124
+
125
+ ## Route Configuration
126
+
127
+ ### RoutesConfig Type
128
+
129
+ ```typescript
130
+ type RoutesConfig = Record<string, RouteConfig>;
131
+ ```
132
+
133
+ Keys are route patterns in the format `"METHOD /path"` or just `"/path"` (matches all methods).
134
+
135
+ **Pattern syntax:**
136
+ - `"GET /api/weather"` -- exact match, GET only
137
+ - `"POST /api/generate"` -- exact match, POST only
138
+ - `"GET /api/premium/*"` -- wildcard, matches all sub-paths
139
+ - `"/api/resource"` -- matches all HTTP methods
140
+ - `"GET /api/lookup/:id"` -- path parameters (Express/Hono style)
141
+
142
+ ### RouteConfig Type
143
+
144
+ ```typescript
145
+ interface RouteConfig {
146
+ accepts: PaymentOption | PaymentOption[];
147
+ resource?: string;
148
+ description?: string;
149
+ mimeType?: string;
150
+ customPaywallHtml?: string;
151
+ unpaidResponseBody?: (context: RequestContext) => {
152
+ contentType: string;
153
+ body: any;
154
+ };
155
+ extensions?: Record<string, unknown>;
156
+ }
157
+ ```
158
+
159
+ | Field | Type | Required | Description |
160
+ |-------|------|----------|-------------|
161
+ | `accepts` | `PaymentOption \| PaymentOption[]` | Yes | Payment configuration(s) |
162
+ | `resource` | `string` | No | Resource identifier URL |
163
+ | `description` | `string` | No | Human-readable description |
164
+ | `mimeType` | `string` | No | Response MIME type (use `"text/html"` for paywall) |
165
+ | `customPaywallHtml` | `string` | No | Custom HTML for browser paywall |
166
+ | `unpaidResponseBody` | `Function` | No | Preview content for unpaid API requests |
167
+ | `extensions` | `Record<string, unknown>` | No | Protocol extensions (e.g., bazaar) |
168
+
169
+ ### PaymentOption Type
170
+
171
+ ```typescript
172
+ interface PaymentOption {
173
+ scheme: string;
174
+ payTo: string;
175
+ price: Price | DynamicPrice;
176
+ network: string;
177
+ maxTimeoutSeconds?: number;
178
+ extra?: Record<string, unknown>;
179
+ }
180
+ ```
181
+
182
+ | Field | Type | Required | Description |
183
+ |-------|------|----------|-------------|
184
+ | `scheme` | `string` | Yes | Payment scheme (`"exact"`) |
185
+ | `payTo` | `string` | Yes | Algorand address to receive payment (58 chars) |
186
+ | `price` | `Price \| DynamicPrice` | Yes | USD price string (`"$0.01"`) or dynamic function |
187
+ | `network` | `string` | Yes | CAIP-2 network identifier |
188
+ | `maxTimeoutSeconds` | `number` | No | Payment validity window (default: 60) |
189
+ | `extra` | `Record<string, unknown>` | No | AVM-specific: `feePayer`, `asset`, `decimals` |
190
+
191
+ ### DynamicPrice Type
192
+
193
+ ```typescript
194
+ type DynamicPrice = (context: RequestContext) => Price;
195
+ type Price = string; // e.g., "$0.01"
196
+ ```
197
+
198
+ ## Core Server Classes
199
+
200
+ ### HTTPFacilitatorClient
201
+
202
+ ```typescript
203
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
204
+
205
+ const client = new HTTPFacilitatorClient({
206
+ url?: string; // Facilitator URL (default: "https://x402.org/facilitator")
207
+ headers?: Record<string, string>; // Custom headers (e.g., auth)
208
+ });
209
+ ```
210
+
211
+ **Methods:**
212
+
213
+ | Method | Returns | Description |
214
+ |--------|---------|-------------|
215
+ | `supported()` | `Promise<SupportedResponse>` | Get supported networks and schemes |
216
+ | `verify({ paymentPayload, paymentRequirements })` | `Promise<VerifyResponse>` | Verify a payment |
217
+ | `settle({ paymentPayload, paymentRequirements })` | `Promise<SettleResponse>` | Settle a payment |
218
+
219
+ ### x402ResourceServer
220
+
221
+ ```typescript
222
+ import { x402ResourceServer } from "@x402-avm/core/server";
223
+
224
+ const server = new x402ResourceServer(facilitatorClient);
225
+ ```
226
+
227
+ Must register AVM scheme after creation:
228
+ ```typescript
229
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
230
+ registerExactAvmScheme(server);
231
+ ```
232
+
233
+ ### x402HTTPResourceServer
234
+
235
+ ```typescript
236
+ import { x402HTTPResourceServer } from "@x402-avm/core/server";
237
+
238
+ const httpServer = new x402HTTPResourceServer(resourceServer, routes);
239
+ ```
240
+
241
+ **Hooks:**
242
+
243
+ | Hook | Signature | Description |
244
+ |------|-----------|-------------|
245
+ | `onProtectedRequest` | `(context, routeConfig) => Promise<{ grantAccess: true } \| { abort: true, reason: string } \| undefined>` | Intercept before payment check |
246
+
247
+ Return `{ grantAccess: true }` to bypass payment (e.g., API key), `{ abort: true, reason }` to reject, or `undefined` to continue to payment flow.
248
+
249
+ ## CAIP-2 Network Constants
250
+
251
+ | Constant | Value | Import |
252
+ |----------|-------|--------|
253
+ | `ALGORAND_TESTNET_CAIP2` | `"algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI="` | `@x402-avm/avm` |
254
+ | `ALGORAND_MAINNET_CAIP2` | `"algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8="` | `@x402-avm/avm` |
255
+
256
+ ## USDC ASA Constants
257
+
258
+ | Constant | Value | Import |
259
+ |----------|-------|--------|
260
+ | `USDC_TESTNET_ASA_ID` | `"10458941"` | `@x402-avm/avm` |
261
+ | `USDC_MAINNET_ASA_ID` | `"31566704"` | `@x402-avm/avm` |
262
+ | `USDC_DECIMALS` | `6` | `@x402-avm/avm` |
263
+
264
+ ## Paywall Configuration
265
+
266
+ ```typescript
267
+ interface PaywallConfig {
268
+ title?: string;
269
+ description?: string;
270
+ logoUrl?: string;
271
+ theme?: {
272
+ primaryColor?: string;
273
+ backgroundColor?: string;
274
+ };
275
+ }
276
+ ```
277
+
278
+ ### Custom PaywallProvider
279
+
280
+ ```typescript
281
+ interface PaywallProvider {
282
+ generatePaywall(
283
+ paymentRequirements: PaymentRequirements,
284
+ routeConfig: RouteConfig,
285
+ paywallConfig?: PaywallConfig,
286
+ ): string; // Returns HTML string
287
+ }
288
+ ```
289
+
290
+ ## Environment Variables
291
+
292
+ ### Resource Server
293
+
294
+ | Variable | Required | Description | Default |
295
+ |----------|----------|-------------|---------|
296
+ | `AVM_ADDRESS` / `RESOURCE_PAY_TO` | Yes | Algorand address receiving payments | -- |
297
+ | `FACILITATOR_URL` | Yes | URL of facilitator server | -- |
298
+ | `PORT` | No | Server port | `4021` |
299
+
300
+ ### Facilitator Server
301
+
302
+ | Variable | Required | Description | Default |
303
+ |----------|----------|-------------|---------|
304
+ | `AVM_PRIVATE_KEY` | Yes | Base64-encoded 64-byte key | -- |
305
+ | `ALGOD_SERVER` | No | Algorand node URL | `https://testnet-api.algonode.cloud` |
306
+ | `ALGOD_TOKEN` | No | Algorand node API token | `""` |
307
+ | `FACILITATOR_PORT` / `PORT` | No | Server port | `4020` |
308
+
309
+ ## Facilitator HTTP Endpoints
310
+
311
+ A facilitator server exposes three endpoints:
312
+
313
+ | Endpoint | Method | Body | Response |
314
+ |----------|--------|------|----------|
315
+ | `/verify` | POST | `{ paymentPayload, paymentRequirements }` | `{ isValid, invalidReason? }` |
316
+ | `/settle` | POST | `{ paymentPayload, paymentRequirements }` | `{ success, transaction?, network?, error? }` |
317
+ | `/supported` | GET | -- | `{ networks, schemes }` |
318
+
319
+ ## Fee Abstraction
320
+
321
+ Fee abstraction is configured through the `extra.feePayer` field in route configuration:
322
+
323
+ ```typescript
324
+ extra: {
325
+ feePayer: "FACILITATOR_FEE_PAYER_ADDRESS",
326
+ }
327
+ ```
328
+
329
+ When a client sees `feePayer` in the payment requirements, it creates a 2-transaction atomic group:
330
+ 1. **Payment transaction** (signed by client): ASA transfer to `payTo`, fee=0
331
+ 2. **Fee transaction** (unsigned, for facilitator): self-payment, fee covers both transactions
332
+
333
+ The facilitator signs the fee transaction during settlement.
334
+
335
+ ## Deployment Patterns
336
+
337
+ ### Express (Node.js)
338
+
339
+ Standard `app.listen()` on a port. Suitable for Docker, VMs, or managed Node.js hosting.
340
+
341
+ ### Hono (Node.js)
342
+
343
+ Use `@hono/node-server` with `serve()`. Same deployment as Express.
344
+
345
+ ### Hono (Cloudflare Workers)
346
+
347
+ Export the Hono app as default export. Set `syncFacilitatorOnStart: false` to avoid cold-start delays. Use `wrangler.toml` for environment variables.
348
+
349
+ ### Hono (Bun)
350
+
351
+ Export `{ port, fetch: app.fetch }` as default export.
352
+
353
+ ### Hono (Deno)
354
+
355
+ Use `Deno.serve({ port }, app.fetch)`.
356
+
357
+ ## Testing
358
+
359
+ ### Manual Test Flow
360
+
361
+ 1. Start facilitator: `PORT=4020 AVM_PRIVATE_KEY=... ts-node facilitator.ts`
362
+ 2. Start resource server: `PORT=4021 FACILITATOR_URL=http://localhost:4020 AVM_ADDRESS=... ts-node server.ts`
363
+ 3. Test public route: `curl http://localhost:4021/api/health` (should return 200)
364
+ 4. Test protected route: `curl http://localhost:4021/api/weather` (should return 402)
365
+ 5. Run client: `AVM_PRIVATE_KEY=... RESOURCE_SERVER_URL=http://localhost:4021 ts-node client.ts`
366
+
367
+ ### Using Online Facilitator
368
+
369
+ Set `FACILITATOR_URL=https://facilitator.goplausible.xyz` to skip running a local facilitator.
370
+
371
+ ## External Resources
372
+
373
+ - [@x402-avm/express on npm](https://www.npmjs.com/package/@x402-avm/express)
374
+ - [@x402-avm/hono on npm](https://www.npmjs.com/package/@x402-avm/hono)
375
+ - [@x402-avm/core on npm](https://www.npmjs.com/package/@x402-avm/core)
376
+ - [@x402-avm/avm on npm](https://www.npmjs.com/package/@x402-avm/avm)
377
+ - [@x402-avm/paywall on npm](https://www.npmjs.com/package/@x402-avm/paywall)
378
+ - [GoPlausible x402-avm Examples](https://github.com/GoPlausible/x402-avm/tree/branch-v2-algorand-publish/examples/)
379
+ - [GoPlausible x402-avm Documentation](https://github.com/GoPlausible/.github/blob/main/profile/algorand-x402-documentation/)
380
+ - [Express.js Documentation](https://expressjs.com/)
381
+ - [Hono Documentation](https://hono.dev/)
382
+ - [Cloudflare Workers Documentation](https://developers.cloudflare.com/workers/)
@@ -0,0 +1,216 @@
1
+ # Creating x402 Payment-Protected Servers
2
+
3
+ Build TypeScript servers that gate API endpoints behind Algorand (AVM) payments using Express.js or Hono middleware.
4
+
5
+ ## Prerequisites
6
+
7
+ Before creating a payment-protected server:
8
+
9
+ 1. **Node.js 18+** installed
10
+ 2. **An Algorand address** to receive payments (58-character address)
11
+ 3. **A facilitator** -- either run your own or use `https://facilitator.goplausible.xyz`
12
+ 4. **TypeScript project** initialized with `tsconfig.json`
13
+
14
+ ## Core Workflow: Middleware-Based Payment Gating
15
+
16
+ The server middleware intercepts requests to protected routes, checks for a valid `PAYMENT-SIGNATURE` header, and either returns 402 (pay first) or passes through to the route handler (payment verified).
17
+
18
+ ```
19
+ Request → Middleware checks PAYMENT-SIGNATURE header
20
+ ├── No header → Return 402 with PaymentRequirements
21
+ ├── Has header → Forward to facilitator
22
+ │ ├── verify() fails → Return 402
23
+ │ └── verify() passes → settle() → Pass to route handler
24
+ └── Route not protected → Pass through
25
+ ```
26
+
27
+ ## How to Proceed
28
+
29
+ ### Step 1: Install Dependencies
30
+
31
+ **Express.js:**
32
+ ```bash
33
+ npm install @x402-avm/express @x402-avm/avm @x402-avm/core express
34
+ npm install -D @types/express typescript
35
+ ```
36
+
37
+ **Hono:**
38
+ ```bash
39
+ npm install @x402-avm/hono @x402-avm/avm @x402-avm/core hono
40
+ npm install -D typescript
41
+ ```
42
+
43
+ **Hono with Node.js server:**
44
+ ```bash
45
+ npm install @x402-avm/hono @x402-avm/avm @x402-avm/core hono @hono/node-server
46
+ ```
47
+
48
+ **With paywall UI (optional):**
49
+ ```bash
50
+ npm install @x402-avm/paywall
51
+ ```
52
+
53
+ ### Step 2: Choose a Middleware Variant
54
+
55
+ There are three middleware variants, from simplest to most configurable:
56
+
57
+ | Variant | Use Case | What It Creates |
58
+ |---------|----------|-----------------|
59
+ | `paymentMiddlewareFromConfig` | Quick start, simple apps | Creates x402ResourceServer internally |
60
+ | `paymentMiddleware` | Need custom server config | Uses your x402ResourceServer instance |
61
+ | `paymentMiddlewareFromHTTPServer` | Need hooks (API key bypass, logging) | Uses x402HTTPResourceServer with hooks |
62
+
63
+ ### Step 3: Define Routes
64
+
65
+ Routes map HTTP method + path patterns to payment configuration:
66
+
67
+ ```typescript
68
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
69
+
70
+ const routes = {
71
+ "GET /api/weather": {
72
+ accepts: {
73
+ scheme: "exact",
74
+ network: ALGORAND_TESTNET_CAIP2,
75
+ payTo: "YOUR_ALGORAND_ADDRESS",
76
+ price: "$0.01",
77
+ },
78
+ description: "Weather data",
79
+ },
80
+ "GET /api/premium/*": {
81
+ accepts: {
82
+ scheme: "exact",
83
+ network: ALGORAND_TESTNET_CAIP2,
84
+ payTo: "YOUR_ALGORAND_ADDRESS",
85
+ price: "$0.10",
86
+ },
87
+ description: "Premium API endpoints",
88
+ },
89
+ };
90
+ ```
91
+
92
+ ### Step 4: Apply Middleware (Express)
93
+
94
+ ```typescript
95
+ import express from "express";
96
+ import { paymentMiddleware, x402ResourceServer } from "@x402-avm/express";
97
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
98
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
99
+
100
+ const app = express();
101
+
102
+ const facilitatorClient = new HTTPFacilitatorClient({
103
+ url: process.env.FACILITATOR_URL || "https://facilitator.goplausible.xyz",
104
+ });
105
+ const server = new x402ResourceServer(facilitatorClient);
106
+ registerExactAvmScheme(server);
107
+
108
+ app.use(paymentMiddleware(routes, server));
109
+
110
+ app.get("/api/weather", (req, res) => {
111
+ res.json({ temperature: 72, condition: "sunny" });
112
+ });
113
+
114
+ app.listen(4021);
115
+ ```
116
+
117
+ ### Step 4 (Alternative): Apply Middleware (Hono)
118
+
119
+ ```typescript
120
+ import { Hono } from "hono";
121
+ import { paymentMiddleware, x402ResourceServer } from "@x402-avm/hono";
122
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
123
+ import { HTTPFacilitatorClient } from "@x402-avm/core/server";
124
+
125
+ const app = new Hono();
126
+
127
+ const facilitatorClient = new HTTPFacilitatorClient({
128
+ url: process.env.FACILITATOR_URL || "https://facilitator.goplausible.xyz",
129
+ });
130
+ const server = new x402ResourceServer(facilitatorClient);
131
+ registerExactAvmScheme(server);
132
+
133
+ app.use(paymentMiddleware(routes, server));
134
+
135
+ app.get("/api/weather", (c) => {
136
+ return c.json({ temperature: 72, condition: "sunny" });
137
+ });
138
+
139
+ export default app;
140
+ ```
141
+
142
+ ### Step 5: Add a Facilitator Server (Optional)
143
+
144
+ If you need your own facilitator instead of the public one:
145
+
146
+ ```typescript
147
+ import express from "express";
148
+ import { x402Facilitator } from "@x402-avm/core/facilitator";
149
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/facilitator";
150
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
151
+ import algosdk from "algosdk";
152
+
153
+ const secretKey = Buffer.from(process.env.AVM_PRIVATE_KEY!, "base64");
154
+ const address = algosdk.encodeAddress(secretKey.slice(32));
155
+ const algodClient = new algosdk.Algodv2("", "https://testnet-api.algonode.cloud", "");
156
+
157
+ // Create signer implementing FacilitatorAvmSigner interface
158
+ const signer = { /* ... see EXAMPLES.md for full implementation ... */ };
159
+
160
+ const facilitator = new x402Facilitator();
161
+ registerExactAvmScheme(facilitator, { signer, networks: ALGORAND_TESTNET_CAIP2 });
162
+
163
+ const app = express();
164
+ app.use(express.json());
165
+ app.post("/verify", async (req, res) => { /* ... */ });
166
+ app.post("/settle", async (req, res) => { /* ... */ });
167
+ app.get("/supported", (req, res) => { /* ... */ });
168
+ app.listen(4020);
169
+ ```
170
+
171
+ ### Step 6: Set Environment Variables
172
+
173
+ ```bash
174
+ # Resource Server
175
+ AVM_ADDRESS=YOUR_ALGORAND_ADDRESS_HERE
176
+ FACILITATOR_URL=https://facilitator.goplausible.xyz
177
+ PORT=4021
178
+
179
+ # Facilitator (if running your own)
180
+ AVM_PRIVATE_KEY=<base64-encoded-64-byte-key>
181
+ ALGOD_SERVER=https://testnet-api.algonode.cloud
182
+ ALGOD_TOKEN=
183
+ FACILITATOR_PORT=4020
184
+ ```
185
+
186
+ ## Important Rules / Guidelines
187
+
188
+ 1. **Register AVM scheme unconditionally** -- always call `registerExactAvmScheme(server)` without environment variable guards
189
+ 2. **Public routes are unaffected** -- only routes listed in the `routes` config object are protected
190
+ 3. **Route patterns support wildcards** -- `"GET /api/premium/*"` matches all sub-paths
191
+ 4. **Method prefix is optional** -- `"/api/resource"` matches all HTTP methods
192
+ 5. **Multi-network routes use arrays** -- pass an array to `accepts` for cross-chain support
193
+ 6. **Facilitator URL is required** -- the resource server must be able to reach a facilitator
194
+ 7. **Price strings use USD notation** -- `"$0.01"` is resolved to the appropriate asset amount
195
+
196
+ ## Common Errors / Troubleshooting
197
+
198
+ | Error | Cause | Solution |
199
+ |-------|-------|----------|
200
+ | All routes return 402 | Route patterns too broad | Check route patterns match intended paths |
201
+ | 402 but no `accepts` array | AVM scheme not registered on server | Call `registerExactAvmScheme(server)` |
202
+ | Facilitator unreachable | Wrong URL or facilitator not running | Check `FACILITATOR_URL` and facilitator status |
203
+ | `paymentMiddleware is not a function` | Wrong import | Import from `@x402-avm/express` or `@x402-avm/hono` |
204
+ | CORS errors in browser | Missing CORS middleware | Add `cors()` middleware before payment middleware |
205
+ | Paywall not showing | Missing `mimeType: "text/html"` | Set `mimeType` in route config for browser routes |
206
+ | Dynamic price error | Price function throws | Ensure price function handles all edge cases |
207
+ | 500 on verify/settle | Facilitator signer error | Check facilitator logs, verify private key |
208
+
209
+ ## References / Further Reading
210
+
211
+ - [create-typescript-x402-server-reference.md](./create-typescript-x402-server-reference.md) - Detailed middleware API reference
212
+ - [create-typescript-x402-server-examples.md](./create-typescript-x402-server-examples.md) - Complete server code examples
213
+ - [@x402-avm/express on npm](https://www.npmjs.com/package/@x402-avm/express)
214
+ - [@x402-avm/hono on npm](https://www.npmjs.com/package/@x402-avm/hono)
215
+ - [GoPlausible x402-avm Examples](https://github.com/GoPlausible/x402-avm/tree/branch-v2-algorand-publish/examples/)
216
+ - [GoPlausible x402-avm Documentation](https://github.com/GoPlausible/.github/blob/main/profile/algorand-x402-documentation/)