@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,879 @@
1
+ # x402 HTTP Client Examples
2
+
3
+ ## Quick Start (Fetch)
4
+
5
+ ```typescript
6
+ import { wrapFetchWithPayment, x402Client } from "@x402-avm/fetch";
7
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
8
+ import algosdk from "algosdk";
9
+
10
+ const secretKey = Buffer.from(process.env.AVM_PRIVATE_KEY!, "base64");
11
+ const address = algosdk.encodeAddress(secretKey.slice(32));
12
+ const signer = {
13
+ address,
14
+ signTransactions: async (txns: Uint8Array[], indexesToSign?: number[]) => {
15
+ return txns.map((txn, i) => {
16
+ if (indexesToSign && !indexesToSign.includes(i)) return null;
17
+ const decoded = algosdk.decodeUnsignedTransaction(txn);
18
+ const signed = algosdk.signTransaction(decoded, secretKey);
19
+ return signed.blob;
20
+ });
21
+ },
22
+ };
23
+
24
+ const client = new x402Client();
25
+ registerExactAvmScheme(client, { signer });
26
+
27
+ const fetchWithPay = wrapFetchWithPayment(fetch, client);
28
+ const response = await fetchWithPay("https://api.example.com/premium-data");
29
+ const data = await response.json();
30
+ console.log(data);
31
+ ```
32
+
33
+ ---
34
+
35
+ ## Quick Start (Axios)
36
+
37
+ ```typescript
38
+ import axios from "axios";
39
+ import { wrapAxiosWithPayment, x402Client } from "@x402-avm/axios";
40
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
41
+ import algosdk from "algosdk";
42
+
43
+ const secretKey = Buffer.from(process.env.AVM_PRIVATE_KEY!, "base64");
44
+ const address = algosdk.encodeAddress(secretKey.slice(32));
45
+ const signer = {
46
+ address,
47
+ signTransactions: async (txns: Uint8Array[], indexesToSign?: number[]) => {
48
+ return txns.map((txn, i) => {
49
+ if (indexesToSign && !indexesToSign.includes(i)) return null;
50
+ const decoded = algosdk.decodeUnsignedTransaction(txn);
51
+ const signed = algosdk.signTransaction(decoded, secretKey);
52
+ return signed.blob;
53
+ });
54
+ },
55
+ };
56
+
57
+ const client = new x402Client();
58
+ registerExactAvmScheme(client, { signer });
59
+
60
+ const api = wrapAxiosWithPayment(axios.create(), client);
61
+ const response = await api.get("https://api.example.com/premium-data");
62
+ console.log(response.data);
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Basic Fetch Usage
68
+
69
+ ```typescript
70
+ import { wrapFetchWithPayment, x402Client } from "@x402-avm/fetch";
71
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
72
+
73
+ const client = new x402Client();
74
+ registerExactAvmScheme(client, { signer });
75
+
76
+ const fetchWithPay = wrapFetchWithPayment(fetch, client);
77
+
78
+ // GET request
79
+ const getResponse = await fetchWithPay("https://api.example.com/paid-content");
80
+ console.log(await getResponse.json());
81
+
82
+ // POST request with body
83
+ const postResponse = await fetchWithPay("https://api.example.com/paid-action", {
84
+ method: "POST",
85
+ headers: { "Content-Type": "application/json" },
86
+ body: JSON.stringify({ query: "premium data" }),
87
+ });
88
+ console.log(await postResponse.json());
89
+ ```
90
+
91
+ ---
92
+
93
+ ## Basic Axios Usage
94
+
95
+ ```typescript
96
+ import axios from "axios";
97
+ import { wrapAxiosWithPayment, x402Client } from "@x402-avm/axios";
98
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
99
+
100
+ const client = new x402Client();
101
+ registerExactAvmScheme(client, { signer });
102
+
103
+ const api = wrapAxiosWithPayment(axios.create({
104
+ baseURL: "https://api.example.com",
105
+ timeout: 30000,
106
+ headers: { Accept: "application/json" },
107
+ }), client);
108
+
109
+ // GET request
110
+ const getResult = await api.get("/paid-content");
111
+ console.log(getResult.data);
112
+
113
+ // POST request
114
+ const postResult = await api.post("/paid-action", {
115
+ query: "premium search",
116
+ });
117
+ console.log(postResult.data);
118
+
119
+ // PUT request with custom headers
120
+ const putResult = await api.put("/paid-resource/123", {
121
+ name: "Updated Name",
122
+ }, {
123
+ headers: { "X-Custom-Header": "value" },
124
+ });
125
+ console.log(putResult.data);
126
+ ```
127
+
128
+ ---
129
+
130
+ ## Wrapping the Default Axios Instance
131
+
132
+ ```typescript
133
+ import axios from "axios";
134
+ import { wrapAxiosWithPayment, x402Client } from "@x402-avm/axios";
135
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
136
+
137
+ const client = new x402Client();
138
+ registerExactAvmScheme(client, { signer });
139
+
140
+ wrapAxiosWithPayment(axios, client);
141
+
142
+ const response = await axios.get("https://api.example.com/paid");
143
+ ```
144
+
145
+ ---
146
+
147
+ ## Config-Based Fetch Setup
148
+
149
+ ```typescript
150
+ import {
151
+ wrapFetchWithPaymentFromConfig,
152
+ type x402ClientConfig,
153
+ } from "@x402-avm/fetch";
154
+ import { ExactAvmScheme } from "@x402-avm/avm";
155
+
156
+ const config: x402ClientConfig = {
157
+ schemes: [
158
+ {
159
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
160
+ client: new ExactAvmScheme(signer),
161
+ },
162
+ ],
163
+ policies: [
164
+ (version, reqs) => reqs.filter((r) => BigInt(r.amount ?? "0") < BigInt("10000000")),
165
+ ],
166
+ };
167
+
168
+ const fetchWithPay = wrapFetchWithPaymentFromConfig(fetch, config);
169
+ const response = await fetchWithPay("https://api.example.com/paid-endpoint");
170
+ ```
171
+
172
+ ---
173
+
174
+ ## Config-Based Axios Setup
175
+
176
+ ```typescript
177
+ import axios from "axios";
178
+ import {
179
+ wrapAxiosWithPaymentFromConfig,
180
+ type x402ClientConfig,
181
+ } from "@x402-avm/axios";
182
+ import { ExactAvmScheme } from "@x402-avm/avm";
183
+
184
+ const config: x402ClientConfig = {
185
+ schemes: [
186
+ {
187
+ network: "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=",
188
+ client: new ExactAvmScheme(signer),
189
+ },
190
+ ],
191
+ policies: [
192
+ (version, reqs) => reqs.filter((r) => BigInt(r.amount ?? "0") < BigInt("5000000")),
193
+ ],
194
+ };
195
+
196
+ const api = wrapAxiosWithPaymentFromConfig(axios.create(), config);
197
+ const response = await api.get("https://api.example.com/paid-endpoint");
198
+ console.log(response.data);
199
+ ```
200
+
201
+ ---
202
+
203
+ ## Wildcard Network Registration
204
+
205
+ ```typescript
206
+ const config: x402ClientConfig = {
207
+ schemes: [
208
+ {
209
+ network: "algorand:*",
210
+ client: new ExactAvmScheme(signer),
211
+ },
212
+ ],
213
+ };
214
+ ```
215
+
216
+ ---
217
+
218
+ ## ClientAvmSigner: Node.js Implementation
219
+
220
+ ```typescript
221
+ import algosdk from "algosdk";
222
+ import type { ClientAvmSigner } from "@x402-avm/avm";
223
+
224
+ function createNodeSigner(privateKeyBase64: string): ClientAvmSigner {
225
+ const secretKey = Buffer.from(privateKeyBase64, "base64");
226
+ const address = algosdk.encodeAddress(secretKey.slice(32));
227
+
228
+ return {
229
+ address,
230
+ signTransactions: async (
231
+ txns: Uint8Array[],
232
+ indexesToSign?: number[],
233
+ ): Promise<(Uint8Array | null)[]> => {
234
+ return txns.map((txnBytes, i) => {
235
+ if (indexesToSign && !indexesToSign.includes(i)) {
236
+ return null;
237
+ }
238
+ const decoded = algosdk.decodeUnsignedTransaction(txnBytes);
239
+ const signed = algosdk.signTransaction(decoded, secretKey);
240
+ return signed.blob;
241
+ });
242
+ },
243
+ };
244
+ }
245
+
246
+ const signer = createNodeSigner(process.env.AVM_PRIVATE_KEY!);
247
+ console.log("Signer address:", signer.address);
248
+ ```
249
+
250
+ ---
251
+
252
+ ## ClientAvmSigner: Browser with @txnlab/use-wallet (React Hook)
253
+
254
+ ```typescript
255
+ import { useWallet } from "@txnlab/use-wallet-react";
256
+ import type { ClientAvmSigner } from "@x402-avm/avm";
257
+
258
+ function useAvmSigner(): ClientAvmSigner | null {
259
+ const { activeAccount, signTransactions } = useWallet();
260
+
261
+ if (!activeAccount) return null;
262
+
263
+ return {
264
+ address: activeAccount.address,
265
+ signTransactions: async (
266
+ txns: Uint8Array[],
267
+ indexesToSign?: number[],
268
+ ): Promise<(Uint8Array | null)[]> => {
269
+ const signed = await signTransactions(txns, indexesToSign);
270
+ return signed;
271
+ },
272
+ };
273
+ }
274
+ ```
275
+
276
+ ---
277
+
278
+ ## ClientAvmSigner: Browser with Pera Wallet (Vanilla JS)
279
+
280
+ ```typescript
281
+ import { PeraWalletConnect } from "@perawallet/connect";
282
+ import { wrapFetchWithPayment, x402Client } from "@x402-avm/fetch";
283
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
284
+ import type { ClientAvmSigner } from "@x402-avm/avm";
285
+
286
+ const peraWallet = new PeraWalletConnect();
287
+
288
+ async function setupPaymentFetch(): Promise<typeof fetch> {
289
+ const accounts = await peraWallet.connect();
290
+ const address = accounts[0];
291
+
292
+ const signer: ClientAvmSigner = {
293
+ address,
294
+ signTransactions: async (txns: Uint8Array[], indexesToSign?: number[]) => {
295
+ const txnGroup = txns.map((txn, i) => ({
296
+ txn,
297
+ signers: indexesToSign && !indexesToSign.includes(i) ? [] : [address],
298
+ }));
299
+
300
+ const signedTxns = await peraWallet.signTransaction([txnGroup]);
301
+ return txns.map((_, i) => {
302
+ if (indexesToSign && !indexesToSign.includes(i)) return null;
303
+ return signedTxns.shift() ?? null;
304
+ });
305
+ },
306
+ };
307
+
308
+ const client = new x402Client();
309
+ registerExactAvmScheme(client, { signer });
310
+ return wrapFetchWithPayment(fetch, client);
311
+ }
312
+
313
+ const paidFetch = await setupPaymentFetch();
314
+ const response = await paidFetch("https://api.example.com/paid-api");
315
+ ```
316
+
317
+ ---
318
+
319
+ ## Payment Policies: Prefer Algorand
320
+
321
+ ```typescript
322
+ import { wrapFetchWithPayment, x402Client, type PaymentPolicy } from "@x402-avm/fetch";
323
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
324
+
325
+ const preferAlgorand: PaymentPolicy = (version, reqs) => {
326
+ const algorandReqs = reqs.filter((r) => r.network.startsWith("algorand:"));
327
+ return algorandReqs.length > 0 ? algorandReqs : reqs;
328
+ };
329
+
330
+ const client = new x402Client();
331
+ registerExactAvmScheme(client, { signer });
332
+ client.registerPolicy(preferAlgorand);
333
+
334
+ const fetchWithPay = wrapFetchWithPayment(fetch, client);
335
+ ```
336
+
337
+ ---
338
+
339
+ ## Payment Policies: Maximum Amount Limit
340
+
341
+ ```typescript
342
+ const maxAmount: PaymentPolicy = (version, reqs) => {
343
+ return reqs.filter((r) => {
344
+ const amount = BigInt(r.amount ?? r.maxAmountRequired ?? "0");
345
+ return amount <= BigInt("1000000"); // 1 USDC
346
+ });
347
+ };
348
+
349
+ client.registerPolicy(maxAmount);
350
+ ```
351
+
352
+ ---
353
+
354
+ ## Payment Policies: Prefer Testnet
355
+
356
+ ```typescript
357
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
358
+
359
+ const preferTestnet: PaymentPolicy = (version, reqs) => {
360
+ const testnetReqs = reqs.filter((r) => r.network === ALGORAND_TESTNET_CAIP2);
361
+ return testnetReqs.length > 0 ? testnetReqs : reqs;
362
+ };
363
+
364
+ client.registerPolicy(preferTestnet);
365
+ ```
366
+
367
+ ---
368
+
369
+ ## Combining Multiple Policies
370
+
371
+ ```typescript
372
+ const client = new x402Client();
373
+ registerExactAvmScheme(client, { signer });
374
+
375
+ client
376
+ .registerPolicy(preferAlgorand)
377
+ .registerPolicy(preferTestnet)
378
+ .registerPolicy(maxAmount);
379
+ ```
380
+
381
+ ---
382
+
383
+ ## Custom Algod Endpoint
384
+
385
+ ```typescript
386
+ const client = new x402Client();
387
+ registerExactAvmScheme(client, {
388
+ signer,
389
+ algodConfig: {
390
+ algodUrl: "https://your-private-node.example.com",
391
+ algodToken: "your-api-token",
392
+ },
393
+ });
394
+ ```
395
+
396
+ ---
397
+
398
+ ## Pre-Configured Algod Client
399
+
400
+ ```typescript
401
+ import algosdk from "algosdk";
402
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
403
+
404
+ const algodClient = new algosdk.Algodv2(
405
+ "your-token",
406
+ "https://your-node.example.com",
407
+ 443,
408
+ );
409
+
410
+ const client = new x402Client();
411
+ registerExactAvmScheme(client, {
412
+ signer,
413
+ algodConfig: {
414
+ algodClient,
415
+ },
416
+ });
417
+ ```
418
+
419
+ ---
420
+
421
+ ## Specific Network Registration
422
+
423
+ ```typescript
424
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
425
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
426
+
427
+ const client = new x402Client();
428
+ registerExactAvmScheme(client, {
429
+ signer,
430
+ networks: [ALGORAND_TESTNET_CAIP2],
431
+ });
432
+ ```
433
+
434
+ ---
435
+
436
+ ## Error Handling (Fetch)
437
+
438
+ ```typescript
439
+ import { wrapFetchWithPayment, x402Client } from "@x402-avm/fetch";
440
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
441
+
442
+ const client = new x402Client();
443
+ registerExactAvmScheme(client, { signer });
444
+ const fetchWithPay = wrapFetchWithPayment(fetch, client);
445
+
446
+ try {
447
+ const response = await fetchWithPay("https://api.example.com/paid-endpoint");
448
+
449
+ if (response.ok) {
450
+ const data = await response.json();
451
+ console.log("Success:", data);
452
+ } else {
453
+ console.error(`Server error: ${response.status} ${response.statusText}`);
454
+ }
455
+ } catch (error) {
456
+ if (error instanceof Error) {
457
+ if (error.message.includes("Failed to parse payment requirements")) {
458
+ console.error("Invalid payment requirements from server");
459
+ } else if (error.message.includes("Failed to create payment payload")) {
460
+ console.error("Could not create payment:", error.message);
461
+ } else if (error.message.includes("Payment already attempted")) {
462
+ console.error("Payment was rejected by the server");
463
+ } else if (error.message.includes("No network/scheme registered")) {
464
+ console.error("Unsupported payment network requested");
465
+ } else if (error.message.includes("Payment creation aborted")) {
466
+ console.error("Payment was blocked by policy");
467
+ } else {
468
+ console.error("Unexpected error:", error.message);
469
+ }
470
+ }
471
+ }
472
+ ```
473
+
474
+ ---
475
+
476
+ ## Error Handling (Axios)
477
+
478
+ ```typescript
479
+ import axios, { AxiosError } from "axios";
480
+ import { wrapAxiosWithPayment, x402Client } from "@x402-avm/axios";
481
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
482
+
483
+ const client = new x402Client();
484
+ registerExactAvmScheme(client, { signer });
485
+ const api = wrapAxiosWithPayment(axios.create(), client);
486
+
487
+ try {
488
+ const response = await api.get("https://api.example.com/paid-content");
489
+ console.log("Success:", response.data);
490
+ } catch (error) {
491
+ if (error instanceof AxiosError) {
492
+ if (error.response) {
493
+ console.error(`Server returned ${error.response.status}:`, error.response.data);
494
+ } else if (error.request) {
495
+ console.error("No response received:", error.message);
496
+ } else {
497
+ console.error("Request setup error:", error.message);
498
+ }
499
+ } else if (error instanceof Error) {
500
+ if (error.message.includes("Failed to parse payment requirements")) {
501
+ console.error("Server sent invalid 402 response");
502
+ } else if (error.message.includes("Failed to create payment payload")) {
503
+ console.error("Could not sign payment:", error.message);
504
+ } else if (error.message.includes("No network/scheme registered")) {
505
+ console.error("Server requires a payment network we don't support");
506
+ } else if (error.message.includes("All payment requirements were filtered out")) {
507
+ console.error("All payment options were rejected by our policies");
508
+ } else {
509
+ console.error("Unexpected error:", error.message);
510
+ }
511
+ }
512
+ }
513
+ ```
514
+
515
+ ---
516
+
517
+ ## Lifecycle Hooks
518
+
519
+ ```typescript
520
+ const client = new x402Client();
521
+ registerExactAvmScheme(client, { signer });
522
+
523
+ client.onBeforePaymentCreation(async (context) => {
524
+ const { selectedRequirements } = context;
525
+ console.log(
526
+ `About to pay ${selectedRequirements.amount} on ${selectedRequirements.network}`,
527
+ );
528
+
529
+ const amountUSDC = Number(selectedRequirements.amount) / 1_000_000;
530
+ if (amountUSDC > 10) {
531
+ return { abort: true, reason: "Amount exceeds $10 USDC limit" };
532
+ }
533
+ });
534
+
535
+ client.onAfterPaymentCreation(async (context) => {
536
+ console.log("Payment created successfully for:", context.paymentRequired.resource?.url);
537
+ });
538
+
539
+ client.onPaymentCreationFailure(async (context) => {
540
+ console.error("Payment failed:", context.error.message);
541
+ });
542
+
543
+ const fetchWithPay = wrapFetchWithPayment(fetch, client);
544
+ ```
545
+
546
+ ---
547
+
548
+ ## Reading Payment Response Headers
549
+
550
+ ```typescript
551
+ import { decodePaymentResponseHeader } from "@x402-avm/fetch";
552
+
553
+ const response = await fetchWithPay("https://api.example.com/paid-endpoint");
554
+
555
+ const paymentResponseHeader =
556
+ response.headers.get("PAYMENT-RESPONSE");
557
+
558
+ if (paymentResponseHeader) {
559
+ const receipt = decodePaymentResponseHeader(paymentResponseHeader);
560
+ console.log("Transaction settled:", receipt);
561
+ }
562
+ ```
563
+
564
+ ---
565
+
566
+ ## Custom Payment Requirements Selector
567
+
568
+ ```typescript
569
+ const cheapestFirst = (version: number, reqs: PaymentRequirements[]) => {
570
+ return reqs.sort((a, b) => {
571
+ const amountA = BigInt(a.amount ?? a.maxAmountRequired ?? "0");
572
+ const amountB = BigInt(b.amount ?? b.maxAmountRequired ?? "0");
573
+ return amountA < amountB ? -1 : amountA > amountB ? 1 : 0;
574
+ })[0];
575
+ };
576
+
577
+ const client = new x402Client(cheapestFirst);
578
+ registerExactAvmScheme(client, { signer });
579
+ ```
580
+
581
+ ---
582
+
583
+ ## Complete Browser Example (React + Pera Wallet)
584
+
585
+ ```tsx
586
+ import React, { useState, useMemo, useCallback } from "react";
587
+ import { WalletProvider, useWallet } from "@txnlab/use-wallet-react";
588
+ import { WalletId } from "@txnlab/use-wallet";
589
+ import { wrapFetchWithPayment, x402Client } from "@x402-avm/fetch";
590
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
591
+ import type { ClientAvmSigner } from "@x402-avm/avm";
592
+
593
+ const WALLET_PROVIDERS = [
594
+ { id: WalletId.PERA },
595
+ { id: WalletId.DEFLY },
596
+ { id: WalletId.LUTE },
597
+ ];
598
+
599
+ function PaidApiDemo() {
600
+ const { activeAccount, signTransactions, providers } = useWallet();
601
+ const [result, setResult] = useState<string>("");
602
+ const [loading, setLoading] = useState(false);
603
+
604
+ const signer: ClientAvmSigner | null = useMemo(() => {
605
+ if (!activeAccount) return null;
606
+ return {
607
+ address: activeAccount.address,
608
+ signTransactions: async (txns: Uint8Array[], indexesToSign?: number[]) => {
609
+ return signTransactions(txns, indexesToSign);
610
+ },
611
+ };
612
+ }, [activeAccount, signTransactions]);
613
+
614
+ const fetchWithPay = useMemo(() => {
615
+ if (!signer) return null;
616
+ const client = new x402Client();
617
+ registerExactAvmScheme(client, { signer });
618
+ return wrapFetchWithPayment(fetch, client);
619
+ }, [signer]);
620
+
621
+ const handleConnect = useCallback(async () => {
622
+ const pera = providers?.find((p) => p.metadata.id === WalletId.PERA);
623
+ if (pera) await pera.connect();
624
+ }, [providers]);
625
+
626
+ const handleFetch = useCallback(async () => {
627
+ if (!fetchWithPay) return;
628
+ setLoading(true);
629
+ try {
630
+ const response = await fetchWithPay("https://api.example.com/premium-content");
631
+ const data = await response.json();
632
+ setResult(JSON.stringify(data, null, 2));
633
+ } catch (err) {
634
+ setResult(`Error: ${err instanceof Error ? err.message : String(err)}`);
635
+ } finally {
636
+ setLoading(false);
637
+ }
638
+ }, [fetchWithPay]);
639
+
640
+ return (
641
+ <div style={{ padding: "20px", fontFamily: "monospace" }}>
642
+ <h1>x402-avm Fetch Demo</h1>
643
+ {!activeAccount ? (
644
+ <button onClick={handleConnect}>Connect Pera Wallet</button>
645
+ ) : (
646
+ <div>
647
+ <p>Connected: {activeAccount.address.slice(0, 8)}...</p>
648
+ <button onClick={handleFetch} disabled={loading}>
649
+ {loading ? "Paying & Fetching..." : "Fetch Premium Content ($0.01 USDC)"}
650
+ </button>
651
+ </div>
652
+ )}
653
+ {result && (
654
+ <pre style={{ background: "#f5f5f5", padding: "10px", marginTop: "10px" }}>
655
+ {result}
656
+ </pre>
657
+ )}
658
+ </div>
659
+ );
660
+ }
661
+
662
+ export default function App() {
663
+ return (
664
+ <WalletProvider wallets={WALLET_PROVIDERS}>
665
+ <PaidApiDemo />
666
+ </WalletProvider>
667
+ );
668
+ }
669
+ ```
670
+
671
+ ---
672
+
673
+ ## Complete Node.js CLI Example
674
+
675
+ ```typescript
676
+ import { wrapFetchWithPayment, x402Client } from "@x402-avm/fetch";
677
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
678
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
679
+ import algosdk from "algosdk";
680
+
681
+ async function main() {
682
+ const privateKey = process.env.AVM_PRIVATE_KEY;
683
+ if (!privateKey) {
684
+ console.error("Error: AVM_PRIVATE_KEY environment variable is required");
685
+ console.error("Format: Base64-encoded 64-byte key (32-byte seed + 32-byte pubkey)");
686
+ process.exit(1);
687
+ }
688
+
689
+ const secretKey = Buffer.from(privateKey, "base64");
690
+ const address = algosdk.encodeAddress(secretKey.slice(32));
691
+ console.log(`Using address: ${address}`);
692
+
693
+ const signer = {
694
+ address,
695
+ signTransactions: async (txns: Uint8Array[], indexesToSign?: number[]) => {
696
+ return txns.map((txn, i) => {
697
+ if (indexesToSign && !indexesToSign.includes(i)) return null;
698
+ const decoded = algosdk.decodeUnsignedTransaction(txn);
699
+ const signed = algosdk.signTransaction(decoded, secretKey);
700
+ return signed.blob;
701
+ });
702
+ },
703
+ };
704
+
705
+ const client = new x402Client();
706
+ registerExactAvmScheme(client, {
707
+ signer,
708
+ algodConfig: {
709
+ algodUrl: process.env.ALGOD_TESTNET_URL || "https://testnet-api.algonode.cloud",
710
+ },
711
+ });
712
+
713
+ client.registerPolicy((version, reqs) => {
714
+ return reqs.filter((r) => BigInt(r.amount ?? "0") <= BigInt("5000000"));
715
+ });
716
+
717
+ client.onBeforePaymentCreation(async ({ selectedRequirements }) => {
718
+ const amountUSDC = Number(selectedRequirements.amount) / 1_000_000;
719
+ console.log(`[x402] Paying $${amountUSDC.toFixed(6)} USDC on ${selectedRequirements.network}`);
720
+ });
721
+
722
+ client.onAfterPaymentCreation(async () => {
723
+ console.log("[x402] Payment transaction signed successfully");
724
+ });
725
+
726
+ const fetchWithPay = wrapFetchWithPayment(fetch, client);
727
+
728
+ const url = process.argv[2] || "https://api.example.com/paid-endpoint";
729
+ console.log(`\nFetching: ${url}`);
730
+
731
+ try {
732
+ const response = await fetchWithPay(url);
733
+ console.log(`Status: ${response.status} ${response.statusText}`);
734
+
735
+ const paymentResponse = response.headers.get("PAYMENT-RESPONSE");
736
+ if (paymentResponse) {
737
+ console.log(`Payment Response: ${paymentResponse}`);
738
+ }
739
+
740
+ const contentType = response.headers.get("content-type") || "";
741
+ if (contentType.includes("application/json")) {
742
+ const data = await response.json();
743
+ console.log("\nResponse:", JSON.stringify(data, null, 2));
744
+ } else {
745
+ const text = await response.text();
746
+ console.log("\nResponse:", text);
747
+ }
748
+ } catch (error) {
749
+ console.error("\nFailed:", error instanceof Error ? error.message : error);
750
+ process.exit(1);
751
+ }
752
+ }
753
+
754
+ main();
755
+ ```
756
+
757
+ ---
758
+
759
+ ## Complete Axios Node.js API Client
760
+
761
+ ```typescript
762
+ import axios, { AxiosError } from "axios";
763
+ import { wrapAxiosWithPayment, x402Client, type PaymentPolicy } from "@x402-avm/axios";
764
+ import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
765
+ import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
766
+ import algosdk from "algosdk";
767
+
768
+ const secretKey = Buffer.from(process.env.AVM_PRIVATE_KEY!, "base64");
769
+ const address = algosdk.encodeAddress(secretKey.slice(32));
770
+
771
+ const signer = {
772
+ address,
773
+ signTransactions: async (txns: Uint8Array[], indexesToSign?: number[]) => {
774
+ return txns.map((txn, i) => {
775
+ if (indexesToSign && !indexesToSign.includes(i)) return null;
776
+ const decoded = algosdk.decodeUnsignedTransaction(txn);
777
+ const signed = algosdk.signTransaction(decoded, secretKey);
778
+ return signed.blob;
779
+ });
780
+ },
781
+ };
782
+
783
+ const client = new x402Client();
784
+ registerExactAvmScheme(client, {
785
+ signer,
786
+ algodConfig: {
787
+ algodUrl: process.env.ALGOD_TESTNET_URL || "https://testnet-api.algonode.cloud",
788
+ },
789
+ });
790
+
791
+ const maxPaymentPolicy: PaymentPolicy = (version, reqs) => {
792
+ return reqs.filter((r) => BigInt(r.amount ?? "0") <= BigInt("5000000"));
793
+ };
794
+
795
+ client.registerPolicy(maxPaymentPolicy);
796
+
797
+ client.onBeforePaymentCreation(async ({ selectedRequirements }) => {
798
+ const usdcAmount = Number(selectedRequirements.amount) / 1_000_000;
799
+ console.log(`[x402] Paying $${usdcAmount.toFixed(6)} to ${selectedRequirements.payTo}`);
800
+ });
801
+
802
+ client.onAfterPaymentCreation(async () => {
803
+ console.log("[x402] Transaction signed and submitted");
804
+ });
805
+
806
+ const api = wrapAxiosWithPayment(
807
+ axios.create({
808
+ baseURL: "https://api.example.com",
809
+ timeout: 30000,
810
+ headers: {
811
+ Accept: "application/json",
812
+ "User-Agent": "x402-avm-client/1.0",
813
+ },
814
+ }),
815
+ client,
816
+ );
817
+
818
+ async function fetchPremiumContent(contentId: string) {
819
+ try {
820
+ const response = await api.get(`/premium/content/${contentId}`);
821
+ console.log("Content:", response.data);
822
+
823
+ const paymentReceipt = response.headers["payment-response"];
824
+ if (paymentReceipt) {
825
+ console.log("Payment receipt:", paymentReceipt);
826
+ }
827
+
828
+ return response.data;
829
+ } catch (error) {
830
+ if (error instanceof AxiosError) {
831
+ if (error.response?.status === 402) {
832
+ console.error("Payment failed -- server rejected our payment");
833
+ } else if (error.response?.status === 404) {
834
+ console.error("Content not found");
835
+ } else {
836
+ console.error(`API error: ${error.response?.status}`, error.response?.data);
837
+ }
838
+ } else {
839
+ console.error("Unexpected error:", error);
840
+ }
841
+ throw error;
842
+ }
843
+ }
844
+
845
+ async function main() {
846
+ console.log(`Wallet address: ${address}`);
847
+ console.log(`Network: ${ALGORAND_TESTNET_CAIP2}\n`);
848
+
849
+ const content = await fetchPremiumContent("article-123");
850
+ }
851
+
852
+ main().catch((err) => {
853
+ console.error("Fatal:", err.message);
854
+ process.exit(1);
855
+ });
856
+ ```
857
+
858
+ ---
859
+
860
+ ## Axios Interceptor Order
861
+
862
+ ```typescript
863
+ const api = axios.create();
864
+
865
+ api.interceptors.request.use((config) => {
866
+ config.headers.set("Authorization", `Bearer ${getToken()}`);
867
+ return config;
868
+ });
869
+
870
+ api.interceptors.response.use(
871
+ (response) => {
872
+ console.log(`${response.config.method} ${response.config.url}: ${response.status}`);
873
+ return response;
874
+ },
875
+ );
876
+
877
+ // Add payment interceptor last
878
+ wrapAxiosWithPayment(api, client);
879
+ ```