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.
- package/LICENSE +21 -0
- package/README.md +112 -0
- package/index.ts +361 -0
- package/lib/mcp-servers.ts +14 -0
- package/lib/x402-fetch.ts +213 -0
- package/memory/algorand-plugin.md +82 -0
- package/openclaw.plugin.json +30 -0
- package/package.json +38 -0
- package/setup.ts +80 -0
- package/skills/algorand-development/SKILL.md +90 -0
- package/skills/algorand-development/references/build-smart-contracts-reference.md +79 -0
- package/skills/algorand-development/references/build-smart-contracts.md +52 -0
- package/skills/algorand-development/references/create-project-reference.md +86 -0
- package/skills/algorand-development/references/create-project.md +89 -0
- package/skills/algorand-development/references/implement-arc-standards-arc32-arc56.md +396 -0
- package/skills/algorand-development/references/implement-arc-standards-arc4.md +265 -0
- package/skills/algorand-development/references/implement-arc-standards.md +92 -0
- package/skills/algorand-development/references/search-algorand-examples-reference.md +119 -0
- package/skills/algorand-development/references/search-algorand-examples.md +89 -0
- package/skills/algorand-development/references/troubleshoot-errors-contract.md +373 -0
- package/skills/algorand-development/references/troubleshoot-errors-transaction.md +599 -0
- package/skills/algorand-development/references/troubleshoot-errors.md +105 -0
- package/skills/algorand-development/references/use-algokit-cli-reference.md +228 -0
- package/skills/algorand-development/references/use-algokit-cli.md +64 -0
- package/skills/algorand-interaction/SKILL.md +223 -0
- package/skills/algorand-interaction/references/algorand-mcp.md +743 -0
- package/skills/algorand-interaction/references/examples-algorand-mcp.md +647 -0
- package/skills/algorand-python/SKILL.md +95 -0
- package/skills/algorand-python/references/build-smart-contracts-decorators.md +413 -0
- package/skills/algorand-python/references/build-smart-contracts-reference.md +55 -0
- package/skills/algorand-python/references/build-smart-contracts-storage.md +452 -0
- package/skills/algorand-python/references/build-smart-contracts-transactions.md +445 -0
- package/skills/algorand-python/references/build-smart-contracts-types.md +438 -0
- package/skills/algorand-python/references/build-smart-contracts.md +82 -0
- package/skills/algorand-python/references/create-project-reference.md +55 -0
- package/skills/algorand-python/references/create-project.md +75 -0
- package/skills/algorand-python/references/implement-arc-standards-arc32-arc56.md +101 -0
- package/skills/algorand-python/references/implement-arc-standards-arc4.md +154 -0
- package/skills/algorand-python/references/implement-arc-standards.md +39 -0
- package/skills/algorand-python/references/troubleshoot-errors-contract.md +355 -0
- package/skills/algorand-python/references/troubleshoot-errors-transaction.md +430 -0
- package/skills/algorand-python/references/troubleshoot-errors.md +46 -0
- package/skills/algorand-python/references/use-algokit-utils-reference.md +350 -0
- package/skills/algorand-python/references/use-algokit-utils.md +76 -0
- package/skills/algorand-typescript/SKILL.md +131 -0
- package/skills/algorand-typescript/references/algorand-ts-migration-from-beta.md +448 -0
- package/skills/algorand-typescript/references/algorand-ts-migration-from-tealscript.md +487 -0
- package/skills/algorand-typescript/references/algorand-ts-migration.md +102 -0
- package/skills/algorand-typescript/references/algorand-typescript-syntax-methods-and-abi.md +134 -0
- package/skills/algorand-typescript/references/algorand-typescript-syntax-reference.md +58 -0
- package/skills/algorand-typescript/references/algorand-typescript-syntax-storage.md +154 -0
- package/skills/algorand-typescript/references/algorand-typescript-syntax-transactions.md +187 -0
- package/skills/algorand-typescript/references/algorand-typescript-syntax-types-and-values.md +150 -0
- package/skills/algorand-typescript/references/algorand-typescript-syntax.md +84 -0
- package/skills/algorand-typescript/references/build-smart-contracts-reference.md +52 -0
- package/skills/algorand-typescript/references/build-smart-contracts.md +74 -0
- package/skills/algorand-typescript/references/call-smart-contracts-reference.md +237 -0
- package/skills/algorand-typescript/references/call-smart-contracts.md +183 -0
- package/skills/algorand-typescript/references/create-project-reference.md +53 -0
- package/skills/algorand-typescript/references/create-project.md +86 -0
- package/skills/algorand-typescript/references/deploy-react-frontend-examples.md +527 -0
- package/skills/algorand-typescript/references/deploy-react-frontend-reference.md +412 -0
- package/skills/algorand-typescript/references/deploy-react-frontend.md +239 -0
- package/skills/algorand-typescript/references/implement-arc-standards-arc32-arc56.md +73 -0
- package/skills/algorand-typescript/references/implement-arc-standards-arc4.md +126 -0
- package/skills/algorand-typescript/references/implement-arc-standards.md +44 -0
- package/skills/algorand-typescript/references/test-smart-contracts-examples.md +245 -0
- package/skills/algorand-typescript/references/test-smart-contracts-unit-tests.md +147 -0
- package/skills/algorand-typescript/references/test-smart-contracts.md +127 -0
- package/skills/algorand-typescript/references/troubleshoot-errors-contract.md +296 -0
- package/skills/algorand-typescript/references/troubleshoot-errors-transaction.md +438 -0
- package/skills/algorand-typescript/references/troubleshoot-errors.md +56 -0
- package/skills/algorand-typescript/references/use-algokit-utils-reference.md +342 -0
- package/skills/algorand-typescript/references/use-algokit-utils.md +74 -0
- package/skills/algorand-x402-python/SKILL.md +113 -0
- package/skills/algorand-x402-python/references/create-python-x402-client-examples.md +469 -0
- package/skills/algorand-x402-python/references/create-python-x402-client-reference.md +313 -0
- package/skills/algorand-x402-python/references/create-python-x402-client.md +207 -0
- package/skills/algorand-x402-python/references/create-python-x402-facilitator-examples.md +924 -0
- package/skills/algorand-x402-python/references/create-python-x402-facilitator-reference.md +629 -0
- package/skills/algorand-x402-python/references/create-python-x402-facilitator.md +408 -0
- package/skills/algorand-x402-python/references/create-python-x402-server-examples.md +703 -0
- package/skills/algorand-x402-python/references/create-python-x402-server-reference.md +303 -0
- package/skills/algorand-x402-python/references/create-python-x402-server.md +221 -0
- package/skills/algorand-x402-python/references/explain-algorand-x402-python-examples.md +605 -0
- package/skills/algorand-x402-python/references/explain-algorand-x402-python-reference.md +315 -0
- package/skills/algorand-x402-python/references/explain-algorand-x402-python.md +167 -0
- package/skills/algorand-x402-python/references/use-python-x402-core-avm-examples.md +554 -0
- package/skills/algorand-x402-python/references/use-python-x402-core-avm-reference.md +278 -0
- package/skills/algorand-x402-python/references/use-python-x402-core-avm.md +166 -0
- package/skills/algorand-x402-typescript/SKILL.md +129 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-client-examples.md +879 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-client-reference.md +371 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-client.md +236 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-facilitator-examples.md +875 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-facilitator-reference.md +461 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-facilitator.md +270 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-nextjs-examples.md +1181 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-nextjs-reference.md +360 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-nextjs.md +251 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-paywall-examples.md +870 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-paywall-reference.md +323 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-paywall.md +281 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-server-examples.md +1135 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-server-reference.md +382 -0
- package/skills/algorand-x402-typescript/references/create-typescript-x402-server.md +216 -0
- package/skills/algorand-x402-typescript/references/explain-algorand-x402-typescript-examples.md +616 -0
- package/skills/algorand-x402-typescript/references/explain-algorand-x402-typescript-reference.md +323 -0
- package/skills/algorand-x402-typescript/references/explain-algorand-x402-typescript.md +232 -0
- package/skills/algorand-x402-typescript/references/use-typescript-x402-core-avm-examples.md +1417 -0
- package/skills/algorand-x402-typescript/references/use-typescript-x402-core-avm-reference.md +504 -0
- package/skills/algorand-x402-typescript/references/use-typescript-x402-core-avm.md +158 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# Creating x402 Facilitator Services
|
|
2
|
+
|
|
3
|
+
Build facilitator services that verify payment transactions are valid, settle them on-chain, and optionally catalog discovered resources via the Bazaar extension.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
Before using this skill, ensure:
|
|
8
|
+
|
|
9
|
+
1. **Node.js with TypeScript** support
|
|
10
|
+
2. **An Algorand account with ALGO** for covering transaction fees during settlement
|
|
11
|
+
3. **algosdk** installed for transaction signing, simulation, and submission
|
|
12
|
+
|
|
13
|
+
## Core Workflow: What a Facilitator Does
|
|
14
|
+
|
|
15
|
+
A facilitator is the trusted intermediary between a resource server and the blockchain. It performs two operations:
|
|
16
|
+
|
|
17
|
+
1. **Verify** -- Confirms that a payment transaction group is valid (correct amounts, recipients, signatures, timing) without submitting to the network
|
|
18
|
+
2. **Settle** -- Submits the verified transaction group to the Algorand network, co-signing the fee-payer transaction
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
Client Resource Server Facilitator Algorand
|
|
22
|
+
| | | |
|
|
23
|
+
|--- Request + Payment ----->| | |
|
|
24
|
+
| |--- Verify(payload) ------->| |
|
|
25
|
+
| |<-- { isValid: true } ------| |
|
|
26
|
+
| |--- Settle(payload) ------->| |
|
|
27
|
+
| | |--- Sign fee txn ---->|
|
|
28
|
+
| | |--- Send group ------>|
|
|
29
|
+
| | |<-- Confirmation -----|
|
|
30
|
+
| |<-- { success, txId } ------| |
|
|
31
|
+
|<--- 200 + Content ---------| | |
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## How to Proceed
|
|
35
|
+
|
|
36
|
+
### Step 1: Install Dependencies
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install @x402-avm/core @x402-avm/avm algosdk express
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
For Bazaar discovery extension:
|
|
43
|
+
```bash
|
|
44
|
+
npm install @x402-avm/extensions
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Step 2: Implement the FacilitatorAvmSigner
|
|
48
|
+
|
|
49
|
+
The `FacilitatorAvmSigner` interface bridges the facilitator to the Algorand blockchain. It handles signing, simulation, submission, and confirmation:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import algosdk from "algosdk";
|
|
53
|
+
import type { FacilitatorAvmSigner } from "@x402-avm/avm";
|
|
54
|
+
|
|
55
|
+
const secretKey = Buffer.from(process.env.AVM_PRIVATE_KEY!, "base64");
|
|
56
|
+
const address = algosdk.encodeAddress(secretKey.slice(32));
|
|
57
|
+
const algodClient = new algosdk.Algodv2("", "https://testnet-api.algonode.cloud", "");
|
|
58
|
+
|
|
59
|
+
const facilitatorSigner: FacilitatorAvmSigner = {
|
|
60
|
+
getAddresses: () => [address],
|
|
61
|
+
|
|
62
|
+
signTransaction: async (txn: Uint8Array, senderAddress: string) => {
|
|
63
|
+
const decoded = algosdk.decodeUnsignedTransaction(txn);
|
|
64
|
+
const signed = algosdk.signTransaction(decoded, secretKey);
|
|
65
|
+
return signed.blob;
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
getAlgodClient: (network: string) => algodClient,
|
|
69
|
+
|
|
70
|
+
simulateTransactions: async (txns: Uint8Array[], network: string) => {
|
|
71
|
+
const stxns = txns.map((txnBytes) => {
|
|
72
|
+
try {
|
|
73
|
+
return algosdk.decodeSignedTransaction(txnBytes);
|
|
74
|
+
} catch {
|
|
75
|
+
const txn = algosdk.decodeUnsignedTransaction(txnBytes);
|
|
76
|
+
return new algosdk.SignedTransaction({ txn });
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
const request = new algosdk.modelsv2.SimulateRequest({
|
|
80
|
+
txnGroups: [
|
|
81
|
+
new algosdk.modelsv2.SimulateRequestTransactionGroup({ txns: stxns }),
|
|
82
|
+
],
|
|
83
|
+
allowEmptySignatures: true,
|
|
84
|
+
});
|
|
85
|
+
return algodClient.simulateTransactions(request).do();
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
sendTransactions: async (signedTxns: Uint8Array[], network: string) => {
|
|
89
|
+
const combined = Buffer.concat(signedTxns.map((t) => Buffer.from(t)));
|
|
90
|
+
const { txId } = await algodClient.sendRawTransaction(combined).do();
|
|
91
|
+
return txId;
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
waitForConfirmation: async (txId: string, network: string, waitRounds = 4) => {
|
|
95
|
+
return algosdk.waitForConfirmation(algodClient, txId, waitRounds);
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Step 3: Create and Register the Facilitator
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
import { x402Facilitator } from "@x402-avm/core/facilitator";
|
|
104
|
+
import { registerExactAvmScheme } from "@x402-avm/avm/exact/facilitator";
|
|
105
|
+
import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
|
|
106
|
+
|
|
107
|
+
const facilitator = new x402Facilitator();
|
|
108
|
+
|
|
109
|
+
registerExactAvmScheme(facilitator, {
|
|
110
|
+
signer: facilitatorSigner,
|
|
111
|
+
networks: ALGORAND_TESTNET_CAIP2,
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Step 4: Create the Express.js Server
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import express from "express";
|
|
119
|
+
|
|
120
|
+
const app = express();
|
|
121
|
+
app.use(express.json());
|
|
122
|
+
|
|
123
|
+
app.get("/supported", async (_req, res) => {
|
|
124
|
+
const supported = facilitator.getSupportedNetworks();
|
|
125
|
+
res.json(supported);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
app.post("/verify", async (req, res) => {
|
|
129
|
+
const { paymentPayload, paymentRequirements } = req.body;
|
|
130
|
+
const result = await facilitator.verify(paymentPayload, paymentRequirements);
|
|
131
|
+
res.json(result);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
app.post("/settle", async (req, res) => {
|
|
135
|
+
const { paymentPayload, paymentRequirements } = req.body;
|
|
136
|
+
const result = await facilitator.settle(paymentPayload, paymentRequirements);
|
|
137
|
+
res.json(result);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
app.listen(4000, () => console.log("Facilitator running on :4000"));
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Step 5: Add Bazaar Discovery Extension (Optional)
|
|
144
|
+
|
|
145
|
+
The Bazaar extension enables automatic cataloging of x402-protected resources. When resource servers declare discovery metadata, the facilitator can index and serve a discovery API:
|
|
146
|
+
|
|
147
|
+
**On the resource server side -- declare discovery info:**
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import { declareDiscoveryExtension } from "@x402-avm/extensions";
|
|
151
|
+
|
|
152
|
+
const weatherDiscovery = declareDiscoveryExtension({
|
|
153
|
+
input: { city: "San Francisco", units: "metric" },
|
|
154
|
+
inputSchema: {
|
|
155
|
+
properties: {
|
|
156
|
+
city: { type: "string" },
|
|
157
|
+
units: { type: "string", enum: ["metric", "imperial"] },
|
|
158
|
+
},
|
|
159
|
+
required: ["city"],
|
|
160
|
+
},
|
|
161
|
+
output: {
|
|
162
|
+
example: { temperature: 18.5, condition: "Partly Cloudy", humidity: 65 },
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**On the facilitator side -- extract and catalog:**
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { extractDiscoveryInfo, type DiscoveredResource } from "@x402-avm/extensions";
|
|
171
|
+
|
|
172
|
+
facilitator.onAfterSettle(async (context) => {
|
|
173
|
+
if (context.result.success) {
|
|
174
|
+
const discovered = extractDiscoveryInfo(
|
|
175
|
+
context.paymentPayload,
|
|
176
|
+
context.requirements,
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
if (discovered) {
|
|
180
|
+
console.log("Cataloged:", discovered.resourceUrl, discovered.method);
|
|
181
|
+
// Store in database for the discovery API
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Step 6: Add Lifecycle Hooks (Optional)
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
facilitator.onBeforeVerify(async (context) => {
|
|
191
|
+
console.log(`Verifying payment for ${context.requirements.resource}`);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
facilitator.onAfterSettle(async (context) => {
|
|
195
|
+
if (context.result.success) {
|
|
196
|
+
console.log(`Settled: ${context.result.txId}`);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Important Rules / Guidelines
|
|
202
|
+
|
|
203
|
+
1. **Facilitator needs ALGO** -- The facilitator address must have ALGO to pay transaction fees during settlement
|
|
204
|
+
2. **Private key security** -- Store `AVM_PRIVATE_KEY` securely. The facilitator co-signs the fee-payer transaction in each group
|
|
205
|
+
3. **Simulation before settlement** -- The `simulateTransactions` method must wrap unsigned transactions with `new algosdk.SignedTransaction({ txn })` and use `allowEmptySignatures: true`
|
|
206
|
+
4. **sendTransactions expects signed bytes** -- Concatenate all signed transaction bytes with `Buffer.concat()` before calling `sendRawTransaction`
|
|
207
|
+
5. **Network registration** -- Use `ALGORAND_TESTNET_CAIP2` or `ALGORAND_MAINNET_CAIP2` constants, not string literals in SDK code
|
|
208
|
+
6. **Bazaar is optional** -- The Bazaar discovery extension adds cataloging capability but is not required for basic facilitator operation
|
|
209
|
+
|
|
210
|
+
## FacilitatorAvmSigner Interface
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
interface FacilitatorAvmSigner {
|
|
214
|
+
/** Returns the list of addresses this signer controls */
|
|
215
|
+
getAddresses(): string[];
|
|
216
|
+
|
|
217
|
+
/** Sign a single transaction for the given sender address */
|
|
218
|
+
signTransaction(txn: Uint8Array, senderAddress: string): Promise<Uint8Array>;
|
|
219
|
+
|
|
220
|
+
/** Get an Algodv2 client for the specified network */
|
|
221
|
+
getAlgodClient(network: string): algosdk.Algodv2;
|
|
222
|
+
|
|
223
|
+
/** Simulate a transaction group (for verification without submission) */
|
|
224
|
+
simulateTransactions(txns: Uint8Array[], network: string): Promise<any>;
|
|
225
|
+
|
|
226
|
+
/** Send signed transactions to the network */
|
|
227
|
+
sendTransactions(signedTxns: Uint8Array[], network: string): Promise<string>;
|
|
228
|
+
|
|
229
|
+
/** Wait for a transaction to be confirmed */
|
|
230
|
+
waitForConfirmation(
|
|
231
|
+
txId: string,
|
|
232
|
+
network: string,
|
|
233
|
+
waitRounds?: number,
|
|
234
|
+
): Promise<any>;
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Bazaar Discovery Architecture
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
Resource Server Facilitator Client
|
|
242
|
+
| | |
|
|
243
|
+
|-- declareDiscoveryExtension() ------>| |
|
|
244
|
+
| (extensions in PaymentRequired) | |
|
|
245
|
+
| | |
|
|
246
|
+
| Client pays ------->| |
|
|
247
|
+
| |-- extractDiscoveryInfo() |
|
|
248
|
+
| | catalogs resource |
|
|
249
|
+
| | |
|
|
250
|
+
| |<--- /discovery/resources -|
|
|
251
|
+
| |---> list of resources --->|
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Common Errors / Troubleshooting
|
|
255
|
+
|
|
256
|
+
| Error | Cause | Solution |
|
|
257
|
+
|-------|-------|----------|
|
|
258
|
+
| `signer not found` | No AVM_PRIVATE_KEY or wrong format | Ensure Base64-encoded 64-byte key |
|
|
259
|
+
| Simulation fails | Mixed signed/unsigned transactions | Wrap unsigned with `new algosdk.SignedTransaction({ txn })` |
|
|
260
|
+
| `sendRawTransaction` fails | Transaction group not properly concatenated | Use `Buffer.concat(signedTxns.map(t => Buffer.from(t)))` |
|
|
261
|
+
| Settlement times out | Network congestion or low fee | Increase `waitRounds` parameter |
|
|
262
|
+
| `No scheme registered` | `registerExactAvmScheme` not called | Register before handling requests |
|
|
263
|
+
| Discovery not extracted | Extensions not passed through payload | Ensure resource server includes extensions in PaymentRequired |
|
|
264
|
+
|
|
265
|
+
## References / Further Reading
|
|
266
|
+
|
|
267
|
+
- [create-typescript-x402-facilitator-reference.md](./create-typescript-x402-facilitator-reference.md) - Detailed API reference
|
|
268
|
+
- [create-typescript-x402-facilitator-examples.md](./create-typescript-x402-facilitator-examples.md) - Complete code examples
|
|
269
|
+
- [x402-avm Examples Repository](https://github.com/GoPlausible/x402-avm/tree/branch-v2-algorand-publish/examples/)
|
|
270
|
+
- [x402-avm Documentation](https://github.com/GoPlausible/.github/blob/main/profile/algorand-x402-documentation/)
|