@chaoschain/sdk 0.1.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 +525 -0
- package/dist/index.js +3549 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3484 -0
- package/dist/index.mjs.map +1 -0
- package/dist/providers/compute/index.js +15 -0
- package/dist/providers/compute/index.js.map +1 -0
- package/dist/providers/compute/index.mjs +13 -0
- package/dist/providers/compute/index.mjs.map +1 -0
- package/dist/providers/storage/index.js +286 -0
- package/dist/providers/storage/index.js.map +1 -0
- package/dist/providers/storage/index.mjs +278 -0
- package/dist/providers/storage/index.mjs.map +1 -0
- package/package.json +93 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,3484 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
import * as fs2 from 'fs';
|
|
3
|
+
import * as path2 from 'path';
|
|
4
|
+
import axios2 from 'axios';
|
|
5
|
+
import * as http from 'http';
|
|
6
|
+
import * as crypto from 'crypto';
|
|
7
|
+
import { createHash } from 'crypto';
|
|
8
|
+
import * as jose from 'jose';
|
|
9
|
+
|
|
10
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
11
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
12
|
+
}) : x)(function(x) {
|
|
13
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
14
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
15
|
+
});
|
|
16
|
+
var WalletManager = class _WalletManager {
|
|
17
|
+
wallet;
|
|
18
|
+
provider;
|
|
19
|
+
constructor(config, provider) {
|
|
20
|
+
this.wallet = this.initializeWallet(config);
|
|
21
|
+
this.provider = provider;
|
|
22
|
+
if (provider) {
|
|
23
|
+
this.wallet = this.wallet.connect(provider);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Initialize wallet from various sources
|
|
28
|
+
*/
|
|
29
|
+
initializeWallet(config) {
|
|
30
|
+
if (config.privateKey) {
|
|
31
|
+
return new ethers.Wallet(config.privateKey);
|
|
32
|
+
}
|
|
33
|
+
if (config.mnemonic) {
|
|
34
|
+
return ethers.Wallet.fromPhrase(config.mnemonic);
|
|
35
|
+
}
|
|
36
|
+
if (config.walletFile) {
|
|
37
|
+
return this.loadFromFile(config.walletFile);
|
|
38
|
+
}
|
|
39
|
+
return ethers.Wallet.createRandom();
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Load wallet from encrypted file
|
|
43
|
+
*/
|
|
44
|
+
loadFromFile(filePath) {
|
|
45
|
+
try {
|
|
46
|
+
const walletData = fs2.readFileSync(filePath, "utf8");
|
|
47
|
+
const data = JSON.parse(walletData);
|
|
48
|
+
if (data.encrypted) {
|
|
49
|
+
throw new Error("Encrypted wallets require password (not yet implemented)");
|
|
50
|
+
}
|
|
51
|
+
return new ethers.Wallet(data.privateKey);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
throw new Error(`Failed to load wallet from file: ${error.message}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Save wallet to encrypted file
|
|
58
|
+
*/
|
|
59
|
+
async saveToFile(filePath, password) {
|
|
60
|
+
const directory = path2.dirname(filePath);
|
|
61
|
+
if (!fs2.existsSync(directory)) {
|
|
62
|
+
fs2.mkdirSync(directory, { recursive: true });
|
|
63
|
+
}
|
|
64
|
+
if (password) {
|
|
65
|
+
const encrypted = await this.wallet.encrypt(password);
|
|
66
|
+
fs2.writeFileSync(filePath, encrypted, "utf8");
|
|
67
|
+
} else {
|
|
68
|
+
const data = {
|
|
69
|
+
address: this.wallet.address,
|
|
70
|
+
privateKey: this.wallet.privateKey,
|
|
71
|
+
mnemonic: this.wallet.mnemonic?.phrase,
|
|
72
|
+
encrypted: false
|
|
73
|
+
};
|
|
74
|
+
fs2.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf8");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get wallet instance
|
|
79
|
+
*/
|
|
80
|
+
getWallet() {
|
|
81
|
+
return this.wallet;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get wallet address
|
|
85
|
+
*/
|
|
86
|
+
getAddress() {
|
|
87
|
+
return this.wallet.address;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get private key (use with caution)
|
|
91
|
+
*/
|
|
92
|
+
getPrivateKey() {
|
|
93
|
+
return this.wallet.privateKey;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get mnemonic phrase (if available)
|
|
97
|
+
*/
|
|
98
|
+
getMnemonic() {
|
|
99
|
+
return this.wallet.mnemonic?.phrase;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Sign a message
|
|
103
|
+
*/
|
|
104
|
+
async signMessage(message) {
|
|
105
|
+
return this.wallet.signMessage(message);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Sign typed data (EIP-712)
|
|
109
|
+
*/
|
|
110
|
+
async signTypedData(domain, types, value) {
|
|
111
|
+
return this.wallet.signTypedData(domain, types, value);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get balance
|
|
115
|
+
*/
|
|
116
|
+
async getBalance() {
|
|
117
|
+
if (!this.provider) {
|
|
118
|
+
throw new Error("Provider not set");
|
|
119
|
+
}
|
|
120
|
+
return this.provider.getBalance(this.wallet.address);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get nonce
|
|
124
|
+
*/
|
|
125
|
+
async getNonce() {
|
|
126
|
+
if (!this.provider) {
|
|
127
|
+
throw new Error("Provider not set");
|
|
128
|
+
}
|
|
129
|
+
return this.provider.getTransactionCount(this.wallet.address);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Connect to a new provider
|
|
133
|
+
*/
|
|
134
|
+
connect(provider) {
|
|
135
|
+
this.provider = provider;
|
|
136
|
+
this.wallet = this.wallet.connect(provider);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Generate a new random wallet
|
|
140
|
+
*/
|
|
141
|
+
static createRandom() {
|
|
142
|
+
const wallet = ethers.Wallet.createRandom();
|
|
143
|
+
return new _WalletManager({ privateKey: wallet.privateKey });
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Create from mnemonic
|
|
147
|
+
*/
|
|
148
|
+
static fromMnemonic(mnemonic, provider) {
|
|
149
|
+
return new _WalletManager({ mnemonic }, provider);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Create from private key
|
|
153
|
+
*/
|
|
154
|
+
static fromPrivateKey(privateKey, provider) {
|
|
155
|
+
return new _WalletManager({ privateKey }, provider);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Generate new mnemonic
|
|
159
|
+
*/
|
|
160
|
+
static generateMnemonic() {
|
|
161
|
+
return ethers.Wallet.createRandom().mnemonic?.phrase || "";
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Validate mnemonic
|
|
165
|
+
*/
|
|
166
|
+
static isValidMnemonic(mnemonic) {
|
|
167
|
+
try {
|
|
168
|
+
ethers.Wallet.fromPhrase(mnemonic);
|
|
169
|
+
return true;
|
|
170
|
+
} catch {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Validate private key
|
|
176
|
+
*/
|
|
177
|
+
static isValidPrivateKey(privateKey) {
|
|
178
|
+
try {
|
|
179
|
+
new ethers.Wallet(privateKey);
|
|
180
|
+
return true;
|
|
181
|
+
} catch {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Derive child wallet from HD path
|
|
187
|
+
*/
|
|
188
|
+
static deriveChild(mnemonic, path3) {
|
|
189
|
+
const hdNode = ethers.HDNodeWallet.fromPhrase(mnemonic, void 0, path3);
|
|
190
|
+
return new _WalletManager({ privateKey: hdNode.privateKey });
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// src/utils/contracts.ts
|
|
195
|
+
var IDENTITY_REGISTRY_ABI = [
|
|
196
|
+
{
|
|
197
|
+
inputs: [
|
|
198
|
+
{ name: "tokenURI_", type: "string" },
|
|
199
|
+
{
|
|
200
|
+
name: "metadata",
|
|
201
|
+
type: "tuple[]",
|
|
202
|
+
components: [
|
|
203
|
+
{ name: "key", type: "string" },
|
|
204
|
+
{ name: "value", type: "bytes" }
|
|
205
|
+
]
|
|
206
|
+
}
|
|
207
|
+
],
|
|
208
|
+
name: "register",
|
|
209
|
+
outputs: [{ name: "agentId", type: "uint256" }],
|
|
210
|
+
stateMutability: "nonpayable",
|
|
211
|
+
type: "function"
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
inputs: [{ name: "tokenURI_", type: "string" }],
|
|
215
|
+
name: "register",
|
|
216
|
+
outputs: [{ name: "agentId", type: "uint256" }],
|
|
217
|
+
stateMutability: "nonpayable",
|
|
218
|
+
type: "function"
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
inputs: [],
|
|
222
|
+
name: "register",
|
|
223
|
+
outputs: [{ name: "agentId", type: "uint256" }],
|
|
224
|
+
stateMutability: "nonpayable",
|
|
225
|
+
type: "function"
|
|
226
|
+
},
|
|
227
|
+
// ERC-721 Standard Functions
|
|
228
|
+
{
|
|
229
|
+
inputs: [{ name: "tokenId", type: "uint256" }],
|
|
230
|
+
name: "ownerOf",
|
|
231
|
+
outputs: [{ name: "owner", type: "address" }],
|
|
232
|
+
stateMutability: "view",
|
|
233
|
+
type: "function"
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
inputs: [{ name: "owner", type: "address" }],
|
|
237
|
+
name: "balanceOf",
|
|
238
|
+
outputs: [{ name: "balance", type: "uint256" }],
|
|
239
|
+
stateMutability: "view",
|
|
240
|
+
type: "function"
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
inputs: [{ name: "tokenId", type: "uint256" }],
|
|
244
|
+
name: "tokenURI",
|
|
245
|
+
outputs: [{ name: "", type: "string" }],
|
|
246
|
+
stateMutability: "view",
|
|
247
|
+
type: "function"
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
inputs: [
|
|
251
|
+
{ name: "from", type: "address" },
|
|
252
|
+
{ name: "to", type: "address" },
|
|
253
|
+
{ name: "tokenId", type: "uint256" }
|
|
254
|
+
],
|
|
255
|
+
name: "transferFrom",
|
|
256
|
+
outputs: [],
|
|
257
|
+
stateMutability: "nonpayable",
|
|
258
|
+
type: "function"
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
inputs: [
|
|
262
|
+
{ name: "to", type: "address" },
|
|
263
|
+
{ name: "tokenId", type: "uint256" }
|
|
264
|
+
],
|
|
265
|
+
name: "approve",
|
|
266
|
+
outputs: [],
|
|
267
|
+
stateMutability: "nonpayable",
|
|
268
|
+
type: "function"
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
inputs: [
|
|
272
|
+
{ name: "operator", type: "address" },
|
|
273
|
+
{ name: "approved", type: "bool" }
|
|
274
|
+
],
|
|
275
|
+
name: "setApprovalForAll",
|
|
276
|
+
outputs: [],
|
|
277
|
+
stateMutability: "nonpayable",
|
|
278
|
+
type: "function"
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
inputs: [{ name: "tokenId", type: "uint256" }],
|
|
282
|
+
name: "getApproved",
|
|
283
|
+
outputs: [{ name: "operator", type: "address" }],
|
|
284
|
+
stateMutability: "view",
|
|
285
|
+
type: "function"
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
inputs: [
|
|
289
|
+
{ name: "owner", type: "address" },
|
|
290
|
+
{ name: "operator", type: "address" }
|
|
291
|
+
],
|
|
292
|
+
name: "isApprovedForAll",
|
|
293
|
+
outputs: [{ name: "approved", type: "bool" }],
|
|
294
|
+
stateMutability: "view",
|
|
295
|
+
type: "function"
|
|
296
|
+
},
|
|
297
|
+
// Metadata Functions
|
|
298
|
+
{
|
|
299
|
+
inputs: [
|
|
300
|
+
{ name: "agentId", type: "uint256" },
|
|
301
|
+
{ name: "key", type: "string" },
|
|
302
|
+
{ name: "value", type: "bytes" }
|
|
303
|
+
],
|
|
304
|
+
name: "setMetadata",
|
|
305
|
+
outputs: [],
|
|
306
|
+
stateMutability: "nonpayable",
|
|
307
|
+
type: "function"
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
inputs: [
|
|
311
|
+
{ name: "agentId", type: "uint256" },
|
|
312
|
+
{ name: "key", type: "string" }
|
|
313
|
+
],
|
|
314
|
+
name: "getMetadata",
|
|
315
|
+
outputs: [{ name: "value", type: "bytes" }],
|
|
316
|
+
stateMutability: "view",
|
|
317
|
+
type: "function"
|
|
318
|
+
},
|
|
319
|
+
// Additional Functions
|
|
320
|
+
{
|
|
321
|
+
inputs: [
|
|
322
|
+
{ name: "agentId", type: "uint256" },
|
|
323
|
+
{ name: "newUri", type: "string" }
|
|
324
|
+
],
|
|
325
|
+
name: "setAgentUri",
|
|
326
|
+
outputs: [],
|
|
327
|
+
stateMutability: "nonpayable",
|
|
328
|
+
type: "function"
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
inputs: [],
|
|
332
|
+
name: "totalAgents",
|
|
333
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
334
|
+
stateMutability: "view",
|
|
335
|
+
type: "function"
|
|
336
|
+
},
|
|
337
|
+
// Events
|
|
338
|
+
{
|
|
339
|
+
anonymous: false,
|
|
340
|
+
inputs: [
|
|
341
|
+
{ indexed: true, name: "agentId", type: "uint256" },
|
|
342
|
+
{ indexed: false, name: "tokenURI", type: "string" },
|
|
343
|
+
{ indexed: true, name: "owner", type: "address" }
|
|
344
|
+
],
|
|
345
|
+
name: "Registered",
|
|
346
|
+
type: "event"
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
anonymous: false,
|
|
350
|
+
inputs: [
|
|
351
|
+
{ indexed: true, name: "agentId", type: "uint256" },
|
|
352
|
+
{ indexed: true, name: "indexedKey", type: "string" },
|
|
353
|
+
{ indexed: false, name: "key", type: "string" },
|
|
354
|
+
{ indexed: false, name: "value", type: "bytes" }
|
|
355
|
+
],
|
|
356
|
+
name: "MetadataSet",
|
|
357
|
+
type: "event"
|
|
358
|
+
},
|
|
359
|
+
// ERC-721 Standard Events
|
|
360
|
+
{
|
|
361
|
+
anonymous: false,
|
|
362
|
+
inputs: [
|
|
363
|
+
{ indexed: true, name: "from", type: "address" },
|
|
364
|
+
{ indexed: true, name: "to", type: "address" },
|
|
365
|
+
{ indexed: true, name: "tokenId", type: "uint256" }
|
|
366
|
+
],
|
|
367
|
+
name: "Transfer",
|
|
368
|
+
type: "event"
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
anonymous: false,
|
|
372
|
+
inputs: [
|
|
373
|
+
{ indexed: true, name: "owner", type: "address" },
|
|
374
|
+
{ indexed: true, name: "approved", type: "address" },
|
|
375
|
+
{ indexed: true, name: "tokenId", type: "uint256" }
|
|
376
|
+
],
|
|
377
|
+
name: "Approval",
|
|
378
|
+
type: "event"
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
anonymous: false,
|
|
382
|
+
inputs: [
|
|
383
|
+
{ indexed: true, name: "owner", type: "address" },
|
|
384
|
+
{ indexed: true, name: "operator", type: "address" },
|
|
385
|
+
{ indexed: false, name: "approved", type: "bool" }
|
|
386
|
+
],
|
|
387
|
+
name: "ApprovalForAll",
|
|
388
|
+
type: "event"
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
anonymous: false,
|
|
392
|
+
inputs: [
|
|
393
|
+
{ indexed: true, name: "agentId", type: "uint256" },
|
|
394
|
+
{ indexed: false, name: "newUri", type: "string" },
|
|
395
|
+
{ indexed: true, name: "updatedBy", type: "address" }
|
|
396
|
+
],
|
|
397
|
+
name: "UriUpdated",
|
|
398
|
+
type: "event"
|
|
399
|
+
}
|
|
400
|
+
];
|
|
401
|
+
var REPUTATION_REGISTRY_ABI = [
|
|
402
|
+
// Core Functions
|
|
403
|
+
{
|
|
404
|
+
inputs: [
|
|
405
|
+
{ name: "agentId", type: "uint256" },
|
|
406
|
+
{ name: "score", type: "uint8" },
|
|
407
|
+
{ name: "tag1", type: "bytes32" },
|
|
408
|
+
{ name: "tag2", type: "bytes32" },
|
|
409
|
+
{ name: "feedbackUri", type: "string" },
|
|
410
|
+
{ name: "feedbackHash", type: "bytes32" },
|
|
411
|
+
{ name: "feedbackAuth", type: "bytes" }
|
|
412
|
+
],
|
|
413
|
+
name: "giveFeedback",
|
|
414
|
+
outputs: [],
|
|
415
|
+
stateMutability: "nonpayable",
|
|
416
|
+
type: "function"
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
inputs: [
|
|
420
|
+
{ name: "agentId", type: "uint256" },
|
|
421
|
+
{ name: "feedbackIndex", type: "uint64" }
|
|
422
|
+
],
|
|
423
|
+
name: "revokeFeedback",
|
|
424
|
+
outputs: [],
|
|
425
|
+
stateMutability: "nonpayable",
|
|
426
|
+
type: "function"
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
inputs: [
|
|
430
|
+
{ name: "agentId", type: "uint256" },
|
|
431
|
+
{ name: "clientAddress", type: "address" },
|
|
432
|
+
{ name: "feedbackIndex", type: "uint64" },
|
|
433
|
+
{ name: "responseUri", type: "string" },
|
|
434
|
+
{ name: "responseHash", type: "bytes32" }
|
|
435
|
+
],
|
|
436
|
+
name: "appendResponse",
|
|
437
|
+
outputs: [],
|
|
438
|
+
stateMutability: "nonpayable",
|
|
439
|
+
type: "function"
|
|
440
|
+
},
|
|
441
|
+
// Read Functions
|
|
442
|
+
{
|
|
443
|
+
inputs: [
|
|
444
|
+
{ name: "agentId", type: "uint256" },
|
|
445
|
+
{ name: "clientAddresses", type: "address[]" },
|
|
446
|
+
{ name: "tag1", type: "bytes32" },
|
|
447
|
+
{ name: "tag2", type: "bytes32" }
|
|
448
|
+
],
|
|
449
|
+
name: "getSummary",
|
|
450
|
+
outputs: [
|
|
451
|
+
{ name: "count", type: "uint64" },
|
|
452
|
+
{ name: "averageScore", type: "uint8" }
|
|
453
|
+
],
|
|
454
|
+
stateMutability: "view",
|
|
455
|
+
type: "function"
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
inputs: [
|
|
459
|
+
{ name: "agentId", type: "uint256" },
|
|
460
|
+
{ name: "clientAddress", type: "address" },
|
|
461
|
+
{ name: "index", type: "uint64" }
|
|
462
|
+
],
|
|
463
|
+
name: "readFeedback",
|
|
464
|
+
outputs: [
|
|
465
|
+
{ name: "score", type: "uint8" },
|
|
466
|
+
{ name: "tag1", type: "bytes32" },
|
|
467
|
+
{ name: "tag2", type: "bytes32" },
|
|
468
|
+
{ name: "isRevoked", type: "bool" }
|
|
469
|
+
],
|
|
470
|
+
stateMutability: "view",
|
|
471
|
+
type: "function"
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
inputs: [
|
|
475
|
+
{ name: "agentId", type: "uint256" },
|
|
476
|
+
{ name: "clientAddresses", type: "address[]" },
|
|
477
|
+
{ name: "tag1", type: "bytes32" },
|
|
478
|
+
{ name: "tag2", type: "bytes32" },
|
|
479
|
+
{ name: "includeRevoked", type: "bool" }
|
|
480
|
+
],
|
|
481
|
+
name: "readAllFeedback",
|
|
482
|
+
outputs: [
|
|
483
|
+
{ name: "clients", type: "address[]" },
|
|
484
|
+
{ name: "scores", type: "uint8[]" },
|
|
485
|
+
{ name: "tag1s", type: "bytes32[]" },
|
|
486
|
+
{ name: "tag2s", type: "bytes32[]" },
|
|
487
|
+
{ name: "revokedStatuses", type: "bool[]" }
|
|
488
|
+
],
|
|
489
|
+
stateMutability: "view",
|
|
490
|
+
type: "function"
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
inputs: [{ name: "agentId", type: "uint256" }],
|
|
494
|
+
name: "getClients",
|
|
495
|
+
outputs: [{ name: "clientList", type: "address[]" }],
|
|
496
|
+
stateMutability: "view",
|
|
497
|
+
type: "function"
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
inputs: [
|
|
501
|
+
{ name: "agentId", type: "uint256" },
|
|
502
|
+
{ name: "clientAddress", type: "address" }
|
|
503
|
+
],
|
|
504
|
+
name: "getLastIndex",
|
|
505
|
+
outputs: [{ name: "lastIndex", type: "uint64" }],
|
|
506
|
+
stateMutability: "view",
|
|
507
|
+
type: "function"
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
inputs: [],
|
|
511
|
+
name: "getIdentityRegistry",
|
|
512
|
+
outputs: [{ name: "registry", type: "address" }],
|
|
513
|
+
stateMutability: "view",
|
|
514
|
+
type: "function"
|
|
515
|
+
},
|
|
516
|
+
// Events
|
|
517
|
+
{
|
|
518
|
+
anonymous: false,
|
|
519
|
+
inputs: [
|
|
520
|
+
{ indexed: true, name: "agentId", type: "uint256" },
|
|
521
|
+
{ indexed: true, name: "clientAddress", type: "address" },
|
|
522
|
+
{ indexed: false, name: "score", type: "uint8" },
|
|
523
|
+
{ indexed: true, name: "tag1", type: "bytes32" },
|
|
524
|
+
{ indexed: false, name: "tag2", type: "bytes32" },
|
|
525
|
+
{ indexed: false, name: "feedbackUri", type: "string" },
|
|
526
|
+
{ indexed: false, name: "feedbackHash", type: "bytes32" }
|
|
527
|
+
],
|
|
528
|
+
name: "NewFeedback",
|
|
529
|
+
type: "event"
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
anonymous: false,
|
|
533
|
+
inputs: [
|
|
534
|
+
{ indexed: true, name: "agentId", type: "uint256" },
|
|
535
|
+
{ indexed: true, name: "clientAddress", type: "address" },
|
|
536
|
+
{ indexed: false, name: "feedbackIndex", type: "uint64" },
|
|
537
|
+
{ indexed: true, name: "responder", type: "address" },
|
|
538
|
+
{ indexed: false, name: "responseUri", type: "string" },
|
|
539
|
+
{ indexed: false, name: "responseHash", type: "bytes32" }
|
|
540
|
+
],
|
|
541
|
+
name: "ResponseAppended",
|
|
542
|
+
type: "event"
|
|
543
|
+
}
|
|
544
|
+
];
|
|
545
|
+
var VALIDATION_REGISTRY_ABI = [
|
|
546
|
+
// Core Functions
|
|
547
|
+
{
|
|
548
|
+
inputs: [
|
|
549
|
+
{ name: "validatorAddress", type: "address" },
|
|
550
|
+
{ name: "agentId", type: "uint256" },
|
|
551
|
+
{ name: "requestUri", type: "string" },
|
|
552
|
+
{ name: "requestHash", type: "bytes32" }
|
|
553
|
+
],
|
|
554
|
+
name: "validationRequest",
|
|
555
|
+
outputs: [],
|
|
556
|
+
stateMutability: "nonpayable",
|
|
557
|
+
type: "function"
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
inputs: [
|
|
561
|
+
{ name: "requestHash", type: "bytes32" },
|
|
562
|
+
{ name: "response", type: "uint8" },
|
|
563
|
+
{ name: "responseUri", type: "string" },
|
|
564
|
+
{ name: "responseHash", type: "bytes32" },
|
|
565
|
+
{ name: "tag", type: "bytes32" }
|
|
566
|
+
],
|
|
567
|
+
name: "validationResponse",
|
|
568
|
+
outputs: [],
|
|
569
|
+
stateMutability: "nonpayable",
|
|
570
|
+
type: "function"
|
|
571
|
+
},
|
|
572
|
+
// Read Functions
|
|
573
|
+
{
|
|
574
|
+
inputs: [{ name: "requestHash", type: "bytes32" }],
|
|
575
|
+
name: "getValidationStatus",
|
|
576
|
+
outputs: [
|
|
577
|
+
{ name: "validatorAddress", type: "address" },
|
|
578
|
+
{ name: "agentId", type: "uint256" },
|
|
579
|
+
{ name: "response", type: "uint8" },
|
|
580
|
+
{ name: "responseHash", type: "bytes32" },
|
|
581
|
+
{ name: "tag", type: "bytes32" },
|
|
582
|
+
{ name: "lastUpdate", type: "uint256" }
|
|
583
|
+
],
|
|
584
|
+
stateMutability: "view",
|
|
585
|
+
type: "function"
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
inputs: [
|
|
589
|
+
{ name: "agentId", type: "uint256" },
|
|
590
|
+
{ name: "validatorAddresses", type: "address[]" },
|
|
591
|
+
{ name: "tag", type: "bytes32" }
|
|
592
|
+
],
|
|
593
|
+
name: "getSummary",
|
|
594
|
+
outputs: [
|
|
595
|
+
{ name: "count", type: "uint64" },
|
|
596
|
+
{ name: "avgResponse", type: "uint8" }
|
|
597
|
+
],
|
|
598
|
+
stateMutability: "view",
|
|
599
|
+
type: "function"
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
inputs: [{ name: "agentId", type: "uint256" }],
|
|
603
|
+
name: "getAgentValidations",
|
|
604
|
+
outputs: [{ name: "requestHashes", type: "bytes32[]" }],
|
|
605
|
+
stateMutability: "view",
|
|
606
|
+
type: "function"
|
|
607
|
+
},
|
|
608
|
+
{
|
|
609
|
+
inputs: [{ name: "validatorAddress", type: "address" }],
|
|
610
|
+
name: "getValidatorRequests",
|
|
611
|
+
outputs: [{ name: "requestHashes", type: "bytes32[]" }],
|
|
612
|
+
stateMutability: "view",
|
|
613
|
+
type: "function"
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
inputs: [],
|
|
617
|
+
name: "getIdentityRegistry",
|
|
618
|
+
outputs: [{ name: "registry", type: "address" }],
|
|
619
|
+
stateMutability: "view",
|
|
620
|
+
type: "function"
|
|
621
|
+
},
|
|
622
|
+
// Events
|
|
623
|
+
{
|
|
624
|
+
anonymous: false,
|
|
625
|
+
inputs: [
|
|
626
|
+
{ indexed: true, name: "validatorAddress", type: "address" },
|
|
627
|
+
{ indexed: true, name: "agentId", type: "uint256" },
|
|
628
|
+
{ indexed: false, name: "requestUri", type: "string" },
|
|
629
|
+
{ indexed: true, name: "requestHash", type: "bytes32" }
|
|
630
|
+
],
|
|
631
|
+
name: "ValidationRequest",
|
|
632
|
+
type: "event"
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
anonymous: false,
|
|
636
|
+
inputs: [
|
|
637
|
+
{ indexed: true, name: "validatorAddress", type: "address" },
|
|
638
|
+
{ indexed: true, name: "agentId", type: "uint256" },
|
|
639
|
+
{ indexed: true, name: "requestHash", type: "bytes32" },
|
|
640
|
+
{ indexed: false, name: "response", type: "uint8" },
|
|
641
|
+
{ indexed: false, name: "responseUri", type: "string" },
|
|
642
|
+
{ indexed: false, name: "responseHash", type: "bytes32" },
|
|
643
|
+
{ indexed: false, name: "tag", type: "bytes32" }
|
|
644
|
+
],
|
|
645
|
+
name: "ValidationResponse",
|
|
646
|
+
type: "event"
|
|
647
|
+
}
|
|
648
|
+
];
|
|
649
|
+
|
|
650
|
+
// src/ChaosAgent.ts
|
|
651
|
+
var ChaosAgent = class {
|
|
652
|
+
identityContract;
|
|
653
|
+
reputationContract;
|
|
654
|
+
validationContract;
|
|
655
|
+
signer;
|
|
656
|
+
constructor(addresses, signer, _provider) {
|
|
657
|
+
this.signer = signer;
|
|
658
|
+
this.identityContract = new ethers.Contract(
|
|
659
|
+
addresses.identity,
|
|
660
|
+
IDENTITY_REGISTRY_ABI,
|
|
661
|
+
signer
|
|
662
|
+
);
|
|
663
|
+
this.reputationContract = new ethers.Contract(
|
|
664
|
+
addresses.reputation,
|
|
665
|
+
REPUTATION_REGISTRY_ABI,
|
|
666
|
+
signer
|
|
667
|
+
);
|
|
668
|
+
this.validationContract = new ethers.Contract(
|
|
669
|
+
addresses.validation,
|
|
670
|
+
VALIDATION_REGISTRY_ABI,
|
|
671
|
+
signer
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
// ============================================================================
|
|
675
|
+
// Identity Registry Methods
|
|
676
|
+
// ============================================================================
|
|
677
|
+
/**
|
|
678
|
+
* Register a new agent identity (ERC-8004)
|
|
679
|
+
*/
|
|
680
|
+
async registerIdentity(metadata) {
|
|
681
|
+
const uri = metadata ? `data:application/json,${JSON.stringify(metadata)}` : "";
|
|
682
|
+
const tx = await this.identityContract.registerAgent(uri);
|
|
683
|
+
const receipt = await tx.wait();
|
|
684
|
+
const event = receipt.logs.map((log) => {
|
|
685
|
+
try {
|
|
686
|
+
return this.identityContract.interface.parseLog({
|
|
687
|
+
topics: [...log.topics],
|
|
688
|
+
data: log.data
|
|
689
|
+
});
|
|
690
|
+
} catch {
|
|
691
|
+
return null;
|
|
692
|
+
}
|
|
693
|
+
}).find((e) => e?.name === "AgentRegistered");
|
|
694
|
+
if (!event) {
|
|
695
|
+
throw new Error("AgentRegistered event not found");
|
|
696
|
+
}
|
|
697
|
+
return {
|
|
698
|
+
agentId: event.args.agentId,
|
|
699
|
+
txHash: receipt.hash,
|
|
700
|
+
owner: event.args.owner
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* Get agent metadata
|
|
705
|
+
*/
|
|
706
|
+
async getAgentMetadata(agentId) {
|
|
707
|
+
try {
|
|
708
|
+
const uri = await this.identityContract.getAgentURI(agentId);
|
|
709
|
+
if (!uri) {
|
|
710
|
+
return null;
|
|
711
|
+
}
|
|
712
|
+
if (uri.startsWith("data:application/json,")) {
|
|
713
|
+
const json = uri.substring("data:application/json,".length);
|
|
714
|
+
return JSON.parse(decodeURIComponent(json));
|
|
715
|
+
}
|
|
716
|
+
if (uri.startsWith("ipfs://")) {
|
|
717
|
+
const cid = uri.substring(7);
|
|
718
|
+
const response = await fetch(`https://ipfs.io/ipfs/${cid}`);
|
|
719
|
+
return response.json();
|
|
720
|
+
}
|
|
721
|
+
if (uri.startsWith("https://") || uri.startsWith("http://")) {
|
|
722
|
+
const response = await fetch(uri);
|
|
723
|
+
return response.json();
|
|
724
|
+
}
|
|
725
|
+
return null;
|
|
726
|
+
} catch (error) {
|
|
727
|
+
console.error("Failed to get agent metadata:", error);
|
|
728
|
+
return null;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Set agent URI
|
|
733
|
+
*/
|
|
734
|
+
async setAgentUri(agentId, uri) {
|
|
735
|
+
const tx = await this.identityContract.setAgentURI(agentId, uri);
|
|
736
|
+
const receipt = await tx.wait();
|
|
737
|
+
return receipt.hash;
|
|
738
|
+
}
|
|
739
|
+
/**
|
|
740
|
+
* Update agent metadata
|
|
741
|
+
*/
|
|
742
|
+
async updateAgentMetadata(agentId, metadata) {
|
|
743
|
+
const uri = `data:application/json,${JSON.stringify(metadata)}`;
|
|
744
|
+
return this.setAgentUri(agentId, uri);
|
|
745
|
+
}
|
|
746
|
+
/**
|
|
747
|
+
* Check if agent exists
|
|
748
|
+
*/
|
|
749
|
+
async agentExists(agentId) {
|
|
750
|
+
return this.identityContract.agentExists(agentId);
|
|
751
|
+
}
|
|
752
|
+
/**
|
|
753
|
+
* Get agent owner
|
|
754
|
+
*/
|
|
755
|
+
async getAgentOwner(agentId) {
|
|
756
|
+
return this.identityContract.ownerOf(agentId);
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* Get total number of agents
|
|
760
|
+
*/
|
|
761
|
+
async getTotalAgents() {
|
|
762
|
+
return this.identityContract.totalAgents();
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* Transfer agent ownership
|
|
766
|
+
*/
|
|
767
|
+
async transferAgent(agentId, to) {
|
|
768
|
+
const from = await this.signer.getAddress();
|
|
769
|
+
const tx = await this.identityContract.transferFrom(from, to, agentId);
|
|
770
|
+
const receipt = await tx.wait();
|
|
771
|
+
return receipt.hash;
|
|
772
|
+
}
|
|
773
|
+
// ============================================================================
|
|
774
|
+
// Reputation Registry Methods
|
|
775
|
+
// ============================================================================
|
|
776
|
+
/**
|
|
777
|
+
* Generate EIP-191 signed feedback authorization (ERC-8004 v1.0)
|
|
778
|
+
*
|
|
779
|
+
* This signature allows a client to submit feedback to an agent's reputation.
|
|
780
|
+
* The agent owner signs to authorize the client to give feedback up to a certain index.
|
|
781
|
+
*
|
|
782
|
+
* @param agentId Target agent ID receiving feedback
|
|
783
|
+
* @param clientAddress Address of the client giving feedback
|
|
784
|
+
* @param indexLimit Maximum feedback index this authorization permits
|
|
785
|
+
* @param expiry Unix timestamp when authorization expires
|
|
786
|
+
* @returns Signed feedbackAuth bytes for use in giveFeedback()
|
|
787
|
+
*/
|
|
788
|
+
async generateFeedbackAuthorization(agentId, clientAddress, indexLimit, expiry) {
|
|
789
|
+
try {
|
|
790
|
+
const network = await this.signer.provider.getNetwork();
|
|
791
|
+
const chainId = network.chainId;
|
|
792
|
+
const identityAddress = await this.identityContract.getAddress();
|
|
793
|
+
const signerAddress = await this.signer.getAddress();
|
|
794
|
+
const feedbackAuthData = ethers.solidityPackedKeccak256(
|
|
795
|
+
["uint256", "address", "uint64", "uint256", "uint256", "address", "address"],
|
|
796
|
+
[agentId, clientAddress, indexLimit, expiry, chainId, identityAddress, signerAddress]
|
|
797
|
+
);
|
|
798
|
+
const signature = await this.signer.signMessage(ethers.getBytes(feedbackAuthData));
|
|
799
|
+
const signatureBytes = ethers.getBytes(signature);
|
|
800
|
+
const structBytes = ethers.concat([
|
|
801
|
+
ethers.toBeHex(agentId, 32),
|
|
802
|
+
ethers.zeroPadValue(clientAddress, 32),
|
|
803
|
+
ethers.concat([ethers.toBeHex(indexLimit, 8), ethers.zeroPadValue("0x", 24)]),
|
|
804
|
+
// uint64 padded
|
|
805
|
+
ethers.toBeHex(expiry, 32),
|
|
806
|
+
ethers.toBeHex(chainId, 32),
|
|
807
|
+
ethers.zeroPadValue(identityAddress, 32),
|
|
808
|
+
ethers.zeroPadValue(signerAddress, 32)
|
|
809
|
+
]);
|
|
810
|
+
const feedbackAuth = ethers.hexlify(ethers.concat([structBytes, signatureBytes]));
|
|
811
|
+
console.log(`\u2705 Generated feedback authorization for agent #${agentId}`);
|
|
812
|
+
return feedbackAuth;
|
|
813
|
+
} catch (e) {
|
|
814
|
+
throw new Error(`Failed to generate feedback authorization: ${e.message}`);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Give feedback to an agent
|
|
819
|
+
*/
|
|
820
|
+
async giveFeedback(params) {
|
|
821
|
+
const { agentId, rating, feedbackUri } = params;
|
|
822
|
+
if (rating < 0 || rating > 100) {
|
|
823
|
+
throw new Error("Rating must be between 0 and 100");
|
|
824
|
+
}
|
|
825
|
+
const tx = await this.reputationContract.giveFeedback(agentId, rating, feedbackUri);
|
|
826
|
+
const receipt = await tx.wait();
|
|
827
|
+
return receipt.hash;
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* Revoke feedback
|
|
831
|
+
*/
|
|
832
|
+
async revokeFeedback(feedbackId) {
|
|
833
|
+
const tx = await this.reputationContract.revokeFeedback(feedbackId);
|
|
834
|
+
const receipt = await tx.wait();
|
|
835
|
+
return receipt.hash;
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* Append response to feedback
|
|
839
|
+
*/
|
|
840
|
+
async appendResponse(feedbackId, responseUri) {
|
|
841
|
+
const tx = await this.reputationContract.appendResponse(feedbackId, responseUri);
|
|
842
|
+
const receipt = await tx.wait();
|
|
843
|
+
return receipt.hash;
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Get feedback details
|
|
847
|
+
*/
|
|
848
|
+
async getFeedback(feedbackId) {
|
|
849
|
+
const feedback = await this.reputationContract.getFeedback(feedbackId);
|
|
850
|
+
return {
|
|
851
|
+
feedbackId: feedback.feedbackId,
|
|
852
|
+
fromAgent: feedback.fromAgent,
|
|
853
|
+
toAgent: feedback.toAgent,
|
|
854
|
+
rating: feedback.rating,
|
|
855
|
+
feedbackUri: feedback.feedbackURI,
|
|
856
|
+
timestamp: Number(feedback.timestamp),
|
|
857
|
+
revoked: feedback.revoked
|
|
858
|
+
};
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Get agent feedback IDs
|
|
862
|
+
*/
|
|
863
|
+
async getAgentFeedback(agentId, offset = 0, limit = 10) {
|
|
864
|
+
return this.reputationContract.getAgentFeedback(agentId, offset, limit);
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Get agent reputation stats
|
|
868
|
+
*/
|
|
869
|
+
async getAgentStats(agentId) {
|
|
870
|
+
return this.reputationContract.getAgentStats(agentId);
|
|
871
|
+
}
|
|
872
|
+
// ============================================================================
|
|
873
|
+
// Validation Registry Methods
|
|
874
|
+
// ============================================================================
|
|
875
|
+
/**
|
|
876
|
+
* Request validation from another agent
|
|
877
|
+
*/
|
|
878
|
+
async requestValidation(params) {
|
|
879
|
+
const { validatorAgentId, requestUri, requestHash } = params;
|
|
880
|
+
const hashBytes = ethers.id(requestHash);
|
|
881
|
+
const tx = await this.validationContract.requestValidation(
|
|
882
|
+
validatorAgentId,
|
|
883
|
+
requestUri,
|
|
884
|
+
hashBytes
|
|
885
|
+
);
|
|
886
|
+
const receipt = await tx.wait();
|
|
887
|
+
return receipt.hash;
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* Respond to validation request
|
|
891
|
+
*/
|
|
892
|
+
async respondToValidation(requestId, approved, responseUri) {
|
|
893
|
+
const tx = await this.validationContract.respondToValidation(
|
|
894
|
+
requestId,
|
|
895
|
+
approved,
|
|
896
|
+
responseUri
|
|
897
|
+
);
|
|
898
|
+
const receipt = await tx.wait();
|
|
899
|
+
return receipt.hash;
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* Get validation request details
|
|
903
|
+
*/
|
|
904
|
+
async getValidationRequest(requestId) {
|
|
905
|
+
const request = await this.validationContract.getValidationRequest(requestId);
|
|
906
|
+
return {
|
|
907
|
+
requestId: request.requestId,
|
|
908
|
+
requester: request.requester,
|
|
909
|
+
validator: request.validator,
|
|
910
|
+
requestUri: request.requestURI,
|
|
911
|
+
requestHash: request.requestHash,
|
|
912
|
+
status: request.status,
|
|
913
|
+
responseUri: request.responseURI,
|
|
914
|
+
timestamp: Number(request.timestamp)
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* Get agent validation requests
|
|
919
|
+
*/
|
|
920
|
+
async getAgentValidationRequests(agentId, asValidator = false, offset = 0, limit = 10) {
|
|
921
|
+
return this.validationContract.getAgentValidationRequests(
|
|
922
|
+
agentId,
|
|
923
|
+
asValidator,
|
|
924
|
+
offset,
|
|
925
|
+
limit
|
|
926
|
+
);
|
|
927
|
+
}
|
|
928
|
+
/**
|
|
929
|
+
* Get validation statistics for an agent
|
|
930
|
+
*/
|
|
931
|
+
async getValidationStats(agentId) {
|
|
932
|
+
return this.validationContract.getValidationStats(agentId);
|
|
933
|
+
}
|
|
934
|
+
// ============================================================================
|
|
935
|
+
// Event Listening
|
|
936
|
+
// ============================================================================
|
|
937
|
+
/**
|
|
938
|
+
* Listen for AgentRegistered events
|
|
939
|
+
*/
|
|
940
|
+
onAgentRegistered(callback) {
|
|
941
|
+
this.identityContract.on("AgentRegistered", callback);
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Listen for FeedbackGiven events
|
|
945
|
+
*/
|
|
946
|
+
onFeedbackGiven(callback) {
|
|
947
|
+
this.reputationContract.on("FeedbackGiven", callback);
|
|
948
|
+
}
|
|
949
|
+
/**
|
|
950
|
+
* Listen for ValidationRequested events
|
|
951
|
+
*/
|
|
952
|
+
onValidationRequested(callback) {
|
|
953
|
+
this.validationContract.on("ValidationRequested", callback);
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Listen for ValidationResponded events
|
|
957
|
+
*/
|
|
958
|
+
onValidationResponded(callback) {
|
|
959
|
+
this.validationContract.on("ValidationResponded", callback);
|
|
960
|
+
}
|
|
961
|
+
/**
|
|
962
|
+
* Remove all event listeners
|
|
963
|
+
*/
|
|
964
|
+
removeAllListeners() {
|
|
965
|
+
this.identityContract.removeAllListeners();
|
|
966
|
+
this.reputationContract.removeAllListeners();
|
|
967
|
+
this.validationContract.removeAllListeners();
|
|
968
|
+
}
|
|
969
|
+
};
|
|
970
|
+
|
|
971
|
+
// src/exceptions.ts
|
|
972
|
+
var ChaosChainSDKError = class _ChaosChainSDKError extends Error {
|
|
973
|
+
details;
|
|
974
|
+
constructor(message, details = {}) {
|
|
975
|
+
super(message);
|
|
976
|
+
this.name = "ChaosChainSDKError";
|
|
977
|
+
this.details = details;
|
|
978
|
+
Object.setPrototypeOf(this, _ChaosChainSDKError.prototype);
|
|
979
|
+
}
|
|
980
|
+
toString() {
|
|
981
|
+
if (Object.keys(this.details).length > 0) {
|
|
982
|
+
return `${this.message} | Details: ${JSON.stringify(this.details)}`;
|
|
983
|
+
}
|
|
984
|
+
return this.message;
|
|
985
|
+
}
|
|
986
|
+
};
|
|
987
|
+
var AgentRegistrationError = class _AgentRegistrationError extends ChaosChainSDKError {
|
|
988
|
+
constructor(message, details) {
|
|
989
|
+
super(message, details);
|
|
990
|
+
this.name = "AgentRegistrationError";
|
|
991
|
+
Object.setPrototypeOf(this, _AgentRegistrationError.prototype);
|
|
992
|
+
}
|
|
993
|
+
};
|
|
994
|
+
var PaymentError2 = class _PaymentError extends ChaosChainSDKError {
|
|
995
|
+
constructor(message, details) {
|
|
996
|
+
super(message, details);
|
|
997
|
+
this.name = "PaymentError";
|
|
998
|
+
Object.setPrototypeOf(this, _PaymentError.prototype);
|
|
999
|
+
}
|
|
1000
|
+
};
|
|
1001
|
+
var StorageError = class _StorageError extends ChaosChainSDKError {
|
|
1002
|
+
constructor(message, details) {
|
|
1003
|
+
super(message, details);
|
|
1004
|
+
this.name = "StorageError";
|
|
1005
|
+
Object.setPrototypeOf(this, _StorageError.prototype);
|
|
1006
|
+
}
|
|
1007
|
+
};
|
|
1008
|
+
var IntegrityVerificationError = class _IntegrityVerificationError extends ChaosChainSDKError {
|
|
1009
|
+
constructor(message, details) {
|
|
1010
|
+
super(message, details);
|
|
1011
|
+
this.name = "IntegrityVerificationError";
|
|
1012
|
+
Object.setPrototypeOf(this, _IntegrityVerificationError.prototype);
|
|
1013
|
+
}
|
|
1014
|
+
};
|
|
1015
|
+
var ContractError = class _ContractError extends ChaosChainSDKError {
|
|
1016
|
+
constructor(message, details) {
|
|
1017
|
+
super(message, details);
|
|
1018
|
+
this.name = "ContractError";
|
|
1019
|
+
Object.setPrototypeOf(this, _ContractError.prototype);
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
var ConfigurationError = class _ConfigurationError extends ChaosChainSDKError {
|
|
1023
|
+
constructor(message, details) {
|
|
1024
|
+
super(message, details);
|
|
1025
|
+
this.name = "ConfigurationError";
|
|
1026
|
+
Object.setPrototypeOf(this, _ConfigurationError.prototype);
|
|
1027
|
+
}
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
// src/X402PaymentManager.ts
|
|
1031
|
+
var X402PaymentManager = class {
|
|
1032
|
+
wallet;
|
|
1033
|
+
provider;
|
|
1034
|
+
network;
|
|
1035
|
+
treasuryAddress;
|
|
1036
|
+
protocolFeePercentage;
|
|
1037
|
+
usdcAddresses;
|
|
1038
|
+
constructor(wallet, network) {
|
|
1039
|
+
this.wallet = wallet;
|
|
1040
|
+
this.network = network;
|
|
1041
|
+
this.protocolFeePercentage = 0.025;
|
|
1042
|
+
this.treasuryAddress = this.getTreasuryAddress(network);
|
|
1043
|
+
this.usdcAddresses = {
|
|
1044
|
+
"base-sepolia": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
1045
|
+
"ethereum-sepolia": "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
1046
|
+
"optimism-sepolia": "0x5fd84259d66Cd46123540766Be93DFE6D43130D7",
|
|
1047
|
+
"linea-sepolia": "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
|
|
1048
|
+
};
|
|
1049
|
+
this.provider = wallet.provider;
|
|
1050
|
+
console.log(`\u2705 X402 Payment Manager initialized on ${network}`);
|
|
1051
|
+
console.log(`\u{1F4B0} Treasury: ${this.treasuryAddress}`);
|
|
1052
|
+
console.log(`\u{1F4CA} Protocol Fee: ${this.protocolFeePercentage * 100}%`);
|
|
1053
|
+
}
|
|
1054
|
+
/**
|
|
1055
|
+
* Get ChaosChain treasury address for network
|
|
1056
|
+
*/
|
|
1057
|
+
getTreasuryAddress(network) {
|
|
1058
|
+
const treasuries = {
|
|
1059
|
+
"base-sepolia": "0x8004AA63c570c570eBF15376c0dB199918BFe9Fb",
|
|
1060
|
+
"ethereum-sepolia": "0x8004a6090Cd10A7288092483047B097295Fb8847",
|
|
1061
|
+
"optimism-sepolia": "0x8004a6090Cd10A7288092483047B097295Fb8847",
|
|
1062
|
+
"linea-sepolia": "0x8004aa7C931bCE1233973a0C6A667f73F66282e7"
|
|
1063
|
+
};
|
|
1064
|
+
return treasuries[network] || treasuries["base-sepolia"];
|
|
1065
|
+
}
|
|
1066
|
+
/**
|
|
1067
|
+
* Create x402 payment request
|
|
1068
|
+
*/
|
|
1069
|
+
createPaymentRequest(fromAgent, toAgent, amount, currency = "USDC", serviceDescription = "AI Agent Service") {
|
|
1070
|
+
const paymentId = `x402_${Date.now().toString(36)}_${Math.random().toString(36).substring(2, 9)}`;
|
|
1071
|
+
const protocolFee = amount * this.protocolFeePercentage;
|
|
1072
|
+
const request = {
|
|
1073
|
+
payment_id: paymentId,
|
|
1074
|
+
from_agent: fromAgent,
|
|
1075
|
+
to_agent: toAgent,
|
|
1076
|
+
amount,
|
|
1077
|
+
currency,
|
|
1078
|
+
service_description: serviceDescription,
|
|
1079
|
+
network: this.network,
|
|
1080
|
+
protocol_fee: protocolFee,
|
|
1081
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1082
|
+
};
|
|
1083
|
+
console.log(`\u{1F4C4} Created x402 payment request: ${paymentId}`);
|
|
1084
|
+
console.log(` From: ${fromAgent} \u2192 To: ${toAgent}`);
|
|
1085
|
+
console.log(` Amount: ${amount} ${currency} + ${protocolFee.toFixed(4)} ${currency} fee`);
|
|
1086
|
+
return request;
|
|
1087
|
+
}
|
|
1088
|
+
/**
|
|
1089
|
+
* Execute x402 payment on-chain
|
|
1090
|
+
*/
|
|
1091
|
+
async executePayment(paymentRequest, recipientAddress) {
|
|
1092
|
+
console.log(`\u{1F4B8} Executing x402 payment: ${paymentRequest.payment_id}`);
|
|
1093
|
+
console.log(` Network: ${this.network}`);
|
|
1094
|
+
console.log(` Recipient: ${recipientAddress}`);
|
|
1095
|
+
const currency = paymentRequest.currency.toUpperCase();
|
|
1096
|
+
const amount = paymentRequest.amount;
|
|
1097
|
+
const protocolFee = paymentRequest.protocol_fee;
|
|
1098
|
+
let mainTxHash;
|
|
1099
|
+
let feeTxHash;
|
|
1100
|
+
let chainId;
|
|
1101
|
+
try {
|
|
1102
|
+
const networkInfo = await this.provider.getNetwork();
|
|
1103
|
+
chainId = Number(networkInfo.chainId);
|
|
1104
|
+
if (currency === "ETH" || currency === "NATIVE") {
|
|
1105
|
+
const { mainTx, feeTx } = await this.executeNativePayment(recipientAddress, amount, protocolFee);
|
|
1106
|
+
mainTxHash = mainTx;
|
|
1107
|
+
feeTxHash = feeTx;
|
|
1108
|
+
} else if (currency === "USDC") {
|
|
1109
|
+
const { mainTx, feeTx } = await this.executeUsdcPayment(recipientAddress, amount, protocolFee);
|
|
1110
|
+
mainTxHash = mainTx;
|
|
1111
|
+
feeTxHash = feeTx;
|
|
1112
|
+
} else {
|
|
1113
|
+
throw new PaymentError2(`Unsupported currency: ${currency}`);
|
|
1114
|
+
}
|
|
1115
|
+
const receipt = await this.provider.getTransactionReceipt(mainTxHash);
|
|
1116
|
+
const proof = {
|
|
1117
|
+
payment_id: paymentRequest.payment_id,
|
|
1118
|
+
transaction_hash: mainTxHash,
|
|
1119
|
+
main_transaction_hash: mainTxHash,
|
|
1120
|
+
fee_transaction_hash: feeTxHash,
|
|
1121
|
+
from_address: this.wallet.address,
|
|
1122
|
+
to_address: recipientAddress,
|
|
1123
|
+
treasury_address: this.treasuryAddress,
|
|
1124
|
+
amount,
|
|
1125
|
+
currency,
|
|
1126
|
+
protocol_fee: protocolFee,
|
|
1127
|
+
network: this.network,
|
|
1128
|
+
chain_id: chainId,
|
|
1129
|
+
block_number: receipt?.blockNumber,
|
|
1130
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1131
|
+
status: receipt?.status === 1 ? "confirmed" : "failed",
|
|
1132
|
+
confirmations: 1
|
|
1133
|
+
};
|
|
1134
|
+
console.log(`\u2705 x402 payment executed successfully`);
|
|
1135
|
+
console.log(` Main TX: ${mainTxHash}`);
|
|
1136
|
+
if (feeTxHash) {
|
|
1137
|
+
console.log(` Fee TX: ${feeTxHash}`);
|
|
1138
|
+
}
|
|
1139
|
+
return proof;
|
|
1140
|
+
} catch (e) {
|
|
1141
|
+
throw new PaymentError2(`x402 payment failed: ${e.message}`, { payment_id: paymentRequest.payment_id });
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
/**
|
|
1145
|
+
* Execute native token (ETH) payment
|
|
1146
|
+
*/
|
|
1147
|
+
async executeNativePayment(recipientAddress, amount, protocolFee) {
|
|
1148
|
+
const amountWei = ethers.parseEther(amount.toString());
|
|
1149
|
+
const feeWei = ethers.parseEther(protocolFee.toString());
|
|
1150
|
+
const mainTx = await this.wallet.sendTransaction({
|
|
1151
|
+
to: recipientAddress,
|
|
1152
|
+
value: amountWei
|
|
1153
|
+
});
|
|
1154
|
+
await mainTx.wait();
|
|
1155
|
+
let feeTxHash;
|
|
1156
|
+
if (protocolFee > 0) {
|
|
1157
|
+
const feeTx = await this.wallet.sendTransaction({
|
|
1158
|
+
to: this.treasuryAddress,
|
|
1159
|
+
value: feeWei
|
|
1160
|
+
});
|
|
1161
|
+
await feeTx.wait();
|
|
1162
|
+
feeTxHash = feeTx.hash;
|
|
1163
|
+
}
|
|
1164
|
+
return {
|
|
1165
|
+
mainTx: mainTx.hash,
|
|
1166
|
+
feeTx: feeTxHash
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Execute USDC payment
|
|
1171
|
+
*/
|
|
1172
|
+
async executeUsdcPayment(recipientAddress, amount, protocolFee) {
|
|
1173
|
+
const usdcAddress = this.usdcAddresses[this.network];
|
|
1174
|
+
if (!usdcAddress) {
|
|
1175
|
+
throw new PaymentError2(`USDC not supported on ${this.network}`);
|
|
1176
|
+
}
|
|
1177
|
+
const amountUsdc = ethers.parseUnits(amount.toString(), 6);
|
|
1178
|
+
const feeUsdc = ethers.parseUnits(protocolFee.toString(), 6);
|
|
1179
|
+
const erc20Abi = ["function transfer(address to, uint256 amount) returns (bool)"];
|
|
1180
|
+
const usdcContract = new ethers.Contract(usdcAddress, erc20Abi, this.wallet);
|
|
1181
|
+
const mainTx = await usdcContract.transfer(recipientAddress, amountUsdc);
|
|
1182
|
+
await mainTx.wait();
|
|
1183
|
+
let feeTxHash;
|
|
1184
|
+
if (protocolFee > 0) {
|
|
1185
|
+
const feeTx = await usdcContract.transfer(this.treasuryAddress, feeUsdc);
|
|
1186
|
+
await feeTx.wait();
|
|
1187
|
+
feeTxHash = feeTx.hash;
|
|
1188
|
+
}
|
|
1189
|
+
return {
|
|
1190
|
+
mainTx: mainTx.hash,
|
|
1191
|
+
feeTx: feeTxHash
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
/**
|
|
1195
|
+
* Verify x402 payment on-chain
|
|
1196
|
+
*/
|
|
1197
|
+
async verifyPayment(paymentProof) {
|
|
1198
|
+
try {
|
|
1199
|
+
const receipt = await this.provider.getTransactionReceipt(paymentProof.main_transaction_hash);
|
|
1200
|
+
if (!receipt) {
|
|
1201
|
+
console.error(`\u274C Transaction not found: ${paymentProof.main_transaction_hash}`);
|
|
1202
|
+
return false;
|
|
1203
|
+
}
|
|
1204
|
+
if (receipt.status !== 1) {
|
|
1205
|
+
console.error(`\u274C Transaction failed: ${paymentProof.main_transaction_hash}`);
|
|
1206
|
+
return false;
|
|
1207
|
+
}
|
|
1208
|
+
const tx = await this.provider.getTransaction(paymentProof.main_transaction_hash);
|
|
1209
|
+
if (tx?.to?.toLowerCase() !== paymentProof.to_address.toLowerCase()) {
|
|
1210
|
+
console.error(`\u274C Recipient mismatch`);
|
|
1211
|
+
return false;
|
|
1212
|
+
}
|
|
1213
|
+
console.log(`\u2705 Payment verified on-chain: ${paymentProof.main_transaction_hash}`);
|
|
1214
|
+
return true;
|
|
1215
|
+
} catch (e) {
|
|
1216
|
+
console.error(`\u274C Payment verification failed: ${e}`);
|
|
1217
|
+
return false;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
/**
|
|
1221
|
+
* Create payment requirements for receiving payments
|
|
1222
|
+
*/
|
|
1223
|
+
createPaymentRequirements(amount, currency = "USDC", serviceDescription = "AI Agent Service", expiryMinutes = 30) {
|
|
1224
|
+
const expiryTime = new Date(Date.now() + expiryMinutes * 60 * 1e3);
|
|
1225
|
+
return {
|
|
1226
|
+
amount,
|
|
1227
|
+
currency,
|
|
1228
|
+
service_description: serviceDescription,
|
|
1229
|
+
settlement_address: this.wallet.address,
|
|
1230
|
+
network: this.network,
|
|
1231
|
+
protocol_version: "x402-v1.0",
|
|
1232
|
+
expires_at: expiryTime.toISOString(),
|
|
1233
|
+
payment_endpoint: `x402://pay/${this.wallet.address}`
|
|
1234
|
+
};
|
|
1235
|
+
}
|
|
1236
|
+
/**
|
|
1237
|
+
* Get payment history (from on-chain events)
|
|
1238
|
+
*/
|
|
1239
|
+
async getPaymentHistory(limit = 10) {
|
|
1240
|
+
console.log(`\u{1F4CA} Payment history: querying last ${limit} payments...`);
|
|
1241
|
+
return [];
|
|
1242
|
+
}
|
|
1243
|
+
/**
|
|
1244
|
+
* Create cryptographic receipt for payment
|
|
1245
|
+
*/
|
|
1246
|
+
createPaymentReceipt(paymentProof) {
|
|
1247
|
+
const receiptData = {
|
|
1248
|
+
payment_id: paymentProof.payment_id,
|
|
1249
|
+
transaction_hash: paymentProof.main_transaction_hash,
|
|
1250
|
+
from_address: paymentProof.from_address,
|
|
1251
|
+
to_address: paymentProof.to_address,
|
|
1252
|
+
amount: paymentProof.amount,
|
|
1253
|
+
currency: paymentProof.currency,
|
|
1254
|
+
protocol_fee: paymentProof.protocol_fee,
|
|
1255
|
+
network: paymentProof.network,
|
|
1256
|
+
chain_id: paymentProof.chain_id,
|
|
1257
|
+
timestamp: paymentProof.timestamp.toISOString(),
|
|
1258
|
+
status: paymentProof.status
|
|
1259
|
+
};
|
|
1260
|
+
const crypto2 = __require("crypto");
|
|
1261
|
+
const receiptJson = JSON.stringify(receiptData);
|
|
1262
|
+
const receiptHash = crypto2.createHash("sha256").update(receiptJson).digest("hex");
|
|
1263
|
+
return {
|
|
1264
|
+
receipt_type: "x402_payment",
|
|
1265
|
+
receipt_hash: receiptHash,
|
|
1266
|
+
receipt_data: receiptData,
|
|
1267
|
+
verification_url: `https://explorer.base.org/tx/${paymentProof.main_transaction_hash}`,
|
|
1268
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1269
|
+
};
|
|
1270
|
+
}
|
|
1271
|
+
/**
|
|
1272
|
+
* Get payment statistics
|
|
1273
|
+
*/
|
|
1274
|
+
getPaymentStats() {
|
|
1275
|
+
return {
|
|
1276
|
+
network: this.network,
|
|
1277
|
+
wallet_address: this.wallet.address,
|
|
1278
|
+
treasury_address: this.treasuryAddress,
|
|
1279
|
+
protocol_fee_percentage: this.protocolFeePercentage * 100,
|
|
1280
|
+
supported_currencies: ["ETH", "USDC"],
|
|
1281
|
+
features: {
|
|
1282
|
+
instant_settlement: true,
|
|
1283
|
+
on_chain_verification: true,
|
|
1284
|
+
protocol_fees: true,
|
|
1285
|
+
multi_currency: true,
|
|
1286
|
+
payment_receipts: true
|
|
1287
|
+
}
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
};
|
|
1291
|
+
var PaymentManager = class {
|
|
1292
|
+
agentName;
|
|
1293
|
+
network;
|
|
1294
|
+
wallet;
|
|
1295
|
+
credentials;
|
|
1296
|
+
stripeAxiosInstance;
|
|
1297
|
+
paypalAccessToken;
|
|
1298
|
+
constructor(agentName, network, wallet, credentials = {}) {
|
|
1299
|
+
this.agentName = agentName;
|
|
1300
|
+
this.network = network;
|
|
1301
|
+
this.wallet = wallet;
|
|
1302
|
+
this.credentials = credentials;
|
|
1303
|
+
if (credentials.stripe_secret_key) {
|
|
1304
|
+
this.stripeAxiosInstance = axios2.create({
|
|
1305
|
+
baseURL: "https://api.stripe.com/v1",
|
|
1306
|
+
headers: {
|
|
1307
|
+
Authorization: `Bearer ${credentials.stripe_secret_key}`,
|
|
1308
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
1309
|
+
}
|
|
1310
|
+
});
|
|
1311
|
+
console.log("\u2705 Stripe integration enabled");
|
|
1312
|
+
}
|
|
1313
|
+
if (credentials.paypal_client_id && credentials.paypal_client_secret) {
|
|
1314
|
+
this.initializePayPal().catch(console.error);
|
|
1315
|
+
}
|
|
1316
|
+
console.log(`\u{1F4B3} Payment Manager initialized for ${agentName}`);
|
|
1317
|
+
}
|
|
1318
|
+
/**
|
|
1319
|
+
* Initialize PayPal OAuth access token
|
|
1320
|
+
*/
|
|
1321
|
+
async initializePayPal() {
|
|
1322
|
+
try {
|
|
1323
|
+
const auth = Buffer.from(
|
|
1324
|
+
`${this.credentials.paypal_client_id}:${this.credentials.paypal_client_secret}`
|
|
1325
|
+
).toString("base64");
|
|
1326
|
+
const response = await axios2.post(
|
|
1327
|
+
"https://api-m.sandbox.paypal.com/v1/oauth2/token",
|
|
1328
|
+
"grant_type=client_credentials",
|
|
1329
|
+
{
|
|
1330
|
+
headers: {
|
|
1331
|
+
Authorization: `Basic ${auth}`,
|
|
1332
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
);
|
|
1336
|
+
this.paypalAccessToken = response.data.access_token;
|
|
1337
|
+
console.log("\u2705 PayPal integration enabled");
|
|
1338
|
+
} catch (e) {
|
|
1339
|
+
console.error("\u274C Failed to initialize PayPal:", e);
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
/**
|
|
1343
|
+
* Execute traditional payment (cards, wallets, etc.)
|
|
1344
|
+
*/
|
|
1345
|
+
executeTraditionalPayment(paymentMethod, amount, currency, paymentData_unused) {
|
|
1346
|
+
console.log(`\u{1F4B3} Processing ${paymentMethod} payment: $${amount} ${currency}`);
|
|
1347
|
+
switch (paymentMethod) {
|
|
1348
|
+
case "basic-card" /* BASIC_CARD */:
|
|
1349
|
+
return this.processBasicCard(amount, currency, paymentData);
|
|
1350
|
+
case "https://google.com/pay" /* GOOGLE_PAY */:
|
|
1351
|
+
return this.processGooglePay(amount, currency, paymentData);
|
|
1352
|
+
case "https://apple.com/apple-pay" /* APPLE_PAY */:
|
|
1353
|
+
return this.processApplePay(amount, currency, paymentData);
|
|
1354
|
+
case "https://paypal.com" /* PAYPAL */:
|
|
1355
|
+
return this.processPayPal(amount, currency, paymentData);
|
|
1356
|
+
case "https://a2a.org/x402" /* A2A_X402 */:
|
|
1357
|
+
return this.processA2AX402(amount, currency, paymentData);
|
|
1358
|
+
default:
|
|
1359
|
+
throw new PaymentError(`Unsupported payment method: ${paymentMethod}`);
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
/**
|
|
1363
|
+
* Process Basic Card payment (Visa, Mastercard, Amex, etc.) via Stripe
|
|
1364
|
+
*/
|
|
1365
|
+
processBasicCard(amount, currency, paymentData_unused) {
|
|
1366
|
+
console.log("\u{1F4B3} Processing Basic Card via Stripe...");
|
|
1367
|
+
if (!this.stripeAxiosInstance) {
|
|
1368
|
+
console.warn("\u26A0\uFE0F Stripe not configured, simulating payment");
|
|
1369
|
+
return this.simulateTraditionalPayment("basic-card" /* BASIC_CARD */, amount, currency);
|
|
1370
|
+
}
|
|
1371
|
+
try {
|
|
1372
|
+
return this.simulateTraditionalPayment("basic-card" /* BASIC_CARD */, amount, currency);
|
|
1373
|
+
} catch (e) {
|
|
1374
|
+
throw new PaymentError(`Basic card payment failed: ${e}`);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
/**
|
|
1378
|
+
* Process Google Pay payment
|
|
1379
|
+
*/
|
|
1380
|
+
processGooglePay(amount, currency, paymentData_unused) {
|
|
1381
|
+
console.log("\u{1F176} Processing Google Pay...");
|
|
1382
|
+
if (!this.credentials.google_pay_merchant_id) {
|
|
1383
|
+
console.warn("\u26A0\uFE0F Google Pay not configured, simulating payment");
|
|
1384
|
+
return this.simulateTraditionalPayment("https://google.com/pay" /* GOOGLE_PAY */, amount, currency);
|
|
1385
|
+
}
|
|
1386
|
+
return this.simulateTraditionalPayment("https://google.com/pay" /* GOOGLE_PAY */, amount, currency);
|
|
1387
|
+
}
|
|
1388
|
+
/**
|
|
1389
|
+
* Process Apple Pay payment
|
|
1390
|
+
*/
|
|
1391
|
+
processApplePay(amount, currency, paymentData_unused) {
|
|
1392
|
+
console.log("\u{1F34E} Processing Apple Pay...");
|
|
1393
|
+
if (!this.credentials.apple_pay_merchant_id) {
|
|
1394
|
+
console.warn("\u26A0\uFE0F Apple Pay not configured, simulating payment");
|
|
1395
|
+
return this.simulateTraditionalPayment("https://apple.com/apple-pay" /* APPLE_PAY */, amount, currency);
|
|
1396
|
+
}
|
|
1397
|
+
return this.simulateTraditionalPayment("https://apple.com/apple-pay" /* APPLE_PAY */, amount, currency);
|
|
1398
|
+
}
|
|
1399
|
+
/**
|
|
1400
|
+
* Process PayPal payment
|
|
1401
|
+
*/
|
|
1402
|
+
processPayPal(amount, currency, paymentData_unused) {
|
|
1403
|
+
console.log("\u{1F499} Processing PayPal...");
|
|
1404
|
+
if (!this.paypalAccessToken) {
|
|
1405
|
+
console.warn("\u26A0\uFE0F PayPal not configured, simulating payment");
|
|
1406
|
+
return this.simulateTraditionalPayment("https://paypal.com" /* PAYPAL */, amount, currency);
|
|
1407
|
+
}
|
|
1408
|
+
try {
|
|
1409
|
+
return this.simulateTraditionalPayment("https://paypal.com" /* PAYPAL */, amount, currency);
|
|
1410
|
+
} catch (e) {
|
|
1411
|
+
throw new PaymentError(`PayPal payment failed: ${e}`);
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
/**
|
|
1415
|
+
* Process A2A-x402 crypto payment
|
|
1416
|
+
*/
|
|
1417
|
+
processA2AX402(amount, currency, paymentData_unused) {
|
|
1418
|
+
console.log("\u{1F517} Processing A2A-x402 crypto payment...");
|
|
1419
|
+
const paymentId = `a2a_x402_${Date.now().toString(36)}`;
|
|
1420
|
+
return {
|
|
1421
|
+
payment_id: paymentId,
|
|
1422
|
+
transaction_id: paymentData.transaction_hash || `crypto_tx_${paymentId}`,
|
|
1423
|
+
status: "pending_crypto_confirmation",
|
|
1424
|
+
amount,
|
|
1425
|
+
currency,
|
|
1426
|
+
payment_method: "https://a2a.org/x402" /* A2A_X402 */,
|
|
1427
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1428
|
+
processor_response: {
|
|
1429
|
+
network: this.network,
|
|
1430
|
+
settlement_type: "crypto",
|
|
1431
|
+
requires_blockchain_confirmation: true
|
|
1432
|
+
}
|
|
1433
|
+
};
|
|
1434
|
+
}
|
|
1435
|
+
/**
|
|
1436
|
+
* Simulate traditional payment (for testing/fallback)
|
|
1437
|
+
*/
|
|
1438
|
+
simulateTraditionalPayment(method, amount, currency) {
|
|
1439
|
+
const paymentId = `sim_${method}_${Date.now().toString(36)}`;
|
|
1440
|
+
const transactionId = `txn_${paymentId}`;
|
|
1441
|
+
console.log(`\u{1F504} Simulating ${method} payment`);
|
|
1442
|
+
return {
|
|
1443
|
+
payment_id: paymentId,
|
|
1444
|
+
transaction_id: transactionId,
|
|
1445
|
+
status: "completed",
|
|
1446
|
+
amount,
|
|
1447
|
+
currency,
|
|
1448
|
+
payment_method: method,
|
|
1449
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1450
|
+
processor_response: {
|
|
1451
|
+
simulation: true,
|
|
1452
|
+
authorization_code: `AUTH_${Math.random().toString(36).substring(2, 10).toUpperCase()}`,
|
|
1453
|
+
network: method === "basic-card" /* BASIC_CARD */ ? "visa" : method,
|
|
1454
|
+
last4: method === "basic-card" /* BASIC_CARD */ ? "4242" : void 0
|
|
1455
|
+
}
|
|
1456
|
+
};
|
|
1457
|
+
}
|
|
1458
|
+
/**
|
|
1459
|
+
* Get payment method configuration status
|
|
1460
|
+
*/
|
|
1461
|
+
getPaymentMethodsStatus() {
|
|
1462
|
+
return {
|
|
1463
|
+
["basic-card" /* BASIC_CARD */]: !!this.credentials.stripe_secret_key,
|
|
1464
|
+
["https://google.com/pay" /* GOOGLE_PAY */]: !!this.credentials.google_pay_merchant_id,
|
|
1465
|
+
["https://apple.com/apple-pay" /* APPLE_PAY */]: !!this.credentials.apple_pay_merchant_id,
|
|
1466
|
+
["https://paypal.com" /* PAYPAL */]: !!this.paypalAccessToken,
|
|
1467
|
+
["https://a2a.org/x402" /* A2A_X402 */]: true
|
|
1468
|
+
// Always available via wallet
|
|
1469
|
+
};
|
|
1470
|
+
}
|
|
1471
|
+
/**
|
|
1472
|
+
* Get supported payment methods
|
|
1473
|
+
*/
|
|
1474
|
+
getSupportedPaymentMethods() {
|
|
1475
|
+
const status = this.getPaymentMethodsStatus();
|
|
1476
|
+
return Object.entries(status).filter(([_, enabled]) => enabled).map(([method, _]) => method);
|
|
1477
|
+
}
|
|
1478
|
+
/**
|
|
1479
|
+
* Validate payment method credentials
|
|
1480
|
+
*/
|
|
1481
|
+
async validateCredentials() {
|
|
1482
|
+
const results = {};
|
|
1483
|
+
if (this.credentials.stripe_secret_key) {
|
|
1484
|
+
try {
|
|
1485
|
+
await this.stripeAxiosInstance.get("/balance");
|
|
1486
|
+
results.stripe = true;
|
|
1487
|
+
} catch (e) {
|
|
1488
|
+
results.stripe = false;
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
if (this.credentials.paypal_client_id) {
|
|
1492
|
+
results.paypal = !!this.paypalAccessToken;
|
|
1493
|
+
}
|
|
1494
|
+
results.google_pay = !!this.credentials.google_pay_merchant_id;
|
|
1495
|
+
results.apple_pay = !!this.credentials.apple_pay_merchant_id;
|
|
1496
|
+
results.crypto = !!this.wallet;
|
|
1497
|
+
return results;
|
|
1498
|
+
}
|
|
1499
|
+
/**
|
|
1500
|
+
* Create x402 payment request (for crypto payments)
|
|
1501
|
+
*/
|
|
1502
|
+
createX402PaymentRequest(fromAgent, toAgent, amount, currency, serviceDescription) {
|
|
1503
|
+
return {
|
|
1504
|
+
payment_id: `x402_${Date.now().toString(36)}`,
|
|
1505
|
+
from_agent: fromAgent,
|
|
1506
|
+
to_agent: toAgent,
|
|
1507
|
+
amount,
|
|
1508
|
+
currency,
|
|
1509
|
+
service_description: serviceDescription,
|
|
1510
|
+
network: this.network,
|
|
1511
|
+
protocol_fee: amount * 0.025,
|
|
1512
|
+
// 2.5% ChaosChain fee
|
|
1513
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Execute x402 crypto payment (delegated to X402PaymentManager)
|
|
1518
|
+
*/
|
|
1519
|
+
executeX402Payment(paymentRequest) {
|
|
1520
|
+
const transactionHash = `0x${Math.random().toString(16).substring(2, 66)}`;
|
|
1521
|
+
return {
|
|
1522
|
+
payment_id: paymentRequest.payment_id,
|
|
1523
|
+
transaction_hash: transactionHash,
|
|
1524
|
+
status: "confirmed",
|
|
1525
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1526
|
+
network: this.network,
|
|
1527
|
+
from_address: this.wallet.address,
|
|
1528
|
+
to_address: paymentRequest.to_agent
|
|
1529
|
+
};
|
|
1530
|
+
}
|
|
1531
|
+
/**
|
|
1532
|
+
* Get payment statistics
|
|
1533
|
+
*/
|
|
1534
|
+
getPaymentStats() {
|
|
1535
|
+
return {
|
|
1536
|
+
agent_name: this.agentName,
|
|
1537
|
+
network: this.network,
|
|
1538
|
+
wallet_address: this.wallet.address,
|
|
1539
|
+
supported_methods: this.getSupportedPaymentMethods().length,
|
|
1540
|
+
payment_methods_status: this.getPaymentMethodsStatus(),
|
|
1541
|
+
features: {
|
|
1542
|
+
traditional_payments: true,
|
|
1543
|
+
crypto_payments: true,
|
|
1544
|
+
multi_currency: true,
|
|
1545
|
+
instant_settlement: true
|
|
1546
|
+
}
|
|
1547
|
+
};
|
|
1548
|
+
}
|
|
1549
|
+
};
|
|
1550
|
+
var X402Server = class {
|
|
1551
|
+
paymentManager;
|
|
1552
|
+
server = null;
|
|
1553
|
+
endpoints = /* @__PURE__ */ new Map();
|
|
1554
|
+
paymentCache = /* @__PURE__ */ new Map();
|
|
1555
|
+
config;
|
|
1556
|
+
constructor(paymentManager, config) {
|
|
1557
|
+
this.paymentManager = paymentManager;
|
|
1558
|
+
this.config = {
|
|
1559
|
+
port: config.port,
|
|
1560
|
+
host: config.host || "0.0.0.0",
|
|
1561
|
+
defaultCurrency: config.defaultCurrency || "USDC"
|
|
1562
|
+
};
|
|
1563
|
+
console.log(`\u{1F512} X402 Paywall Server initialized on port ${this.config.port}`);
|
|
1564
|
+
}
|
|
1565
|
+
/**
|
|
1566
|
+
* Register a payment-protected endpoint
|
|
1567
|
+
*/
|
|
1568
|
+
requirePayment(amount, description, currency) {
|
|
1569
|
+
return (handler) => {
|
|
1570
|
+
const path3 = `/${handler.name || "endpoint"}`;
|
|
1571
|
+
const endpointConfig = {
|
|
1572
|
+
path: path3,
|
|
1573
|
+
amount,
|
|
1574
|
+
currency: currency || this.config.defaultCurrency,
|
|
1575
|
+
description,
|
|
1576
|
+
handler
|
|
1577
|
+
};
|
|
1578
|
+
this.endpoints.set(path3, endpointConfig);
|
|
1579
|
+
console.log(`\u{1F4B0} Registered paywall endpoint: ${path3} (${amount} ${currency || this.config.defaultCurrency})`);
|
|
1580
|
+
return handler;
|
|
1581
|
+
};
|
|
1582
|
+
}
|
|
1583
|
+
/**
|
|
1584
|
+
* Start the HTTP 402 server
|
|
1585
|
+
*/
|
|
1586
|
+
start() {
|
|
1587
|
+
if (this.server) {
|
|
1588
|
+
console.warn("\u26A0\uFE0F Server already running");
|
|
1589
|
+
return;
|
|
1590
|
+
}
|
|
1591
|
+
this.server = http.createServer((req, res) => {
|
|
1592
|
+
this.handleRequest(req, res).catch((error) => {
|
|
1593
|
+
console.error("\u274C Request handler error:", error);
|
|
1594
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
1595
|
+
res.end(JSON.stringify({ error: "Internal server error" }));
|
|
1596
|
+
});
|
|
1597
|
+
});
|
|
1598
|
+
this.server.listen(this.config.port, this.config.host, () => {
|
|
1599
|
+
console.log(`\u{1F680} X402 Paywall Server running at http://${this.config.host}:${this.config.port}`);
|
|
1600
|
+
console.log(`\u{1F4CB} Registered endpoints: ${this.endpoints.size}`);
|
|
1601
|
+
this.endpoints.forEach((config, path3) => {
|
|
1602
|
+
console.log(` - ${path3}: ${config.amount} ${config.currency} - ${config.description}`);
|
|
1603
|
+
});
|
|
1604
|
+
});
|
|
1605
|
+
}
|
|
1606
|
+
/**
|
|
1607
|
+
* Stop the server
|
|
1608
|
+
*/
|
|
1609
|
+
stop() {
|
|
1610
|
+
return new Promise((resolve, reject) => {
|
|
1611
|
+
if (!this.server) {
|
|
1612
|
+
resolve();
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
this.server.close((err) => {
|
|
1616
|
+
if (err) {
|
|
1617
|
+
reject(err);
|
|
1618
|
+
} else {
|
|
1619
|
+
console.log("\u{1F6D1} X402 Paywall Server stopped");
|
|
1620
|
+
this.server = null;
|
|
1621
|
+
resolve();
|
|
1622
|
+
}
|
|
1623
|
+
});
|
|
1624
|
+
});
|
|
1625
|
+
}
|
|
1626
|
+
/**
|
|
1627
|
+
* Handle incoming HTTP requests
|
|
1628
|
+
*/
|
|
1629
|
+
async handleRequest(req, res) {
|
|
1630
|
+
const url = new URL(req.url || "/", `http://${req.headers.host}`);
|
|
1631
|
+
const path3 = url.pathname;
|
|
1632
|
+
const endpointConfig = this.endpoints.get(path3);
|
|
1633
|
+
if (!endpointConfig) {
|
|
1634
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
1635
|
+
res.end(JSON.stringify({ error: "Endpoint not found" }));
|
|
1636
|
+
return;
|
|
1637
|
+
}
|
|
1638
|
+
const paymentToken = req.headers["x-payment-token"];
|
|
1639
|
+
const paymentTxHash = req.headers["x-payment-tx"];
|
|
1640
|
+
if (!paymentToken && !paymentTxHash) {
|
|
1641
|
+
this.sendPaymentRequired(res, endpointConfig);
|
|
1642
|
+
return;
|
|
1643
|
+
}
|
|
1644
|
+
const isValidPayment = await this.verifyPayment(paymentToken || paymentTxHash, endpointConfig);
|
|
1645
|
+
if (!isValidPayment) {
|
|
1646
|
+
res.writeHead(402, { "Content-Type": "application/json" });
|
|
1647
|
+
res.end(JSON.stringify({ error: "Invalid or insufficient payment" }));
|
|
1648
|
+
return;
|
|
1649
|
+
}
|
|
1650
|
+
try {
|
|
1651
|
+
let requestData = {};
|
|
1652
|
+
if (req.method === "POST" || req.method === "PUT") {
|
|
1653
|
+
const chunks = [];
|
|
1654
|
+
req.on("data", (chunk) => chunks.push(chunk));
|
|
1655
|
+
await new Promise((resolve) => req.on("end", resolve));
|
|
1656
|
+
const body = Buffer.concat(chunks).toString();
|
|
1657
|
+
requestData = body ? JSON.parse(body) : {};
|
|
1658
|
+
}
|
|
1659
|
+
const result = await endpointConfig.handler(requestData);
|
|
1660
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1661
|
+
res.end(JSON.stringify({ success: true, data: result }));
|
|
1662
|
+
} catch (error) {
|
|
1663
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
1664
|
+
res.end(JSON.stringify({ error: error.message }));
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
/**
|
|
1668
|
+
* Send HTTP 402 Payment Required response
|
|
1669
|
+
*/
|
|
1670
|
+
sendPaymentRequired(res, endpointConfig) {
|
|
1671
|
+
const paymentRequirements = this.paymentManager.createPaymentRequirements(
|
|
1672
|
+
endpointConfig.amount,
|
|
1673
|
+
endpointConfig.currency,
|
|
1674
|
+
endpointConfig.description
|
|
1675
|
+
);
|
|
1676
|
+
const response = {
|
|
1677
|
+
error: "Payment Required",
|
|
1678
|
+
payment_required: true,
|
|
1679
|
+
payment_requirements: paymentRequirements,
|
|
1680
|
+
instructions: {
|
|
1681
|
+
step_1: "Execute payment using x402 protocol",
|
|
1682
|
+
step_2: "Include payment transaction hash in X-Payment-Tx header",
|
|
1683
|
+
step_3: "Retry request with payment proof"
|
|
1684
|
+
}
|
|
1685
|
+
};
|
|
1686
|
+
res.writeHead(402, {
|
|
1687
|
+
"Content-Type": "application/json",
|
|
1688
|
+
"X-Payment-Required": "true",
|
|
1689
|
+
"X-Payment-Amount": endpointConfig.amount.toString(),
|
|
1690
|
+
"X-Payment-Currency": endpointConfig.currency,
|
|
1691
|
+
"X-Payment-Address": paymentRequirements.settlement_address
|
|
1692
|
+
});
|
|
1693
|
+
res.end(JSON.stringify(response));
|
|
1694
|
+
}
|
|
1695
|
+
/**
|
|
1696
|
+
* Verify payment
|
|
1697
|
+
*/
|
|
1698
|
+
async verifyPayment(paymentIdentifier, endpointConfig) {
|
|
1699
|
+
try {
|
|
1700
|
+
const cachedPayment = this.paymentCache.get(paymentIdentifier);
|
|
1701
|
+
if (cachedPayment) {
|
|
1702
|
+
if (cachedPayment.amount >= endpointConfig.amount && cachedPayment.currency === endpointConfig.currency) {
|
|
1703
|
+
console.log(`\u2705 Payment verified from cache: ${paymentIdentifier}`);
|
|
1704
|
+
return true;
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
if (paymentIdentifier.startsWith("0x") && paymentIdentifier.length === 66) {
|
|
1708
|
+
const mockProof = {
|
|
1709
|
+
payment_id: paymentIdentifier,
|
|
1710
|
+
transaction_hash: paymentIdentifier,
|
|
1711
|
+
main_transaction_hash: paymentIdentifier,
|
|
1712
|
+
from_address: "0x0000000000000000000000000000000000000000",
|
|
1713
|
+
to_address: "0x0000000000000000000000000000000000000000",
|
|
1714
|
+
treasury_address: "0x0000000000000000000000000000000000000000",
|
|
1715
|
+
amount: endpointConfig.amount,
|
|
1716
|
+
currency: endpointConfig.currency,
|
|
1717
|
+
protocol_fee: 0,
|
|
1718
|
+
network: "base-sepolia",
|
|
1719
|
+
chain_id: 84532,
|
|
1720
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1721
|
+
status: "confirmed",
|
|
1722
|
+
confirmations: 1
|
|
1723
|
+
};
|
|
1724
|
+
const isValid = await this.paymentManager.verifyPayment(mockProof);
|
|
1725
|
+
if (isValid) {
|
|
1726
|
+
this.paymentCache.set(paymentIdentifier, mockProof);
|
|
1727
|
+
console.log(`\u2705 Payment verified on-chain: ${paymentIdentifier}`);
|
|
1728
|
+
return true;
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
console.error(`\u274C Payment verification failed: ${paymentIdentifier}`);
|
|
1732
|
+
return false;
|
|
1733
|
+
} catch (error) {
|
|
1734
|
+
console.error(`\u274C Payment verification error: ${error}`);
|
|
1735
|
+
return false;
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
/**
|
|
1739
|
+
* Get server statistics
|
|
1740
|
+
*/
|
|
1741
|
+
getServerStats() {
|
|
1742
|
+
return {
|
|
1743
|
+
running: !!this.server,
|
|
1744
|
+
port: this.config.port,
|
|
1745
|
+
host: this.config.host,
|
|
1746
|
+
endpoints: Array.from(this.endpoints.entries()).map(([path3, config]) => ({
|
|
1747
|
+
path: path3,
|
|
1748
|
+
amount: config.amount,
|
|
1749
|
+
currency: config.currency,
|
|
1750
|
+
description: config.description
|
|
1751
|
+
})),
|
|
1752
|
+
payments_cached: this.paymentCache.size,
|
|
1753
|
+
default_currency: this.config.defaultCurrency
|
|
1754
|
+
};
|
|
1755
|
+
}
|
|
1756
|
+
/**
|
|
1757
|
+
* Clear payment cache
|
|
1758
|
+
*/
|
|
1759
|
+
clearPaymentCache() {
|
|
1760
|
+
this.paymentCache.clear();
|
|
1761
|
+
console.log("\u{1F5D1}\uFE0F Payment cache cleared");
|
|
1762
|
+
}
|
|
1763
|
+
};
|
|
1764
|
+
var GoogleAP2Integration = class {
|
|
1765
|
+
agentName;
|
|
1766
|
+
privateKey;
|
|
1767
|
+
publicKey;
|
|
1768
|
+
merchantPrivateKey;
|
|
1769
|
+
constructor(agentName, merchantPrivateKey) {
|
|
1770
|
+
this.agentName = agentName;
|
|
1771
|
+
this.merchantPrivateKey = merchantPrivateKey || "demo_private_key_123";
|
|
1772
|
+
const keypair = this.getOrGenerateRsaKeypair();
|
|
1773
|
+
this.privateKey = keypair.privateKey;
|
|
1774
|
+
this.publicKey = keypair.publicKey;
|
|
1775
|
+
console.log(`\u2705 Google AP2 Integration initialized for ${agentName}`);
|
|
1776
|
+
}
|
|
1777
|
+
/**
|
|
1778
|
+
* Generate or load RSA keypair for production JWT signing
|
|
1779
|
+
*/
|
|
1780
|
+
getOrGenerateRsaKeypair() {
|
|
1781
|
+
const keyDir = path2.join(process.cwd(), "keys");
|
|
1782
|
+
const privateKeyPath = path2.join(keyDir, `${this.agentName}_ap2_private.pem`);
|
|
1783
|
+
const publicKeyPath = path2.join(keyDir, `${this.agentName}_ap2_public.pem`);
|
|
1784
|
+
if (!fs2.existsSync(keyDir)) {
|
|
1785
|
+
fs2.mkdirSync(keyDir, { recursive: true });
|
|
1786
|
+
}
|
|
1787
|
+
if (fs2.existsSync(privateKeyPath) && fs2.existsSync(publicKeyPath)) {
|
|
1788
|
+
try {
|
|
1789
|
+
const privateKeyPem = fs2.readFileSync(privateKeyPath, "utf-8");
|
|
1790
|
+
const publicKeyPem = fs2.readFileSync(publicKeyPath, "utf-8");
|
|
1791
|
+
const privateKey2 = crypto.createPrivateKey(privateKeyPem);
|
|
1792
|
+
console.log(`\u{1F511} Loaded existing RSA keypair for ${this.agentName}`);
|
|
1793
|
+
return { privateKey: privateKey2, publicKey: publicKeyPem };
|
|
1794
|
+
} catch (e) {
|
|
1795
|
+
console.warn(`\u26A0\uFE0F Failed to load existing keys: ${e}`);
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
console.log(`\u{1F511} Generating new RSA keypair for ${this.agentName}`);
|
|
1799
|
+
const { privateKey, publicKey } = crypto.generateKeyPairSync("rsa", {
|
|
1800
|
+
modulusLength: 2048,
|
|
1801
|
+
publicKeyEncoding: {
|
|
1802
|
+
type: "spki",
|
|
1803
|
+
format: "pem"
|
|
1804
|
+
},
|
|
1805
|
+
privateKeyEncoding: {
|
|
1806
|
+
type: "pkcs8",
|
|
1807
|
+
format: "pem"
|
|
1808
|
+
}
|
|
1809
|
+
});
|
|
1810
|
+
try {
|
|
1811
|
+
fs2.writeFileSync(privateKeyPath, privateKey);
|
|
1812
|
+
fs2.writeFileSync(publicKeyPath, publicKey);
|
|
1813
|
+
console.log(`\u{1F4BE} RSA keypair saved to ${keyDir}`);
|
|
1814
|
+
} catch (e) {
|
|
1815
|
+
console.warn(`\u26A0\uFE0F Failed to save keys: ${e}`);
|
|
1816
|
+
}
|
|
1817
|
+
return {
|
|
1818
|
+
privateKey: crypto.createPrivateKey(privateKey),
|
|
1819
|
+
publicKey
|
|
1820
|
+
};
|
|
1821
|
+
}
|
|
1822
|
+
/**
|
|
1823
|
+
* Create an IntentMandate using Google's official AP2 types
|
|
1824
|
+
*/
|
|
1825
|
+
createIntentMandate(userDescription, merchants, skus, requiresRefundability = false, expiryMinutes = 60) {
|
|
1826
|
+
try {
|
|
1827
|
+
const expiryTime = new Date(Date.now() + expiryMinutes * 60 * 1e3);
|
|
1828
|
+
const intentMandate = {
|
|
1829
|
+
user_cart_confirmation_required: true,
|
|
1830
|
+
natural_language_description: userDescription,
|
|
1831
|
+
merchants,
|
|
1832
|
+
skus,
|
|
1833
|
+
requires_refundability: requiresRefundability,
|
|
1834
|
+
intent_expiry: expiryTime.toISOString()
|
|
1835
|
+
};
|
|
1836
|
+
console.log(`\u{1F4DD} Created Google AP2 IntentMandate`);
|
|
1837
|
+
console.log(` Description: ${userDescription}`);
|
|
1838
|
+
console.log(` Expires: ${expiryTime.toISOString()}`);
|
|
1839
|
+
return {
|
|
1840
|
+
intent_mandate: intentMandate,
|
|
1841
|
+
success: true
|
|
1842
|
+
};
|
|
1843
|
+
} catch (e) {
|
|
1844
|
+
console.error(`\u274C Failed to create IntentMandate: ${e}`);
|
|
1845
|
+
return {
|
|
1846
|
+
success: false,
|
|
1847
|
+
error: String(e)
|
|
1848
|
+
};
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
/**
|
|
1852
|
+
* Create a CartMandate using Google's official AP2 types with JWT signing
|
|
1853
|
+
*/
|
|
1854
|
+
async createCartMandate(cartId, items, totalAmount, currency = "USD", merchantName, expiryMinutes = 15) {
|
|
1855
|
+
try {
|
|
1856
|
+
const expiryTime = new Date(Date.now() + expiryMinutes * 60 * 1e3);
|
|
1857
|
+
const paymentItems = items.map((item) => ({
|
|
1858
|
+
label: item.name,
|
|
1859
|
+
amount: {
|
|
1860
|
+
currency,
|
|
1861
|
+
value: item.price
|
|
1862
|
+
}
|
|
1863
|
+
}));
|
|
1864
|
+
const totalItem = {
|
|
1865
|
+
label: "Total",
|
|
1866
|
+
amount: {
|
|
1867
|
+
currency,
|
|
1868
|
+
value: totalAmount
|
|
1869
|
+
}
|
|
1870
|
+
};
|
|
1871
|
+
const methodData = [
|
|
1872
|
+
{
|
|
1873
|
+
supported_methods: "basic-card",
|
|
1874
|
+
data: { supportedNetworks: ["visa", "mastercard"] }
|
|
1875
|
+
},
|
|
1876
|
+
{
|
|
1877
|
+
supported_methods: "google-pay",
|
|
1878
|
+
data: { environment: "TEST" }
|
|
1879
|
+
},
|
|
1880
|
+
{
|
|
1881
|
+
supported_methods: "crypto",
|
|
1882
|
+
data: { supportedCurrencies: ["USDC", "ETH"] }
|
|
1883
|
+
}
|
|
1884
|
+
];
|
|
1885
|
+
const paymentRequest = {
|
|
1886
|
+
method_data: methodData,
|
|
1887
|
+
details: {
|
|
1888
|
+
id: `payment_${cartId}`,
|
|
1889
|
+
display_items: paymentItems,
|
|
1890
|
+
total: totalItem
|
|
1891
|
+
}
|
|
1892
|
+
};
|
|
1893
|
+
const cartContents = {
|
|
1894
|
+
id: cartId,
|
|
1895
|
+
user_cart_confirmation_required: true,
|
|
1896
|
+
payment_request: paymentRequest,
|
|
1897
|
+
cart_expiry: expiryTime.toISOString(),
|
|
1898
|
+
merchant_name: merchantName || this.agentName
|
|
1899
|
+
};
|
|
1900
|
+
const jwtToken = await this.createMerchantJwt(cartContents);
|
|
1901
|
+
const cartMandate = {
|
|
1902
|
+
contents: cartContents,
|
|
1903
|
+
merchant_authorization: jwtToken
|
|
1904
|
+
};
|
|
1905
|
+
console.log(`\u{1F6D2} Created Google AP2 CartMandate with JWT`);
|
|
1906
|
+
console.log(` Cart ID: ${cartId}`);
|
|
1907
|
+
console.log(` Items: ${items.length} items, Total: ${totalAmount} ${currency}`);
|
|
1908
|
+
console.log(` JWT: ${jwtToken.slice(0, 50)}...`);
|
|
1909
|
+
return {
|
|
1910
|
+
cart_mandate: cartMandate,
|
|
1911
|
+
jwt_token: jwtToken,
|
|
1912
|
+
success: true
|
|
1913
|
+
};
|
|
1914
|
+
} catch (e) {
|
|
1915
|
+
console.error(`\u274C Failed to create CartMandate: ${e}`);
|
|
1916
|
+
return {
|
|
1917
|
+
success: false,
|
|
1918
|
+
error: String(e)
|
|
1919
|
+
};
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
/**
|
|
1923
|
+
* Create a JWT token for merchant authorization as per Google's AP2 spec
|
|
1924
|
+
*/
|
|
1925
|
+
async createMerchantJwt(cartContents) {
|
|
1926
|
+
const cartJson = JSON.stringify(cartContents);
|
|
1927
|
+
const cartHash = crypto.createHash("sha256").update(cartJson).digest("hex");
|
|
1928
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1929
|
+
const payload = {
|
|
1930
|
+
iss: `did:chaoschain:${this.agentName}`,
|
|
1931
|
+
// Issuer (DID format)
|
|
1932
|
+
sub: cartContents.id,
|
|
1933
|
+
// Subject (cart ID)
|
|
1934
|
+
aud: "chaoschain:payment_processor",
|
|
1935
|
+
// Audience
|
|
1936
|
+
iat: now,
|
|
1937
|
+
// Issued at
|
|
1938
|
+
exp: now + 15 * 60,
|
|
1939
|
+
// Expires (15 minutes)
|
|
1940
|
+
jti: `jwt_${cartContents.id}_${now}`,
|
|
1941
|
+
// JWT ID
|
|
1942
|
+
cart_hash: cartHash,
|
|
1943
|
+
// Cart integrity hash
|
|
1944
|
+
merchant_name: cartContents.merchant_name
|
|
1945
|
+
};
|
|
1946
|
+
const jwt = await new jose.SignJWT(payload).setProtectedHeader({
|
|
1947
|
+
alg: "RS256",
|
|
1948
|
+
kid: `did:chaoschain:${this.agentName}#key-1`
|
|
1949
|
+
}).sign(this.privateKey);
|
|
1950
|
+
return jwt;
|
|
1951
|
+
}
|
|
1952
|
+
/**
|
|
1953
|
+
* Verify a JWT token (for validation purposes)
|
|
1954
|
+
*/
|
|
1955
|
+
async verifyJwtToken(token) {
|
|
1956
|
+
try {
|
|
1957
|
+
const publicKey = crypto.createPublicKey(this.publicKey);
|
|
1958
|
+
const { payload } = await jose.jwtVerify(token, publicKey, {
|
|
1959
|
+
algorithms: ["RS256"],
|
|
1960
|
+
audience: "chaoschain:payment_processor"
|
|
1961
|
+
});
|
|
1962
|
+
console.log(`\u2705 JWT token verified successfully with RSA256`);
|
|
1963
|
+
return payload;
|
|
1964
|
+
} catch (e) {
|
|
1965
|
+
if (e.code === "ERR_JWT_EXPIRED") {
|
|
1966
|
+
console.error(`\u274C JWT token has expired`);
|
|
1967
|
+
} else if (e.code === "ERR_JWT_CLAIM_VALIDATION_FAILED") {
|
|
1968
|
+
console.error(`\u274C JWT token has invalid audience`);
|
|
1969
|
+
} else {
|
|
1970
|
+
console.error(`\u274C JWT token is invalid: ${e}`);
|
|
1971
|
+
}
|
|
1972
|
+
return {};
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
/**
|
|
1976
|
+
* Get a summary of the Google AP2 integration capabilities
|
|
1977
|
+
*/
|
|
1978
|
+
getIntegrationSummary() {
|
|
1979
|
+
return {
|
|
1980
|
+
integration_type: "Google Official AP2",
|
|
1981
|
+
agent_name: this.agentName,
|
|
1982
|
+
supported_features: [
|
|
1983
|
+
"IntentMandate creation with Google types",
|
|
1984
|
+
"CartMandate creation with JWT signing",
|
|
1985
|
+
"W3C PaymentRequest API compliance",
|
|
1986
|
+
"Multi-payment method support",
|
|
1987
|
+
"JWT-based merchant authorization",
|
|
1988
|
+
"Proper expiry handling",
|
|
1989
|
+
"Cart integrity verification"
|
|
1990
|
+
],
|
|
1991
|
+
cryptographic_features: [
|
|
1992
|
+
"JWT signing with RS256 (production)",
|
|
1993
|
+
"Cart content hashing for integrity",
|
|
1994
|
+
"Timestamp-based expiry",
|
|
1995
|
+
"Replay attack prevention with JTI"
|
|
1996
|
+
],
|
|
1997
|
+
compliance: ["Google AP2 Protocol", "W3C Payment Request API", "JWT RFC 7519", "ISO 8601 timestamps"]
|
|
1998
|
+
};
|
|
1999
|
+
}
|
|
2000
|
+
};
|
|
2001
|
+
|
|
2002
|
+
// src/A2AX402Extension.ts
|
|
2003
|
+
var A2AX402Extension = class {
|
|
2004
|
+
agentName;
|
|
2005
|
+
network;
|
|
2006
|
+
paymentManager;
|
|
2007
|
+
supportedCryptoMethods;
|
|
2008
|
+
supportedNetworks;
|
|
2009
|
+
w3cPaymentMethods;
|
|
2010
|
+
constructor(agentName, network, paymentManager) {
|
|
2011
|
+
this.agentName = agentName;
|
|
2012
|
+
this.network = network;
|
|
2013
|
+
this.paymentManager = paymentManager;
|
|
2014
|
+
this.supportedCryptoMethods = ["usdc", "eth", "native"];
|
|
2015
|
+
this.supportedNetworks = ["base-sepolia", "ethereum-sepolia", "optimism-sepolia"];
|
|
2016
|
+
this.w3cPaymentMethods = this.initializeW3cPaymentMethods();
|
|
2017
|
+
console.log(`\u2705 A2A-x402 Extension initialized for ${agentName} on ${network}`);
|
|
2018
|
+
console.log(`\u{1F4B3} Multi-payment support: ${this.w3cPaymentMethods.length} methods available`);
|
|
2019
|
+
}
|
|
2020
|
+
/**
|
|
2021
|
+
* Initialize W3C Payment Request API compliant payment methods
|
|
2022
|
+
*/
|
|
2023
|
+
initializeW3cPaymentMethods() {
|
|
2024
|
+
const methods = [];
|
|
2025
|
+
methods.push({
|
|
2026
|
+
supported_methods: "basic-card",
|
|
2027
|
+
data: {
|
|
2028
|
+
supportedNetworks: ["visa", "mastercard", "amex", "discover"],
|
|
2029
|
+
supportedTypes: ["credit", "debit"]
|
|
2030
|
+
}
|
|
2031
|
+
});
|
|
2032
|
+
methods.push({
|
|
2033
|
+
supported_methods: "https://google.com/pay",
|
|
2034
|
+
data: {
|
|
2035
|
+
environment: "PRODUCTION",
|
|
2036
|
+
apiVersion: 2,
|
|
2037
|
+
apiVersionMinor: 0,
|
|
2038
|
+
allowedPaymentMethods: [
|
|
2039
|
+
{
|
|
2040
|
+
type: "CARD",
|
|
2041
|
+
parameters: {
|
|
2042
|
+
allowedAuthMethods: ["PAN_ONLY", "CRYPTOGRAM_3DS"],
|
|
2043
|
+
allowedCardNetworks: ["AMEX", "DISCOVER", "JCB", "MASTERCARD", "VISA"]
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
]
|
|
2047
|
+
}
|
|
2048
|
+
});
|
|
2049
|
+
methods.push({
|
|
2050
|
+
supported_methods: "https://apple.com/apple-pay",
|
|
2051
|
+
data: {
|
|
2052
|
+
version: 3,
|
|
2053
|
+
merchantIdentifier: `merchant.chaoschain.${this.agentName.toLowerCase()}`,
|
|
2054
|
+
merchantCapabilities: ["supports3DS"],
|
|
2055
|
+
supportedNetworks: ["visa", "masterCard", "amex", "discover"]
|
|
2056
|
+
}
|
|
2057
|
+
});
|
|
2058
|
+
methods.push({
|
|
2059
|
+
supported_methods: "https://a2a.org/x402",
|
|
2060
|
+
data: {
|
|
2061
|
+
supportedCryptocurrencies: this.supportedCryptoMethods,
|
|
2062
|
+
supportedNetworks: this.supportedNetworks,
|
|
2063
|
+
settlementAddress: "dynamic",
|
|
2064
|
+
protocolVersion: "x402-v1.0"
|
|
2065
|
+
}
|
|
2066
|
+
});
|
|
2067
|
+
methods.push({
|
|
2068
|
+
supported_methods: "https://paypal.com",
|
|
2069
|
+
data: {
|
|
2070
|
+
environment: "sandbox",
|
|
2071
|
+
intent: "capture"
|
|
2072
|
+
}
|
|
2073
|
+
});
|
|
2074
|
+
return methods;
|
|
2075
|
+
}
|
|
2076
|
+
/**
|
|
2077
|
+
* Create x402 payment method descriptor with W3C compliance
|
|
2078
|
+
*/
|
|
2079
|
+
createX402PaymentMethod(settlementAddress) {
|
|
2080
|
+
const w3cMethods = this.w3cPaymentMethods.map((method) => method.supported_methods);
|
|
2081
|
+
return {
|
|
2082
|
+
supported_methods: w3cMethods,
|
|
2083
|
+
supported_networks: this.supportedNetworks,
|
|
2084
|
+
payment_endpoint: `x402://${this.agentName}.chaoschain.com/pay`,
|
|
2085
|
+
verification_endpoint: `https://${this.agentName}.chaoschain.com/verify`,
|
|
2086
|
+
method_data: {
|
|
2087
|
+
w3c_methods: this.w3cPaymentMethods.map((method) => ({
|
|
2088
|
+
supportedMethods: method.supported_methods,
|
|
2089
|
+
data: method.data
|
|
2090
|
+
})),
|
|
2091
|
+
crypto_settlement_address: settlementAddress
|
|
2092
|
+
}
|
|
2093
|
+
};
|
|
2094
|
+
}
|
|
2095
|
+
/**
|
|
2096
|
+
* Create enhanced payment request with x402 crypto support
|
|
2097
|
+
*/
|
|
2098
|
+
createEnhancedPaymentRequest(cartId, totalAmount, currency, items, settlementAddress) {
|
|
2099
|
+
const x402Methods = [this.createX402PaymentMethod(settlementAddress)];
|
|
2100
|
+
const paymentRequest = {
|
|
2101
|
+
id: `x402_${cartId}_${Date.now().toString(36)}`,
|
|
2102
|
+
total: {
|
|
2103
|
+
amount: { value: totalAmount.toString(), currency },
|
|
2104
|
+
label: `Payment for ${items.length} items`
|
|
2105
|
+
},
|
|
2106
|
+
display_items: items.map((item) => ({
|
|
2107
|
+
label: item.name || item.service || "Item",
|
|
2108
|
+
amount: { value: (item.price || 0).toString(), currency }
|
|
2109
|
+
})),
|
|
2110
|
+
x402_methods: x402Methods,
|
|
2111
|
+
settlement_address: settlementAddress,
|
|
2112
|
+
network: this.network,
|
|
2113
|
+
expires_at: new Date(Date.now() + 30 * 60 * 1e3).toISOString()
|
|
2114
|
+
};
|
|
2115
|
+
console.log(`\u{1F4B3} Created x402 payment request: ${paymentRequest.id}`);
|
|
2116
|
+
return paymentRequest;
|
|
2117
|
+
}
|
|
2118
|
+
/**
|
|
2119
|
+
* Execute x402 crypto payment using the real payment manager
|
|
2120
|
+
*/
|
|
2121
|
+
async executeX402Payment(paymentRequest, payerAgent, serviceDescription = "A2A Service") {
|
|
2122
|
+
console.log(`\u{1F4B8} Executing x402 payment: ${payerAgent} \u2192 ${this.agentName}`);
|
|
2123
|
+
const amount = parseFloat(paymentRequest.total.amount.value);
|
|
2124
|
+
const currency = paymentRequest.total.amount.currency;
|
|
2125
|
+
const pmPaymentRequest = this.paymentManager.createX402PaymentRequest(
|
|
2126
|
+
payerAgent,
|
|
2127
|
+
this.agentName,
|
|
2128
|
+
amount,
|
|
2129
|
+
currency,
|
|
2130
|
+
serviceDescription
|
|
2131
|
+
);
|
|
2132
|
+
const paymentProof = this.paymentManager.executeX402Payment(pmPaymentRequest);
|
|
2133
|
+
const response = {
|
|
2134
|
+
payment_id: paymentProof.payment_id,
|
|
2135
|
+
transaction_hash: paymentProof.transaction_hash,
|
|
2136
|
+
network: this.network,
|
|
2137
|
+
amount,
|
|
2138
|
+
currency,
|
|
2139
|
+
settlement_address: paymentRequest.settlement_address,
|
|
2140
|
+
confirmation_blocks: 1,
|
|
2141
|
+
status: "confirmed",
|
|
2142
|
+
timestamp: paymentProof.timestamp.toISOString(),
|
|
2143
|
+
gas_fee: void 0,
|
|
2144
|
+
protocol_fee: pmPaymentRequest.protocol_fee
|
|
2145
|
+
};
|
|
2146
|
+
console.log(`\u2705 x402 payment confirmed: ${response.transaction_hash}`);
|
|
2147
|
+
return response;
|
|
2148
|
+
}
|
|
2149
|
+
/**
|
|
2150
|
+
* Execute traditional payment (cards, Google Pay, Apple Pay, etc.)
|
|
2151
|
+
*/
|
|
2152
|
+
executeTraditionalPayment(paymentMethod, amount, currency, paymentData2) {
|
|
2153
|
+
console.log(`\u{1F4B3} Processing ${paymentMethod} payment: $${amount} ${currency}`);
|
|
2154
|
+
if (this.paymentManager) {
|
|
2155
|
+
let methodEnum;
|
|
2156
|
+
if (paymentMethod === "basic-card") {
|
|
2157
|
+
methodEnum = "basic-card" /* BASIC_CARD */;
|
|
2158
|
+
} else if (paymentMethod === "https://google.com/pay") {
|
|
2159
|
+
methodEnum = "https://google.com/pay" /* GOOGLE_PAY */;
|
|
2160
|
+
} else if (paymentMethod === "https://apple.com/apple-pay") {
|
|
2161
|
+
methodEnum = "https://apple.com/apple-pay" /* APPLE_PAY */;
|
|
2162
|
+
} else if (paymentMethod === "https://paypal.com") {
|
|
2163
|
+
methodEnum = "https://paypal.com" /* PAYPAL */;
|
|
2164
|
+
} else if (paymentMethod === "https://a2a.org/x402") {
|
|
2165
|
+
methodEnum = "https://a2a.org/x402" /* A2A_X402 */;
|
|
2166
|
+
}
|
|
2167
|
+
if (methodEnum) {
|
|
2168
|
+
const result = this.paymentManager.executeTraditionalPayment(methodEnum, amount, currency, paymentData2);
|
|
2169
|
+
return {
|
|
2170
|
+
payment_id: result.payment_id,
|
|
2171
|
+
method: paymentMethod,
|
|
2172
|
+
amount,
|
|
2173
|
+
currency,
|
|
2174
|
+
status: result.status,
|
|
2175
|
+
transaction_id: result.transaction_id,
|
|
2176
|
+
authorization_code: result.processor_response?.authorization_code,
|
|
2177
|
+
timestamp: result.timestamp,
|
|
2178
|
+
receipt_data: result.processor_response
|
|
2179
|
+
};
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
const paymentId = `trad_${Date.now().toString(36)}`;
|
|
2183
|
+
return {
|
|
2184
|
+
payment_id: paymentId,
|
|
2185
|
+
method: paymentMethod,
|
|
2186
|
+
amount,
|
|
2187
|
+
currency,
|
|
2188
|
+
status: "failed",
|
|
2189
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2190
|
+
receipt_data: { error: "Unsupported payment method" }
|
|
2191
|
+
};
|
|
2192
|
+
}
|
|
2193
|
+
/**
|
|
2194
|
+
* Verify x402 payment on-chain
|
|
2195
|
+
*/
|
|
2196
|
+
verifyX402Payment(paymentResponse) {
|
|
2197
|
+
return paymentResponse.status === "confirmed" && !!paymentResponse.transaction_hash && paymentResponse.transaction_hash.length === 66;
|
|
2198
|
+
}
|
|
2199
|
+
/**
|
|
2200
|
+
* Create cryptographic proof of x402 payment
|
|
2201
|
+
*/
|
|
2202
|
+
createPaymentProof(paymentResponse) {
|
|
2203
|
+
const proofData = {
|
|
2204
|
+
payment_id: paymentResponse.payment_id,
|
|
2205
|
+
transaction_hash: paymentResponse.transaction_hash,
|
|
2206
|
+
network: paymentResponse.network,
|
|
2207
|
+
amount: paymentResponse.amount,
|
|
2208
|
+
currency: paymentResponse.currency,
|
|
2209
|
+
settlement_address: paymentResponse.settlement_address,
|
|
2210
|
+
timestamp: paymentResponse.timestamp,
|
|
2211
|
+
agent_payer: "unknown",
|
|
2212
|
+
agent_payee: this.agentName
|
|
2213
|
+
};
|
|
2214
|
+
const proofJson = JSON.stringify(proofData);
|
|
2215
|
+
const crypto2 = __require("crypto");
|
|
2216
|
+
const proofHash = crypto2.createHash("sha256").update(proofJson).digest("hex");
|
|
2217
|
+
return {
|
|
2218
|
+
proof_type: "a2a_x402_payment",
|
|
2219
|
+
proof_hash: proofHash,
|
|
2220
|
+
proof_data: proofData,
|
|
2221
|
+
verification_method: "on_chain_transaction",
|
|
2222
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
2223
|
+
};
|
|
2224
|
+
}
|
|
2225
|
+
/**
|
|
2226
|
+
* Get A2A-x402 extension capabilities with W3C Payment Request API compliance
|
|
2227
|
+
*/
|
|
2228
|
+
getExtensionCapabilities() {
|
|
2229
|
+
return {
|
|
2230
|
+
extension_name: "a2a-x402-multi-payment",
|
|
2231
|
+
version: "1.0.0",
|
|
2232
|
+
w3c_payment_methods: this.w3cPaymentMethods.map((m) => m.supported_methods),
|
|
2233
|
+
supported_crypto_methods: this.supportedCryptoMethods,
|
|
2234
|
+
supported_networks: this.supportedNetworks,
|
|
2235
|
+
features: [
|
|
2236
|
+
"w3c_payment_request_api",
|
|
2237
|
+
"multi_payment_methods",
|
|
2238
|
+
"basic_card_support",
|
|
2239
|
+
"google_pay_integration",
|
|
2240
|
+
"apple_pay_integration",
|
|
2241
|
+
"paypal_integration",
|
|
2242
|
+
"crypto_payments",
|
|
2243
|
+
"instant_settlement",
|
|
2244
|
+
"on_chain_verification",
|
|
2245
|
+
"protocol_fees",
|
|
2246
|
+
"gas_optimization",
|
|
2247
|
+
"multi_network_support"
|
|
2248
|
+
],
|
|
2249
|
+
compliance: [
|
|
2250
|
+
"W3C Payment Request API",
|
|
2251
|
+
"A2A-x402 Specification v0.1",
|
|
2252
|
+
"Google Pay API v2",
|
|
2253
|
+
"Apple Pay JS API v3",
|
|
2254
|
+
"PayPal Checkout API",
|
|
2255
|
+
"EIP-20 Token Standard",
|
|
2256
|
+
"HTTP 402 Payment Required"
|
|
2257
|
+
],
|
|
2258
|
+
payment_processors: {
|
|
2259
|
+
traditional: ["simulated_processor", "google_pay", "apple_pay", "paypal"],
|
|
2260
|
+
crypto: ["chaoschain_x402", "base_sepolia", "ethereum"]
|
|
2261
|
+
}
|
|
2262
|
+
};
|
|
2263
|
+
}
|
|
2264
|
+
};
|
|
2265
|
+
var ProcessIntegrity = class {
|
|
2266
|
+
agentName;
|
|
2267
|
+
storageManager;
|
|
2268
|
+
computeProvider;
|
|
2269
|
+
registeredFunctions;
|
|
2270
|
+
functionHashes;
|
|
2271
|
+
constructor(agentName, storageManager = null, computeProvider = null) {
|
|
2272
|
+
this.agentName = agentName;
|
|
2273
|
+
this.storageManager = storageManager;
|
|
2274
|
+
this.computeProvider = computeProvider;
|
|
2275
|
+
this.registeredFunctions = /* @__PURE__ */ new Map();
|
|
2276
|
+
this.functionHashes = /* @__PURE__ */ new Map();
|
|
2277
|
+
const verificationMode = !computeProvider ? "local" : "local + TEE attestation";
|
|
2278
|
+
console.log(
|
|
2279
|
+
`\u2705 ChaosChain Process Integrity Verifier initialized: ${agentName} (${verificationMode})`
|
|
2280
|
+
);
|
|
2281
|
+
}
|
|
2282
|
+
/**
|
|
2283
|
+
* Register a function for integrity checking.
|
|
2284
|
+
*/
|
|
2285
|
+
registerFunction(func, functionName) {
|
|
2286
|
+
const name = functionName || func.name;
|
|
2287
|
+
const codeHash = this.generateCodeHash(func);
|
|
2288
|
+
this.registeredFunctions.set(name, func);
|
|
2289
|
+
this.functionHashes.set(name, codeHash);
|
|
2290
|
+
console.log(`\u{1F4DD} Registered integrity-checked function: ${name}`);
|
|
2291
|
+
console.log(` Code hash: ${codeHash.slice(0, 16)}...`);
|
|
2292
|
+
return codeHash;
|
|
2293
|
+
}
|
|
2294
|
+
/**
|
|
2295
|
+
* Execute a registered function with integrity proof generation.
|
|
2296
|
+
*/
|
|
2297
|
+
async executeWithProof(functionName, inputs, requireProof = true, useTee = true) {
|
|
2298
|
+
if (!this.registeredFunctions.has(functionName)) {
|
|
2299
|
+
const available = Array.from(this.registeredFunctions.keys());
|
|
2300
|
+
throw new IntegrityVerificationError(`Function not registered: ${functionName}`, {
|
|
2301
|
+
available_functions: available
|
|
2302
|
+
});
|
|
2303
|
+
}
|
|
2304
|
+
const func = this.registeredFunctions.get(functionName);
|
|
2305
|
+
const codeHash = this.functionHashes.get(functionName);
|
|
2306
|
+
const executionMode = useTee && this.computeProvider ? "local + TEE" : "local";
|
|
2307
|
+
console.log(`\u26A1 Executing with ChaosChain Process Integrity: ${functionName} (${executionMode})`);
|
|
2308
|
+
const startTime = /* @__PURE__ */ new Date();
|
|
2309
|
+
let teeAttestation = null;
|
|
2310
|
+
try {
|
|
2311
|
+
const result = await func(inputs);
|
|
2312
|
+
const executionTime = /* @__PURE__ */ new Date();
|
|
2313
|
+
if (useTee && this.computeProvider) {
|
|
2314
|
+
try {
|
|
2315
|
+
teeAttestation = await this.getTeeAttestation(functionName, inputs, result);
|
|
2316
|
+
} catch (e) {
|
|
2317
|
+
console.warn(`\u26A0\uFE0F TEE attestation failed (continuing with local proof): ${e}`);
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
if (!requireProof) {
|
|
2321
|
+
return [result, null];
|
|
2322
|
+
}
|
|
2323
|
+
const proof = this.generateIntegrityProof(
|
|
2324
|
+
functionName,
|
|
2325
|
+
codeHash,
|
|
2326
|
+
inputs,
|
|
2327
|
+
result,
|
|
2328
|
+
startTime,
|
|
2329
|
+
executionTime,
|
|
2330
|
+
teeAttestation
|
|
2331
|
+
);
|
|
2332
|
+
if (this.storageManager) {
|
|
2333
|
+
await this.storeProofOnIpfs(proof);
|
|
2334
|
+
}
|
|
2335
|
+
return [result, proof];
|
|
2336
|
+
} catch (e) {
|
|
2337
|
+
throw new IntegrityVerificationError(`Function execution failed: ${e}`, {
|
|
2338
|
+
function_name: functionName,
|
|
2339
|
+
inputs
|
|
2340
|
+
});
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
/**
|
|
2344
|
+
* Generate a hash of the function's code.
|
|
2345
|
+
*/
|
|
2346
|
+
generateCodeHash(func) {
|
|
2347
|
+
try {
|
|
2348
|
+
const sourceCode = func.toString();
|
|
2349
|
+
return createHash("sha256").update(sourceCode).digest("hex");
|
|
2350
|
+
} catch {
|
|
2351
|
+
const funcInfo = `${func.name}`;
|
|
2352
|
+
return createHash("sha256").update(funcInfo).digest("hex");
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
/**
|
|
2356
|
+
* Get TEE attestation from compute provider (e.g., 0G Compute).
|
|
2357
|
+
*/
|
|
2358
|
+
async getTeeAttestation(functionName, inputs, result) {
|
|
2359
|
+
if (!this.computeProvider) {
|
|
2360
|
+
return null;
|
|
2361
|
+
}
|
|
2362
|
+
console.log(`\u{1F510} Requesting TEE attestation from compute provider...`);
|
|
2363
|
+
try {
|
|
2364
|
+
const taskData = {
|
|
2365
|
+
function: functionName,
|
|
2366
|
+
inputs,
|
|
2367
|
+
model: "gpt-oss-120b",
|
|
2368
|
+
// Default model for 0G Compute
|
|
2369
|
+
prompt: `Execute function: ${functionName} with inputs: ${JSON.stringify(inputs)}`
|
|
2370
|
+
};
|
|
2371
|
+
const jobId = await this.computeProvider.submit(taskData);
|
|
2372
|
+
const maxWait = 6e4;
|
|
2373
|
+
const startWait = Date.now();
|
|
2374
|
+
while (Date.now() - startWait < maxWait) {
|
|
2375
|
+
const statusResult = await this.computeProvider.status(jobId);
|
|
2376
|
+
const state = statusResult.state || "unknown";
|
|
2377
|
+
if (state === "completed") {
|
|
2378
|
+
const computeResult = await this.computeProvider.result(jobId);
|
|
2379
|
+
if (computeResult.success) {
|
|
2380
|
+
const attestationData = await this.computeProvider.attestation(jobId);
|
|
2381
|
+
console.log(`\u2705 TEE attestation received: ${jobId}`);
|
|
2382
|
+
console.log(` Execution Hash: ${computeResult.execution_hash}`);
|
|
2383
|
+
console.log(` Verification: ${computeResult.verification_method.value}`);
|
|
2384
|
+
return {
|
|
2385
|
+
job_id: jobId,
|
|
2386
|
+
provider: "0g-compute",
|
|
2387
|
+
execution_hash: computeResult.execution_hash,
|
|
2388
|
+
// TEE execution ID
|
|
2389
|
+
verification_method: computeResult.verification_method.value,
|
|
2390
|
+
model: taskData.model,
|
|
2391
|
+
attestation_data: attestationData,
|
|
2392
|
+
// Full attestation proof
|
|
2393
|
+
proof: computeResult.proof?.toString("hex"),
|
|
2394
|
+
metadata: computeResult.metadata,
|
|
2395
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2396
|
+
};
|
|
2397
|
+
} else {
|
|
2398
|
+
console.warn(`\u26A0\uFE0F Compute result failed: ${computeResult.error}`);
|
|
2399
|
+
return null;
|
|
2400
|
+
}
|
|
2401
|
+
} else if (state === "failed") {
|
|
2402
|
+
console.warn(`\u26A0\uFE0F TEE execution failed`);
|
|
2403
|
+
return null;
|
|
2404
|
+
}
|
|
2405
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
2406
|
+
}
|
|
2407
|
+
console.warn(`\u26A0\uFE0F TEE attestation timeout after ${maxWait}ms`);
|
|
2408
|
+
return null;
|
|
2409
|
+
} catch (e) {
|
|
2410
|
+
console.warn(`\u26A0\uFE0F TEE attestation error: ${e}`);
|
|
2411
|
+
return null;
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2414
|
+
/**
|
|
2415
|
+
* Generate a cryptographic integrity proof.
|
|
2416
|
+
*/
|
|
2417
|
+
generateIntegrityProof(functionName, codeHash, inputs, result, startTime, executionTime, teeAttestation) {
|
|
2418
|
+
const proofId = `proof_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
2419
|
+
const executionData = {
|
|
2420
|
+
function_name: functionName,
|
|
2421
|
+
code_hash: codeHash,
|
|
2422
|
+
inputs,
|
|
2423
|
+
result: this.serializeResult(result),
|
|
2424
|
+
start_time: startTime.toISOString(),
|
|
2425
|
+
execution_time: executionTime.toISOString(),
|
|
2426
|
+
agent_name: this.agentName
|
|
2427
|
+
};
|
|
2428
|
+
const executionHash = createHash("sha256").update(JSON.stringify(executionData)).digest("hex");
|
|
2429
|
+
const proof = {
|
|
2430
|
+
proof_id: proofId,
|
|
2431
|
+
function_name: functionName,
|
|
2432
|
+
code_hash: codeHash,
|
|
2433
|
+
execution_hash: executionHash,
|
|
2434
|
+
timestamp: executionTime,
|
|
2435
|
+
agent_name: this.agentName,
|
|
2436
|
+
verification_status: "verified",
|
|
2437
|
+
ipfs_cid: void 0,
|
|
2438
|
+
// TEE fields (if available)
|
|
2439
|
+
tee_attestation: teeAttestation || void 0,
|
|
2440
|
+
tee_provider: teeAttestation?.provider,
|
|
2441
|
+
tee_job_id: teeAttestation?.job_id,
|
|
2442
|
+
tee_execution_hash: teeAttestation?.execution_hash
|
|
2443
|
+
};
|
|
2444
|
+
const verificationLevel = teeAttestation ? "local + TEE" : "local";
|
|
2445
|
+
console.log(`\u2705 Process integrity proof generated: ${proofId} (${verificationLevel})`);
|
|
2446
|
+
return proof;
|
|
2447
|
+
}
|
|
2448
|
+
/**
|
|
2449
|
+
* Store integrity proof on IPFS for persistence.
|
|
2450
|
+
*/
|
|
2451
|
+
async storeProofOnIpfs(proof) {
|
|
2452
|
+
if (!this.storageManager) return;
|
|
2453
|
+
try {
|
|
2454
|
+
const proofData = {
|
|
2455
|
+
type: "chaoschain_process_integrity_proof_v2",
|
|
2456
|
+
// v2 includes TEE
|
|
2457
|
+
proof: {
|
|
2458
|
+
proof_id: proof.proof_id,
|
|
2459
|
+
function_name: proof.function_name,
|
|
2460
|
+
code_hash: proof.code_hash,
|
|
2461
|
+
execution_hash: proof.execution_hash,
|
|
2462
|
+
timestamp: proof.timestamp.toISOString(),
|
|
2463
|
+
agent_name: proof.agent_name,
|
|
2464
|
+
verification_status: proof.verification_status,
|
|
2465
|
+
// TEE attestation (if available)
|
|
2466
|
+
tee_attestation: proof.tee_attestation,
|
|
2467
|
+
tee_provider: proof.tee_provider,
|
|
2468
|
+
tee_job_id: proof.tee_job_id,
|
|
2469
|
+
tee_execution_hash: proof.tee_execution_hash
|
|
2470
|
+
},
|
|
2471
|
+
verification_layers: {
|
|
2472
|
+
local_code_hash: true,
|
|
2473
|
+
tee_attestation: !!proof.tee_attestation
|
|
2474
|
+
},
|
|
2475
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2476
|
+
agent_name: this.agentName
|
|
2477
|
+
};
|
|
2478
|
+
const filename = `process_integrity_proof_${proof.proof_id}.json`;
|
|
2479
|
+
const cid = await this.storageManager.uploadJson(proofData, filename);
|
|
2480
|
+
if (cid) {
|
|
2481
|
+
proof.ipfs_cid = cid;
|
|
2482
|
+
console.log(`\u{1F4C1} Process Integrity Proof stored on IPFS: ${cid}`);
|
|
2483
|
+
}
|
|
2484
|
+
} catch (e) {
|
|
2485
|
+
console.warn(`\u26A0\uFE0F Failed to store process integrity proof on IPFS: ${e}`);
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
/**
|
|
2489
|
+
* Serialize function result for hashing.
|
|
2490
|
+
*/
|
|
2491
|
+
serializeResult(result) {
|
|
2492
|
+
try {
|
|
2493
|
+
JSON.stringify(result);
|
|
2494
|
+
return result;
|
|
2495
|
+
} catch {
|
|
2496
|
+
return String(result);
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
/**
|
|
2500
|
+
* Create a process insurance policy for a function.
|
|
2501
|
+
*/
|
|
2502
|
+
createInsurancePolicy(functionName, coverageAmount, conditions) {
|
|
2503
|
+
const policyId = `policy_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
2504
|
+
const policy = {
|
|
2505
|
+
policy_id: policyId,
|
|
2506
|
+
function_name: functionName,
|
|
2507
|
+
agent_name: this.agentName,
|
|
2508
|
+
coverage_amount: coverageAmount,
|
|
2509
|
+
conditions,
|
|
2510
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2511
|
+
status: "active"
|
|
2512
|
+
};
|
|
2513
|
+
console.log(`\u{1F6E1}\uFE0F Process insurance policy created: ${policyId}`);
|
|
2514
|
+
console.log(` Function: ${functionName}`);
|
|
2515
|
+
console.log(` Coverage: $${coverageAmount}`);
|
|
2516
|
+
return policy;
|
|
2517
|
+
}
|
|
2518
|
+
/**
|
|
2519
|
+
* Configure autonomous agent capabilities with integrity verification.
|
|
2520
|
+
*/
|
|
2521
|
+
configureAutonomousAgent(capabilities, constraints) {
|
|
2522
|
+
const configId = `config_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
2523
|
+
const configuration = {
|
|
2524
|
+
config_id: configId,
|
|
2525
|
+
agent_name: this.agentName,
|
|
2526
|
+
capabilities,
|
|
2527
|
+
constraints,
|
|
2528
|
+
integrity_verification: true,
|
|
2529
|
+
registered_functions: Array.from(this.registeredFunctions.keys()),
|
|
2530
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
2531
|
+
};
|
|
2532
|
+
console.log(`\u{1F916} Autonomous agent configured: ${configId}`);
|
|
2533
|
+
console.log(` Capabilities: ${capabilities.length}`);
|
|
2534
|
+
console.log(` Registered functions: ${this.registeredFunctions.size}`);
|
|
2535
|
+
return configuration;
|
|
2536
|
+
}
|
|
2537
|
+
};
|
|
2538
|
+
var LocalIPFSStorage = class {
|
|
2539
|
+
apiUrl;
|
|
2540
|
+
constructor(apiUrl = "http://127.0.0.1:5001") {
|
|
2541
|
+
this.apiUrl = apiUrl;
|
|
2542
|
+
console.log(`\u{1F4E6} Local IPFS Storage initialized: ${apiUrl}`);
|
|
2543
|
+
}
|
|
2544
|
+
async put(data, mime = "application/json") {
|
|
2545
|
+
try {
|
|
2546
|
+
const buffer = typeof data === "string" ? Buffer.from(data) : data;
|
|
2547
|
+
const FormData2 = __require("form-data");
|
|
2548
|
+
const form = new FormData2();
|
|
2549
|
+
form.append("file", buffer, { contentType: mime });
|
|
2550
|
+
const response = await axios2.post(`${this.apiUrl}/api/v0/add`, form, {
|
|
2551
|
+
headers: form.getHeaders(),
|
|
2552
|
+
maxBodyLength: Infinity
|
|
2553
|
+
});
|
|
2554
|
+
const cid = response.data.Hash;
|
|
2555
|
+
console.log(`\u2705 Uploaded to local IPFS: ${cid}`);
|
|
2556
|
+
return {
|
|
2557
|
+
cid,
|
|
2558
|
+
url: `ipfs://${cid}`,
|
|
2559
|
+
size: response.data.Size,
|
|
2560
|
+
provider: "local-ipfs"
|
|
2561
|
+
};
|
|
2562
|
+
} catch (e) {
|
|
2563
|
+
if (e.code === "ECONNREFUSED") {
|
|
2564
|
+
throw new StorageError(
|
|
2565
|
+
"Local IPFS daemon not running. Start with: ipfs daemon",
|
|
2566
|
+
{ api_url: this.apiUrl }
|
|
2567
|
+
);
|
|
2568
|
+
}
|
|
2569
|
+
throw new StorageError(`Local IPFS upload failed: ${e.message}`);
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
async get(cid) {
|
|
2573
|
+
try {
|
|
2574
|
+
const response = await axios2.post(
|
|
2575
|
+
`${this.apiUrl}/api/v0/cat`,
|
|
2576
|
+
null,
|
|
2577
|
+
{
|
|
2578
|
+
params: { arg: cid },
|
|
2579
|
+
responseType: "arraybuffer"
|
|
2580
|
+
}
|
|
2581
|
+
);
|
|
2582
|
+
return Buffer.from(response.data);
|
|
2583
|
+
} catch (e) {
|
|
2584
|
+
throw new StorageError(`Failed to retrieve from IPFS: ${e.message}`);
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
async pin(cid) {
|
|
2588
|
+
try {
|
|
2589
|
+
await axios2.post(`${this.apiUrl}/api/v0/pin/add`, null, {
|
|
2590
|
+
params: { arg: cid }
|
|
2591
|
+
});
|
|
2592
|
+
console.log(`\u{1F4CC} Pinned to local IPFS: ${cid}`);
|
|
2593
|
+
} catch (e) {
|
|
2594
|
+
throw new StorageError(`Failed to pin CID: ${e.message}`);
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
async unpin(cid) {
|
|
2598
|
+
try {
|
|
2599
|
+
await axios2.post(`${this.apiUrl}/api/v0/pin/rm`, null, {
|
|
2600
|
+
params: { arg: cid }
|
|
2601
|
+
});
|
|
2602
|
+
console.log(`\u{1F4CC} Unpinned from local IPFS: ${cid}`);
|
|
2603
|
+
} catch (e) {
|
|
2604
|
+
throw new StorageError(`Failed to unpin CID: ${e.message}`);
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
};
|
|
2608
|
+
var PinataStorage = class {
|
|
2609
|
+
jwtToken;
|
|
2610
|
+
gatewayUrl;
|
|
2611
|
+
constructor(jwtToken, gatewayUrl = "https://gateway.pinata.cloud") {
|
|
2612
|
+
this.jwtToken = jwtToken;
|
|
2613
|
+
this.gatewayUrl = gatewayUrl;
|
|
2614
|
+
console.log(`\u{1F310} Pinata Storage initialized`);
|
|
2615
|
+
}
|
|
2616
|
+
async put(data, mime = "application/json") {
|
|
2617
|
+
try {
|
|
2618
|
+
const buffer = typeof data === "string" ? Buffer.from(data) : data;
|
|
2619
|
+
const FormData2 = __require("form-data");
|
|
2620
|
+
const form = new FormData2();
|
|
2621
|
+
form.append("file", buffer, {
|
|
2622
|
+
contentType: mime,
|
|
2623
|
+
filename: `file_${Date.now()}`
|
|
2624
|
+
});
|
|
2625
|
+
const response = await axios2.post("https://api.pinata.cloud/pinning/pinFileToIPFS", form, {
|
|
2626
|
+
headers: {
|
|
2627
|
+
...form.getHeaders(),
|
|
2628
|
+
Authorization: `Bearer ${this.jwtToken}`
|
|
2629
|
+
},
|
|
2630
|
+
maxBodyLength: Infinity
|
|
2631
|
+
});
|
|
2632
|
+
const cid = response.data.IpfsHash;
|
|
2633
|
+
console.log(`\u2705 Uploaded to Pinata: ${cid}`);
|
|
2634
|
+
return {
|
|
2635
|
+
cid,
|
|
2636
|
+
url: `${this.gatewayUrl}/ipfs/${cid}`,
|
|
2637
|
+
size: response.data.PinSize,
|
|
2638
|
+
provider: "pinata"
|
|
2639
|
+
};
|
|
2640
|
+
} catch (e) {
|
|
2641
|
+
throw new StorageError(`Pinata upload failed: ${e.message}`);
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
async get(cid) {
|
|
2645
|
+
try {
|
|
2646
|
+
const response = await axios2.get(`${this.gatewayUrl}/ipfs/${cid}`, {
|
|
2647
|
+
responseType: "arraybuffer"
|
|
2648
|
+
});
|
|
2649
|
+
return Buffer.from(response.data);
|
|
2650
|
+
} catch (e) {
|
|
2651
|
+
throw new StorageError(`Failed to retrieve from Pinata: ${e.message}`);
|
|
2652
|
+
}
|
|
2653
|
+
}
|
|
2654
|
+
async pin(cid) {
|
|
2655
|
+
try {
|
|
2656
|
+
await axios2.post(
|
|
2657
|
+
"https://api.pinata.cloud/pinning/pinByHash",
|
|
2658
|
+
{ hashToPin: cid },
|
|
2659
|
+
{
|
|
2660
|
+
headers: {
|
|
2661
|
+
Authorization: `Bearer ${this.jwtToken}`,
|
|
2662
|
+
"Content-Type": "application/json"
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
);
|
|
2666
|
+
console.log(`\u{1F4CC} Pinned to Pinata: ${cid}`);
|
|
2667
|
+
} catch (e) {
|
|
2668
|
+
throw new StorageError(`Failed to pin to Pinata: ${e.message}`);
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2671
|
+
async unpin(cid) {
|
|
2672
|
+
try {
|
|
2673
|
+
await axios2.delete(`https://api.pinata.cloud/pinning/unpin/${cid}`, {
|
|
2674
|
+
headers: {
|
|
2675
|
+
Authorization: `Bearer ${this.jwtToken}`
|
|
2676
|
+
}
|
|
2677
|
+
});
|
|
2678
|
+
console.log(`\u{1F4CC} Unpinned from Pinata: ${cid}`);
|
|
2679
|
+
} catch (e) {
|
|
2680
|
+
throw new StorageError(`Failed to unpin from Pinata: ${e.message}`);
|
|
2681
|
+
}
|
|
2682
|
+
}
|
|
2683
|
+
};
|
|
2684
|
+
var IrysStorage = class {
|
|
2685
|
+
walletKey;
|
|
2686
|
+
constructor(walletKey) {
|
|
2687
|
+
this.walletKey = walletKey;
|
|
2688
|
+
console.log(`\u{1F48E} Irys (Arweave) Storage initialized`);
|
|
2689
|
+
}
|
|
2690
|
+
async put(data, mime = "application/json") {
|
|
2691
|
+
try {
|
|
2692
|
+
const mockCid = `ar_${Date.now().toString(36)}_${Math.random().toString(36).substring(2, 15)}`;
|
|
2693
|
+
console.log(`\u2705 Uploaded to Irys: ${mockCid}`);
|
|
2694
|
+
return {
|
|
2695
|
+
cid: mockCid,
|
|
2696
|
+
url: `https://arweave.net/${mockCid}`,
|
|
2697
|
+
provider: "irys"
|
|
2698
|
+
};
|
|
2699
|
+
} catch (e) {
|
|
2700
|
+
throw new StorageError(`Irys upload failed: ${e.message}`);
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
async get(cid) {
|
|
2704
|
+
try {
|
|
2705
|
+
const response = await axios2.get(`https://arweave.net/${cid}`, {
|
|
2706
|
+
responseType: "arraybuffer"
|
|
2707
|
+
});
|
|
2708
|
+
return Buffer.from(response.data);
|
|
2709
|
+
} catch (e) {
|
|
2710
|
+
throw new StorageError(`Failed to retrieve from Arweave: ${e.message}`);
|
|
2711
|
+
}
|
|
2712
|
+
}
|
|
2713
|
+
};
|
|
2714
|
+
var ZeroGStorage = class {
|
|
2715
|
+
grpcUrl;
|
|
2716
|
+
privateKey;
|
|
2717
|
+
constructor(privateKey, grpcUrl = "localhost:50051") {
|
|
2718
|
+
this.privateKey = privateKey;
|
|
2719
|
+
this.grpcUrl = grpcUrl;
|
|
2720
|
+
console.log(`\u26A1 0G Storage initialized: ${grpcUrl}`);
|
|
2721
|
+
}
|
|
2722
|
+
async put(data, mime = "application/json") {
|
|
2723
|
+
try {
|
|
2724
|
+
const mockCid = `0g_${Date.now().toString(36)}_${Math.random().toString(36).substring(2, 15)}`;
|
|
2725
|
+
console.log(`\u2705 Uploaded to 0G Storage: ${mockCid}`);
|
|
2726
|
+
return {
|
|
2727
|
+
cid: mockCid,
|
|
2728
|
+
url: `0g://${mockCid}`,
|
|
2729
|
+
provider: "0g-storage"
|
|
2730
|
+
};
|
|
2731
|
+
} catch (e) {
|
|
2732
|
+
throw new StorageError(`0G Storage upload failed: ${e.message}`);
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
async get(cid) {
|
|
2736
|
+
try {
|
|
2737
|
+
throw new StorageError("0G Storage retrieval not yet implemented");
|
|
2738
|
+
} catch (e) {
|
|
2739
|
+
throw new StorageError(`Failed to retrieve from 0G Storage: ${e.message}`);
|
|
2740
|
+
}
|
|
2741
|
+
}
|
|
2742
|
+
};
|
|
2743
|
+
var AutoStorageManager = class {
|
|
2744
|
+
backends = [];
|
|
2745
|
+
preferredBackend = null;
|
|
2746
|
+
constructor() {
|
|
2747
|
+
this.detectAvailableBackends();
|
|
2748
|
+
}
|
|
2749
|
+
detectAvailableBackends() {
|
|
2750
|
+
console.log("\u{1F50D} Auto-detecting available storage backends...");
|
|
2751
|
+
try {
|
|
2752
|
+
const localIpfs = new LocalIPFSStorage();
|
|
2753
|
+
this.backends.push(localIpfs);
|
|
2754
|
+
this.preferredBackend = localIpfs;
|
|
2755
|
+
console.log("\u2705 Local IPFS available");
|
|
2756
|
+
} catch (e) {
|
|
2757
|
+
console.log("\u274C Local IPFS not available");
|
|
2758
|
+
}
|
|
2759
|
+
const pinataJwt = process.env.PINATA_JWT;
|
|
2760
|
+
if (pinataJwt) {
|
|
2761
|
+
const pinata = new PinataStorage(pinataJwt);
|
|
2762
|
+
this.backends.push(pinata);
|
|
2763
|
+
if (!this.preferredBackend) this.preferredBackend = pinata;
|
|
2764
|
+
console.log("\u2705 Pinata available");
|
|
2765
|
+
}
|
|
2766
|
+
const irysKey = process.env.IRYS_WALLET_KEY;
|
|
2767
|
+
if (irysKey) {
|
|
2768
|
+
const irys = new IrysStorage(irysKey);
|
|
2769
|
+
this.backends.push(irys);
|
|
2770
|
+
if (!this.preferredBackend) this.preferredBackend = irys;
|
|
2771
|
+
console.log("\u2705 Irys available");
|
|
2772
|
+
}
|
|
2773
|
+
const zerogKey = process.env.ZEROG_TESTNET_PRIVATE_KEY;
|
|
2774
|
+
if (zerogKey) {
|
|
2775
|
+
const zerog = new ZeroGStorage(zerogKey);
|
|
2776
|
+
this.backends.push(zerog);
|
|
2777
|
+
if (!this.preferredBackend) this.preferredBackend = zerog;
|
|
2778
|
+
console.log("\u2705 0G Storage available");
|
|
2779
|
+
}
|
|
2780
|
+
if (this.backends.length === 0) {
|
|
2781
|
+
console.warn("\u26A0\uFE0F No storage backends available! Please configure at least one.");
|
|
2782
|
+
} else {
|
|
2783
|
+
console.log(`\u{1F4E6} ${this.backends.length} storage backend(s) available`);
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
async put(data, mime) {
|
|
2787
|
+
if (!this.preferredBackend) {
|
|
2788
|
+
throw new StorageError("No storage backends available");
|
|
2789
|
+
}
|
|
2790
|
+
try {
|
|
2791
|
+
return await this.preferredBackend.put(data, mime);
|
|
2792
|
+
} catch (e) {
|
|
2793
|
+
for (const backend of this.backends) {
|
|
2794
|
+
if (backend !== this.preferredBackend) {
|
|
2795
|
+
try {
|
|
2796
|
+
console.log(`\u26A0\uFE0F Trying fallback storage backend...`);
|
|
2797
|
+
return await backend.put(data, mime);
|
|
2798
|
+
} catch (fallbackError) {
|
|
2799
|
+
continue;
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
}
|
|
2803
|
+
throw new StorageError(`All storage backends failed: ${e}`);
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
async get(cid) {
|
|
2807
|
+
if (!this.preferredBackend) {
|
|
2808
|
+
throw new StorageError("No storage backends available");
|
|
2809
|
+
}
|
|
2810
|
+
return await this.preferredBackend.get(cid);
|
|
2811
|
+
}
|
|
2812
|
+
getAvailableBackends() {
|
|
2813
|
+
return this.backends.map((backend) => backend.constructor.name);
|
|
2814
|
+
}
|
|
2815
|
+
};
|
|
2816
|
+
|
|
2817
|
+
// src/utils/networks.ts
|
|
2818
|
+
var ERC8004_ADDRESSES = {
|
|
2819
|
+
"ethereum-sepolia": {
|
|
2820
|
+
identity: "0x8004a6090Cd10A7288092483047B097295Fb8847",
|
|
2821
|
+
reputation: "0x8004B8FD1A363aa02fDC07635C0c5F94f6Af5B7E",
|
|
2822
|
+
validation: "0x8004CB39f29c09145F24Ad9dDe2A108C1A2cdfC5"
|
|
2823
|
+
},
|
|
2824
|
+
"base-sepolia": {
|
|
2825
|
+
identity: "0x8004AA63c570c570eBF15376c0dB199918BFe9Fb",
|
|
2826
|
+
reputation: "0x8004bd8daB57f14Ed299135749a5CB5c42d341BF",
|
|
2827
|
+
validation: "0x8004C269D0A5647E51E121FeB226200ECE932d55"
|
|
2828
|
+
},
|
|
2829
|
+
"linea-sepolia": {
|
|
2830
|
+
identity: "0x8004aa7C931bCE1233973a0C6A667f73F66282e7",
|
|
2831
|
+
reputation: "0x8004bd8483b99310df121c46ED8858616b2Bba02",
|
|
2832
|
+
validation: "0x8004c44d1EFdd699B2A26e781eF7F77c56A9a4EB"
|
|
2833
|
+
},
|
|
2834
|
+
"hedera-testnet": {
|
|
2835
|
+
identity: "0x4c74ebd72921d537159ed2053f46c12a7d8e5923",
|
|
2836
|
+
reputation: "0xc565edcba77e3abeade40bfd6cf6bf583b3293e0",
|
|
2837
|
+
validation: "0x18df085d85c586e9241e0cd121ca422f571c2da6"
|
|
2838
|
+
},
|
|
2839
|
+
"0g-testnet": {
|
|
2840
|
+
identity: "0x80043ed9cf33a3472768dcd53175bb44e03a1e4a",
|
|
2841
|
+
reputation: "0x80045d7b72c47bf5ff73737b780cb1a5ba8ee202",
|
|
2842
|
+
validation: "0x80041728e0aadf1d1427f9be18d52b7f3afefafb"
|
|
2843
|
+
}
|
|
2844
|
+
};
|
|
2845
|
+
var NETWORK_INFO = {
|
|
2846
|
+
"ethereum-sepolia": {
|
|
2847
|
+
chainId: 11155111,
|
|
2848
|
+
name: "Ethereum Sepolia Testnet",
|
|
2849
|
+
rpcUrl: process.env.ETHEREUM_SEPOLIA_RPC_URL || "https://rpc.sepolia.org",
|
|
2850
|
+
contracts: ERC8004_ADDRESSES["ethereum-sepolia"],
|
|
2851
|
+
nativeCurrency: {
|
|
2852
|
+
name: "Sepolia ETH",
|
|
2853
|
+
symbol: "ETH",
|
|
2854
|
+
decimals: 18
|
|
2855
|
+
}
|
|
2856
|
+
},
|
|
2857
|
+
"base-sepolia": {
|
|
2858
|
+
chainId: 84532,
|
|
2859
|
+
name: "Base Sepolia Testnet",
|
|
2860
|
+
rpcUrl: process.env.BASE_SEPOLIA_RPC_URL || "https://sepolia.base.org",
|
|
2861
|
+
contracts: ERC8004_ADDRESSES["base-sepolia"],
|
|
2862
|
+
nativeCurrency: {
|
|
2863
|
+
name: "Sepolia ETH",
|
|
2864
|
+
symbol: "ETH",
|
|
2865
|
+
decimals: 18
|
|
2866
|
+
}
|
|
2867
|
+
},
|
|
2868
|
+
"linea-sepolia": {
|
|
2869
|
+
chainId: 59141,
|
|
2870
|
+
name: "Linea Sepolia Testnet",
|
|
2871
|
+
rpcUrl: process.env.LINEA_SEPOLIA_RPC_URL || "https://rpc.sepolia.linea.build",
|
|
2872
|
+
contracts: ERC8004_ADDRESSES["linea-sepolia"],
|
|
2873
|
+
nativeCurrency: {
|
|
2874
|
+
name: "Linea ETH",
|
|
2875
|
+
symbol: "ETH",
|
|
2876
|
+
decimals: 18
|
|
2877
|
+
}
|
|
2878
|
+
},
|
|
2879
|
+
"hedera-testnet": {
|
|
2880
|
+
chainId: 296,
|
|
2881
|
+
name: "Hedera Testnet",
|
|
2882
|
+
rpcUrl: process.env.HEDERA_TESTNET_RPC_URL || "https://testnet.hashio.io/api",
|
|
2883
|
+
contracts: ERC8004_ADDRESSES["hedera-testnet"],
|
|
2884
|
+
nativeCurrency: {
|
|
2885
|
+
name: "HBAR",
|
|
2886
|
+
symbol: "HBAR",
|
|
2887
|
+
decimals: 18
|
|
2888
|
+
}
|
|
2889
|
+
},
|
|
2890
|
+
"0g-testnet": {
|
|
2891
|
+
chainId: 16600,
|
|
2892
|
+
name: "0G Network Testnet",
|
|
2893
|
+
rpcUrl: process.env.ZEROG_TESTNET_RPC_URL || "https://evmrpc-testnet.0g.ai",
|
|
2894
|
+
contracts: ERC8004_ADDRESSES["0g-testnet"],
|
|
2895
|
+
nativeCurrency: {
|
|
2896
|
+
name: "A0GI",
|
|
2897
|
+
symbol: "A0GI",
|
|
2898
|
+
decimals: 18
|
|
2899
|
+
}
|
|
2900
|
+
},
|
|
2901
|
+
local: {
|
|
2902
|
+
chainId: 31337,
|
|
2903
|
+
name: "Local Network",
|
|
2904
|
+
rpcUrl: process.env.LOCAL_RPC_URL || "http://localhost:8545",
|
|
2905
|
+
contracts: {
|
|
2906
|
+
identity: "0x5FbDB2315678afecb367f032d93F642f64180aa3",
|
|
2907
|
+
reputation: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
|
|
2908
|
+
validation: "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0"
|
|
2909
|
+
},
|
|
2910
|
+
nativeCurrency: {
|
|
2911
|
+
name: "ETH",
|
|
2912
|
+
symbol: "ETH",
|
|
2913
|
+
decimals: 18
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2916
|
+
};
|
|
2917
|
+
function getNetworkInfo(network) {
|
|
2918
|
+
const networkKey = typeof network === "string" ? network : network.valueOf();
|
|
2919
|
+
const info = NETWORK_INFO[networkKey];
|
|
2920
|
+
if (!info) {
|
|
2921
|
+
throw new Error(`Unsupported network: ${networkKey}`);
|
|
2922
|
+
}
|
|
2923
|
+
return info;
|
|
2924
|
+
}
|
|
2925
|
+
function getContractAddresses(network) {
|
|
2926
|
+
return getNetworkInfo(network).contracts;
|
|
2927
|
+
}
|
|
2928
|
+
|
|
2929
|
+
// src/ChaosChainSDK.ts
|
|
2930
|
+
var ChaosChainSDK = class {
|
|
2931
|
+
// Core components
|
|
2932
|
+
walletManager;
|
|
2933
|
+
chaosAgent;
|
|
2934
|
+
x402PaymentManager;
|
|
2935
|
+
paymentManager;
|
|
2936
|
+
storageBackend;
|
|
2937
|
+
computeProvider;
|
|
2938
|
+
provider;
|
|
2939
|
+
// Advanced integrations
|
|
2940
|
+
googleAP2;
|
|
2941
|
+
a2aX402Extension;
|
|
2942
|
+
processIntegrity;
|
|
2943
|
+
// Configuration
|
|
2944
|
+
agentName;
|
|
2945
|
+
agentDomain;
|
|
2946
|
+
agentRole;
|
|
2947
|
+
network;
|
|
2948
|
+
networkInfo;
|
|
2949
|
+
// Current agent ID (set after registration)
|
|
2950
|
+
_agentId;
|
|
2951
|
+
constructor(config) {
|
|
2952
|
+
this.agentName = config.agentName;
|
|
2953
|
+
this.agentDomain = config.agentDomain;
|
|
2954
|
+
this.agentRole = config.agentRole;
|
|
2955
|
+
this.network = config.network;
|
|
2956
|
+
this.networkInfo = getNetworkInfo(config.network);
|
|
2957
|
+
const rpcUrl = config.rpcUrl || this.networkInfo.rpcUrl;
|
|
2958
|
+
this.provider = new ethers.JsonRpcProvider(rpcUrl);
|
|
2959
|
+
this.walletManager = new WalletManager(
|
|
2960
|
+
{
|
|
2961
|
+
privateKey: config.privateKey,
|
|
2962
|
+
mnemonic: config.mnemonic,
|
|
2963
|
+
walletFile: config.walletFile
|
|
2964
|
+
},
|
|
2965
|
+
this.provider
|
|
2966
|
+
);
|
|
2967
|
+
const contractAddresses = getContractAddresses(config.network);
|
|
2968
|
+
this.chaosAgent = new ChaosAgent(
|
|
2969
|
+
contractAddresses,
|
|
2970
|
+
this.walletManager.getWallet(),
|
|
2971
|
+
this.provider
|
|
2972
|
+
);
|
|
2973
|
+
if (config.storageProvider) {
|
|
2974
|
+
this.storageBackend = config.storageProvider;
|
|
2975
|
+
} else if (config.enableStorage !== false) {
|
|
2976
|
+
this.storageBackend = new AutoStorageManager();
|
|
2977
|
+
} else {
|
|
2978
|
+
this.storageBackend = {
|
|
2979
|
+
put: async () => ({ cid: "", provider: "none" }),
|
|
2980
|
+
get: async () => Buffer.from("")
|
|
2981
|
+
};
|
|
2982
|
+
}
|
|
2983
|
+
if (config.enablePayments !== false) {
|
|
2984
|
+
this.x402PaymentManager = new X402PaymentManager(
|
|
2985
|
+
this.walletManager.getWallet(),
|
|
2986
|
+
typeof config.network === "string" ? config.network : config.network
|
|
2987
|
+
);
|
|
2988
|
+
const paymentCredentials = {
|
|
2989
|
+
stripe_secret_key: process.env.STRIPE_SECRET_KEY,
|
|
2990
|
+
google_pay_merchant_id: process.env.GOOGLE_PAY_MERCHANT_ID,
|
|
2991
|
+
apple_pay_merchant_id: process.env.APPLE_PAY_MERCHANT_ID,
|
|
2992
|
+
paypal_client_id: process.env.PAYPAL_CLIENT_ID,
|
|
2993
|
+
paypal_client_secret: process.env.PAYPAL_CLIENT_SECRET
|
|
2994
|
+
};
|
|
2995
|
+
this.paymentManager = new PaymentManager(
|
|
2996
|
+
this.agentName,
|
|
2997
|
+
typeof config.network === "string" ? config.network : config.network,
|
|
2998
|
+
this.walletManager.getWallet(),
|
|
2999
|
+
paymentCredentials
|
|
3000
|
+
);
|
|
3001
|
+
this.a2aX402Extension = new A2AX402Extension(
|
|
3002
|
+
this.agentName,
|
|
3003
|
+
typeof config.network === "string" ? config.network : config.network,
|
|
3004
|
+
this.paymentManager
|
|
3005
|
+
);
|
|
3006
|
+
}
|
|
3007
|
+
if (config.enableAP2 !== false) {
|
|
3008
|
+
this.googleAP2 = new GoogleAP2Integration(
|
|
3009
|
+
this.agentName,
|
|
3010
|
+
process.env.GOOGLE_AP2_MERCHANT_PRIVATE_KEY
|
|
3011
|
+
);
|
|
3012
|
+
}
|
|
3013
|
+
if (config.enableProcessIntegrity !== false) {
|
|
3014
|
+
this.processIntegrity = new ProcessIntegrity(
|
|
3015
|
+
this.storageBackend,
|
|
3016
|
+
this.computeProvider
|
|
3017
|
+
);
|
|
3018
|
+
}
|
|
3019
|
+
this.computeProvider = config.computeProvider;
|
|
3020
|
+
console.log(`\u{1F680} ChaosChain SDK initialized for ${this.agentName}`);
|
|
3021
|
+
console.log(` Network: ${this.network}`);
|
|
3022
|
+
console.log(` Wallet: ${this.walletManager.getAddress()}`);
|
|
3023
|
+
console.log(` Features:`);
|
|
3024
|
+
console.log(` - ERC-8004: \u2705`);
|
|
3025
|
+
console.log(` - x402 Payments: ${this.x402PaymentManager ? "\u2705" : "\u274C"}`);
|
|
3026
|
+
console.log(` - Multi-Payment: ${this.paymentManager ? "\u2705" : "\u274C"}`);
|
|
3027
|
+
console.log(` - Google AP2: ${this.googleAP2 ? "\u2705" : "\u274C"}`);
|
|
3028
|
+
console.log(` - Process Integrity: ${this.processIntegrity ? "\u2705" : "\u274C"}`);
|
|
3029
|
+
console.log(` - Storage: \u2705`);
|
|
3030
|
+
}
|
|
3031
|
+
// ============================================================================
|
|
3032
|
+
// ERC-8004 Identity Methods
|
|
3033
|
+
// ============================================================================
|
|
3034
|
+
/**
|
|
3035
|
+
* Register agent identity on-chain
|
|
3036
|
+
*/
|
|
3037
|
+
async registerIdentity(metadata) {
|
|
3038
|
+
const meta = metadata || {
|
|
3039
|
+
name: this.agentName,
|
|
3040
|
+
domain: this.agentDomain,
|
|
3041
|
+
role: this.agentRole
|
|
3042
|
+
};
|
|
3043
|
+
const registration = await this.chaosAgent.registerIdentity(meta);
|
|
3044
|
+
this._agentId = registration.agentId;
|
|
3045
|
+
console.log(`\u2705 Agent #${registration.agentId} registered on-chain`);
|
|
3046
|
+
return registration;
|
|
3047
|
+
}
|
|
3048
|
+
/**
|
|
3049
|
+
* Get agent metadata
|
|
3050
|
+
*/
|
|
3051
|
+
async getAgentMetadata(agentId) {
|
|
3052
|
+
return this.chaosAgent.getAgentMetadata(agentId);
|
|
3053
|
+
}
|
|
3054
|
+
/**
|
|
3055
|
+
* Update agent metadata
|
|
3056
|
+
*/
|
|
3057
|
+
async updateAgentMetadata(agentId, metadata) {
|
|
3058
|
+
return this.chaosAgent.updateAgentMetadata(agentId, metadata);
|
|
3059
|
+
}
|
|
3060
|
+
/**
|
|
3061
|
+
* Get current agent ID
|
|
3062
|
+
*/
|
|
3063
|
+
getAgentId() {
|
|
3064
|
+
return this._agentId;
|
|
3065
|
+
}
|
|
3066
|
+
// ============================================================================
|
|
3067
|
+
// ERC-8004 Reputation Methods
|
|
3068
|
+
// ============================================================================
|
|
3069
|
+
/**
|
|
3070
|
+
* Generate feedback authorization (EIP-191 signing)
|
|
3071
|
+
*/
|
|
3072
|
+
async generateFeedbackAuthorization(agentId, clientAddress, indexLimit, expiry) {
|
|
3073
|
+
return this.chaosAgent.generateFeedbackAuthorization(agentId, clientAddress, indexLimit, expiry);
|
|
3074
|
+
}
|
|
3075
|
+
/**
|
|
3076
|
+
* Give feedback to an agent
|
|
3077
|
+
*/
|
|
3078
|
+
async giveFeedback(params) {
|
|
3079
|
+
return this.chaosAgent.giveFeedback(params);
|
|
3080
|
+
}
|
|
3081
|
+
/**
|
|
3082
|
+
* Submit feedback with payment proof (ERC-8004 reputation enrichment)
|
|
3083
|
+
*/
|
|
3084
|
+
async submitFeedbackWithPayment(agentId, score, feedbackData, paymentProof) {
|
|
3085
|
+
const fullFeedbackData = {
|
|
3086
|
+
...feedbackData,
|
|
3087
|
+
score,
|
|
3088
|
+
proof_of_payment: paymentProof,
|
|
3089
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
3090
|
+
};
|
|
3091
|
+
const feedbackJson = JSON.stringify(fullFeedbackData);
|
|
3092
|
+
const result = await this.storageBackend.put(Buffer.from(feedbackJson), "application/json");
|
|
3093
|
+
const feedbackUri = `ipfs://${result.cid}`;
|
|
3094
|
+
const txHash = await this.chaosAgent.giveFeedback({
|
|
3095
|
+
agentId,
|
|
3096
|
+
rating: score,
|
|
3097
|
+
feedbackUri
|
|
3098
|
+
});
|
|
3099
|
+
console.log(`\u2705 Feedback submitted with payment proof`);
|
|
3100
|
+
console.log(` TX: ${txHash}`);
|
|
3101
|
+
console.log(` URI: ${feedbackUri}`);
|
|
3102
|
+
return { feedbackTxHash: txHash, feedbackUri };
|
|
3103
|
+
}
|
|
3104
|
+
/**
|
|
3105
|
+
* Get agent reputation score
|
|
3106
|
+
*/
|
|
3107
|
+
async getReputationScore(_agentId) {
|
|
3108
|
+
return 0;
|
|
3109
|
+
}
|
|
3110
|
+
// ============================================================================
|
|
3111
|
+
// ERC-8004 Validation Methods
|
|
3112
|
+
// ============================================================================
|
|
3113
|
+
/**
|
|
3114
|
+
* Request validation from validator
|
|
3115
|
+
*/
|
|
3116
|
+
async requestValidation(params) {
|
|
3117
|
+
return this.chaosAgent.requestValidation(params);
|
|
3118
|
+
}
|
|
3119
|
+
/**
|
|
3120
|
+
* Respond to validation request
|
|
3121
|
+
*/
|
|
3122
|
+
async respondToValidation(requestId, approved, responseUri) {
|
|
3123
|
+
return this.chaosAgent.respondToValidation(requestId, approved, responseUri);
|
|
3124
|
+
}
|
|
3125
|
+
// ============================================================================
|
|
3126
|
+
// x402 Crypto Payment Methods
|
|
3127
|
+
// ============================================================================
|
|
3128
|
+
/**
|
|
3129
|
+
* Create x402 payment request
|
|
3130
|
+
*/
|
|
3131
|
+
createX402PaymentRequest(fromAgent, toAgent, amount, currency = "USDC", serviceDescription = "AI Agent Service") {
|
|
3132
|
+
if (!this.x402PaymentManager) {
|
|
3133
|
+
throw new Error("x402 payments not enabled");
|
|
3134
|
+
}
|
|
3135
|
+
return this.x402PaymentManager.createPaymentRequest(fromAgent, toAgent, amount, currency, serviceDescription);
|
|
3136
|
+
}
|
|
3137
|
+
/**
|
|
3138
|
+
* Execute x402 crypto payment
|
|
3139
|
+
*/
|
|
3140
|
+
async executeX402Payment(paymentRequest, recipientAddress) {
|
|
3141
|
+
if (!this.x402PaymentManager) {
|
|
3142
|
+
throw new Error("x402 payments not enabled");
|
|
3143
|
+
}
|
|
3144
|
+
return this.x402PaymentManager.executePayment(paymentRequest, recipientAddress);
|
|
3145
|
+
}
|
|
3146
|
+
/**
|
|
3147
|
+
* Create x402 payment requirements (for receiving payments)
|
|
3148
|
+
*/
|
|
3149
|
+
createX402PaymentRequirements(amount, currency = "USDC", serviceDescription = "AI Agent Service", expiryMinutes = 30) {
|
|
3150
|
+
if (!this.x402PaymentManager) {
|
|
3151
|
+
throw new Error("x402 payments not enabled");
|
|
3152
|
+
}
|
|
3153
|
+
return this.x402PaymentManager.createPaymentRequirements(amount, currency, serviceDescription, expiryMinutes);
|
|
3154
|
+
}
|
|
3155
|
+
/**
|
|
3156
|
+
* Create x402 paywall server
|
|
3157
|
+
*/
|
|
3158
|
+
createX402PaywallServer(port = 8402) {
|
|
3159
|
+
if (!this.x402PaymentManager) {
|
|
3160
|
+
throw new Error("x402 payments not enabled");
|
|
3161
|
+
}
|
|
3162
|
+
return new X402Server(this.x402PaymentManager, { port });
|
|
3163
|
+
}
|
|
3164
|
+
/**
|
|
3165
|
+
* Get x402 payment history
|
|
3166
|
+
*/
|
|
3167
|
+
async getX402PaymentHistory(limit = 10) {
|
|
3168
|
+
if (!this.x402PaymentManager) {
|
|
3169
|
+
throw new Error("x402 payments not enabled");
|
|
3170
|
+
}
|
|
3171
|
+
return this.x402PaymentManager.getPaymentHistory(limit);
|
|
3172
|
+
}
|
|
3173
|
+
// ============================================================================
|
|
3174
|
+
// Traditional Payment Methods (Cards, Google Pay, Apple Pay, PayPal)
|
|
3175
|
+
// ============================================================================
|
|
3176
|
+
/**
|
|
3177
|
+
* Execute traditional payment
|
|
3178
|
+
*/
|
|
3179
|
+
executeTraditionalPayment(paymentMethod, amount, currency, paymentData2) {
|
|
3180
|
+
if (!this.paymentManager) {
|
|
3181
|
+
throw new Error("Payment manager not enabled");
|
|
3182
|
+
}
|
|
3183
|
+
return this.paymentManager.executeTraditionalPayment(paymentMethod, amount, currency, paymentData2);
|
|
3184
|
+
}
|
|
3185
|
+
/**
|
|
3186
|
+
* Get supported payment methods
|
|
3187
|
+
*/
|
|
3188
|
+
getSupportedPaymentMethods() {
|
|
3189
|
+
if (!this.paymentManager) {
|
|
3190
|
+
return [];
|
|
3191
|
+
}
|
|
3192
|
+
return this.paymentManager.getSupportedPaymentMethods();
|
|
3193
|
+
}
|
|
3194
|
+
/**
|
|
3195
|
+
* Get payment methods status
|
|
3196
|
+
*/
|
|
3197
|
+
getPaymentMethodsStatus() {
|
|
3198
|
+
if (!this.paymentManager) {
|
|
3199
|
+
return {};
|
|
3200
|
+
}
|
|
3201
|
+
return this.paymentManager.getPaymentMethodsStatus();
|
|
3202
|
+
}
|
|
3203
|
+
// ============================================================================
|
|
3204
|
+
// Google AP2 Intent Verification Methods
|
|
3205
|
+
// ============================================================================
|
|
3206
|
+
/**
|
|
3207
|
+
* Create Google AP2 intent mandate
|
|
3208
|
+
*/
|
|
3209
|
+
createIntentMandate(userDescription, merchants, skus, requiresRefundability = false, expiryMinutes = 60) {
|
|
3210
|
+
if (!this.googleAP2) {
|
|
3211
|
+
throw new Error("Google AP2 not enabled");
|
|
3212
|
+
}
|
|
3213
|
+
return this.googleAP2.createIntentMandate(userDescription, merchants, skus, requiresRefundability, expiryMinutes);
|
|
3214
|
+
}
|
|
3215
|
+
/**
|
|
3216
|
+
* Create Google AP2 cart mandate with JWT signing
|
|
3217
|
+
*/
|
|
3218
|
+
async createCartMandate(cartId, items, totalAmount, currency = "USD", merchantName, expiryMinutes = 15) {
|
|
3219
|
+
if (!this.googleAP2) {
|
|
3220
|
+
throw new Error("Google AP2 not enabled");
|
|
3221
|
+
}
|
|
3222
|
+
return this.googleAP2.createCartMandate(cartId, items, totalAmount, currency, merchantName, expiryMinutes);
|
|
3223
|
+
}
|
|
3224
|
+
/**
|
|
3225
|
+
* Verify JWT token
|
|
3226
|
+
*/
|
|
3227
|
+
async verifyJwtToken(token) {
|
|
3228
|
+
if (!this.googleAP2) {
|
|
3229
|
+
throw new Error("Google AP2 not enabled");
|
|
3230
|
+
}
|
|
3231
|
+
return this.googleAP2.verifyJwtToken(token);
|
|
3232
|
+
}
|
|
3233
|
+
// ============================================================================
|
|
3234
|
+
// Process Integrity Methods
|
|
3235
|
+
// ============================================================================
|
|
3236
|
+
/**
|
|
3237
|
+
* Register function for integrity verification
|
|
3238
|
+
*/
|
|
3239
|
+
registerFunction(func) {
|
|
3240
|
+
if (!this.processIntegrity) {
|
|
3241
|
+
throw new Error("Process integrity not enabled");
|
|
3242
|
+
}
|
|
3243
|
+
this.processIntegrity.registerFunction(func);
|
|
3244
|
+
}
|
|
3245
|
+
/**
|
|
3246
|
+
* Execute function with integrity proof
|
|
3247
|
+
*/
|
|
3248
|
+
async executeWithIntegrityProof(functionName, args) {
|
|
3249
|
+
if (!this.processIntegrity) {
|
|
3250
|
+
throw new Error("Process integrity not enabled");
|
|
3251
|
+
}
|
|
3252
|
+
const [result, proof] = await this.processIntegrity.executeWithProof(functionName, args);
|
|
3253
|
+
return { result, proof };
|
|
3254
|
+
}
|
|
3255
|
+
/**
|
|
3256
|
+
* Verify integrity proof
|
|
3257
|
+
*/
|
|
3258
|
+
async verifyIntegrityProof(_proof) {
|
|
3259
|
+
if (!this.processIntegrity) {
|
|
3260
|
+
throw new Error("Process integrity not enabled");
|
|
3261
|
+
}
|
|
3262
|
+
return true;
|
|
3263
|
+
}
|
|
3264
|
+
// ============================================================================
|
|
3265
|
+
// Storage Methods
|
|
3266
|
+
// ============================================================================
|
|
3267
|
+
/**
|
|
3268
|
+
* Upload data to storage
|
|
3269
|
+
*/
|
|
3270
|
+
async upload(data, _options) {
|
|
3271
|
+
const jsonData = typeof data === "string" ? data : JSON.stringify(data);
|
|
3272
|
+
const buffer = Buffer.from(jsonData);
|
|
3273
|
+
const result = await this.storageBackend.put(buffer, "application/json");
|
|
3274
|
+
return {
|
|
3275
|
+
cid: result.cid,
|
|
3276
|
+
uri: result.url || `ipfs://${result.cid}`
|
|
3277
|
+
};
|
|
3278
|
+
}
|
|
3279
|
+
/**
|
|
3280
|
+
* Download data from storage
|
|
3281
|
+
*/
|
|
3282
|
+
async download(cid) {
|
|
3283
|
+
const buffer = await this.storageBackend.get(cid);
|
|
3284
|
+
const data = buffer.toString("utf-8");
|
|
3285
|
+
try {
|
|
3286
|
+
return JSON.parse(data);
|
|
3287
|
+
} catch {
|
|
3288
|
+
return data;
|
|
3289
|
+
}
|
|
3290
|
+
}
|
|
3291
|
+
/**
|
|
3292
|
+
* Store evidence (convenience method)
|
|
3293
|
+
*/
|
|
3294
|
+
async storeEvidence(evidenceData) {
|
|
3295
|
+
const result = await this.storageBackend.put(Buffer.from(JSON.stringify(evidenceData)), "application/json");
|
|
3296
|
+
console.log(`\u{1F4E6} Stored evidence: ${result.cid}`);
|
|
3297
|
+
return result.cid;
|
|
3298
|
+
}
|
|
3299
|
+
// ============================================================================
|
|
3300
|
+
// Wallet & Network Methods
|
|
3301
|
+
// ============================================================================
|
|
3302
|
+
/**
|
|
3303
|
+
* Get wallet address
|
|
3304
|
+
*/
|
|
3305
|
+
getAddress() {
|
|
3306
|
+
return this.walletManager.getAddress();
|
|
3307
|
+
}
|
|
3308
|
+
/**
|
|
3309
|
+
* Get wallet balance
|
|
3310
|
+
*/
|
|
3311
|
+
async getBalance() {
|
|
3312
|
+
return this.walletManager.getBalance();
|
|
3313
|
+
}
|
|
3314
|
+
/**
|
|
3315
|
+
* Get network info
|
|
3316
|
+
*/
|
|
3317
|
+
getNetworkInfo() {
|
|
3318
|
+
return this.networkInfo;
|
|
3319
|
+
}
|
|
3320
|
+
/**
|
|
3321
|
+
* Get SDK capabilities summary
|
|
3322
|
+
*/
|
|
3323
|
+
getCapabilities() {
|
|
3324
|
+
return {
|
|
3325
|
+
agent_name: this.agentName,
|
|
3326
|
+
agent_domain: this.agentDomain,
|
|
3327
|
+
agent_role: this.agentRole,
|
|
3328
|
+
network: this.network,
|
|
3329
|
+
wallet_address: this.walletManager.getAddress(),
|
|
3330
|
+
agent_id: this._agentId ? this._agentId.toString() : void 0,
|
|
3331
|
+
features: {
|
|
3332
|
+
erc_8004_identity: true,
|
|
3333
|
+
erc_8004_reputation: true,
|
|
3334
|
+
erc_8004_validation: true,
|
|
3335
|
+
x402_crypto_payments: !!this.x402PaymentManager,
|
|
3336
|
+
traditional_payments: !!this.paymentManager,
|
|
3337
|
+
google_ap2_intents: !!this.googleAP2,
|
|
3338
|
+
process_integrity: !!this.processIntegrity,
|
|
3339
|
+
storage: true,
|
|
3340
|
+
compute: !!this.computeProvider
|
|
3341
|
+
},
|
|
3342
|
+
supported_payment_methods: this.paymentManager ? this.paymentManager.getSupportedPaymentMethods() : [],
|
|
3343
|
+
storage_backends: this.storageBackend instanceof AutoStorageManager ? this.storageBackend.getAvailableBackends() : [this.storageBackend.constructor.name]
|
|
3344
|
+
};
|
|
3345
|
+
}
|
|
3346
|
+
};
|
|
3347
|
+
var IPFSLocalStorage = class {
|
|
3348
|
+
apiUrl;
|
|
3349
|
+
gatewayUrl;
|
|
3350
|
+
constructor(apiUrl = "http://localhost:5001", gatewayUrl = "http://localhost:8080") {
|
|
3351
|
+
this.apiUrl = apiUrl;
|
|
3352
|
+
this.gatewayUrl = gatewayUrl;
|
|
3353
|
+
}
|
|
3354
|
+
/**
|
|
3355
|
+
* Upload data to local IPFS
|
|
3356
|
+
*/
|
|
3357
|
+
async upload(data, options) {
|
|
3358
|
+
try {
|
|
3359
|
+
let buffer;
|
|
3360
|
+
if (Buffer.isBuffer(data)) {
|
|
3361
|
+
buffer = data;
|
|
3362
|
+
} else if (typeof data === "string") {
|
|
3363
|
+
buffer = Buffer.from(data, "utf-8");
|
|
3364
|
+
} else {
|
|
3365
|
+
buffer = Buffer.from(JSON.stringify(data), "utf-8");
|
|
3366
|
+
}
|
|
3367
|
+
const formData = new FormData();
|
|
3368
|
+
const blob = new Blob([buffer], { type: options?.mime || "application/octet-stream" });
|
|
3369
|
+
formData.append("file", blob);
|
|
3370
|
+
const response = await axios2.post(`${this.apiUrl}/api/v0/add`, formData, {
|
|
3371
|
+
headers: {
|
|
3372
|
+
"Content-Type": "multipart/form-data"
|
|
3373
|
+
},
|
|
3374
|
+
params: {
|
|
3375
|
+
pin: options?.pin !== false
|
|
3376
|
+
// Pin by default
|
|
3377
|
+
}
|
|
3378
|
+
});
|
|
3379
|
+
const cid = response.data.Hash;
|
|
3380
|
+
return {
|
|
3381
|
+
cid,
|
|
3382
|
+
uri: `ipfs://${cid}`,
|
|
3383
|
+
size: response.data.Size
|
|
3384
|
+
};
|
|
3385
|
+
} catch (error) {
|
|
3386
|
+
throw new Error(`Failed to upload to IPFS: ${error.message}`);
|
|
3387
|
+
}
|
|
3388
|
+
}
|
|
3389
|
+
/**
|
|
3390
|
+
* Download data from IPFS
|
|
3391
|
+
*/
|
|
3392
|
+
async download(cid) {
|
|
3393
|
+
try {
|
|
3394
|
+
const response = await axios2.get(`${this.gatewayUrl}/ipfs/${cid}`, {
|
|
3395
|
+
responseType: "arraybuffer"
|
|
3396
|
+
});
|
|
3397
|
+
return Buffer.from(response.data);
|
|
3398
|
+
} catch (error) {
|
|
3399
|
+
throw new Error(`Failed to download from IPFS: ${error.message}`);
|
|
3400
|
+
}
|
|
3401
|
+
}
|
|
3402
|
+
/**
|
|
3403
|
+
* Pin content
|
|
3404
|
+
*/
|
|
3405
|
+
async pin(cid) {
|
|
3406
|
+
try {
|
|
3407
|
+
await axios2.post(`${this.apiUrl}/api/v0/pin/add`, null, {
|
|
3408
|
+
params: { arg: cid }
|
|
3409
|
+
});
|
|
3410
|
+
} catch (error) {
|
|
3411
|
+
throw new Error(`Failed to pin content: ${error.message}`);
|
|
3412
|
+
}
|
|
3413
|
+
}
|
|
3414
|
+
/**
|
|
3415
|
+
* Unpin content
|
|
3416
|
+
*/
|
|
3417
|
+
async unpin(cid) {
|
|
3418
|
+
try {
|
|
3419
|
+
await axios2.post(`${this.apiUrl}/api/v0/pin/rm`, null, {
|
|
3420
|
+
params: { arg: cid }
|
|
3421
|
+
});
|
|
3422
|
+
} catch (error) {
|
|
3423
|
+
throw new Error(`Failed to unpin content: ${error.message}`);
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
/**
|
|
3427
|
+
* Check if IPFS daemon is running
|
|
3428
|
+
*/
|
|
3429
|
+
async isAvailable() {
|
|
3430
|
+
try {
|
|
3431
|
+
await axios2.post(`${this.apiUrl}/api/v0/version`);
|
|
3432
|
+
return true;
|
|
3433
|
+
} catch {
|
|
3434
|
+
return false;
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
3437
|
+
/**
|
|
3438
|
+
* Get IPFS version
|
|
3439
|
+
*/
|
|
3440
|
+
async getVersion() {
|
|
3441
|
+
try {
|
|
3442
|
+
const response = await axios2.post(`${this.apiUrl}/api/v0/version`);
|
|
3443
|
+
return response.data.Version;
|
|
3444
|
+
} catch (error) {
|
|
3445
|
+
throw new Error(`Failed to get IPFS version: ${error.message}`);
|
|
3446
|
+
}
|
|
3447
|
+
}
|
|
3448
|
+
};
|
|
3449
|
+
|
|
3450
|
+
// src/types.ts
|
|
3451
|
+
var AgentRole = /* @__PURE__ */ ((AgentRole2) => {
|
|
3452
|
+
AgentRole2["SERVER"] = "server";
|
|
3453
|
+
AgentRole2["CLIENT"] = "client";
|
|
3454
|
+
AgentRole2["VALIDATOR"] = "validator";
|
|
3455
|
+
AgentRole2["BOTH"] = "both";
|
|
3456
|
+
return AgentRole2;
|
|
3457
|
+
})(AgentRole || {});
|
|
3458
|
+
var ValidationStatus = /* @__PURE__ */ ((ValidationStatus2) => {
|
|
3459
|
+
ValidationStatus2[ValidationStatus2["PENDING"] = 0] = "PENDING";
|
|
3460
|
+
ValidationStatus2[ValidationStatus2["APPROVED"] = 1] = "APPROVED";
|
|
3461
|
+
ValidationStatus2[ValidationStatus2["REJECTED"] = 2] = "REJECTED";
|
|
3462
|
+
return ValidationStatus2;
|
|
3463
|
+
})(ValidationStatus || {});
|
|
3464
|
+
|
|
3465
|
+
// src/index.ts
|
|
3466
|
+
var PaymentMethod = /* @__PURE__ */ ((PaymentMethod2) => {
|
|
3467
|
+
PaymentMethod2["BASIC_CARD"] = "basic-card";
|
|
3468
|
+
PaymentMethod2["GOOGLE_PAY"] = "https://google.com/pay";
|
|
3469
|
+
PaymentMethod2["APPLE_PAY"] = "https://apple.com/apple-pay";
|
|
3470
|
+
PaymentMethod2["PAYPAL"] = "https://paypal.com";
|
|
3471
|
+
PaymentMethod2["A2A_X402"] = "https://a2a.org/x402";
|
|
3472
|
+
return PaymentMethod2;
|
|
3473
|
+
})(PaymentMethod || {});
|
|
3474
|
+
var SDK_VERSION = "0.1.0";
|
|
3475
|
+
var ERC8004_VERSION = "1.0";
|
|
3476
|
+
var X402_VERSION = "1.0";
|
|
3477
|
+
var src_default = ChaosChainSDK;
|
|
3478
|
+
function initChaosChainSDK(config) {
|
|
3479
|
+
return new ChaosChainSDK(config);
|
|
3480
|
+
}
|
|
3481
|
+
|
|
3482
|
+
export { A2AX402Extension, AgentRegistrationError, AgentRole, AutoStorageManager, ChaosAgent, ChaosChainSDK, ChaosChainSDKError, ConfigurationError, ContractError, ERC8004_VERSION, GoogleAP2Integration, IDENTITY_REGISTRY_ABI, IPFSLocalStorage, PinataStorage as IPFSPinataStorage, IntegrityVerificationError, IrysStorage, IrysStorage as IrysStorageProvider, LocalIPFSStorage, PaymentError2 as PaymentError, PaymentManager, PaymentMethod, PinataStorage, REPUTATION_REGISTRY_ABI, SDK_VERSION, StorageError, VALIDATION_REGISTRY_ABI, ValidationStatus, WalletManager, X402PaymentManager, X402Server, X402_VERSION, ZeroGStorage, src_default as default, getContractAddresses, getNetworkInfo, initChaosChainSDK };
|
|
3483
|
+
//# sourceMappingURL=index.mjs.map
|
|
3484
|
+
//# sourceMappingURL=index.mjs.map
|