@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.
- 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 +41 -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
package/skills/algorand-x402-typescript/references/create-typescript-x402-facilitator-reference.md
ADDED
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
# x402 Facilitator Reference
|
|
2
|
+
|
|
3
|
+
Detailed API reference for `@x402-avm/core/facilitator`, `@x402-avm/avm/exact/facilitator`, and `@x402-avm/extensions` packages.
|
|
4
|
+
|
|
5
|
+
## Package: @x402-avm/core
|
|
6
|
+
|
|
7
|
+
### Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @x402-avm/core @x402-avm/avm algosdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Facilitator Exports from @x402-avm/core/facilitator
|
|
14
|
+
|
|
15
|
+
| Export | Type | Description |
|
|
16
|
+
|--------|------|-------------|
|
|
17
|
+
| `x402Facilitator` | Class | Core facilitator for verifying and settling payments |
|
|
18
|
+
|
|
19
|
+
### Server Exports from @x402-avm/core/server
|
|
20
|
+
|
|
21
|
+
| Export | Type | Description |
|
|
22
|
+
|--------|------|-------------|
|
|
23
|
+
| `x402ResourceServer` | Class | Transport-agnostic resource server |
|
|
24
|
+
| `x402HTTPResourceServer` | Class | HTTP-aware resource server with route config |
|
|
25
|
+
| `HTTPFacilitatorClient` | Class | Client for communicating with a remote facilitator |
|
|
26
|
+
| `ResourceConfig` | Type | Resource payment configuration |
|
|
27
|
+
| `RouteConfig` | Type | HTTP route configuration |
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## x402Facilitator Class
|
|
32
|
+
|
|
33
|
+
The core facilitator that verifies payment validity and settles transactions on-chain.
|
|
34
|
+
|
|
35
|
+
### Methods
|
|
36
|
+
|
|
37
|
+
| Method | Signature | Description |
|
|
38
|
+
|--------|-----------|-------------|
|
|
39
|
+
| `verify` | `(payload, requirements) => Promise<VerifyResult>` | Verify a payment payload without submitting |
|
|
40
|
+
| `settle` | `(payload, requirements) => Promise<SettleResult>` | Verify and settle a payment on-chain |
|
|
41
|
+
| `getSupportedNetworks` | `() => SupportedNetworks` | Return all registered networks |
|
|
42
|
+
| `onBeforeVerify` | `(hook) => void` | Register pre-verification hook |
|
|
43
|
+
| `onAfterVerify` | `(hook) => void` | Register post-verification hook |
|
|
44
|
+
| `onBeforeSettle` | `(hook) => void` | Register pre-settlement hook |
|
|
45
|
+
| `onAfterSettle` | `(hook) => void` | Register post-settlement hook |
|
|
46
|
+
|
|
47
|
+
### verify()
|
|
48
|
+
|
|
49
|
+
Validates a payment payload against requirements without submitting to the network. Checks:
|
|
50
|
+
- Transaction group structure
|
|
51
|
+
- Amounts and recipients
|
|
52
|
+
- Timing (not expired)
|
|
53
|
+
- Signatures (via simulation)
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
const result = await facilitator.verify(paymentPayload, paymentRequirements);
|
|
57
|
+
// result: { isValid: boolean, error?: string }
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### settle()
|
|
61
|
+
|
|
62
|
+
Verifies the payment, co-signs the fee-payer transaction, and submits the group to the network.
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
const result = await facilitator.settle(paymentPayload, paymentRequirements);
|
|
66
|
+
// result: { success: boolean, txId?: string, error?: string }
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## FacilitatorAvmSigner Interface
|
|
72
|
+
|
|
73
|
+
The interface that bridges the facilitator to the Algorand blockchain.
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
interface FacilitatorAvmSigner {
|
|
77
|
+
/**
|
|
78
|
+
* Returns the list of Algorand addresses this facilitator controls.
|
|
79
|
+
* Used to identify which transactions in a group the facilitator should sign.
|
|
80
|
+
*/
|
|
81
|
+
getAddresses(): string[];
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Sign a single unsigned transaction.
|
|
85
|
+
* @param txn - Raw unsigned transaction bytes (msgpack)
|
|
86
|
+
* @param senderAddress - The sender address of the transaction
|
|
87
|
+
* @returns Signed transaction bytes
|
|
88
|
+
*/
|
|
89
|
+
signTransaction(txn: Uint8Array, senderAddress: string): Promise<Uint8Array>;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Get an Algodv2 client configured for the specified network.
|
|
93
|
+
* @param network - CAIP-2 network identifier
|
|
94
|
+
* @returns Configured algosdk.Algodv2 instance
|
|
95
|
+
*/
|
|
96
|
+
getAlgodClient(network: string): algosdk.Algodv2;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Simulate a transaction group for verification without submission.
|
|
100
|
+
* Must handle both signed and unsigned transactions in the group.
|
|
101
|
+
* Use allowEmptySignatures: true for unsigned transactions.
|
|
102
|
+
* @param txns - Array of transaction bytes (mixed signed/unsigned)
|
|
103
|
+
* @param network - CAIP-2 network identifier
|
|
104
|
+
* @returns Simulation result
|
|
105
|
+
*/
|
|
106
|
+
simulateTransactions(txns: Uint8Array[], network: string): Promise<any>;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Send signed transactions to the Algorand network.
|
|
110
|
+
* All transactions must be fully signed before calling this method.
|
|
111
|
+
* Concatenate bytes with Buffer.concat() before sendRawTransaction.
|
|
112
|
+
* @param signedTxns - Array of signed transaction bytes
|
|
113
|
+
* @param network - CAIP-2 network identifier
|
|
114
|
+
* @returns Transaction ID
|
|
115
|
+
*/
|
|
116
|
+
sendTransactions(signedTxns: Uint8Array[], network: string): Promise<string>;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Wait for a transaction to be confirmed on the network.
|
|
120
|
+
* @param txId - Transaction ID to wait for
|
|
121
|
+
* @param network - CAIP-2 network identifier
|
|
122
|
+
* @param waitRounds - Number of rounds to wait (default: 4)
|
|
123
|
+
* @returns Confirmation result
|
|
124
|
+
*/
|
|
125
|
+
waitForConfirmation(
|
|
126
|
+
txId: string,
|
|
127
|
+
network: string,
|
|
128
|
+
waitRounds?: number,
|
|
129
|
+
): Promise<any>;
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Implementation Notes
|
|
134
|
+
|
|
135
|
+
**simulateTransactions**: Must handle mixed signed/unsigned transaction bytes. Wrap unsigned transactions with `new algosdk.SignedTransaction({ txn })`:
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
simulateTransactions: async (txns, network) => {
|
|
139
|
+
const stxns = txns.map((txnBytes) => {
|
|
140
|
+
try {
|
|
141
|
+
return algosdk.decodeSignedTransaction(txnBytes);
|
|
142
|
+
} catch {
|
|
143
|
+
const txn = algosdk.decodeUnsignedTransaction(txnBytes);
|
|
144
|
+
return new algosdk.SignedTransaction({ txn });
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
// ...
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**sendTransactions**: Concatenate all signed transaction bytes before sending:
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
sendTransactions: async (signedTxns, network) => {
|
|
155
|
+
const combined = Buffer.concat(signedTxns.map(t => Buffer.from(t)));
|
|
156
|
+
const { txId } = await algodClient.sendRawTransaction(combined).do();
|
|
157
|
+
return txId;
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Subpath: @x402-avm/avm/exact/facilitator
|
|
164
|
+
|
|
165
|
+
### registerExactAvmScheme (Facilitator)
|
|
166
|
+
|
|
167
|
+
Registers the AVM exact payment scheme with a facilitator instance.
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { registerExactAvmScheme } from "@x402-avm/avm/exact/facilitator";
|
|
171
|
+
|
|
172
|
+
function registerExactAvmScheme(
|
|
173
|
+
facilitator: x402Facilitator,
|
|
174
|
+
config: {
|
|
175
|
+
signer: FacilitatorAvmSigner;
|
|
176
|
+
networks: string | string[];
|
|
177
|
+
},
|
|
178
|
+
): void;
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Note: The `registerExactAvmScheme` function exists at three import paths with different signatures:
|
|
182
|
+
- `@x402-avm/avm/exact/client` -- For client-side (takes `ClientAvmSigner`)
|
|
183
|
+
- `@x402-avm/avm/exact/server` -- For resource server (no signer needed)
|
|
184
|
+
- `@x402-avm/avm/exact/facilitator` -- For facilitator (takes `FacilitatorAvmSigner`)
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Package: @x402-avm/extensions
|
|
189
|
+
|
|
190
|
+
### Installation
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
npm install @x402-avm/extensions @x402-avm/core
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Bazaar Discovery Exports
|
|
197
|
+
|
|
198
|
+
| Export | Type | Description |
|
|
199
|
+
|--------|------|-------------|
|
|
200
|
+
| `BAZAAR` | Constant | Extension key string |
|
|
201
|
+
| `declareDiscoveryExtension` | Function | Declares discovery metadata for a resource |
|
|
202
|
+
| `bazaarResourceServerExtension` | Object | Resource server extension that enriches declarations |
|
|
203
|
+
| `extractDiscoveryInfo` | Function | Extracts discovery info from payment flow |
|
|
204
|
+
| `validateDiscoveryExtension` | Function | Validates a discovery extension object |
|
|
205
|
+
| `validateAndExtract` | Function | Validates and extracts in one step |
|
|
206
|
+
| `extractDiscoveryInfoFromExtension` | Function | Lower-level extraction from extension object |
|
|
207
|
+
| `withBazaar` | Function | Extends a facilitator client with Bazaar query capabilities |
|
|
208
|
+
| `WithExtensions` | Type | Type utility for chaining extensions |
|
|
209
|
+
| `DiscoveryInfo` | Type | Discovery information structure |
|
|
210
|
+
| `DiscoveredResource` | Type | Fully extracted resource with metadata |
|
|
211
|
+
| `ValidationResult` | Type | Result of extension validation |
|
|
212
|
+
| `DiscoveryResourcesResponse` | Type | Response from discovery query |
|
|
213
|
+
| `DiscoveryResource` | Type | Single discovered resource entry |
|
|
214
|
+
| `ListDiscoveryResourcesParams` | Type | Query parameters for listing resources |
|
|
215
|
+
| `BazaarClientExtension` | Type | Extension methods added by withBazaar |
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## declareDiscoveryExtension
|
|
220
|
+
|
|
221
|
+
Creates discovery metadata to include in the `PaymentRequired` response.
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
function declareDiscoveryExtension(config: {
|
|
225
|
+
/** Example input values (query params or body) */
|
|
226
|
+
input?: Record<string, any>;
|
|
227
|
+
/** JSON Schema for validating input */
|
|
228
|
+
inputSchema?: object;
|
|
229
|
+
/** Body type for POST endpoints */
|
|
230
|
+
bodyType?: "json" | "form-data";
|
|
231
|
+
/** Output specification */
|
|
232
|
+
output?: {
|
|
233
|
+
/** Example response */
|
|
234
|
+
example?: any;
|
|
235
|
+
/** JSON Schema for output */
|
|
236
|
+
schema?: object;
|
|
237
|
+
};
|
|
238
|
+
}): { bazaar: { info: DiscoveryInfo; schema: object } };
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Discovery Info Structure
|
|
242
|
+
|
|
243
|
+
V2 format includes:
|
|
244
|
+
- `info`: Contains the actual discovery data (method, params, output examples)
|
|
245
|
+
- `schema`: JSON Schema that validates the structure of `info`
|
|
246
|
+
|
|
247
|
+
V1 compatibility: V1 data stored in `PaymentRequirements.outputSchema` is automatically transformed to V2 `DiscoveryInfo` format.
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## extractDiscoveryInfo
|
|
252
|
+
|
|
253
|
+
Extracts discovery information from a payment flow. Handles both V2 and V1 formats automatically.
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
function extractDiscoveryInfo(
|
|
257
|
+
paymentPayload: PaymentPayload,
|
|
258
|
+
paymentRequirements: PaymentRequirements,
|
|
259
|
+
validate?: boolean, // default: true
|
|
260
|
+
): DiscoveredResource | null;
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### DiscoveredResource
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
interface DiscoveredResource {
|
|
267
|
+
/** URL of the discovered resource */
|
|
268
|
+
resourceUrl: string;
|
|
269
|
+
/** HTTP method (GET, POST, etc.) */
|
|
270
|
+
method: string;
|
|
271
|
+
/** x402 protocol version (1 or 2) */
|
|
272
|
+
x402Version: number;
|
|
273
|
+
/** Human-readable description */
|
|
274
|
+
description: string;
|
|
275
|
+
/** Response MIME type */
|
|
276
|
+
mimeType: string;
|
|
277
|
+
/** Full discovery information */
|
|
278
|
+
discoveryInfo: DiscoveryInfo;
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## bazaarResourceServerExtension
|
|
285
|
+
|
|
286
|
+
A resource server extension that enriches discovery declarations at request time by narrowing the HTTP method to the actual method used.
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
// Register on resource server
|
|
290
|
+
httpServer.resourceServer.registerExtension(bazaarResourceServerExtension);
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
When the resource server builds a `PaymentRequired` response, this extension's `enrichDeclaration` hook automatically sets the method field based on the incoming HTTP request method.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## withBazaar
|
|
298
|
+
|
|
299
|
+
Extends an `HTTPFacilitatorClient` with Bazaar discovery query capabilities.
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
function withBazaar<T extends HTTPFacilitatorClient>(
|
|
303
|
+
client: T,
|
|
304
|
+
): T & { extensions: { discovery: BazaarClientExtension } };
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### BazaarClientExtension
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
interface BazaarClientExtension {
|
|
311
|
+
listResources(params?: ListDiscoveryResourcesParams): Promise<DiscoveryResourcesResponse>;
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### ListDiscoveryResourcesParams
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
interface ListDiscoveryResourcesParams {
|
|
319
|
+
/** Filter by resource type (e.g., "http") */
|
|
320
|
+
type?: string;
|
|
321
|
+
/** Maximum number of results */
|
|
322
|
+
limit?: number;
|
|
323
|
+
/** Offset for pagination */
|
|
324
|
+
offset?: number;
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### DiscoveryResourcesResponse
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
interface DiscoveryResourcesResponse {
|
|
332
|
+
items: DiscoveryResource[];
|
|
333
|
+
pagination: {
|
|
334
|
+
limit: number;
|
|
335
|
+
offset: number;
|
|
336
|
+
total: number;
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## WithExtensions Type Utility
|
|
344
|
+
|
|
345
|
+
Properly merges extension types when chaining multiple extensions on a client.
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
type WithExtensions<T, E> = T extends { extensions: infer Existing }
|
|
349
|
+
? Omit<T, "extensions"> & { extensions: Existing & E }
|
|
350
|
+
: T & { extensions: E };
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
When `T` has no existing extensions, the result is `T & { extensions: E }`. When `T` already has extensions (from chaining), the new extension type is merged with existing ones.
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## Lifecycle Hooks
|
|
358
|
+
|
|
359
|
+
### Facilitator Hooks
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
facilitator.onBeforeVerify(async (context) => {
|
|
363
|
+
// context.paymentPayload, context.requirements
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
facilitator.onAfterVerify(async (context) => {
|
|
367
|
+
// context.result - verification result
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
facilitator.onBeforeSettle(async (context) => {
|
|
371
|
+
// context.paymentPayload, context.requirements
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
facilitator.onAfterSettle(async (context) => {
|
|
375
|
+
// context.result - settlement result
|
|
376
|
+
// context.paymentPayload, context.requirements
|
|
377
|
+
// Good place to extract discovery info for Bazaar cataloging
|
|
378
|
+
});
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## Environment Variables
|
|
384
|
+
|
|
385
|
+
| Variable | Description | Format |
|
|
386
|
+
|----------|-------------|--------|
|
|
387
|
+
| `AVM_PRIVATE_KEY` | Facilitator's Algorand private key | Base64-encoded 64-byte key (32-byte seed + 32-byte pubkey) |
|
|
388
|
+
| `ALGOD_SERVER` | Algod server URL | URL string |
|
|
389
|
+
| `ALGOD_TOKEN` | Algod API token | String |
|
|
390
|
+
| `ALGOD_TESTNET_URL` | Custom testnet Algod URL | URL (default: `https://testnet-api.algonode.cloud`) |
|
|
391
|
+
| `ALGOD_MAINNET_URL` | Custom mainnet Algod URL | URL (default: `https://mainnet-api.algonode.cloud`) |
|
|
392
|
+
| `FACILITATOR_URL` | URL of the facilitator service | URL string |
|
|
393
|
+
| `FACILITATOR_API_KEY` | API key for authenticated facilitator access | String |
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
## Network Constants
|
|
398
|
+
|
|
399
|
+
| Constant | Value |
|
|
400
|
+
|----------|-------|
|
|
401
|
+
| `ALGORAND_TESTNET_CAIP2` | `"algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI="` |
|
|
402
|
+
| `ALGORAND_MAINNET_CAIP2` | `"algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8="` |
|
|
403
|
+
| `USDC_TESTNET_ASA_ID` | `"10458941"` |
|
|
404
|
+
| `USDC_MAINNET_ASA_ID` | `"31566704"` |
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## Testing
|
|
409
|
+
|
|
410
|
+
### Testing a Facilitator Locally
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
# Start the facilitator
|
|
414
|
+
AVM_PRIVATE_KEY="your-base64-key" npx tsx facilitator.ts
|
|
415
|
+
|
|
416
|
+
# Check supported networks
|
|
417
|
+
curl http://localhost:4000/supported
|
|
418
|
+
|
|
419
|
+
# Verify a payment (requires valid payload)
|
|
420
|
+
curl -X POST http://localhost:4000/verify \
|
|
421
|
+
-H "Content-Type: application/json" \
|
|
422
|
+
-d '{"paymentPayload": {...}, "paymentRequirements": {...}}'
|
|
423
|
+
|
|
424
|
+
# Settle a payment
|
|
425
|
+
curl -X POST http://localhost:4000/settle \
|
|
426
|
+
-H "Content-Type: application/json" \
|
|
427
|
+
-d '{"paymentPayload": {...}, "paymentRequirements": {...}}'
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Testing Bazaar Discovery
|
|
431
|
+
|
|
432
|
+
```bash
|
|
433
|
+
# List all discovered resources
|
|
434
|
+
curl http://localhost:4000/discovery/resources
|
|
435
|
+
|
|
436
|
+
# Filter by type
|
|
437
|
+
curl "http://localhost:4000/discovery/resources?type=http"
|
|
438
|
+
|
|
439
|
+
# With pagination
|
|
440
|
+
curl "http://localhost:4000/discovery/resources?limit=10&offset=0"
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
## Important Notes
|
|
446
|
+
|
|
447
|
+
- The facilitator address must have ALGO to cover transaction fees. Each settlement requires a minimum of 0.001 ALGO for the fee-payer transaction.
|
|
448
|
+
- `simulateTransactions` must handle both signed and unsigned transaction bytes in the same group. The client signs their payment transaction; the facilitator's fee-payer transaction arrives unsigned.
|
|
449
|
+
- `sendTransactions` receives an array of individually signed transaction bytes. Concatenate them with `Buffer.concat()` before calling `sendRawTransaction`.
|
|
450
|
+
- The `registerExactAvmScheme` function at `@x402-avm/avm/exact/facilitator` is distinct from the client and server variants. Always import from the correct subpath.
|
|
451
|
+
- Bazaar discovery is purely additive. If no extensions are present in the payment payload, the facilitator operates normally without cataloging.
|
|
452
|
+
- The `withBazaar` function mutates the client in place and adds an `extensions.discovery` namespace. It is safe to chain with other extension wrappers.
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
## External Resources
|
|
457
|
+
|
|
458
|
+
- [x402-avm Examples Repository](https://github.com/GoPlausible/x402-avm/tree/branch-v2-algorand-publish/examples/)
|
|
459
|
+
- [x402-avm Documentation](https://github.com/GoPlausible/.github/blob/main/profile/algorand-x402-documentation/)
|
|
460
|
+
- [algosdk TypeScript Reference](https://algorand.github.io/js-algorand-sdk/)
|
|
461
|
+
- [Algorand Simulate API](https://developer.algorand.org/docs/rest-apis/algod/#post-v2transactionssimulate)
|