@virtuals-protocol/acp-node 0.3.0-beta.13 → 0.3.0-beta.15
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/dist/index.d.mts +16 -14
- package/dist/index.d.ts +16 -14
- package/dist/index.js +1566 -1395
- package/dist/index.mjs +1570 -1398
- package/package.json +13 -3
package/dist/index.mjs
CHANGED
|
@@ -2,51 +2,41 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
|
2
2
|
var __commonJS = (cb, mod) => function __require() {
|
|
3
3
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
4
4
|
};
|
|
5
|
-
var __async = (__this, __arguments, generator) => {
|
|
6
|
-
return new Promise((resolve, reject) => {
|
|
7
|
-
var fulfilled = (value) => {
|
|
8
|
-
try {
|
|
9
|
-
step(generator.next(value));
|
|
10
|
-
} catch (e) {
|
|
11
|
-
reject(e);
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
var rejected = (value) => {
|
|
15
|
-
try {
|
|
16
|
-
step(generator.throw(value));
|
|
17
|
-
} catch (e) {
|
|
18
|
-
reject(e);
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
22
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
23
|
-
});
|
|
24
|
-
};
|
|
25
5
|
|
|
26
6
|
// package.json
|
|
27
7
|
var require_package = __commonJS({
|
|
28
8
|
"package.json"(exports, module) {
|
|
29
9
|
module.exports = {
|
|
30
10
|
name: "@virtuals-protocol/acp-node",
|
|
31
|
-
version: "0.3.0-beta.
|
|
11
|
+
version: "0.3.0-beta.15",
|
|
32
12
|
main: "./dist/index.js",
|
|
33
13
|
module: "./dist/index.mjs",
|
|
34
14
|
types: "./dist/index.d.ts",
|
|
35
15
|
scripts: {
|
|
36
|
-
test:
|
|
16
|
+
test: "jest",
|
|
17
|
+
"test:watch": "jest --watch",
|
|
18
|
+
"test:coverage": "jest --coverage",
|
|
37
19
|
tsup: "tsup src/index.ts --dts --format cjs,esm --out-dir dist"
|
|
38
20
|
},
|
|
39
21
|
author: "",
|
|
40
22
|
license: "ISC",
|
|
41
23
|
description: "",
|
|
42
24
|
devDependencies: {
|
|
25
|
+
"@babel/core": "^7.28.5",
|
|
26
|
+
"@babel/preset-env": "^7.28.5",
|
|
27
|
+
"@babel/preset-typescript": "^7.28.5",
|
|
28
|
+
"@types/jest": "^30.0.0",
|
|
29
|
+
"babel-jest": "^30.2.0",
|
|
30
|
+
dotenv: "^17.2.3",
|
|
31
|
+
jest: "^30.2.0",
|
|
32
|
+
"ts-jest": "^29.4.5",
|
|
43
33
|
typescript: "^5.8.3"
|
|
44
34
|
},
|
|
45
35
|
dependencies: {
|
|
46
36
|
"@aa-sdk/core": "^4.73.0",
|
|
47
37
|
"@account-kit/infra": "^4.73.0",
|
|
48
38
|
"@account-kit/smart-contracts": "^4.73.0",
|
|
49
|
-
"@virtuals-protocol/acp-node": "^0.3.0-beta.
|
|
39
|
+
"@virtuals-protocol/acp-node": "^0.3.0-beta.10",
|
|
50
40
|
ajv: "^8.17.1",
|
|
51
41
|
"socket.io-client": "^4.8.1",
|
|
52
42
|
tsup: "^8.5.0",
|
|
@@ -1230,7 +1220,7 @@ var ACP_ABI = [
|
|
|
1230
1220
|
var acpAbi_default = ACP_ABI;
|
|
1231
1221
|
|
|
1232
1222
|
// src/acpClient.ts
|
|
1233
|
-
import { zeroAddress as
|
|
1223
|
+
import { zeroAddress as zeroAddress3 } from "viem";
|
|
1234
1224
|
import { io } from "socket.io-client";
|
|
1235
1225
|
|
|
1236
1226
|
// src/contractClients/baseAcpContractClient.ts
|
|
@@ -1241,7 +1231,8 @@ import {
|
|
|
1241
1231
|
http as http2,
|
|
1242
1232
|
keccak256,
|
|
1243
1233
|
toEventSignature,
|
|
1244
|
-
toHex
|
|
1234
|
+
toHex,
|
|
1235
|
+
zeroAddress
|
|
1245
1236
|
} from "viem";
|
|
1246
1237
|
|
|
1247
1238
|
// src/configs/acpConfigs.ts
|
|
@@ -1280,22 +1271,20 @@ var Fare = class _Fare {
|
|
|
1280
1271
|
formatAmount(amount) {
|
|
1281
1272
|
return parseUnits(amount.toString(), this.decimals);
|
|
1282
1273
|
}
|
|
1283
|
-
static fromContractAddress(
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
transport: http(config.rpcEndpoint)
|
|
1291
|
-
});
|
|
1292
|
-
const decimals = yield publicClient.readContract({
|
|
1293
|
-
address: contractAddress,
|
|
1294
|
-
abi: erc20Abi,
|
|
1295
|
-
functionName: "decimals"
|
|
1296
|
-
});
|
|
1297
|
-
return new _Fare(contractAddress, decimals);
|
|
1274
|
+
static async fromContractAddress(contractAddress, config = baseAcpConfig) {
|
|
1275
|
+
if (contractAddress === config.baseFare.contractAddress) {
|
|
1276
|
+
return config.baseFare;
|
|
1277
|
+
}
|
|
1278
|
+
const publicClient = createPublicClient({
|
|
1279
|
+
chain: config.chain,
|
|
1280
|
+
transport: http(config.rpcEndpoint)
|
|
1298
1281
|
});
|
|
1282
|
+
const decimals = await publicClient.readContract({
|
|
1283
|
+
address: contractAddress,
|
|
1284
|
+
abi: erc20Abi,
|
|
1285
|
+
functionName: "decimals"
|
|
1286
|
+
});
|
|
1287
|
+
return new _Fare(contractAddress, decimals);
|
|
1299
1288
|
}
|
|
1300
1289
|
};
|
|
1301
1290
|
var FareAmountBase = class {
|
|
@@ -1303,14 +1292,12 @@ var FareAmountBase = class {
|
|
|
1303
1292
|
this.amount = amount;
|
|
1304
1293
|
this.fare = fare;
|
|
1305
1294
|
}
|
|
1306
|
-
static fromContractAddress(
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
return new FareBigInt(amount, fare);
|
|
1313
|
-
});
|
|
1295
|
+
static async fromContractAddress(amount, contractAddress, config = baseAcpConfig) {
|
|
1296
|
+
const fare = await Fare.fromContractAddress(contractAddress, config);
|
|
1297
|
+
if (typeof amount === "number") {
|
|
1298
|
+
return new FareAmount(amount, fare);
|
|
1299
|
+
}
|
|
1300
|
+
return new FareBigInt(amount, fare);
|
|
1314
1301
|
}
|
|
1315
1302
|
};
|
|
1316
1303
|
var FareAmount = class extends FareAmountBase {
|
|
@@ -3267,6 +3254,241 @@ var FIAT_TOKEN_V2_ABI = [
|
|
|
3267
3254
|
];
|
|
3268
3255
|
var fiatTokenV2Abi_default = FIAT_TOKEN_V2_ABI;
|
|
3269
3256
|
|
|
3257
|
+
// src/abis/singleSignerValidationModuleAbi.ts
|
|
3258
|
+
var SINGLE_SIGNER_VALIDATION_MODULE_ABI = [
|
|
3259
|
+
{ inputs: [], name: "InvalidSignatureType", type: "error" },
|
|
3260
|
+
{
|
|
3261
|
+
inputs: [],
|
|
3262
|
+
name: "NotAuthorized",
|
|
3263
|
+
type: "error"
|
|
3264
|
+
},
|
|
3265
|
+
{ inputs: [], name: "NotImplemented", type: "error" },
|
|
3266
|
+
{
|
|
3267
|
+
inputs: [],
|
|
3268
|
+
name: "UnexpectedDataPassed",
|
|
3269
|
+
type: "error"
|
|
3270
|
+
},
|
|
3271
|
+
{
|
|
3272
|
+
anonymous: true,
|
|
3273
|
+
inputs: [
|
|
3274
|
+
{
|
|
3275
|
+
indexed: true,
|
|
3276
|
+
internalType: "address",
|
|
3277
|
+
name: "account",
|
|
3278
|
+
type: "address"
|
|
3279
|
+
},
|
|
3280
|
+
{
|
|
3281
|
+
indexed: true,
|
|
3282
|
+
internalType: "uint32",
|
|
3283
|
+
name: "entityId",
|
|
3284
|
+
type: "uint32"
|
|
3285
|
+
},
|
|
3286
|
+
{
|
|
3287
|
+
indexed: true,
|
|
3288
|
+
internalType: "address",
|
|
3289
|
+
name: "newSigner",
|
|
3290
|
+
type: "address"
|
|
3291
|
+
},
|
|
3292
|
+
{
|
|
3293
|
+
indexed: false,
|
|
3294
|
+
internalType: "address",
|
|
3295
|
+
name: "previousSigner",
|
|
3296
|
+
type: "address"
|
|
3297
|
+
}
|
|
3298
|
+
],
|
|
3299
|
+
name: "SignerTransferred",
|
|
3300
|
+
type: "event"
|
|
3301
|
+
},
|
|
3302
|
+
{
|
|
3303
|
+
inputs: [],
|
|
3304
|
+
name: "moduleId",
|
|
3305
|
+
outputs: [{ internalType: "string", name: "", type: "string" }],
|
|
3306
|
+
stateMutability: "pure",
|
|
3307
|
+
type: "function"
|
|
3308
|
+
},
|
|
3309
|
+
{
|
|
3310
|
+
inputs: [{ internalType: "bytes", name: "data", type: "bytes" }],
|
|
3311
|
+
name: "onInstall",
|
|
3312
|
+
outputs: [],
|
|
3313
|
+
stateMutability: "nonpayable",
|
|
3314
|
+
type: "function"
|
|
3315
|
+
},
|
|
3316
|
+
{
|
|
3317
|
+
inputs: [{ internalType: "bytes", name: "data", type: "bytes" }],
|
|
3318
|
+
name: "onUninstall",
|
|
3319
|
+
outputs: [],
|
|
3320
|
+
stateMutability: "nonpayable",
|
|
3321
|
+
type: "function"
|
|
3322
|
+
},
|
|
3323
|
+
{
|
|
3324
|
+
inputs: [
|
|
3325
|
+
{ internalType: "address", name: "account", type: "address" },
|
|
3326
|
+
{
|
|
3327
|
+
internalType: "bytes32",
|
|
3328
|
+
name: "hash",
|
|
3329
|
+
type: "bytes32"
|
|
3330
|
+
}
|
|
3331
|
+
],
|
|
3332
|
+
name: "replaySafeHash",
|
|
3333
|
+
outputs: [{ internalType: "bytes32", name: "", type: "bytes32" }],
|
|
3334
|
+
stateMutability: "view",
|
|
3335
|
+
type: "function"
|
|
3336
|
+
},
|
|
3337
|
+
{
|
|
3338
|
+
inputs: [
|
|
3339
|
+
{ internalType: "uint32", name: "entityId", type: "uint32" },
|
|
3340
|
+
{
|
|
3341
|
+
internalType: "address",
|
|
3342
|
+
name: "account",
|
|
3343
|
+
type: "address"
|
|
3344
|
+
}
|
|
3345
|
+
],
|
|
3346
|
+
name: "signers",
|
|
3347
|
+
outputs: [{ internalType: "address", name: "", type: "address" }],
|
|
3348
|
+
stateMutability: "view",
|
|
3349
|
+
type: "function"
|
|
3350
|
+
},
|
|
3351
|
+
{
|
|
3352
|
+
inputs: [{ internalType: "bytes4", name: "interfaceId", type: "bytes4" }],
|
|
3353
|
+
name: "supportsInterface",
|
|
3354
|
+
outputs: [{ internalType: "bool", name: "", type: "bool" }],
|
|
3355
|
+
stateMutability: "view",
|
|
3356
|
+
type: "function"
|
|
3357
|
+
},
|
|
3358
|
+
{
|
|
3359
|
+
inputs: [
|
|
3360
|
+
{ internalType: "uint32", name: "entityId", type: "uint32" },
|
|
3361
|
+
{
|
|
3362
|
+
internalType: "address",
|
|
3363
|
+
name: "newSigner",
|
|
3364
|
+
type: "address"
|
|
3365
|
+
}
|
|
3366
|
+
],
|
|
3367
|
+
name: "transferSigner",
|
|
3368
|
+
outputs: [],
|
|
3369
|
+
stateMutability: "nonpayable",
|
|
3370
|
+
type: "function"
|
|
3371
|
+
},
|
|
3372
|
+
{
|
|
3373
|
+
inputs: [
|
|
3374
|
+
{ internalType: "address", name: "account", type: "address" },
|
|
3375
|
+
{
|
|
3376
|
+
internalType: "uint32",
|
|
3377
|
+
name: "entityId",
|
|
3378
|
+
type: "uint32"
|
|
3379
|
+
},
|
|
3380
|
+
{ internalType: "address", name: "sender", type: "address" },
|
|
3381
|
+
{
|
|
3382
|
+
internalType: "uint256",
|
|
3383
|
+
name: "",
|
|
3384
|
+
type: "uint256"
|
|
3385
|
+
},
|
|
3386
|
+
{ internalType: "bytes", name: "", type: "bytes" },
|
|
3387
|
+
{
|
|
3388
|
+
internalType: "bytes",
|
|
3389
|
+
name: "",
|
|
3390
|
+
type: "bytes"
|
|
3391
|
+
}
|
|
3392
|
+
],
|
|
3393
|
+
name: "validateRuntime",
|
|
3394
|
+
outputs: [],
|
|
3395
|
+
stateMutability: "view",
|
|
3396
|
+
type: "function"
|
|
3397
|
+
},
|
|
3398
|
+
{
|
|
3399
|
+
inputs: [
|
|
3400
|
+
{ internalType: "address", name: "account", type: "address" },
|
|
3401
|
+
{
|
|
3402
|
+
internalType: "uint32",
|
|
3403
|
+
name: "entityId",
|
|
3404
|
+
type: "uint32"
|
|
3405
|
+
},
|
|
3406
|
+
{ internalType: "address", name: "", type: "address" },
|
|
3407
|
+
{
|
|
3408
|
+
internalType: "bytes32",
|
|
3409
|
+
name: "digest",
|
|
3410
|
+
type: "bytes32"
|
|
3411
|
+
},
|
|
3412
|
+
{ internalType: "bytes", name: "signature", type: "bytes" }
|
|
3413
|
+
],
|
|
3414
|
+
name: "validateSignature",
|
|
3415
|
+
outputs: [{ internalType: "bytes4", name: "", type: "bytes4" }],
|
|
3416
|
+
stateMutability: "view",
|
|
3417
|
+
type: "function"
|
|
3418
|
+
},
|
|
3419
|
+
{
|
|
3420
|
+
inputs: [
|
|
3421
|
+
{
|
|
3422
|
+
internalType: "uint32",
|
|
3423
|
+
name: "entityId",
|
|
3424
|
+
type: "uint32"
|
|
3425
|
+
},
|
|
3426
|
+
{
|
|
3427
|
+
components: [
|
|
3428
|
+
{ internalType: "address", name: "sender", type: "address" },
|
|
3429
|
+
{
|
|
3430
|
+
internalType: "uint256",
|
|
3431
|
+
name: "nonce",
|
|
3432
|
+
type: "uint256"
|
|
3433
|
+
},
|
|
3434
|
+
{ internalType: "bytes", name: "initCode", type: "bytes" },
|
|
3435
|
+
{
|
|
3436
|
+
internalType: "bytes",
|
|
3437
|
+
name: "callData",
|
|
3438
|
+
type: "bytes"
|
|
3439
|
+
},
|
|
3440
|
+
{
|
|
3441
|
+
internalType: "bytes32",
|
|
3442
|
+
name: "accountGasLimits",
|
|
3443
|
+
type: "bytes32"
|
|
3444
|
+
},
|
|
3445
|
+
{
|
|
3446
|
+
internalType: "uint256",
|
|
3447
|
+
name: "preVerificationGas",
|
|
3448
|
+
type: "uint256"
|
|
3449
|
+
},
|
|
3450
|
+
{ internalType: "bytes32", name: "gasFees", type: "bytes32" },
|
|
3451
|
+
{
|
|
3452
|
+
internalType: "bytes",
|
|
3453
|
+
name: "paymasterAndData",
|
|
3454
|
+
type: "bytes"
|
|
3455
|
+
},
|
|
3456
|
+
{ internalType: "bytes", name: "signature", type: "bytes" }
|
|
3457
|
+
],
|
|
3458
|
+
internalType: "struct PackedUserOperation",
|
|
3459
|
+
name: "userOp",
|
|
3460
|
+
type: "tuple"
|
|
3461
|
+
},
|
|
3462
|
+
{ internalType: "bytes32", name: "userOpHash", type: "bytes32" }
|
|
3463
|
+
],
|
|
3464
|
+
name: "validateUserOp",
|
|
3465
|
+
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
|
|
3466
|
+
stateMutability: "view",
|
|
3467
|
+
type: "function"
|
|
3468
|
+
}
|
|
3469
|
+
];
|
|
3470
|
+
var singleSignerValidationModuleAbi_default = SINGLE_SIGNER_VALIDATION_MODULE_ABI;
|
|
3471
|
+
|
|
3472
|
+
// src/constants.ts
|
|
3473
|
+
import { base as base2, baseSepolia as baseSepolia2 } from "viem/chains";
|
|
3474
|
+
var USDC_TOKEN_ADDRESS = {
|
|
3475
|
+
[baseSepolia2.id]: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
3476
|
+
[base2.id]: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
|
|
3477
|
+
};
|
|
3478
|
+
var X402AuthorizationTypes = [
|
|
3479
|
+
{ name: "from", type: "address" },
|
|
3480
|
+
{ name: "to", type: "address" },
|
|
3481
|
+
{ name: "value", type: "uint256" },
|
|
3482
|
+
{ name: "validAfter", type: "uint256" },
|
|
3483
|
+
{ name: "validBefore", type: "uint256" },
|
|
3484
|
+
{ name: "nonce", type: "bytes32" }
|
|
3485
|
+
];
|
|
3486
|
+
var HTTP_STATUS_CODES = {
|
|
3487
|
+
OK: 200,
|
|
3488
|
+
PAYMENT_REQUIRED: 402
|
|
3489
|
+
};
|
|
3490
|
+
var SINGLE_SIGNER_VALIDATION_MODULE_ADDRESS = "0x00000000000099DE0BF6fA90dEB851E2A2df7d83";
|
|
3491
|
+
|
|
3270
3492
|
// src/contractClients/baseAcpContractClient.ts
|
|
3271
3493
|
var MemoType = /* @__PURE__ */ ((MemoType3) => {
|
|
3272
3494
|
MemoType3[MemoType3["MESSAGE"] = 0] = "MESSAGE";
|
|
@@ -3309,6 +3531,44 @@ var BaseAcpContractClient = class {
|
|
|
3309
3531
|
transport: http2(this.config.rpcEndpoint)
|
|
3310
3532
|
});
|
|
3311
3533
|
}
|
|
3534
|
+
async validateSessionKeyOnChain(sessionSignerAddress, sessionEntityKeyId) {
|
|
3535
|
+
const onChainSignerAddress = (await this.publicClient.readContract({
|
|
3536
|
+
address: SINGLE_SIGNER_VALIDATION_MODULE_ADDRESS,
|
|
3537
|
+
abi: singleSignerValidationModuleAbi_default,
|
|
3538
|
+
functionName: "signers",
|
|
3539
|
+
args: [sessionEntityKeyId, this.agentWalletAddress]
|
|
3540
|
+
})).toLowerCase();
|
|
3541
|
+
if (onChainSignerAddress === zeroAddress.toLowerCase()) {
|
|
3542
|
+
throw new acpError_default(
|
|
3543
|
+
`ACP Contract Client validation failed:
|
|
3544
|
+
${JSON.stringify(
|
|
3545
|
+
{
|
|
3546
|
+
reason: "no whitelisted wallet registered on-chain for entity id",
|
|
3547
|
+
entityId: sessionEntityKeyId,
|
|
3548
|
+
agentWalletAddress: this.agentWalletAddress
|
|
3549
|
+
},
|
|
3550
|
+
null,
|
|
3551
|
+
2
|
|
3552
|
+
)}`
|
|
3553
|
+
);
|
|
3554
|
+
}
|
|
3555
|
+
if (onChainSignerAddress !== sessionSignerAddress.toLowerCase()) {
|
|
3556
|
+
throw new acpError_default(
|
|
3557
|
+
`ACP Contract Client validation failed:
|
|
3558
|
+
${JSON.stringify(
|
|
3559
|
+
{
|
|
3560
|
+
agentWalletAddress: this.agentWalletAddress,
|
|
3561
|
+
entityId: sessionEntityKeyId,
|
|
3562
|
+
givenWhitelistedWalletAddress: sessionSignerAddress,
|
|
3563
|
+
expectedWhitelistedWalletAddress: onChainSignerAddress,
|
|
3564
|
+
reason: "session signer address mismatch"
|
|
3565
|
+
},
|
|
3566
|
+
null,
|
|
3567
|
+
2
|
|
3568
|
+
)}`
|
|
3569
|
+
);
|
|
3570
|
+
}
|
|
3571
|
+
}
|
|
3312
3572
|
get walletAddress() {
|
|
3313
3573
|
return this.agentWalletAddress;
|
|
3314
3574
|
}
|
|
@@ -3468,43 +3728,39 @@ var BaseAcpContractClient = class {
|
|
|
3468
3728
|
throw new acpError_default("Failed to wrap eth", error);
|
|
3469
3729
|
}
|
|
3470
3730
|
}
|
|
3471
|
-
getX402PaymentDetails(jobId) {
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
}
|
|
3487
|
-
});
|
|
3731
|
+
async getX402PaymentDetails(jobId) {
|
|
3732
|
+
try {
|
|
3733
|
+
const result = await this.publicClient.readContract({
|
|
3734
|
+
address: this.contractAddress,
|
|
3735
|
+
abi: this.abi,
|
|
3736
|
+
functionName: "x402PaymentDetails",
|
|
3737
|
+
args: [BigInt(jobId)]
|
|
3738
|
+
});
|
|
3739
|
+
return {
|
|
3740
|
+
isX402: result[0],
|
|
3741
|
+
isBudgetReceived: result[1]
|
|
3742
|
+
};
|
|
3743
|
+
} catch (error) {
|
|
3744
|
+
throw new acpError_default("Failed to get X402 payment details", error);
|
|
3745
|
+
}
|
|
3488
3746
|
}
|
|
3489
|
-
submitTransferWithAuthorization(from, to, value, validAfter, validBefore, nonce, signature) {
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
}
|
|
3507
|
-
});
|
|
3747
|
+
async submitTransferWithAuthorization(from, to, value, validAfter, validBefore, nonce, signature) {
|
|
3748
|
+
try {
|
|
3749
|
+
const operations = [];
|
|
3750
|
+
const data = encodeFunctionData({
|
|
3751
|
+
abi: fiatTokenV2Abi_default,
|
|
3752
|
+
functionName: "transferWithAuthorization",
|
|
3753
|
+
args: [from, to, value, validAfter, validBefore, nonce, signature]
|
|
3754
|
+
});
|
|
3755
|
+
const payload = {
|
|
3756
|
+
data,
|
|
3757
|
+
contractAddress: this.config.baseFare.contractAddress
|
|
3758
|
+
};
|
|
3759
|
+
operations.push(payload);
|
|
3760
|
+
return operations;
|
|
3761
|
+
} catch (error) {
|
|
3762
|
+
throw new acpError_default("Failed to submit TransferWithAuthorization", error);
|
|
3763
|
+
}
|
|
3508
3764
|
}
|
|
3509
3765
|
};
|
|
3510
3766
|
var baseAcpContractClient_default = BaseAcpContractClient;
|
|
@@ -3572,29 +3828,8 @@ function safeBase64Encode(data) {
|
|
|
3572
3828
|
}
|
|
3573
3829
|
|
|
3574
3830
|
// src/acpJobOffering.ts
|
|
3575
|
-
import { zeroAddress } from "viem";
|
|
3831
|
+
import { zeroAddress as zeroAddress2 } from "viem";
|
|
3576
3832
|
import Ajv from "ajv";
|
|
3577
|
-
|
|
3578
|
-
// src/constants.ts
|
|
3579
|
-
import { base as base2, baseSepolia as baseSepolia2 } from "viem/chains";
|
|
3580
|
-
var USDC_TOKEN_ADDRESS = {
|
|
3581
|
-
[baseSepolia2.id]: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
3582
|
-
[base2.id]: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
|
|
3583
|
-
};
|
|
3584
|
-
var X402AuthorizationTypes = [
|
|
3585
|
-
{ name: "from", type: "address" },
|
|
3586
|
-
{ name: "to", type: "address" },
|
|
3587
|
-
{ name: "value", type: "uint256" },
|
|
3588
|
-
{ name: "validAfter", type: "uint256" },
|
|
3589
|
-
{ name: "validBefore", type: "uint256" },
|
|
3590
|
-
{ name: "nonce", type: "bytes32" }
|
|
3591
|
-
];
|
|
3592
|
-
var HTTP_STATUS_CODES = {
|
|
3593
|
-
OK: 200,
|
|
3594
|
-
PAYMENT_REQUIRED: 402
|
|
3595
|
-
};
|
|
3596
|
-
|
|
3597
|
-
// src/acpJobOffering.ts
|
|
3598
3833
|
var AcpJobOffering = class {
|
|
3599
3834
|
constructor(acpClient, acpContractClient, providerAddress, name, price, priceType = "fixed" /* FIXED */, requirement) {
|
|
3600
3835
|
this.acpClient = acpClient;
|
|
@@ -3606,89 +3841,87 @@ var AcpJobOffering = class {
|
|
|
3606
3841
|
this.requirement = requirement;
|
|
3607
3842
|
this.ajv = new Ajv({ allErrors: true });
|
|
3608
3843
|
}
|
|
3609
|
-
initiateJob(
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
throw new acpError_default(this.ajv.errorsText(validator.errors));
|
|
3616
|
-
}
|
|
3844
|
+
async initiateJob(serviceRequirement, evaluatorAddress, expiredAt = new Date(Date.now() + 1e3 * 60 * 60 * 24)) {
|
|
3845
|
+
if (this.requirement && typeof this.requirement === "object") {
|
|
3846
|
+
const validator = this.ajv.compile(this.requirement);
|
|
3847
|
+
const valid = validator(serviceRequirement);
|
|
3848
|
+
if (!valid) {
|
|
3849
|
+
throw new acpError_default(this.ajv.errorsText(validator.errors));
|
|
3617
3850
|
}
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3851
|
+
}
|
|
3852
|
+
const finalServiceRequirement = {
|
|
3853
|
+
name: this.name,
|
|
3854
|
+
requirement: serviceRequirement,
|
|
3855
|
+
priceValue: this.price,
|
|
3856
|
+
priceType: this.priceType
|
|
3857
|
+
};
|
|
3858
|
+
const fareAmount = new FareAmount(
|
|
3859
|
+
this.priceType === "fixed" /* FIXED */ ? this.price : 0,
|
|
3860
|
+
this.acpContractClient.config.baseFare
|
|
3861
|
+
);
|
|
3862
|
+
const account = await this.acpClient.getByClientAndProvider(
|
|
3863
|
+
this.acpContractClient.walletAddress,
|
|
3864
|
+
this.providerAddress,
|
|
3865
|
+
this.acpContractClient
|
|
3866
|
+
);
|
|
3867
|
+
const isV1 = [
|
|
3868
|
+
baseSepoliaAcpConfig.contractAddress,
|
|
3869
|
+
baseSepoliaAcpX402Config.contractAddress,
|
|
3870
|
+
baseAcpConfig.contractAddress,
|
|
3871
|
+
baseAcpX402Config.contractAddress
|
|
3872
|
+
].includes(this.acpContractClient.config.contractAddress);
|
|
3873
|
+
let createJobPayload;
|
|
3874
|
+
const chainId = this.acpContractClient.config.chain.id;
|
|
3875
|
+
const isUsdcPaymentToken = USDC_TOKEN_ADDRESS[chainId].toLowerCase() === fareAmount.fare.contractAddress.toLowerCase();
|
|
3876
|
+
const isX402Job = this.acpContractClient.config.x402Config && isUsdcPaymentToken;
|
|
3877
|
+
if (isV1 || !account) {
|
|
3878
|
+
createJobPayload = this.acpContractClient.createJob(
|
|
3630
3879
|
this.providerAddress,
|
|
3631
|
-
this.acpContractClient
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
baseSepoliaAcpConfig.contractAddress,
|
|
3635
|
-
baseSepoliaAcpX402Config.contractAddress,
|
|
3636
|
-
baseAcpConfig.contractAddress,
|
|
3637
|
-
baseAcpX402Config.contractAddress
|
|
3638
|
-
].includes(this.acpContractClient.config.contractAddress);
|
|
3639
|
-
let createJobPayload;
|
|
3640
|
-
const chainId = this.acpContractClient.config.chain.id;
|
|
3641
|
-
const isUsdcPaymentToken = USDC_TOKEN_ADDRESS[chainId].toLowerCase() === fareAmount.fare.contractAddress.toLowerCase();
|
|
3642
|
-
const isX402Job = this.acpContractClient.config.x402Config && isUsdcPaymentToken;
|
|
3643
|
-
if (isV1 || !account) {
|
|
3644
|
-
createJobPayload = this.acpContractClient.createJob(
|
|
3645
|
-
this.providerAddress,
|
|
3646
|
-
evaluatorAddress || this.acpContractClient.walletAddress,
|
|
3647
|
-
expiredAt,
|
|
3648
|
-
fareAmount.fare.contractAddress,
|
|
3649
|
-
fareAmount.amount,
|
|
3650
|
-
"",
|
|
3651
|
-
isX402Job
|
|
3652
|
-
);
|
|
3653
|
-
} else {
|
|
3654
|
-
createJobPayload = this.acpContractClient.createJobWithAccount(
|
|
3655
|
-
account.id,
|
|
3656
|
-
evaluatorAddress || zeroAddress,
|
|
3657
|
-
fareAmount.amount,
|
|
3658
|
-
fareAmount.fare.contractAddress,
|
|
3659
|
-
expiredAt,
|
|
3660
|
-
isX402Job
|
|
3661
|
-
);
|
|
3662
|
-
}
|
|
3663
|
-
const { userOpHash } = yield this.acpContractClient.handleOperation([
|
|
3664
|
-
createJobPayload
|
|
3665
|
-
]);
|
|
3666
|
-
const jobId = yield this.acpContractClient.getJobId(
|
|
3667
|
-
userOpHash,
|
|
3668
|
-
this.acpContractClient.walletAddress,
|
|
3669
|
-
this.providerAddress
|
|
3670
|
-
);
|
|
3671
|
-
const payloads = [];
|
|
3672
|
-
const setBudgetWithPaymentTokenPayload = this.acpContractClient.setBudgetWithPaymentToken(
|
|
3673
|
-
jobId,
|
|
3880
|
+
evaluatorAddress || this.acpContractClient.walletAddress,
|
|
3881
|
+
expiredAt,
|
|
3882
|
+
fareAmount.fare.contractAddress,
|
|
3674
3883
|
fareAmount.amount,
|
|
3675
|
-
|
|
3884
|
+
"",
|
|
3885
|
+
isX402Job
|
|
3676
3886
|
);
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
true,
|
|
3686
|
-
1 /* NEGOTIATION */
|
|
3687
|
-
)
|
|
3887
|
+
} else {
|
|
3888
|
+
createJobPayload = this.acpContractClient.createJobWithAccount(
|
|
3889
|
+
account.id,
|
|
3890
|
+
evaluatorAddress || zeroAddress2,
|
|
3891
|
+
fareAmount.amount,
|
|
3892
|
+
fareAmount.fare.contractAddress,
|
|
3893
|
+
expiredAt,
|
|
3894
|
+
isX402Job
|
|
3688
3895
|
);
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3896
|
+
}
|
|
3897
|
+
const { userOpHash } = await this.acpContractClient.handleOperation([
|
|
3898
|
+
createJobPayload
|
|
3899
|
+
]);
|
|
3900
|
+
const jobId = await this.acpContractClient.getJobId(
|
|
3901
|
+
userOpHash,
|
|
3902
|
+
this.acpContractClient.walletAddress,
|
|
3903
|
+
this.providerAddress
|
|
3904
|
+
);
|
|
3905
|
+
const payloads = [];
|
|
3906
|
+
const setBudgetWithPaymentTokenPayload = this.acpContractClient.setBudgetWithPaymentToken(
|
|
3907
|
+
jobId,
|
|
3908
|
+
fareAmount.amount,
|
|
3909
|
+
fareAmount.fare.contractAddress
|
|
3910
|
+
);
|
|
3911
|
+
if (setBudgetWithPaymentTokenPayload) {
|
|
3912
|
+
payloads.push(setBudgetWithPaymentTokenPayload);
|
|
3913
|
+
}
|
|
3914
|
+
payloads.push(
|
|
3915
|
+
this.acpContractClient.createMemo(
|
|
3916
|
+
jobId,
|
|
3917
|
+
JSON.stringify(finalServiceRequirement),
|
|
3918
|
+
0 /* MESSAGE */,
|
|
3919
|
+
true,
|
|
3920
|
+
1 /* NEGOTIATION */
|
|
3921
|
+
)
|
|
3922
|
+
);
|
|
3923
|
+
await this.acpContractClient.handleOperation(payloads);
|
|
3924
|
+
return jobId;
|
|
3692
3925
|
}
|
|
3693
3926
|
};
|
|
3694
3927
|
var acpJobOffering_default = AcpJobOffering;
|
|
@@ -3710,10 +3943,9 @@ var AcpJob = class {
|
|
|
3710
3943
|
this.netPayableAmount = netPayableAmount;
|
|
3711
3944
|
this.priceType = "fixed" /* FIXED */;
|
|
3712
3945
|
this.priceValue = 0;
|
|
3713
|
-
|
|
3714
|
-
const content = (_a = this.memos.find(
|
|
3946
|
+
const content = this.memos.find(
|
|
3715
3947
|
(m) => m.nextPhase === 1 /* NEGOTIATION */
|
|
3716
|
-
)
|
|
3948
|
+
)?.content;
|
|
3717
3949
|
if (!content) {
|
|
3718
3950
|
return;
|
|
3719
3951
|
}
|
|
@@ -3744,18 +3976,16 @@ var AcpJob = class {
|
|
|
3744
3976
|
return this.acpContractClient.config.baseFare;
|
|
3745
3977
|
}
|
|
3746
3978
|
get deliverable() {
|
|
3747
|
-
|
|
3748
|
-
return (_a = this.memos.find((m) => m.nextPhase === 4 /* COMPLETED */)) == null ? void 0 : _a.content;
|
|
3979
|
+
return this.memos.find((m) => m.nextPhase === 4 /* COMPLETED */)?.content;
|
|
3749
3980
|
}
|
|
3750
3981
|
get rejectionReason() {
|
|
3751
|
-
var _a;
|
|
3752
3982
|
const requestMemo = this.memos.find(
|
|
3753
3983
|
(m) => m.nextPhase === 1 /* NEGOTIATION */ && m.status === "REJECTED" /* REJECTED */
|
|
3754
3984
|
);
|
|
3755
3985
|
if (requestMemo) {
|
|
3756
3986
|
return requestMemo.signedReason;
|
|
3757
3987
|
}
|
|
3758
|
-
return
|
|
3988
|
+
return this.memos.find((m) => m.nextPhase === 5 /* REJECTED */)?.content;
|
|
3759
3989
|
}
|
|
3760
3990
|
get providerAgent() {
|
|
3761
3991
|
return this.acpClient.getAgent(this.providerAddress);
|
|
@@ -3772,330 +4002,304 @@ var AcpJob = class {
|
|
|
3772
4002
|
get latestMemo() {
|
|
3773
4003
|
return this.memos[this.memos.length - 1];
|
|
3774
4004
|
}
|
|
3775
|
-
createRequirement(content) {
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
this.
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
return yield this.acpContractClient.handleOperation(operations);
|
|
3788
|
-
});
|
|
4005
|
+
async createRequirement(content) {
|
|
4006
|
+
const operations = [];
|
|
4007
|
+
operations.push(
|
|
4008
|
+
this.acpContractClient.createMemo(
|
|
4009
|
+
this.id,
|
|
4010
|
+
content,
|
|
4011
|
+
0 /* MESSAGE */,
|
|
4012
|
+
true,
|
|
4013
|
+
2 /* TRANSACTION */
|
|
4014
|
+
)
|
|
4015
|
+
);
|
|
4016
|
+
return await this.acpContractClient.handleOperation(operations);
|
|
3789
4017
|
}
|
|
3790
|
-
createPayableRequirement(
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
if (type === 8 /* PAYABLE_TRANSFER_ESCROW */) {
|
|
3794
|
-
operations.push(
|
|
3795
|
-
this.acpContractClient.approveAllowance(
|
|
3796
|
-
amount.amount,
|
|
3797
|
-
amount.fare.contractAddress
|
|
3798
|
-
)
|
|
3799
|
-
);
|
|
3800
|
-
}
|
|
3801
|
-
const feeAmount = new FareAmount(0, this.acpContractClient.config.baseFare);
|
|
4018
|
+
async createPayableRequirement(content, type, amount, recipient, expiredAt = new Date(Date.now() + 1e3 * 60 * 5)) {
|
|
4019
|
+
const operations = [];
|
|
4020
|
+
if (type === 8 /* PAYABLE_TRANSFER_ESCROW */) {
|
|
3802
4021
|
operations.push(
|
|
3803
|
-
this.acpContractClient.
|
|
3804
|
-
this.id,
|
|
3805
|
-
content,
|
|
4022
|
+
this.acpContractClient.approveAllowance(
|
|
3806
4023
|
amount.amount,
|
|
3807
|
-
recipient,
|
|
3808
|
-
this.priceType === "percentage" /* PERCENTAGE */ ? BigInt(Math.round(this.priceValue * 1e4)) : feeAmount.amount,
|
|
3809
|
-
this.priceType === "percentage" /* PERCENTAGE */ ? 3 /* PERCENTAGE_FEE */ : 0 /* NO_FEE */,
|
|
3810
|
-
2 /* TRANSACTION */,
|
|
3811
|
-
type,
|
|
3812
|
-
expiredAt,
|
|
3813
4024
|
amount.fare.contractAddress
|
|
3814
4025
|
)
|
|
3815
4026
|
);
|
|
3816
|
-
|
|
3817
|
-
|
|
4027
|
+
}
|
|
4028
|
+
const feeAmount = new FareAmount(0, this.acpContractClient.config.baseFare);
|
|
4029
|
+
const isPercentagePricing = this.priceType === "percentage" /* PERCENTAGE */;
|
|
4030
|
+
operations.push(
|
|
4031
|
+
this.acpContractClient.createPayableMemo(
|
|
4032
|
+
this.id,
|
|
4033
|
+
content,
|
|
4034
|
+
amount.amount,
|
|
4035
|
+
recipient,
|
|
4036
|
+
isPercentagePricing ? BigInt(Math.round(this.priceValue * 1e4)) : feeAmount.amount,
|
|
4037
|
+
isPercentagePricing ? 3 /* PERCENTAGE_FEE */ : 0 /* NO_FEE */,
|
|
4038
|
+
2 /* TRANSACTION */,
|
|
4039
|
+
type,
|
|
4040
|
+
expiredAt,
|
|
4041
|
+
amount.fare.contractAddress
|
|
4042
|
+
)
|
|
4043
|
+
);
|
|
4044
|
+
return await this.acpContractClient.handleOperation(operations);
|
|
3818
4045
|
}
|
|
3819
|
-
payAndAcceptRequirement(reason) {
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
4046
|
+
async payAndAcceptRequirement(reason) {
|
|
4047
|
+
const memo = this.memos.find(
|
|
4048
|
+
(m) => m.nextPhase === 2 /* TRANSACTION */
|
|
4049
|
+
);
|
|
4050
|
+
if (!memo) {
|
|
4051
|
+
throw new acpError_default("No notification memo found");
|
|
4052
|
+
}
|
|
4053
|
+
const operations = [];
|
|
4054
|
+
const baseFareAmount = new FareAmount(this.price, this.baseFare);
|
|
4055
|
+
const transferAmount = memo.payableDetails ? await FareAmountBase.fromContractAddress(
|
|
4056
|
+
memo.payableDetails.amount,
|
|
4057
|
+
memo.payableDetails.token,
|
|
4058
|
+
this.config
|
|
4059
|
+
) : new FareAmount(0, this.baseFare);
|
|
4060
|
+
const totalAmount = baseFareAmount.fare.contractAddress === transferAmount.fare.contractAddress ? baseFareAmount.add(transferAmount) : baseFareAmount;
|
|
4061
|
+
operations.push(
|
|
4062
|
+
this.acpContractClient.approveAllowance(
|
|
4063
|
+
totalAmount.amount,
|
|
4064
|
+
this.baseFare.contractAddress
|
|
4065
|
+
)
|
|
4066
|
+
);
|
|
4067
|
+
if (baseFareAmount.fare.contractAddress !== transferAmount.fare.contractAddress) {
|
|
3835
4068
|
operations.push(
|
|
3836
4069
|
this.acpContractClient.approveAllowance(
|
|
3837
|
-
|
|
3838
|
-
|
|
4070
|
+
transferAmount.amount,
|
|
4071
|
+
transferAmount.fare.contractAddress
|
|
3839
4072
|
)
|
|
3840
4073
|
);
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
)
|
|
3858
|
-
);
|
|
3859
|
-
const x402PaymentDetails = yield this.acpContractClient.getX402PaymentDetails(this.id);
|
|
3860
|
-
if (x402PaymentDetails.isX402) {
|
|
3861
|
-
yield this.performX402Payment(this.price);
|
|
3862
|
-
}
|
|
3863
|
-
return yield this.acpContractClient.handleOperation(operations);
|
|
3864
|
-
});
|
|
4074
|
+
}
|
|
4075
|
+
operations.push(this.acpContractClient.signMemo(memo.id, true, reason));
|
|
4076
|
+
operations.push(
|
|
4077
|
+
this.acpContractClient.createMemo(
|
|
4078
|
+
this.id,
|
|
4079
|
+
`Payment made. ${reason ?? ""}`.trim(),
|
|
4080
|
+
0 /* MESSAGE */,
|
|
4081
|
+
true,
|
|
4082
|
+
3 /* EVALUATION */
|
|
4083
|
+
)
|
|
4084
|
+
);
|
|
4085
|
+
const x402PaymentDetails = await this.acpContractClient.getX402PaymentDetails(this.id);
|
|
4086
|
+
if (x402PaymentDetails.isX402) {
|
|
4087
|
+
await this.performX402Payment(this.price);
|
|
4088
|
+
}
|
|
4089
|
+
return await this.acpContractClient.handleOperation(operations);
|
|
3865
4090
|
}
|
|
3866
|
-
respond(accept, reason) {
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
4091
|
+
async respond(accept, reason) {
|
|
4092
|
+
const memoContent = `${reason || `Job ${this.id} ${accept ? "accepted" : "rejected"}.`}`;
|
|
4093
|
+
if (accept) {
|
|
4094
|
+
await this.accept(memoContent);
|
|
4095
|
+
return this.createRequirement(memoContent);
|
|
4096
|
+
}
|
|
4097
|
+
return await this.reject(memoContent);
|
|
4098
|
+
}
|
|
4099
|
+
async accept(reason) {
|
|
4100
|
+
const memoContent = `Job ${this.id} accepted. ${reason || ""}`;
|
|
4101
|
+
const latestMemo = this.latestMemo;
|
|
4102
|
+
if (latestMemo?.nextPhase !== 1 /* NEGOTIATION */) {
|
|
4103
|
+
throw new acpError_default("No request memo found");
|
|
4104
|
+
}
|
|
4105
|
+
return await latestMemo.sign(true, memoContent);
|
|
3875
4106
|
}
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
4107
|
+
async reject(reason) {
|
|
4108
|
+
const memoContent = `Job ${this.id} rejected. ${reason || ""}`;
|
|
4109
|
+
if (this.phase === 0 /* REQUEST */) {
|
|
3879
4110
|
const latestMemo = this.latestMemo;
|
|
3880
|
-
if (
|
|
4111
|
+
if (latestMemo?.nextPhase !== 1 /* NEGOTIATION */) {
|
|
3881
4112
|
throw new acpError_default("No request memo found");
|
|
3882
4113
|
}
|
|
3883
|
-
return
|
|
3884
|
-
}
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
const operations = [];
|
|
3897
|
-
operations.push(
|
|
3898
|
-
this.acpContractClient.createMemo(
|
|
3899
|
-
this.id,
|
|
3900
|
-
memoContent,
|
|
3901
|
-
0 /* MESSAGE */,
|
|
3902
|
-
true,
|
|
3903
|
-
5 /* REJECTED */
|
|
3904
|
-
)
|
|
3905
|
-
);
|
|
3906
|
-
return yield this.acpContractClient.handleOperation(operations);
|
|
3907
|
-
});
|
|
4114
|
+
return await latestMemo.sign(false, memoContent);
|
|
4115
|
+
}
|
|
4116
|
+
const operations = [];
|
|
4117
|
+
operations.push(
|
|
4118
|
+
this.acpContractClient.createMemo(
|
|
4119
|
+
this.id,
|
|
4120
|
+
memoContent,
|
|
4121
|
+
0 /* MESSAGE */,
|
|
4122
|
+
true,
|
|
4123
|
+
5 /* REJECTED */
|
|
4124
|
+
)
|
|
4125
|
+
);
|
|
4126
|
+
return await this.acpContractClient.handleOperation(operations);
|
|
3908
4127
|
}
|
|
3909
|
-
rejectPayable() {
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
this.
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
return yield this.acpContractClient.handleOperation(operations);
|
|
3935
|
-
});
|
|
4128
|
+
async rejectPayable(reason = "", amount, expiredAt = new Date(Date.now() + 1e3 * 60 * 5)) {
|
|
4129
|
+
const memoContent = `Job ${this.id} rejected. ${reason}`;
|
|
4130
|
+
const feeAmount = new FareAmount(0, this.acpContractClient.config.baseFare);
|
|
4131
|
+
const operations = [];
|
|
4132
|
+
operations.push(
|
|
4133
|
+
this.acpContractClient.approveAllowance(
|
|
4134
|
+
amount.amount,
|
|
4135
|
+
amount.fare.contractAddress
|
|
4136
|
+
)
|
|
4137
|
+
);
|
|
4138
|
+
operations.push(
|
|
4139
|
+
this.acpContractClient.createPayableMemo(
|
|
4140
|
+
this.id,
|
|
4141
|
+
memoContent,
|
|
4142
|
+
amount.amount,
|
|
4143
|
+
this.clientAddress,
|
|
4144
|
+
feeAmount.amount,
|
|
4145
|
+
0 /* NO_FEE */,
|
|
4146
|
+
5 /* REJECTED */,
|
|
4147
|
+
7 /* PAYABLE_TRANSFER */,
|
|
4148
|
+
expiredAt,
|
|
4149
|
+
amount.fare.contractAddress
|
|
4150
|
+
)
|
|
4151
|
+
);
|
|
4152
|
+
return await this.acpContractClient.handleOperation(operations);
|
|
3936
4153
|
}
|
|
3937
|
-
deliver(deliverable) {
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
);
|
|
3953
|
-
return yield this.acpContractClient.handleOperation(operations);
|
|
3954
|
-
});
|
|
4154
|
+
async deliver(deliverable) {
|
|
4155
|
+
if (this.latestMemo?.nextPhase !== 3 /* EVALUATION */) {
|
|
4156
|
+
throw new acpError_default("No transaction memo found");
|
|
4157
|
+
}
|
|
4158
|
+
const operations = [];
|
|
4159
|
+
operations.push(
|
|
4160
|
+
this.acpContractClient.createMemo(
|
|
4161
|
+
this.id,
|
|
4162
|
+
preparePayload(deliverable),
|
|
4163
|
+
0 /* MESSAGE */,
|
|
4164
|
+
true,
|
|
4165
|
+
4 /* COMPLETED */
|
|
4166
|
+
)
|
|
4167
|
+
);
|
|
4168
|
+
return await this.acpContractClient.handleOperation(operations);
|
|
3955
4169
|
}
|
|
3956
|
-
deliverPayable(
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
this.
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
return yield this.acpContractClient.handleOperation(operations);
|
|
3985
|
-
});
|
|
4170
|
+
async deliverPayable(deliverable, amount, skipFee = false, expiredAt = new Date(Date.now() + 1e3 * 60 * 5)) {
|
|
4171
|
+
if (this.latestMemo?.nextPhase !== 3 /* EVALUATION */) {
|
|
4172
|
+
throw new acpError_default("No transaction memo found");
|
|
4173
|
+
}
|
|
4174
|
+
const operations = [];
|
|
4175
|
+
operations.push(
|
|
4176
|
+
this.acpContractClient.approveAllowance(
|
|
4177
|
+
amount.amount,
|
|
4178
|
+
amount.fare.contractAddress
|
|
4179
|
+
)
|
|
4180
|
+
);
|
|
4181
|
+
const feeAmount = new FareAmount(0, this.acpContractClient.config.baseFare);
|
|
4182
|
+
const isPercentagePricing = this.priceType === "percentage" /* PERCENTAGE */ && !skipFee;
|
|
4183
|
+
operations.push(
|
|
4184
|
+
this.acpContractClient.createPayableMemo(
|
|
4185
|
+
this.id,
|
|
4186
|
+
preparePayload(deliverable),
|
|
4187
|
+
amount.amount,
|
|
4188
|
+
this.clientAddress,
|
|
4189
|
+
isPercentagePricing ? BigInt(Math.round(this.priceValue * 1e4)) : feeAmount.amount,
|
|
4190
|
+
isPercentagePricing ? 3 /* PERCENTAGE_FEE */ : 0 /* NO_FEE */,
|
|
4191
|
+
4 /* COMPLETED */,
|
|
4192
|
+
7 /* PAYABLE_TRANSFER */,
|
|
4193
|
+
expiredAt,
|
|
4194
|
+
amount.fare.contractAddress
|
|
4195
|
+
)
|
|
4196
|
+
);
|
|
4197
|
+
return await this.acpContractClient.handleOperation(operations);
|
|
3986
4198
|
}
|
|
3987
|
-
evaluate(accept, reason) {
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
const memo = this.latestMemo;
|
|
3994
|
-
yield memo.sign(accept, reason);
|
|
3995
|
-
});
|
|
4199
|
+
async evaluate(accept, reason) {
|
|
4200
|
+
if (this.latestMemo?.nextPhase !== 4 /* COMPLETED */) {
|
|
4201
|
+
throw new acpError_default("No evaluation memo found");
|
|
4202
|
+
}
|
|
4203
|
+
const memo = this.latestMemo;
|
|
4204
|
+
await memo.sign(accept, reason);
|
|
3996
4205
|
}
|
|
3997
|
-
createNotification(content) {
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
this.
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
return yield this.acpContractClient.handleOperation(operations);
|
|
4010
|
-
});
|
|
4206
|
+
async createNotification(content) {
|
|
4207
|
+
const operations = [];
|
|
4208
|
+
operations.push(
|
|
4209
|
+
this.acpContractClient.createMemo(
|
|
4210
|
+
this.id,
|
|
4211
|
+
content,
|
|
4212
|
+
9 /* NOTIFICATION */,
|
|
4213
|
+
true,
|
|
4214
|
+
4 /* COMPLETED */
|
|
4215
|
+
)
|
|
4216
|
+
);
|
|
4217
|
+
return await this.acpContractClient.handleOperation(operations);
|
|
4011
4218
|
}
|
|
4012
|
-
createPayableNotification(
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
});
|
|
4219
|
+
async createPayableNotification(content, amount, skipFee = false, expiredAt = new Date(Date.now() + 1e3 * 60 * 5)) {
|
|
4220
|
+
const operations = [];
|
|
4221
|
+
operations.push(
|
|
4222
|
+
this.acpContractClient.approveAllowance(
|
|
4223
|
+
amount.amount,
|
|
4224
|
+
amount.fare.contractAddress
|
|
4225
|
+
)
|
|
4226
|
+
);
|
|
4227
|
+
const feeAmount = new FareAmount(0, this.acpContractClient.config.baseFare);
|
|
4228
|
+
const isPercentagePricing = this.priceType === "percentage" /* PERCENTAGE */ && !skipFee;
|
|
4229
|
+
operations.push(
|
|
4230
|
+
this.acpContractClient.createPayableMemo(
|
|
4231
|
+
this.id,
|
|
4232
|
+
content,
|
|
4233
|
+
amount.amount,
|
|
4234
|
+
this.clientAddress,
|
|
4235
|
+
isPercentagePricing ? BigInt(Math.round(this.priceValue * 1e4)) : feeAmount.amount,
|
|
4236
|
+
isPercentagePricing ? 3 /* PERCENTAGE_FEE */ : 0 /* NO_FEE */,
|
|
4237
|
+
4 /* COMPLETED */,
|
|
4238
|
+
10 /* PAYABLE_NOTIFICATION */,
|
|
4239
|
+
expiredAt,
|
|
4240
|
+
amount.fare.contractAddress
|
|
4241
|
+
)
|
|
4242
|
+
);
|
|
4243
|
+
return await this.acpContractClient.handleOperation(operations);
|
|
4038
4244
|
}
|
|
4039
|
-
performX402Payment(budget) {
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4245
|
+
async performX402Payment(budget) {
|
|
4246
|
+
const paymentUrl = "/acp-budget";
|
|
4247
|
+
const x402PayableREquirements = await this.acpContractClient.performX402Request(
|
|
4248
|
+
paymentUrl,
|
|
4249
|
+
this.acpContractClient.getAcpVersion(),
|
|
4250
|
+
budget.toString()
|
|
4251
|
+
);
|
|
4252
|
+
if (!x402PayableREquirements.isPaymentRequired) {
|
|
4253
|
+
return;
|
|
4254
|
+
}
|
|
4255
|
+
if (!x402PayableREquirements.data.accepts.length) {
|
|
4256
|
+
throw new acpError_default("No X402 payment requirements found");
|
|
4257
|
+
}
|
|
4258
|
+
const requirement = x402PayableREquirements.data.accepts[0];
|
|
4259
|
+
const { encodedPayment, signature, message } = await this.acpContractClient.generateX402Payment(
|
|
4260
|
+
{
|
|
4261
|
+
to: requirement.payTo,
|
|
4262
|
+
value: Number(requirement.maxAmountRequired),
|
|
4263
|
+
maxTimeoutSeconds: requirement.maxTimeoutSeconds,
|
|
4264
|
+
asset: requirement.asset
|
|
4265
|
+
},
|
|
4266
|
+
x402PayableREquirements.data
|
|
4267
|
+
);
|
|
4268
|
+
await this.acpContractClient.updateJobX402Nonce(this.id, message.nonce);
|
|
4269
|
+
const x402Response = await this.acpContractClient.performX402Request(
|
|
4270
|
+
paymentUrl,
|
|
4271
|
+
this.acpContractClient.getAcpVersion(),
|
|
4272
|
+
budget.toString(),
|
|
4273
|
+
encodedPayment
|
|
4274
|
+
);
|
|
4275
|
+
if (x402Response.isPaymentRequired) {
|
|
4276
|
+
const operations = await this.acpContractClient.submitTransferWithAuthorization(
|
|
4277
|
+
message.from,
|
|
4278
|
+
message.to,
|
|
4279
|
+
BigInt(message.value),
|
|
4280
|
+
BigInt(message.validAfter),
|
|
4281
|
+
BigInt(message.validBefore),
|
|
4282
|
+
message.nonce,
|
|
4283
|
+
signature
|
|
4069
4284
|
);
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
yield this.acpContractClient.handleOperation(operations);
|
|
4285
|
+
await this.acpContractClient.handleOperation(operations);
|
|
4286
|
+
}
|
|
4287
|
+
let waitMs = 2e3;
|
|
4288
|
+
const maxWaitMs = 3e4;
|
|
4289
|
+
let iterationCount = 0;
|
|
4290
|
+
const maxIterations = 10;
|
|
4291
|
+
while (true) {
|
|
4292
|
+
const x402PaymentDetails = await this.acpContractClient.getX402PaymentDetails(this.id);
|
|
4293
|
+
if (x402PaymentDetails.isBudgetReceived) {
|
|
4294
|
+
break;
|
|
4081
4295
|
}
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
const maxIterations = 10;
|
|
4086
|
-
while (true) {
|
|
4087
|
-
const x402PaymentDetails = yield this.acpContractClient.getX402PaymentDetails(this.id);
|
|
4088
|
-
if (x402PaymentDetails.isBudgetReceived) {
|
|
4089
|
-
break;
|
|
4090
|
-
}
|
|
4091
|
-
iterationCount++;
|
|
4092
|
-
if (iterationCount >= maxIterations) {
|
|
4093
|
-
throw new acpError_default("X402 payment timed out");
|
|
4094
|
-
}
|
|
4095
|
-
yield new Promise((resolve) => setTimeout(resolve, waitMs));
|
|
4096
|
-
waitMs = Math.min(waitMs * 2, maxWaitMs);
|
|
4296
|
+
iterationCount++;
|
|
4297
|
+
if (iterationCount >= maxIterations) {
|
|
4298
|
+
throw new acpError_default("X402 payment timed out");
|
|
4097
4299
|
}
|
|
4098
|
-
|
|
4300
|
+
await new Promise((resolve) => setTimeout(resolve, waitMs));
|
|
4301
|
+
waitMs = Math.min(waitMs * 2, maxWaitMs);
|
|
4302
|
+
}
|
|
4099
4303
|
}
|
|
4100
4304
|
};
|
|
4101
4305
|
var acpJob_default = AcpJob;
|
|
@@ -4122,28 +4326,23 @@ var AcpMemo = class {
|
|
|
4122
4326
|
this.structuredContent = tryParseJson(this.content) || void 0;
|
|
4123
4327
|
}
|
|
4124
4328
|
get payloadType() {
|
|
4125
|
-
|
|
4126
|
-
return (_a = this.structuredContent) == null ? void 0 : _a.type;
|
|
4329
|
+
return this.structuredContent?.type;
|
|
4127
4330
|
}
|
|
4128
4331
|
getStructuredContent() {
|
|
4129
4332
|
return this.structuredContent;
|
|
4130
4333
|
}
|
|
4131
|
-
create(jobId, isSecured = true) {
|
|
4132
|
-
return
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
);
|
|
4140
|
-
});
|
|
4334
|
+
async create(jobId, isSecured = true) {
|
|
4335
|
+
return await this.contractClient.createMemo(
|
|
4336
|
+
jobId,
|
|
4337
|
+
this.content,
|
|
4338
|
+
this.type,
|
|
4339
|
+
isSecured,
|
|
4340
|
+
this.nextPhase
|
|
4341
|
+
);
|
|
4141
4342
|
}
|
|
4142
|
-
sign(approved, reason) {
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
return yield this.contractClient.handleOperation([payload]);
|
|
4146
|
-
});
|
|
4343
|
+
async sign(approved, reason) {
|
|
4344
|
+
const payload = this.contractClient.signMemo(this.id, approved, reason);
|
|
4345
|
+
return await this.contractClient.handleOperation([payload]);
|
|
4147
4346
|
}
|
|
4148
4347
|
};
|
|
4149
4348
|
var acpMemo_default = AcpMemo;
|
|
@@ -4157,14 +4356,12 @@ var AcpAccount = class {
|
|
|
4157
4356
|
this.providerAddress = providerAddress;
|
|
4158
4357
|
this.metadata = metadata;
|
|
4159
4358
|
}
|
|
4160
|
-
updateMetadata(metadata) {
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
return hash;
|
|
4167
|
-
});
|
|
4359
|
+
async updateMetadata(metadata) {
|
|
4360
|
+
const hash = await this.contractClient.updateAccountMetadata(
|
|
4361
|
+
this.id,
|
|
4362
|
+
JSON.stringify(metadata)
|
|
4363
|
+
);
|
|
4364
|
+
return hash;
|
|
4168
4365
|
}
|
|
4169
4366
|
};
|
|
4170
4367
|
|
|
@@ -4176,8 +4373,8 @@ var AcpClient = class {
|
|
|
4176
4373
|
if (this.contractClients.length === 0) {
|
|
4177
4374
|
throw new acpError_default("ACP contract client is required");
|
|
4178
4375
|
}
|
|
4179
|
-
this.contractClients.
|
|
4180
|
-
if (client.
|
|
4376
|
+
this.contractClients.forEach((client) => {
|
|
4377
|
+
if (client.walletAddress !== this.contractClients[0].walletAddress) {
|
|
4181
4378
|
throw new acpError_default(
|
|
4182
4379
|
"All contract clients must have the same agent wallet address"
|
|
4183
4380
|
);
|
|
@@ -4185,7 +4382,7 @@ var AcpClient = class {
|
|
|
4185
4382
|
});
|
|
4186
4383
|
this.onNewTask = options.onNewTask;
|
|
4187
4384
|
this.onEvaluate = options.onEvaluate || this.defaultOnEvaluate;
|
|
4188
|
-
this.init();
|
|
4385
|
+
this.init(options.skipSocketConnection);
|
|
4189
4386
|
}
|
|
4190
4387
|
contractClientByAddress(address) {
|
|
4191
4388
|
if (!address) {
|
|
@@ -4205,282 +4402,48 @@ var AcpClient = class {
|
|
|
4205
4402
|
get acpUrl() {
|
|
4206
4403
|
return this.acpContractClient.config.acpUrl;
|
|
4207
4404
|
}
|
|
4208
|
-
defaultOnEvaluate(job) {
|
|
4209
|
-
|
|
4210
|
-
yield job.evaluate(true, "Evaluated by default");
|
|
4211
|
-
});
|
|
4405
|
+
async defaultOnEvaluate(job) {
|
|
4406
|
+
await job.evaluate(true, "Evaluated by default");
|
|
4212
4407
|
}
|
|
4213
4408
|
get walletAddress() {
|
|
4214
|
-
if (Array.isArray(this.acpContractClient)) {
|
|
4215
|
-
return this.acpContractClient[0].walletAddress;
|
|
4216
|
-
}
|
|
4217
4409
|
return this.acpContractClient.walletAddress;
|
|
4218
4410
|
}
|
|
4219
|
-
init() {
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
}
|
|
4233
|
-
|
|
4234
|
-
console.log("Joined ACP Room");
|
|
4235
|
-
callback(true);
|
|
4236
|
-
});
|
|
4237
|
-
socket.on(
|
|
4238
|
-
"onEvaluate" /* ON_EVALUATE */,
|
|
4239
|
-
(data, callback) => __async(this, null, function* () {
|
|
4240
|
-
callback(true);
|
|
4241
|
-
if (this.onEvaluate) {
|
|
4242
|
-
const job = new acpJob_default(
|
|
4243
|
-
this,
|
|
4244
|
-
data.id,
|
|
4245
|
-
data.clientAddress,
|
|
4246
|
-
data.providerAddress,
|
|
4247
|
-
data.evaluatorAddress,
|
|
4248
|
-
data.price,
|
|
4249
|
-
data.priceTokenAddress,
|
|
4250
|
-
data.memos.map((memo) => {
|
|
4251
|
-
return new acpMemo_default(
|
|
4252
|
-
this.contractClientByAddress(data.contractAddress),
|
|
4253
|
-
memo.id,
|
|
4254
|
-
memo.memoType,
|
|
4255
|
-
memo.content,
|
|
4256
|
-
memo.nextPhase,
|
|
4257
|
-
memo.status,
|
|
4258
|
-
memo.senderAddress,
|
|
4259
|
-
memo.signedReason,
|
|
4260
|
-
memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
|
|
4261
|
-
memo.payableDetails,
|
|
4262
|
-
memo.txHash,
|
|
4263
|
-
memo.signedTxHash
|
|
4264
|
-
);
|
|
4265
|
-
}),
|
|
4266
|
-
data.phase,
|
|
4267
|
-
data.context,
|
|
4268
|
-
data.contractAddress,
|
|
4269
|
-
data.netPayableAmount
|
|
4270
|
-
);
|
|
4271
|
-
this.onEvaluate(job);
|
|
4272
|
-
}
|
|
4273
|
-
})
|
|
4274
|
-
);
|
|
4275
|
-
socket.on(
|
|
4276
|
-
"onNewTask" /* ON_NEW_TASK */,
|
|
4277
|
-
(data, callback) => __async(this, null, function* () {
|
|
4278
|
-
callback(true);
|
|
4279
|
-
if (this.onNewTask) {
|
|
4280
|
-
const job = new acpJob_default(
|
|
4281
|
-
this,
|
|
4282
|
-
data.id,
|
|
4283
|
-
data.clientAddress,
|
|
4284
|
-
data.providerAddress,
|
|
4285
|
-
data.evaluatorAddress,
|
|
4286
|
-
data.price,
|
|
4287
|
-
data.priceTokenAddress,
|
|
4288
|
-
data.memos.map((memo) => {
|
|
4289
|
-
return new acpMemo_default(
|
|
4290
|
-
this.contractClientByAddress(data.contractAddress),
|
|
4291
|
-
memo.id,
|
|
4292
|
-
memo.memoType,
|
|
4293
|
-
memo.content,
|
|
4294
|
-
memo.nextPhase,
|
|
4295
|
-
memo.status,
|
|
4296
|
-
memo.senderAddress,
|
|
4297
|
-
memo.signedReason,
|
|
4298
|
-
memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
|
|
4299
|
-
memo.payableDetails,
|
|
4300
|
-
memo.txHash,
|
|
4301
|
-
memo.signedTxHash
|
|
4302
|
-
);
|
|
4303
|
-
}),
|
|
4304
|
-
data.phase,
|
|
4305
|
-
data.context,
|
|
4306
|
-
data.contractAddress,
|
|
4307
|
-
data.netPayableAmount
|
|
4308
|
-
);
|
|
4309
|
-
this.onNewTask(
|
|
4310
|
-
job,
|
|
4311
|
-
job.memos.find((m) => m.id == data.memoToSign)
|
|
4312
|
-
);
|
|
4313
|
-
}
|
|
4314
|
-
})
|
|
4315
|
-
);
|
|
4316
|
-
const cleanup = () => __async(this, null, function* () {
|
|
4317
|
-
if (socket) {
|
|
4318
|
-
socket.disconnect();
|
|
4319
|
-
}
|
|
4320
|
-
process.exit(0);
|
|
4321
|
-
});
|
|
4322
|
-
process.on("SIGINT", cleanup);
|
|
4323
|
-
process.on("SIGTERM", cleanup);
|
|
4324
|
-
});
|
|
4325
|
-
}
|
|
4326
|
-
browseAgents(keyword, options) {
|
|
4327
|
-
return __async(this, null, function* () {
|
|
4328
|
-
let { cluster, sort_by, top_k, graduationStatus, onlineStatus } = options;
|
|
4329
|
-
top_k = top_k != null ? top_k : 5;
|
|
4330
|
-
let url = `${this.acpUrl}/api/agents/v4/search?search=${keyword}`;
|
|
4331
|
-
if (sort_by && sort_by.length > 0) {
|
|
4332
|
-
url += `&sortBy=${sort_by.map((s) => s).join(",")}`;
|
|
4333
|
-
}
|
|
4334
|
-
if (top_k) {
|
|
4335
|
-
url += `&top_k=${top_k}`;
|
|
4336
|
-
}
|
|
4337
|
-
if (this.walletAddress) {
|
|
4338
|
-
url += `&walletAddressesToExclude=${this.walletAddress}`;
|
|
4339
|
-
}
|
|
4340
|
-
if (cluster) {
|
|
4341
|
-
url += `&cluster=${cluster}`;
|
|
4342
|
-
}
|
|
4343
|
-
if (graduationStatus) {
|
|
4344
|
-
url += `&graduationStatus=${graduationStatus}`;
|
|
4345
|
-
}
|
|
4346
|
-
if (onlineStatus) {
|
|
4347
|
-
url += `&onlineStatus=${onlineStatus}`;
|
|
4348
|
-
}
|
|
4349
|
-
const response = yield fetch(url);
|
|
4350
|
-
const data = yield response.json();
|
|
4351
|
-
const availableContractClientAddresses = this.contractClients.map(
|
|
4352
|
-
(client) => client.contractAddress.toLowerCase()
|
|
4353
|
-
);
|
|
4354
|
-
return data.data.filter(
|
|
4355
|
-
(agent) => agent.walletAddress.toLowerCase() !== this.walletAddress.toLowerCase()
|
|
4356
|
-
).filter(
|
|
4357
|
-
(agent) => availableContractClientAddresses.includes(
|
|
4358
|
-
agent.contractAddress.toLowerCase()
|
|
4359
|
-
)
|
|
4360
|
-
).map((agent) => {
|
|
4361
|
-
const acpContractClient = this.contractClients.find(
|
|
4362
|
-
(client) => client.contractAddress.toLowerCase() === agent.contractAddress.toLowerCase()
|
|
4363
|
-
);
|
|
4364
|
-
if (!acpContractClient) {
|
|
4365
|
-
throw new acpError_default("ACP contract client not found");
|
|
4366
|
-
}
|
|
4367
|
-
return {
|
|
4368
|
-
id: agent.id,
|
|
4369
|
-
name: agent.name,
|
|
4370
|
-
description: agent.description,
|
|
4371
|
-
jobOfferings: agent.jobs.map((jobs) => {
|
|
4372
|
-
return new acpJobOffering_default(
|
|
4373
|
-
this,
|
|
4374
|
-
acpContractClient,
|
|
4375
|
-
agent.walletAddress,
|
|
4376
|
-
jobs.name,
|
|
4377
|
-
jobs.priceV2.value,
|
|
4378
|
-
jobs.priceV2.type,
|
|
4379
|
-
jobs.requirement
|
|
4380
|
-
);
|
|
4381
|
-
}),
|
|
4382
|
-
contractAddress: agent.contractAddress,
|
|
4383
|
-
twitterHandle: agent.twitterHandle,
|
|
4384
|
-
walletAddress: agent.walletAddress,
|
|
4385
|
-
metrics: agent.metrics,
|
|
4386
|
-
resource: agent.resources
|
|
4387
|
-
};
|
|
4388
|
-
});
|
|
4411
|
+
async init(skipSocketConnection = false) {
|
|
4412
|
+
if (skipSocketConnection) {
|
|
4413
|
+
return;
|
|
4414
|
+
}
|
|
4415
|
+
const socket = io(this.acpUrl, {
|
|
4416
|
+
auth: {
|
|
4417
|
+
walletAddress: this.walletAddress
|
|
4418
|
+
},
|
|
4419
|
+
extraHeaders: {
|
|
4420
|
+
"x-sdk-version": version,
|
|
4421
|
+
"x-sdk-language": "node",
|
|
4422
|
+
"x-contract-address": this.contractClients[0].contractAddress
|
|
4423
|
+
// always prioritize the first client
|
|
4424
|
+
},
|
|
4425
|
+
transports: ["websocket"]
|
|
4389
4426
|
});
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
if (providerAddress === this.walletAddress) {
|
|
4394
|
-
throw new acpError_default(
|
|
4395
|
-
"Provider address cannot be the same as the client address"
|
|
4396
|
-
);
|
|
4397
|
-
}
|
|
4398
|
-
const account = yield this.getByClientAndProvider(
|
|
4399
|
-
this.walletAddress,
|
|
4400
|
-
providerAddress,
|
|
4401
|
-
this.acpContractClient
|
|
4402
|
-
);
|
|
4403
|
-
const isV1 = [
|
|
4404
|
-
baseSepoliaAcpConfig.contractAddress,
|
|
4405
|
-
baseSepoliaAcpX402Config.contractAddress,
|
|
4406
|
-
baseAcpConfig.contractAddress,
|
|
4407
|
-
baseAcpX402Config.contractAddress
|
|
4408
|
-
].includes(this.acpContractClient.config.contractAddress);
|
|
4409
|
-
const defaultEvaluatorAddress = isV1 && !evaluatorAddress ? this.walletAddress : zeroAddress2;
|
|
4410
|
-
const chainId = this.acpContractClient.config.chain.id;
|
|
4411
|
-
const isUsdcPaymentToken = USDC_TOKEN_ADDRESS[chainId].toLowerCase() === fareAmount.fare.contractAddress.toLowerCase();
|
|
4412
|
-
const isX402Job = this.acpContractClient.config.x402Config && isUsdcPaymentToken;
|
|
4413
|
-
const createJobPayload = isV1 || !account ? this.acpContractClient.createJob(
|
|
4414
|
-
providerAddress,
|
|
4415
|
-
evaluatorAddress || defaultEvaluatorAddress,
|
|
4416
|
-
expiredAt,
|
|
4417
|
-
fareAmount.fare.contractAddress,
|
|
4418
|
-
fareAmount.amount,
|
|
4419
|
-
"",
|
|
4420
|
-
isX402Job
|
|
4421
|
-
) : this.acpContractClient.createJobWithAccount(
|
|
4422
|
-
account.id,
|
|
4423
|
-
evaluatorAddress || defaultEvaluatorAddress,
|
|
4424
|
-
fareAmount.amount,
|
|
4425
|
-
fareAmount.fare.contractAddress,
|
|
4426
|
-
expiredAt,
|
|
4427
|
-
isX402Job
|
|
4428
|
-
);
|
|
4429
|
-
const { userOpHash } = yield this.acpContractClient.handleOperation([
|
|
4430
|
-
createJobPayload
|
|
4431
|
-
]);
|
|
4432
|
-
const jobId = yield this.acpContractClient.getJobId(
|
|
4433
|
-
userOpHash,
|
|
4434
|
-
this.walletAddress,
|
|
4435
|
-
providerAddress
|
|
4436
|
-
);
|
|
4437
|
-
const payloads = [];
|
|
4438
|
-
const setBudgetWithPaymentTokenPayload = this.acpContractClient.setBudgetWithPaymentToken(
|
|
4439
|
-
jobId,
|
|
4440
|
-
fareAmount.amount,
|
|
4441
|
-
fareAmount.fare.contractAddress
|
|
4442
|
-
);
|
|
4443
|
-
if (setBudgetWithPaymentTokenPayload) {
|
|
4444
|
-
payloads.push(setBudgetWithPaymentTokenPayload);
|
|
4445
|
-
}
|
|
4446
|
-
payloads.push(
|
|
4447
|
-
this.acpContractClient.createMemo(
|
|
4448
|
-
jobId,
|
|
4449
|
-
preparePayload(serviceRequirement),
|
|
4450
|
-
0 /* MESSAGE */,
|
|
4451
|
-
true,
|
|
4452
|
-
1 /* NEGOTIATION */
|
|
4453
|
-
)
|
|
4454
|
-
);
|
|
4455
|
-
yield this.acpContractClient.handleOperation(payloads);
|
|
4456
|
-
return jobId;
|
|
4427
|
+
socket.on("roomJoined" /* ROOM_JOINED */, (_, callback) => {
|
|
4428
|
+
console.log("Joined ACP Room");
|
|
4429
|
+
callback(true);
|
|
4457
4430
|
});
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
headers: {
|
|
4465
|
-
"wallet-address": this.walletAddress
|
|
4466
|
-
}
|
|
4467
|
-
});
|
|
4468
|
-
const data = yield response.json();
|
|
4469
|
-
if (data.error) {
|
|
4470
|
-
throw new acpError_default(data.error.message);
|
|
4471
|
-
}
|
|
4472
|
-
return data.data.map((job) => {
|
|
4473
|
-
return new acpJob_default(
|
|
4431
|
+
socket.on(
|
|
4432
|
+
"onEvaluate" /* ON_EVALUATE */,
|
|
4433
|
+
async (data, callback) => {
|
|
4434
|
+
callback(true);
|
|
4435
|
+
if (this.onEvaluate) {
|
|
4436
|
+
const job = new acpJob_default(
|
|
4474
4437
|
this,
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4438
|
+
data.id,
|
|
4439
|
+
data.clientAddress,
|
|
4440
|
+
data.providerAddress,
|
|
4441
|
+
data.evaluatorAddress,
|
|
4442
|
+
data.price,
|
|
4443
|
+
data.priceTokenAddress,
|
|
4444
|
+
data.memos.map((memo) => {
|
|
4482
4445
|
return new acpMemo_default(
|
|
4483
|
-
this.contractClientByAddress(
|
|
4446
|
+
this.contractClientByAddress(data.contractAddress),
|
|
4484
4447
|
memo.id,
|
|
4485
4448
|
memo.memoType,
|
|
4486
4449
|
memo.content,
|
|
@@ -4494,42 +4457,31 @@ var AcpClient = class {
|
|
|
4494
4457
|
memo.signedTxHash
|
|
4495
4458
|
);
|
|
4496
4459
|
}),
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4460
|
+
data.phase,
|
|
4461
|
+
data.context,
|
|
4462
|
+
data.contractAddress,
|
|
4463
|
+
data.netPayableAmount
|
|
4501
4464
|
);
|
|
4502
|
-
|
|
4503
|
-
} catch (error) {
|
|
4504
|
-
throw new acpError_default("Failed to get active jobs", error);
|
|
4505
|
-
}
|
|
4506
|
-
});
|
|
4507
|
-
}
|
|
4508
|
-
getPendingMemoJobs(page = 1, pageSize = 10) {
|
|
4509
|
-
return __async(this, null, function* () {
|
|
4510
|
-
let url = `${this.acpUrl}/api/jobs/pending-memos?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
|
|
4511
|
-
try {
|
|
4512
|
-
const response = yield fetch(url, {
|
|
4513
|
-
headers: {
|
|
4514
|
-
"wallet-address": this.acpContractClient.walletAddress
|
|
4515
|
-
}
|
|
4516
|
-
});
|
|
4517
|
-
const data = yield response.json();
|
|
4518
|
-
if (data.error) {
|
|
4519
|
-
throw new acpError_default(data.error.message);
|
|
4465
|
+
this.onEvaluate(job);
|
|
4520
4466
|
}
|
|
4521
|
-
|
|
4522
|
-
|
|
4467
|
+
}
|
|
4468
|
+
);
|
|
4469
|
+
socket.on(
|
|
4470
|
+
"onNewTask" /* ON_NEW_TASK */,
|
|
4471
|
+
async (data, callback) => {
|
|
4472
|
+
callback(true);
|
|
4473
|
+
if (this.onNewTask) {
|
|
4474
|
+
const job = new acpJob_default(
|
|
4523
4475
|
this,
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4476
|
+
data.id,
|
|
4477
|
+
data.clientAddress,
|
|
4478
|
+
data.providerAddress,
|
|
4479
|
+
data.evaluatorAddress,
|
|
4480
|
+
data.price,
|
|
4481
|
+
data.priceTokenAddress,
|
|
4482
|
+
data.memos.map((memo) => {
|
|
4531
4483
|
return new acpMemo_default(
|
|
4532
|
-
this.contractClientByAddress(
|
|
4484
|
+
this.contractClientByAddress(data.contractAddress),
|
|
4533
4485
|
memo.id,
|
|
4534
4486
|
memo.memoType,
|
|
4535
4487
|
memo.content,
|
|
@@ -4538,137 +4490,274 @@ var AcpClient = class {
|
|
|
4538
4490
|
memo.senderAddress,
|
|
4539
4491
|
memo.signedReason,
|
|
4540
4492
|
memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
|
|
4541
|
-
|
|
4493
|
+
memo.payableDetails,
|
|
4542
4494
|
memo.txHash,
|
|
4543
4495
|
memo.signedTxHash
|
|
4544
4496
|
);
|
|
4545
4497
|
}),
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4498
|
+
data.phase,
|
|
4499
|
+
data.context,
|
|
4500
|
+
data.contractAddress,
|
|
4501
|
+
data.netPayableAmount
|
|
4550
4502
|
);
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4503
|
+
this.onNewTask(
|
|
4504
|
+
job,
|
|
4505
|
+
job.memos.find((m) => m.id == data.memoToSign)
|
|
4506
|
+
);
|
|
4507
|
+
}
|
|
4554
4508
|
}
|
|
4555
|
-
|
|
4509
|
+
);
|
|
4510
|
+
const cleanup = async () => {
|
|
4511
|
+
if (socket) {
|
|
4512
|
+
socket.disconnect();
|
|
4513
|
+
}
|
|
4514
|
+
process.exit(0);
|
|
4515
|
+
};
|
|
4516
|
+
process.on("SIGINT", cleanup);
|
|
4517
|
+
process.on("SIGTERM", cleanup);
|
|
4556
4518
|
}
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4519
|
+
async browseAgents(keyword, options) {
|
|
4520
|
+
let { cluster, sort_by, top_k, graduationStatus, onlineStatus } = options;
|
|
4521
|
+
top_k = top_k ?? 5;
|
|
4522
|
+
let url = `${this.acpUrl}/api/agents/v4/search?search=${keyword}`;
|
|
4523
|
+
if (sort_by && sort_by.length > 0) {
|
|
4524
|
+
url += `&sortBy=${sort_by.map((s) => s).join(",")}`;
|
|
4525
|
+
}
|
|
4526
|
+
if (top_k) {
|
|
4527
|
+
url += `&top_k=${top_k}`;
|
|
4528
|
+
}
|
|
4529
|
+
if (this.walletAddress) {
|
|
4530
|
+
url += `&walletAddressesToExclude=${this.walletAddress}`;
|
|
4531
|
+
}
|
|
4532
|
+
if (cluster) {
|
|
4533
|
+
url += `&cluster=${cluster}`;
|
|
4534
|
+
}
|
|
4535
|
+
if (graduationStatus) {
|
|
4536
|
+
url += `&graduationStatus=${graduationStatus}`;
|
|
4537
|
+
}
|
|
4538
|
+
if (onlineStatus) {
|
|
4539
|
+
url += `&onlineStatus=${onlineStatus}`;
|
|
4540
|
+
}
|
|
4541
|
+
const response = await fetch(url);
|
|
4542
|
+
const data = await response.json();
|
|
4543
|
+
const availableContractClientAddresses = this.contractClients.map(
|
|
4544
|
+
(client) => client.contractAddress.toLowerCase()
|
|
4545
|
+
);
|
|
4546
|
+
return data.data.filter(
|
|
4547
|
+
(agent) => agent.walletAddress.toLowerCase() !== this.walletAddress.toLowerCase()
|
|
4548
|
+
).filter(
|
|
4549
|
+
(agent) => availableContractClientAddresses.includes(
|
|
4550
|
+
agent.contractAddress.toLowerCase()
|
|
4551
|
+
)
|
|
4552
|
+
).map((agent) => {
|
|
4553
|
+
const acpContractClient = this.contractClients.find(
|
|
4554
|
+
(client) => client.contractAddress.toLowerCase() === agent.contractAddress.toLowerCase()
|
|
4555
|
+
);
|
|
4556
|
+
if (!acpContractClient) {
|
|
4557
|
+
throw new acpError_default("ACP contract client not found");
|
|
4558
|
+
}
|
|
4559
|
+
return {
|
|
4560
|
+
id: agent.id,
|
|
4561
|
+
name: agent.name,
|
|
4562
|
+
description: agent.description,
|
|
4563
|
+
jobOfferings: agent.jobs.map((jobs) => {
|
|
4564
|
+
return new acpJobOffering_default(
|
|
4572
4565
|
this,
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
job.memos.map((memo) => {
|
|
4580
|
-
return new acpMemo_default(
|
|
4581
|
-
this.contractClientByAddress(job.contractAddress),
|
|
4582
|
-
memo.id,
|
|
4583
|
-
memo.memoType,
|
|
4584
|
-
memo.content,
|
|
4585
|
-
memo.nextPhase,
|
|
4586
|
-
memo.status,
|
|
4587
|
-
memo.senderAddress,
|
|
4588
|
-
memo.signedReason,
|
|
4589
|
-
memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
|
|
4590
|
-
memo.payableDetails,
|
|
4591
|
-
memo.txHash,
|
|
4592
|
-
memo.signedTxHash
|
|
4593
|
-
);
|
|
4594
|
-
}),
|
|
4595
|
-
job.phase,
|
|
4596
|
-
job.context,
|
|
4597
|
-
job.contractAddress,
|
|
4598
|
-
job.netPayableAmount
|
|
4566
|
+
acpContractClient,
|
|
4567
|
+
agent.walletAddress,
|
|
4568
|
+
jobs.name,
|
|
4569
|
+
jobs.priceV2.value,
|
|
4570
|
+
jobs.priceV2.type,
|
|
4571
|
+
jobs.requirement
|
|
4599
4572
|
);
|
|
4600
|
-
})
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4573
|
+
}),
|
|
4574
|
+
contractAddress: agent.contractAddress,
|
|
4575
|
+
twitterHandle: agent.twitterHandle,
|
|
4576
|
+
walletAddress: agent.walletAddress,
|
|
4577
|
+
metrics: agent.metrics,
|
|
4578
|
+
resource: agent.resources
|
|
4579
|
+
};
|
|
4604
4580
|
});
|
|
4605
4581
|
}
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4582
|
+
async initiateJob(providerAddress, serviceRequirement, fareAmount, evaluatorAddress, expiredAt = new Date(Date.now() + 1e3 * 60 * 60 * 24)) {
|
|
4583
|
+
if (providerAddress === this.walletAddress) {
|
|
4584
|
+
throw new acpError_default(
|
|
4585
|
+
"Provider address cannot be the same as the client address"
|
|
4586
|
+
);
|
|
4587
|
+
}
|
|
4588
|
+
const account = await this.getByClientAndProvider(
|
|
4589
|
+
this.walletAddress,
|
|
4590
|
+
providerAddress,
|
|
4591
|
+
this.acpContractClient
|
|
4592
|
+
);
|
|
4593
|
+
const isV1 = [
|
|
4594
|
+
baseSepoliaAcpConfig.contractAddress,
|
|
4595
|
+
baseSepoliaAcpX402Config.contractAddress,
|
|
4596
|
+
baseAcpConfig.contractAddress,
|
|
4597
|
+
baseAcpX402Config.contractAddress
|
|
4598
|
+
].includes(this.acpContractClient.config.contractAddress);
|
|
4599
|
+
const defaultEvaluatorAddress = isV1 && !evaluatorAddress ? this.walletAddress : zeroAddress3;
|
|
4600
|
+
const chainId = this.acpContractClient.config.chain.id;
|
|
4601
|
+
const isUsdcPaymentToken = USDC_TOKEN_ADDRESS[chainId].toLowerCase() === fareAmount.fare.contractAddress.toLowerCase();
|
|
4602
|
+
const isX402Job = this.acpContractClient.config.x402Config && isUsdcPaymentToken;
|
|
4603
|
+
const createJobPayload = isV1 || !account ? this.acpContractClient.createJob(
|
|
4604
|
+
providerAddress,
|
|
4605
|
+
evaluatorAddress || defaultEvaluatorAddress,
|
|
4606
|
+
expiredAt,
|
|
4607
|
+
fareAmount.fare.contractAddress,
|
|
4608
|
+
fareAmount.amount,
|
|
4609
|
+
"",
|
|
4610
|
+
isX402Job
|
|
4611
|
+
) : this.acpContractClient.createJobWithAccount(
|
|
4612
|
+
account.id,
|
|
4613
|
+
evaluatorAddress || defaultEvaluatorAddress,
|
|
4614
|
+
fareAmount.amount,
|
|
4615
|
+
fareAmount.fare.contractAddress,
|
|
4616
|
+
expiredAt,
|
|
4617
|
+
isX402Job
|
|
4618
|
+
);
|
|
4619
|
+
const { userOpHash } = await this.acpContractClient.handleOperation([
|
|
4620
|
+
createJobPayload
|
|
4621
|
+
]);
|
|
4622
|
+
const jobId = await this.acpContractClient.getJobId(
|
|
4623
|
+
userOpHash,
|
|
4624
|
+
this.walletAddress,
|
|
4625
|
+
providerAddress
|
|
4626
|
+
);
|
|
4627
|
+
const payloads = [];
|
|
4628
|
+
const setBudgetWithPaymentTokenPayload = this.acpContractClient.setBudgetWithPaymentToken(
|
|
4629
|
+
jobId,
|
|
4630
|
+
fareAmount.amount,
|
|
4631
|
+
fareAmount.fare.contractAddress
|
|
4632
|
+
);
|
|
4633
|
+
if (setBudgetWithPaymentTokenPayload) {
|
|
4634
|
+
payloads.push(setBudgetWithPaymentTokenPayload);
|
|
4635
|
+
}
|
|
4636
|
+
payloads.push(
|
|
4637
|
+
this.acpContractClient.createMemo(
|
|
4638
|
+
jobId,
|
|
4639
|
+
preparePayload(serviceRequirement),
|
|
4640
|
+
0 /* MESSAGE */,
|
|
4641
|
+
true,
|
|
4642
|
+
1 /* NEGOTIATION */
|
|
4643
|
+
)
|
|
4644
|
+
);
|
|
4645
|
+
await this.acpContractClient.handleOperation(payloads);
|
|
4646
|
+
return jobId;
|
|
4647
|
+
}
|
|
4648
|
+
async getActiveJobs(page = 1, pageSize = 10) {
|
|
4649
|
+
let url = `${this.acpUrl}/api/jobs/active?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
|
|
4650
|
+
try {
|
|
4651
|
+
const response = await fetch(url, {
|
|
4652
|
+
headers: {
|
|
4653
|
+
"wallet-address": this.walletAddress
|
|
4618
4654
|
}
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
job.clientAddress,
|
|
4624
|
-
job.providerAddress,
|
|
4625
|
-
job.evaluatorAddress,
|
|
4626
|
-
job.price,
|
|
4627
|
-
job.priceTokenAddress,
|
|
4628
|
-
job.memos.map((memo) => {
|
|
4629
|
-
return new acpMemo_default(
|
|
4630
|
-
this.contractClientByAddress(job.contractAddress),
|
|
4631
|
-
memo.id,
|
|
4632
|
-
memo.memoType,
|
|
4633
|
-
memo.content,
|
|
4634
|
-
memo.nextPhase,
|
|
4635
|
-
memo.status,
|
|
4636
|
-
memo.senderAddress,
|
|
4637
|
-
memo.signedReason,
|
|
4638
|
-
memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
|
|
4639
|
-
memo.payableDetails,
|
|
4640
|
-
memo.txHash,
|
|
4641
|
-
memo.signedTxHash
|
|
4642
|
-
);
|
|
4643
|
-
}),
|
|
4644
|
-
job.phase,
|
|
4645
|
-
job.context,
|
|
4646
|
-
job.contractAddress,
|
|
4647
|
-
job.netPayableAmount
|
|
4648
|
-
);
|
|
4649
|
-
});
|
|
4650
|
-
} catch (error) {
|
|
4651
|
-
throw new acpError_default("Failed to get cancelled jobs", error);
|
|
4655
|
+
});
|
|
4656
|
+
const data = await response.json();
|
|
4657
|
+
if (data.error) {
|
|
4658
|
+
throw new acpError_default(data.error.message);
|
|
4652
4659
|
}
|
|
4653
|
-
|
|
4660
|
+
return data.data.map((job) => {
|
|
4661
|
+
return new acpJob_default(
|
|
4662
|
+
this,
|
|
4663
|
+
job.id,
|
|
4664
|
+
job.clientAddress,
|
|
4665
|
+
job.providerAddress,
|
|
4666
|
+
job.evaluatorAddress,
|
|
4667
|
+
job.price,
|
|
4668
|
+
job.priceTokenAddress,
|
|
4669
|
+
job.memos.map((memo) => {
|
|
4670
|
+
return new acpMemo_default(
|
|
4671
|
+
this.contractClientByAddress(job.contractAddress),
|
|
4672
|
+
memo.id,
|
|
4673
|
+
memo.memoType,
|
|
4674
|
+
memo.content,
|
|
4675
|
+
memo.nextPhase,
|
|
4676
|
+
memo.status,
|
|
4677
|
+
memo.senderAddress,
|
|
4678
|
+
memo.signedReason,
|
|
4679
|
+
memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
|
|
4680
|
+
memo.payableDetails,
|
|
4681
|
+
memo.txHash,
|
|
4682
|
+
memo.signedTxHash
|
|
4683
|
+
);
|
|
4684
|
+
}),
|
|
4685
|
+
job.phase,
|
|
4686
|
+
job.context,
|
|
4687
|
+
job.contractAddress,
|
|
4688
|
+
job.netPayableAmount
|
|
4689
|
+
);
|
|
4690
|
+
});
|
|
4691
|
+
} catch (error) {
|
|
4692
|
+
if (error instanceof acpError_default) {
|
|
4693
|
+
return error;
|
|
4694
|
+
}
|
|
4695
|
+
throw new acpError_default("Failed to get active jobs", error);
|
|
4696
|
+
}
|
|
4697
|
+
}
|
|
4698
|
+
async getPendingMemoJobs(page = 1, pageSize = 10) {
|
|
4699
|
+
let url = `${this.acpUrl}/api/jobs/pending-memos?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
|
|
4700
|
+
try {
|
|
4701
|
+
const response = await fetch(url, {
|
|
4702
|
+
headers: {
|
|
4703
|
+
"wallet-address": this.acpContractClient.walletAddress
|
|
4704
|
+
}
|
|
4705
|
+
});
|
|
4706
|
+
const data = await response.json();
|
|
4707
|
+
if (data.error) {
|
|
4708
|
+
throw new acpError_default(data.error.message);
|
|
4709
|
+
}
|
|
4710
|
+
return data.data.map((job) => {
|
|
4711
|
+
return new acpJob_default(
|
|
4712
|
+
this,
|
|
4713
|
+
job.id,
|
|
4714
|
+
job.clientAddress,
|
|
4715
|
+
job.providerAddress,
|
|
4716
|
+
job.evaluatorAddress,
|
|
4717
|
+
job.price,
|
|
4718
|
+
job.priceTokenAddress,
|
|
4719
|
+
job.memos.map((memo) => {
|
|
4720
|
+
return new acpMemo_default(
|
|
4721
|
+
this.contractClientByAddress(job.contractAddress),
|
|
4722
|
+
memo.id,
|
|
4723
|
+
memo.memoType,
|
|
4724
|
+
memo.content,
|
|
4725
|
+
memo.nextPhase,
|
|
4726
|
+
memo.status,
|
|
4727
|
+
memo.senderAddress,
|
|
4728
|
+
memo.signedReason,
|
|
4729
|
+
memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
|
|
4730
|
+
typeof memo.payableDetails === "string" ? tryParseJson(memo.payableDetails) || void 0 : memo.payableDetails,
|
|
4731
|
+
memo.txHash,
|
|
4732
|
+
memo.signedTxHash
|
|
4733
|
+
);
|
|
4734
|
+
}),
|
|
4735
|
+
job.phase,
|
|
4736
|
+
job.context,
|
|
4737
|
+
job.contractAddress,
|
|
4738
|
+
job.netPayableAmount
|
|
4739
|
+
);
|
|
4740
|
+
});
|
|
4741
|
+
} catch (error) {
|
|
4742
|
+
if (error instanceof acpError_default) {
|
|
4743
|
+
return error;
|
|
4744
|
+
}
|
|
4745
|
+
throw new acpError_default("Failed to get pending memo jobs", error);
|
|
4746
|
+
}
|
|
4654
4747
|
}
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
"wallet-address": this.acpContractClient.walletAddress
|
|
4662
|
-
}
|
|
4663
|
-
});
|
|
4664
|
-
const data = yield response.json();
|
|
4665
|
-
if (data.error) {
|
|
4666
|
-
throw new acpError_default(data.error.message);
|
|
4667
|
-
}
|
|
4668
|
-
const job = data.data;
|
|
4669
|
-
if (!job) {
|
|
4670
|
-
return;
|
|
4748
|
+
async getCompletedJobs(page = 1, pageSize = 10) {
|
|
4749
|
+
let url = `${this.acpUrl}/api/jobs/completed?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
|
|
4750
|
+
try {
|
|
4751
|
+
const response = await fetch(url, {
|
|
4752
|
+
headers: {
|
|
4753
|
+
"wallet-address": this.acpContractClient.walletAddress
|
|
4671
4754
|
}
|
|
4755
|
+
});
|
|
4756
|
+
const data = await response.json();
|
|
4757
|
+
if (data.error) {
|
|
4758
|
+
throw new acpError_default(data.error.message);
|
|
4759
|
+
}
|
|
4760
|
+
return data.data.map((job) => {
|
|
4672
4761
|
return new acpJob_default(
|
|
4673
4762
|
this,
|
|
4674
4763
|
job.id,
|
|
@@ -4698,100 +4787,200 @@ var AcpClient = class {
|
|
|
4698
4787
|
job.contractAddress,
|
|
4699
4788
|
job.netPayableAmount
|
|
4700
4789
|
);
|
|
4701
|
-
}
|
|
4702
|
-
|
|
4790
|
+
});
|
|
4791
|
+
} catch (error) {
|
|
4792
|
+
if (error instanceof acpError_default) {
|
|
4793
|
+
return error;
|
|
4703
4794
|
}
|
|
4704
|
-
|
|
4795
|
+
throw new acpError_default("Failed to get completed jobs", error);
|
|
4796
|
+
}
|
|
4705
4797
|
}
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
"wallet-address": this.walletAddress
|
|
4713
|
-
}
|
|
4714
|
-
});
|
|
4715
|
-
const data = yield response.json();
|
|
4716
|
-
if (data.error) {
|
|
4717
|
-
throw new acpError_default(data.error.message);
|
|
4718
|
-
}
|
|
4719
|
-
const memo = data.data;
|
|
4720
|
-
if (!memo) {
|
|
4721
|
-
return;
|
|
4798
|
+
async getCancelledJobs(page = 1, pageSize = 10) {
|
|
4799
|
+
let url = `${this.acpUrl}/api/jobs/cancelled?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
|
|
4800
|
+
try {
|
|
4801
|
+
const response = await fetch(url, {
|
|
4802
|
+
headers: {
|
|
4803
|
+
"wallet-address": this.walletAddress
|
|
4722
4804
|
}
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4805
|
+
});
|
|
4806
|
+
const data = await response.json();
|
|
4807
|
+
if (data.error) {
|
|
4808
|
+
throw new acpError_default(data.error.message);
|
|
4809
|
+
}
|
|
4810
|
+
return data.data.map((job) => {
|
|
4811
|
+
return new acpJob_default(
|
|
4812
|
+
this,
|
|
4813
|
+
job.id,
|
|
4814
|
+
job.clientAddress,
|
|
4815
|
+
job.providerAddress,
|
|
4816
|
+
job.evaluatorAddress,
|
|
4817
|
+
job.price,
|
|
4818
|
+
job.priceTokenAddress,
|
|
4819
|
+
job.memos.map((memo) => {
|
|
4820
|
+
return new acpMemo_default(
|
|
4821
|
+
this.contractClientByAddress(job.contractAddress),
|
|
4822
|
+
memo.id,
|
|
4823
|
+
memo.memoType,
|
|
4824
|
+
memo.content,
|
|
4825
|
+
memo.nextPhase,
|
|
4826
|
+
memo.status,
|
|
4827
|
+
memo.senderAddress,
|
|
4828
|
+
memo.signedReason,
|
|
4829
|
+
memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
|
|
4830
|
+
memo.payableDetails,
|
|
4831
|
+
memo.txHash,
|
|
4832
|
+
memo.signedTxHash
|
|
4833
|
+
);
|
|
4834
|
+
}),
|
|
4835
|
+
job.phase,
|
|
4836
|
+
job.context,
|
|
4837
|
+
job.contractAddress,
|
|
4838
|
+
job.netPayableAmount
|
|
4736
4839
|
);
|
|
4737
|
-
}
|
|
4738
|
-
|
|
4840
|
+
});
|
|
4841
|
+
} catch (error) {
|
|
4842
|
+
if (error instanceof Error) {
|
|
4843
|
+
return error;
|
|
4739
4844
|
}
|
|
4740
|
-
|
|
4845
|
+
throw new acpError_default("Failed to get cancelled jobs", error);
|
|
4846
|
+
}
|
|
4741
4847
|
}
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
const response =
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4848
|
+
async getJobById(jobId) {
|
|
4849
|
+
let url = `${this.acpUrl}/api/jobs/${jobId}`;
|
|
4850
|
+
try {
|
|
4851
|
+
const response = await fetch(url, {
|
|
4852
|
+
headers: {
|
|
4853
|
+
"wallet-address": this.acpContractClient.walletAddress
|
|
4854
|
+
}
|
|
4855
|
+
});
|
|
4856
|
+
const data = await response.json();
|
|
4857
|
+
if (data.error) {
|
|
4858
|
+
throw new acpError_default(data.error.message);
|
|
4859
|
+
}
|
|
4860
|
+
const job = data.data;
|
|
4861
|
+
if (!job) {
|
|
4749
4862
|
return;
|
|
4750
4863
|
}
|
|
4751
|
-
return
|
|
4752
|
-
|
|
4864
|
+
return new acpJob_default(
|
|
4865
|
+
this,
|
|
4866
|
+
job.id,
|
|
4867
|
+
job.clientAddress,
|
|
4868
|
+
job.providerAddress,
|
|
4869
|
+
job.evaluatorAddress,
|
|
4870
|
+
job.price,
|
|
4871
|
+
job.priceTokenAddress,
|
|
4872
|
+
job.memos.map((memo) => {
|
|
4873
|
+
return new acpMemo_default(
|
|
4874
|
+
this.contractClientByAddress(job.contractAddress),
|
|
4875
|
+
memo.id,
|
|
4876
|
+
memo.memoType,
|
|
4877
|
+
memo.content,
|
|
4878
|
+
memo.nextPhase,
|
|
4879
|
+
memo.status,
|
|
4880
|
+
memo.senderAddress,
|
|
4881
|
+
memo.signedReason,
|
|
4882
|
+
memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
|
|
4883
|
+
memo.payableDetails,
|
|
4884
|
+
memo.txHash,
|
|
4885
|
+
memo.signedTxHash
|
|
4886
|
+
);
|
|
4887
|
+
}),
|
|
4888
|
+
job.phase,
|
|
4889
|
+
job.context,
|
|
4890
|
+
job.contractAddress,
|
|
4891
|
+
job.netPayableAmount
|
|
4892
|
+
);
|
|
4893
|
+
} catch (error) {
|
|
4894
|
+
if (error instanceof acpError_default) {
|
|
4895
|
+
return error;
|
|
4896
|
+
}
|
|
4897
|
+
throw new acpError_default("Failed to get job by id", error);
|
|
4898
|
+
}
|
|
4753
4899
|
}
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
if (!data.data) {
|
|
4761
|
-
return null;
|
|
4900
|
+
async getMemoById(jobId, memoId) {
|
|
4901
|
+
let url = `${this.acpUrl}/api/jobs/${jobId}/memos/${memoId}`;
|
|
4902
|
+
try {
|
|
4903
|
+
const response = await fetch(url, {
|
|
4904
|
+
headers: {
|
|
4905
|
+
"wallet-address": this.walletAddress
|
|
4762
4906
|
}
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
data.data.providerAddress,
|
|
4768
|
-
data.data.metadata
|
|
4769
|
-
);
|
|
4770
|
-
} catch (error) {
|
|
4771
|
-
throw new acpError_default("Failed to get account by job id", error);
|
|
4907
|
+
});
|
|
4908
|
+
const data = await response.json();
|
|
4909
|
+
if (data.error) {
|
|
4910
|
+
throw new acpError_default(data.error.message);
|
|
4772
4911
|
}
|
|
4773
|
-
|
|
4912
|
+
const memo = data.data;
|
|
4913
|
+
if (!memo) {
|
|
4914
|
+
return;
|
|
4915
|
+
}
|
|
4916
|
+
return new acpMemo_default(
|
|
4917
|
+
this.contractClientByAddress(memo.contractAddress),
|
|
4918
|
+
memo.id,
|
|
4919
|
+
memo.memoType,
|
|
4920
|
+
memo.content,
|
|
4921
|
+
memo.nextPhase,
|
|
4922
|
+
memo.status,
|
|
4923
|
+
memo.senderAddress,
|
|
4924
|
+
memo.signedReason,
|
|
4925
|
+
memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
|
|
4926
|
+
memo.payableDetails,
|
|
4927
|
+
memo.txHash,
|
|
4928
|
+
memo.signedTxHash
|
|
4929
|
+
);
|
|
4930
|
+
} catch (error) {
|
|
4931
|
+
if (error instanceof acpError_default) {
|
|
4932
|
+
return error;
|
|
4933
|
+
}
|
|
4934
|
+
throw new acpError_default("Failed to get memo by id", error);
|
|
4935
|
+
}
|
|
4774
4936
|
}
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
throw new acpError_default("Failed to get account by client and provider", error);
|
|
4937
|
+
async getAgent(walletAddress) {
|
|
4938
|
+
const url = `${this.acpUrl}/api/agents?filters[walletAddress]=${walletAddress}`;
|
|
4939
|
+
const response = await fetch(url);
|
|
4940
|
+
const data = await response.json();
|
|
4941
|
+
const agents = data.data || [];
|
|
4942
|
+
if (agents.length === 0) {
|
|
4943
|
+
return;
|
|
4944
|
+
}
|
|
4945
|
+
return agents[0];
|
|
4946
|
+
}
|
|
4947
|
+
async getAccountByJobId(jobId, acpContractClient) {
|
|
4948
|
+
try {
|
|
4949
|
+
const url = `${this.acpUrl}/api/accounts/job/${jobId}`;
|
|
4950
|
+
const response = await fetch(url);
|
|
4951
|
+
const data = await response.json();
|
|
4952
|
+
if (!data.data) {
|
|
4953
|
+
return null;
|
|
4793
4954
|
}
|
|
4794
|
-
|
|
4955
|
+
return new AcpAccount(
|
|
4956
|
+
acpContractClient || this.contractClients[0],
|
|
4957
|
+
data.data.id,
|
|
4958
|
+
data.data.clientAddress,
|
|
4959
|
+
data.data.providerAddress,
|
|
4960
|
+
data.data.metadata
|
|
4961
|
+
);
|
|
4962
|
+
} catch (error) {
|
|
4963
|
+
throw new acpError_default("Failed to get account by job id", error);
|
|
4964
|
+
}
|
|
4965
|
+
}
|
|
4966
|
+
async getByClientAndProvider(clientAddress, providerAddress, acpContractClient) {
|
|
4967
|
+
try {
|
|
4968
|
+
const url = `${this.acpUrl}/api/accounts/client/${clientAddress}/provider/${providerAddress}`;
|
|
4969
|
+
const response = await fetch(url);
|
|
4970
|
+
const data = await response.json();
|
|
4971
|
+
if (!data.data) {
|
|
4972
|
+
return null;
|
|
4973
|
+
}
|
|
4974
|
+
return new AcpAccount(
|
|
4975
|
+
acpContractClient || this.contractClients[0],
|
|
4976
|
+
data.data.id,
|
|
4977
|
+
data.data.clientAddress,
|
|
4978
|
+
data.data.providerAddress,
|
|
4979
|
+
data.data.metadata
|
|
4980
|
+
);
|
|
4981
|
+
} catch (error) {
|
|
4982
|
+
throw new acpError_default("Failed to get account by client and provider", error);
|
|
4983
|
+
}
|
|
4795
4984
|
}
|
|
4796
4985
|
};
|
|
4797
4986
|
var acpClient_default = AcpClient;
|
|
@@ -4818,136 +5007,127 @@ var AcpX402 = class {
|
|
|
4818
5007
|
this.sessionKeyClient = sessionKeyClient;
|
|
4819
5008
|
this.publicClient = publicClient;
|
|
4820
5009
|
}
|
|
4821
|
-
signUpdateJobNonceMessage(jobId, nonce) {
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
return signature;
|
|
4826
|
-
});
|
|
5010
|
+
async signUpdateJobNonceMessage(jobId, nonce) {
|
|
5011
|
+
const message = `${jobId}-${nonce}`;
|
|
5012
|
+
const signature = await this.sessionKeyClient.account.getSigner().signMessage(message);
|
|
5013
|
+
return signature;
|
|
4827
5014
|
}
|
|
4828
|
-
updateJobNonce(jobId, nonce) {
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
);
|
|
4851
|
-
}
|
|
4852
|
-
const acpJob = yield response.json();
|
|
4853
|
-
return acpJob;
|
|
4854
|
-
} catch (error) {
|
|
4855
|
-
throw new acpError_default("Failed to update job X402 nonce", error);
|
|
5015
|
+
async updateJobNonce(jobId, nonce) {
|
|
5016
|
+
try {
|
|
5017
|
+
const apiUrl = `${this.config.acpUrl}/api/jobs/${jobId}/x402-nonce`;
|
|
5018
|
+
const signature = await this.signUpdateJobNonceMessage(jobId, nonce);
|
|
5019
|
+
const response = await fetch(apiUrl, {
|
|
5020
|
+
method: "POST",
|
|
5021
|
+
headers: {
|
|
5022
|
+
"x-signature": signature,
|
|
5023
|
+
"x-nonce": nonce,
|
|
5024
|
+
"Content-Type": "application/json"
|
|
5025
|
+
},
|
|
5026
|
+
body: JSON.stringify({
|
|
5027
|
+
data: {
|
|
5028
|
+
nonce
|
|
5029
|
+
}
|
|
5030
|
+
})
|
|
5031
|
+
});
|
|
5032
|
+
if (!response.ok) {
|
|
5033
|
+
throw new acpError_default(
|
|
5034
|
+
"Failed to update job X402 nonce",
|
|
5035
|
+
response.statusText
|
|
5036
|
+
);
|
|
4856
5037
|
}
|
|
4857
|
-
|
|
5038
|
+
const acpJob = await response.json();
|
|
5039
|
+
return acpJob;
|
|
5040
|
+
} catch (error) {
|
|
5041
|
+
throw new acpError_default("Failed to update job X402 nonce", error);
|
|
5042
|
+
}
|
|
4858
5043
|
}
|
|
4859
|
-
generatePayment(payableRequest, requirements) {
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
functionName: "name"
|
|
4872
|
-
},
|
|
4873
|
-
{
|
|
4874
|
-
address: USDC_CONTRACT,
|
|
4875
|
-
abi: fiatTokenV2Abi_default,
|
|
4876
|
-
functionName: "version"
|
|
4877
|
-
}
|
|
4878
|
-
]
|
|
4879
|
-
});
|
|
4880
|
-
const nonce = `0x${randomBytes(32).toString("hex")}`;
|
|
4881
|
-
const message = {
|
|
4882
|
-
from: this.sessionKeyClient.account.address,
|
|
4883
|
-
to: payableRequest.to,
|
|
4884
|
-
value: payableRequest.value.toString(),
|
|
4885
|
-
validAfter: validAfter.toString(),
|
|
4886
|
-
validBefore: validBefore.toString(),
|
|
4887
|
-
nonce
|
|
4888
|
-
};
|
|
4889
|
-
const typedData = {
|
|
4890
|
-
types: {
|
|
4891
|
-
TransferWithAuthorization: X402AuthorizationTypes
|
|
4892
|
-
},
|
|
4893
|
-
domain: {
|
|
4894
|
-
name: tokenName.result,
|
|
4895
|
-
version: tokenVersion.result,
|
|
4896
|
-
chainId: this.config.chain.id,
|
|
4897
|
-
verifyingContract: USDC_CONTRACT
|
|
5044
|
+
async generatePayment(payableRequest, requirements) {
|
|
5045
|
+
try {
|
|
5046
|
+
const USDC_CONTRACT = this.config.baseFare.contractAddress;
|
|
5047
|
+
const timeNow = Math.floor(Date.now() / 1e3);
|
|
5048
|
+
const validAfter = timeNow.toString();
|
|
5049
|
+
const validBefore = (timeNow + requirements.accepts[0].maxTimeoutSeconds).toString();
|
|
5050
|
+
const [tokenName, tokenVersion] = await this.publicClient.multicall({
|
|
5051
|
+
contracts: [
|
|
5052
|
+
{
|
|
5053
|
+
address: USDC_CONTRACT,
|
|
5054
|
+
abi: erc20Abi3,
|
|
5055
|
+
functionName: "name"
|
|
4898
5056
|
},
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
typedData
|
|
4904
|
-
});
|
|
4905
|
-
const payload = {
|
|
4906
|
-
x402Version: requirements.x402Version,
|
|
4907
|
-
scheme: requirements.accepts[0].scheme,
|
|
4908
|
-
network: requirements.accepts[0].network,
|
|
4909
|
-
payload: {
|
|
4910
|
-
signature,
|
|
4911
|
-
authorization: message
|
|
5057
|
+
{
|
|
5058
|
+
address: USDC_CONTRACT,
|
|
5059
|
+
abi: fiatTokenV2Abi_default,
|
|
5060
|
+
functionName: "version"
|
|
4912
5061
|
}
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
5062
|
+
]
|
|
5063
|
+
});
|
|
5064
|
+
const nonce = `0x${randomBytes(32).toString("hex")}`;
|
|
5065
|
+
const message = {
|
|
5066
|
+
from: this.sessionKeyClient.account.address,
|
|
5067
|
+
to: payableRequest.to,
|
|
5068
|
+
value: payableRequest.value.toString(),
|
|
5069
|
+
validAfter: validAfter.toString(),
|
|
5070
|
+
validBefore: validBefore.toString(),
|
|
5071
|
+
nonce
|
|
5072
|
+
};
|
|
5073
|
+
const typedData = {
|
|
5074
|
+
types: {
|
|
5075
|
+
TransferWithAuthorization: X402AuthorizationTypes
|
|
5076
|
+
},
|
|
5077
|
+
domain: {
|
|
5078
|
+
name: tokenName.result,
|
|
5079
|
+
version: tokenVersion.result,
|
|
5080
|
+
chainId: this.config.chain.id,
|
|
5081
|
+
verifyingContract: USDC_CONTRACT
|
|
5082
|
+
},
|
|
5083
|
+
primaryType: "TransferWithAuthorization",
|
|
5084
|
+
message
|
|
5085
|
+
};
|
|
5086
|
+
const signature = await this.sessionKeyClient.signTypedData({
|
|
5087
|
+
typedData
|
|
5088
|
+
});
|
|
5089
|
+
const payload = {
|
|
5090
|
+
x402Version: requirements.x402Version,
|
|
5091
|
+
scheme: requirements.accepts[0].scheme,
|
|
5092
|
+
network: requirements.accepts[0].network,
|
|
5093
|
+
payload: {
|
|
4917
5094
|
signature,
|
|
4918
|
-
message
|
|
4919
|
-
};
|
|
4920
|
-
} catch (error) {
|
|
4921
|
-
throw new acpError_default("Failed to generate X402 payment", error);
|
|
4922
|
-
}
|
|
4923
|
-
});
|
|
4924
|
-
}
|
|
4925
|
-
performRequest(url, version2, budget, signature) {
|
|
4926
|
-
return __async(this, null, function* () {
|
|
4927
|
-
var _a;
|
|
4928
|
-
const baseUrl = (_a = this.config.x402Config) == null ? void 0 : _a.url;
|
|
4929
|
-
if (!baseUrl) throw new acpError_default("X402 URL not configured");
|
|
4930
|
-
try {
|
|
4931
|
-
const headers = {};
|
|
4932
|
-
if (signature) headers["x-payment"] = signature;
|
|
4933
|
-
if (budget) headers["x-budget"] = budget.toString();
|
|
4934
|
-
headers["x-acp-version"] = version2;
|
|
4935
|
-
const res = yield fetch(`${baseUrl}${url}`, { method: "GET", headers });
|
|
4936
|
-
const data = yield res.json();
|
|
4937
|
-
if (!res.ok && res.status !== HTTP_STATUS_CODES.PAYMENT_REQUIRED) {
|
|
4938
|
-
throw new acpError_default(
|
|
4939
|
-
"Invalid response status code for X402 request",
|
|
4940
|
-
data
|
|
4941
|
-
);
|
|
5095
|
+
authorization: message
|
|
4942
5096
|
}
|
|
4943
|
-
|
|
4944
|
-
|
|
5097
|
+
};
|
|
5098
|
+
const encodedPayment = safeBase64Encode(JSON.stringify(payload));
|
|
5099
|
+
return {
|
|
5100
|
+
encodedPayment,
|
|
5101
|
+
signature,
|
|
5102
|
+
message
|
|
5103
|
+
};
|
|
5104
|
+
} catch (error) {
|
|
5105
|
+
throw new acpError_default("Failed to generate X402 payment", error);
|
|
5106
|
+
}
|
|
5107
|
+
}
|
|
5108
|
+
async performRequest(url, version2, budget, signature) {
|
|
5109
|
+
const baseUrl = this.config.x402Config?.url;
|
|
5110
|
+
if (!baseUrl) throw new acpError_default("X402 URL not configured");
|
|
5111
|
+
try {
|
|
5112
|
+
const headers = {};
|
|
5113
|
+
if (signature) headers["x-payment"] = signature;
|
|
5114
|
+
if (budget) headers["x-budget"] = budget.toString();
|
|
5115
|
+
headers["x-acp-version"] = version2;
|
|
5116
|
+
const res = await fetch(`${baseUrl}${url}`, { method: "GET", headers });
|
|
5117
|
+
const data = await res.json();
|
|
5118
|
+
if (!res.ok && res.status !== HTTP_STATUS_CODES.PAYMENT_REQUIRED) {
|
|
5119
|
+
throw new acpError_default(
|
|
5120
|
+
"Invalid response status code for X402 request",
|
|
4945
5121
|
data
|
|
4946
|
-
|
|
4947
|
-
} catch (error) {
|
|
4948
|
-
throw new acpError_default("Failed to perform X402 request", error);
|
|
5122
|
+
);
|
|
4949
5123
|
}
|
|
4950
|
-
|
|
5124
|
+
return {
|
|
5125
|
+
isPaymentRequired: res.status === HTTP_STATUS_CODES.PAYMENT_REQUIRED,
|
|
5126
|
+
data
|
|
5127
|
+
};
|
|
5128
|
+
} catch (error) {
|
|
5129
|
+
throw new acpError_default("Failed to perform X402 request", error);
|
|
5130
|
+
}
|
|
4951
5131
|
}
|
|
4952
5132
|
};
|
|
4953
5133
|
|
|
@@ -4959,37 +5139,46 @@ var AcpContractClient = class _AcpContractClient extends baseAcpContractClient_d
|
|
|
4959
5139
|
this.MAX_FEE_PER_GAS = 2e7;
|
|
4960
5140
|
this.MAX_PRIORITY_FEE_PER_GAS = 21e6;
|
|
4961
5141
|
}
|
|
4962
|
-
static build(
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
return acpContractClient;
|
|
4970
|
-
});
|
|
5142
|
+
static async build(walletPrivateKey, sessionEntityKeyId, agentWalletAddress, config = baseAcpConfig) {
|
|
5143
|
+
const acpContractClient = new _AcpContractClient(
|
|
5144
|
+
agentWalletAddress,
|
|
5145
|
+
config
|
|
5146
|
+
);
|
|
5147
|
+
await acpContractClient.init(walletPrivateKey, sessionEntityKeyId);
|
|
5148
|
+
return acpContractClient;
|
|
4971
5149
|
}
|
|
4972
|
-
init(privateKey, sessionEntityKeyId) {
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
this.
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
this.
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
5150
|
+
async init(privateKey, sessionEntityKeyId) {
|
|
5151
|
+
const sessionKeySigner = LocalAccountSigner.privateKeyToAccountSigner(privateKey);
|
|
5152
|
+
this._sessionKeyClient = await createModularAccountV2Client({
|
|
5153
|
+
chain: this.chain,
|
|
5154
|
+
transport: alchemy({
|
|
5155
|
+
rpcUrl: this.config.alchemyRpcUrl
|
|
5156
|
+
}),
|
|
5157
|
+
signer: sessionKeySigner,
|
|
5158
|
+
policyId: "186aaa4a-5f57-4156-83fb-e456365a8820",
|
|
5159
|
+
accountAddress: this.agentWalletAddress,
|
|
5160
|
+
signerEntity: {
|
|
5161
|
+
entityId: sessionEntityKeyId,
|
|
5162
|
+
isGlobalValidation: true
|
|
5163
|
+
}
|
|
5164
|
+
});
|
|
5165
|
+
this._acpX402 = new AcpX402(
|
|
5166
|
+
this.config,
|
|
5167
|
+
this.sessionKeyClient,
|
|
5168
|
+
this.publicClient
|
|
5169
|
+
);
|
|
5170
|
+
const account = this.sessionKeyClient.account;
|
|
5171
|
+
const sessionSignerAddress = await account.getSigner().getAddress();
|
|
5172
|
+
if (!await account.isAccountDeployed()) {
|
|
5173
|
+
throw new acpError_default(
|
|
5174
|
+
`ACP Contract Client validation failed: agent account ${this.agentWalletAddress} is not deployed on-chain`
|
|
4992
5175
|
);
|
|
5176
|
+
}
|
|
5177
|
+
await this.validateSessionKeyOnChain(sessionSignerAddress, sessionEntityKeyId);
|
|
5178
|
+
console.log("Connected to ACP:", {
|
|
5179
|
+
agentWalletAddress: this.agentWalletAddress,
|
|
5180
|
+
whitelistedWalletAddress: sessionSignerAddress,
|
|
5181
|
+
entityId: sessionEntityKeyId
|
|
4993
5182
|
});
|
|
4994
5183
|
}
|
|
4995
5184
|
getRandomNonce(bits = 152) {
|
|
@@ -5013,74 +5202,68 @@ var AcpContractClient = class _AcpContractClient extends baseAcpContractClient_d
|
|
|
5013
5202
|
}
|
|
5014
5203
|
return this._acpX402;
|
|
5015
5204
|
}
|
|
5016
|
-
calculateGasFees() {
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
return finalMaxFeePerGas;
|
|
5020
|
-
});
|
|
5205
|
+
async calculateGasFees() {
|
|
5206
|
+
const finalMaxFeePerGas = BigInt(this.MAX_FEE_PER_GAS) + BigInt(this.MAX_PRIORITY_FEE_PER_GAS) * BigInt(Math.max(0, this.PRIORITY_FEE_MULTIPLIER - 1));
|
|
5207
|
+
return finalMaxFeePerGas;
|
|
5021
5208
|
}
|
|
5022
|
-
handleOperation(operations) {
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5209
|
+
async handleOperation(operations) {
|
|
5210
|
+
const payload = {
|
|
5211
|
+
uo: operations.map((op) => ({
|
|
5212
|
+
target: op.contractAddress,
|
|
5213
|
+
data: op.data,
|
|
5214
|
+
value: op.value
|
|
5215
|
+
})),
|
|
5216
|
+
overrides: {
|
|
5217
|
+
nonceKey: this.getRandomNonce()
|
|
5218
|
+
}
|
|
5219
|
+
};
|
|
5220
|
+
let retries = this.config.maxRetries;
|
|
5221
|
+
let finalError;
|
|
5222
|
+
while (retries > 0) {
|
|
5223
|
+
try {
|
|
5224
|
+
if (this.config.maxRetries > retries) {
|
|
5225
|
+
const gasFees = await this.calculateGasFees();
|
|
5226
|
+
payload["overrides"] = {
|
|
5227
|
+
maxFeePerGas: `0x${gasFees.toString(16)}`
|
|
5228
|
+
};
|
|
5032
5229
|
}
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
}
|
|
5044
|
-
const { hash } = yield this.sessionKeyClient.sendUserOperation(payload);
|
|
5045
|
-
const txnHash = yield this.sessionKeyClient.waitForUserOperationTransaction({
|
|
5046
|
-
hash
|
|
5047
|
-
});
|
|
5048
|
-
return { userOpHash: hash, txnHash };
|
|
5049
|
-
} catch (error) {
|
|
5050
|
-
retries -= 1;
|
|
5051
|
-
if (retries === 0) {
|
|
5052
|
-
finalError = error;
|
|
5053
|
-
break;
|
|
5054
|
-
}
|
|
5055
|
-
yield new Promise((resolve) => setTimeout(resolve, 2e3 * retries));
|
|
5230
|
+
const { hash } = await this.sessionKeyClient.sendUserOperation(payload);
|
|
5231
|
+
const txnHash = await this.sessionKeyClient.waitForUserOperationTransaction({
|
|
5232
|
+
hash
|
|
5233
|
+
});
|
|
5234
|
+
return { userOpHash: hash, txnHash };
|
|
5235
|
+
} catch (error) {
|
|
5236
|
+
retries -= 1;
|
|
5237
|
+
if (retries === 0) {
|
|
5238
|
+
finalError = error;
|
|
5239
|
+
break;
|
|
5056
5240
|
}
|
|
5241
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3 * retries));
|
|
5057
5242
|
}
|
|
5058
|
-
|
|
5059
|
-
|
|
5243
|
+
}
|
|
5244
|
+
throw new acpError_default(`Failed to send user operation`, finalError);
|
|
5060
5245
|
}
|
|
5061
|
-
getJobId(createJobUserOpHash, clientAddress, providerAddress) {
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
return Number(createdJobEvent.args.jobId);
|
|
5083
|
-
});
|
|
5246
|
+
async getJobId(createJobUserOpHash, clientAddress, providerAddress) {
|
|
5247
|
+
const result = await this.sessionKeyClient.getUserOperationReceipt(createJobUserOpHash);
|
|
5248
|
+
if (!result) {
|
|
5249
|
+
throw new acpError_default("Failed to get user operation receipt");
|
|
5250
|
+
}
|
|
5251
|
+
const contractLogs = result.logs.filter((log) => {
|
|
5252
|
+
return log.address.toLowerCase() === this.contractAddress.toLowerCase();
|
|
5253
|
+
}).map(
|
|
5254
|
+
(log) => decodeEventLog({
|
|
5255
|
+
abi: this.abi,
|
|
5256
|
+
data: log.data,
|
|
5257
|
+
topics: log.topics
|
|
5258
|
+
})
|
|
5259
|
+
);
|
|
5260
|
+
const createdJobEvent = contractLogs.find(
|
|
5261
|
+
(log) => log.eventName === "JobCreated" && log.args.client.toLowerCase() === clientAddress.toLowerCase() && log.args.provider.toLowerCase() === providerAddress.toLowerCase()
|
|
5262
|
+
);
|
|
5263
|
+
if (!createdJobEvent) {
|
|
5264
|
+
throw new acpError_default("Failed to find created job event");
|
|
5265
|
+
}
|
|
5266
|
+
return Number(createdJobEvent.args.jobId);
|
|
5084
5267
|
}
|
|
5085
5268
|
createJob(providerAddress, evaluatorAddress, expireAt, paymentTokenAddress, budgetBaseUnit, metadata, isX402Job) {
|
|
5086
5269
|
try {
|
|
@@ -5151,20 +5334,14 @@ var AcpContractClient = class _AcpContractClient extends baseAcpContractClient_d
|
|
|
5151
5334
|
updateAccountMetadata(accountId, metadata) {
|
|
5152
5335
|
throw new acpError_default("Not Supported");
|
|
5153
5336
|
}
|
|
5154
|
-
updateJobX402Nonce(jobId, nonce) {
|
|
5155
|
-
return
|
|
5156
|
-
return yield this.acpX402.updateJobNonce(jobId, nonce);
|
|
5157
|
-
});
|
|
5337
|
+
async updateJobX402Nonce(jobId, nonce) {
|
|
5338
|
+
return await this.acpX402.updateJobNonce(jobId, nonce);
|
|
5158
5339
|
}
|
|
5159
|
-
generateX402Payment(payableRequest, requirements) {
|
|
5160
|
-
return
|
|
5161
|
-
return yield this.acpX402.generatePayment(payableRequest, requirements);
|
|
5162
|
-
});
|
|
5340
|
+
async generateX402Payment(payableRequest, requirements) {
|
|
5341
|
+
return await this.acpX402.generatePayment(payableRequest, requirements);
|
|
5163
5342
|
}
|
|
5164
|
-
performX402Request(url, version2, budget, signature) {
|
|
5165
|
-
return
|
|
5166
|
-
return yield this.acpX402.performRequest(url, version2, budget, signature);
|
|
5167
|
-
});
|
|
5343
|
+
async performX402Request(url, version2, budget, signature) {
|
|
5344
|
+
return await this.acpX402.performRequest(url, version2, budget, signature);
|
|
5168
5345
|
}
|
|
5169
5346
|
getAcpVersion() {
|
|
5170
5347
|
return "1";
|
|
@@ -5892,68 +6069,77 @@ var AcpContractClientV2 = class _AcpContractClientV2 extends baseAcpContractClie
|
|
|
5892
6069
|
this.MAX_FEE_PER_GAS = 2e7;
|
|
5893
6070
|
this.MAX_PRIORITY_FEE_PER_GAS = 21e6;
|
|
5894
6071
|
}
|
|
5895
|
-
static build(
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
|
|
5899
|
-
transport: http3(config.rpcEndpoint)
|
|
5900
|
-
});
|
|
5901
|
-
const [jobManagerAddress, memoManagerAddress, accountManagerAddress] = yield publicClient.multicall({
|
|
5902
|
-
contracts: [
|
|
5903
|
-
{
|
|
5904
|
-
address: config.contractAddress,
|
|
5905
|
-
abi: config.abi,
|
|
5906
|
-
functionName: "jobManager"
|
|
5907
|
-
},
|
|
5908
|
-
{
|
|
5909
|
-
address: config.contractAddress,
|
|
5910
|
-
abi: config.abi,
|
|
5911
|
-
functionName: "memoManager"
|
|
5912
|
-
},
|
|
5913
|
-
{
|
|
5914
|
-
address: config.contractAddress,
|
|
5915
|
-
abi: config.abi,
|
|
5916
|
-
functionName: "accountManager"
|
|
5917
|
-
}
|
|
5918
|
-
]
|
|
5919
|
-
});
|
|
5920
|
-
if (!jobManagerAddress || !memoManagerAddress || !accountManagerAddress) {
|
|
5921
|
-
throw new acpError_default(
|
|
5922
|
-
"Failed to get job manager, memo manager, or account manager address"
|
|
5923
|
-
);
|
|
5924
|
-
}
|
|
5925
|
-
const acpContractClient = new _AcpContractClientV2(
|
|
5926
|
-
jobManagerAddress.result,
|
|
5927
|
-
memoManagerAddress.result,
|
|
5928
|
-
accountManagerAddress.result,
|
|
5929
|
-
agentWalletAddress,
|
|
5930
|
-
config
|
|
5931
|
-
);
|
|
5932
|
-
yield acpContractClient.init(walletPrivateKey, sessionEntityKeyId);
|
|
5933
|
-
return acpContractClient;
|
|
6072
|
+
static async build(walletPrivateKey, sessionEntityKeyId, agentWalletAddress, config = baseAcpConfigV2) {
|
|
6073
|
+
const publicClient = createPublicClient4({
|
|
6074
|
+
chain: config.chain,
|
|
6075
|
+
transport: http3(config.rpcEndpoint)
|
|
5934
6076
|
});
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
6077
|
+
const [jobManagerAddress, memoManagerAddress, accountManagerAddress] = await publicClient.multicall({
|
|
6078
|
+
contracts: [
|
|
6079
|
+
{
|
|
6080
|
+
address: config.contractAddress,
|
|
6081
|
+
abi: config.abi,
|
|
6082
|
+
functionName: "jobManager"
|
|
6083
|
+
},
|
|
6084
|
+
{
|
|
6085
|
+
address: config.contractAddress,
|
|
6086
|
+
abi: config.abi,
|
|
6087
|
+
functionName: "memoManager"
|
|
6088
|
+
},
|
|
6089
|
+
{
|
|
6090
|
+
address: config.contractAddress,
|
|
6091
|
+
abi: config.abi,
|
|
6092
|
+
functionName: "accountManager"
|
|
5950
6093
|
}
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
6094
|
+
]
|
|
6095
|
+
});
|
|
6096
|
+
if (!jobManagerAddress || !memoManagerAddress || !accountManagerAddress) {
|
|
6097
|
+
throw new acpError_default(
|
|
6098
|
+
"Failed to get job manager, memo manager, or account manager address"
|
|
6099
|
+
);
|
|
6100
|
+
}
|
|
6101
|
+
const acpContractClient = new _AcpContractClientV2(
|
|
6102
|
+
jobManagerAddress.result,
|
|
6103
|
+
memoManagerAddress.result,
|
|
6104
|
+
accountManagerAddress.result,
|
|
6105
|
+
agentWalletAddress,
|
|
6106
|
+
config
|
|
6107
|
+
);
|
|
6108
|
+
await acpContractClient.init(walletPrivateKey, sessionEntityKeyId);
|
|
6109
|
+
return acpContractClient;
|
|
6110
|
+
}
|
|
6111
|
+
async init(privateKey, sessionEntityKeyId) {
|
|
6112
|
+
const sessionKeySigner = LocalAccountSigner2.privateKeyToAccountSigner(privateKey);
|
|
6113
|
+
this._sessionKeyClient = await createModularAccountV2Client2({
|
|
6114
|
+
chain: this.chain,
|
|
6115
|
+
transport: alchemy2({
|
|
6116
|
+
rpcUrl: this.config.alchemyRpcUrl
|
|
6117
|
+
}),
|
|
6118
|
+
signer: sessionKeySigner,
|
|
6119
|
+
policyId: "186aaa4a-5f57-4156-83fb-e456365a8820",
|
|
6120
|
+
accountAddress: this.agentWalletAddress,
|
|
6121
|
+
signerEntity: {
|
|
6122
|
+
entityId: sessionEntityKeyId,
|
|
6123
|
+
isGlobalValidation: true
|
|
6124
|
+
}
|
|
6125
|
+
});
|
|
6126
|
+
this._acpX402 = new AcpX402(
|
|
6127
|
+
this.config,
|
|
6128
|
+
this.sessionKeyClient,
|
|
6129
|
+
this.publicClient
|
|
6130
|
+
);
|
|
6131
|
+
const account = this.sessionKeyClient.account;
|
|
6132
|
+
const sessionSignerAddress = await account.getSigner().getAddress();
|
|
6133
|
+
if (!await account.isAccountDeployed()) {
|
|
6134
|
+
throw new acpError_default(
|
|
6135
|
+
`ACP Contract Client validation failed: agent account ${this.agentWalletAddress} is not deployed on-chain`
|
|
5956
6136
|
);
|
|
6137
|
+
}
|
|
6138
|
+
await this.validateSessionKeyOnChain(sessionSignerAddress, sessionEntityKeyId);
|
|
6139
|
+
console.log("Connected to ACP:", {
|
|
6140
|
+
agentWalletAddress: this.agentWalletAddress,
|
|
6141
|
+
whitelistedWalletAddress: sessionSignerAddress,
|
|
6142
|
+
entityId: sessionEntityKeyId
|
|
5957
6143
|
});
|
|
5958
6144
|
}
|
|
5959
6145
|
getRandomNonce(bits = 152) {
|
|
@@ -5977,116 +6163,102 @@ var AcpContractClientV2 = class _AcpContractClientV2 extends baseAcpContractClie
|
|
|
5977
6163
|
}
|
|
5978
6164
|
return this._acpX402;
|
|
5979
6165
|
}
|
|
5980
|
-
calculateGasFees() {
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
return finalMaxFeePerGas;
|
|
5984
|
-
});
|
|
6166
|
+
async calculateGasFees() {
|
|
6167
|
+
const finalMaxFeePerGas = BigInt(this.MAX_FEE_PER_GAS) + BigInt(this.MAX_PRIORITY_FEE_PER_GAS) * BigInt(Math.max(0, this.PRIORITY_FEE_MULTIPLIER - 1));
|
|
6168
|
+
return finalMaxFeePerGas;
|
|
5985
6169
|
}
|
|
5986
|
-
handleOperation(operations) {
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
6170
|
+
async handleOperation(operations) {
|
|
6171
|
+
const payload = {
|
|
6172
|
+
uo: operations.map((operation) => ({
|
|
6173
|
+
target: operation.contractAddress,
|
|
6174
|
+
data: operation.data,
|
|
6175
|
+
value: operation.value
|
|
6176
|
+
})),
|
|
6177
|
+
overrides: {
|
|
6178
|
+
nonceKey: this.getRandomNonce()
|
|
6179
|
+
}
|
|
6180
|
+
};
|
|
6181
|
+
let retries = this.config.maxRetries;
|
|
6182
|
+
let finalError;
|
|
6183
|
+
while (retries > 0) {
|
|
6184
|
+
try {
|
|
6185
|
+
if (this.config.maxRetries > retries) {
|
|
6186
|
+
const gasFees = await this.calculateGasFees();
|
|
6187
|
+
payload["overrides"] = {
|
|
6188
|
+
maxFeePerGas: `0x${gasFees.toString(16)}`
|
|
6189
|
+
};
|
|
5996
6190
|
}
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
maxFeePerGas: `0x${gasFees.toString(16)}`
|
|
6006
|
-
};
|
|
6191
|
+
const { hash } = await this.sessionKeyClient.sendUserOperation(payload);
|
|
6192
|
+
const txnHash = await this.sessionKeyClient.waitForUserOperationTransaction({
|
|
6193
|
+
hash,
|
|
6194
|
+
tag: "pending",
|
|
6195
|
+
retries: {
|
|
6196
|
+
intervalMs: 200,
|
|
6197
|
+
multiplier: 1.1,
|
|
6198
|
+
maxRetries: 10
|
|
6007
6199
|
}
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
maxRetries: 10
|
|
6016
|
-
}
|
|
6017
|
-
});
|
|
6018
|
-
return { userOpHash: hash, txnHash };
|
|
6019
|
-
} catch (error) {
|
|
6020
|
-
retries -= 1;
|
|
6021
|
-
if (retries === 0) {
|
|
6022
|
-
finalError = error;
|
|
6023
|
-
break;
|
|
6024
|
-
}
|
|
6025
|
-
yield new Promise((resolve) => setTimeout(resolve, 2e3 * retries));
|
|
6200
|
+
});
|
|
6201
|
+
return { userOpHash: hash, txnHash };
|
|
6202
|
+
} catch (error) {
|
|
6203
|
+
retries -= 1;
|
|
6204
|
+
if (retries === 0) {
|
|
6205
|
+
finalError = error;
|
|
6206
|
+
break;
|
|
6026
6207
|
}
|
|
6208
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3 * retries));
|
|
6027
6209
|
}
|
|
6028
|
-
|
|
6029
|
-
|
|
6210
|
+
}
|
|
6211
|
+
throw new acpError_default(`Failed to send user operation`, finalError);
|
|
6030
6212
|
}
|
|
6031
|
-
getJobId(createJobUserOpHash, clientAddress, providerAddress) {
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
return Number(createdJobEvent.args.jobId);
|
|
6056
|
-
});
|
|
6213
|
+
async getJobId(createJobUserOpHash, clientAddress, providerAddress) {
|
|
6214
|
+
const result = await this.sessionKeyClient.getUserOperationReceipt(
|
|
6215
|
+
createJobUserOpHash,
|
|
6216
|
+
"pending"
|
|
6217
|
+
);
|
|
6218
|
+
if (!result) {
|
|
6219
|
+
throw new acpError_default("Failed to get user operation receipt");
|
|
6220
|
+
}
|
|
6221
|
+
const contractLogs = result.logs.filter((log) => {
|
|
6222
|
+
return log.address.toLowerCase() === this.jobManagerAddress.toLowerCase();
|
|
6223
|
+
}).map(
|
|
6224
|
+
(log) => decodeEventLog2({
|
|
6225
|
+
abi: jobManagerAbi_default,
|
|
6226
|
+
data: log.data,
|
|
6227
|
+
topics: log.topics
|
|
6228
|
+
})
|
|
6229
|
+
);
|
|
6230
|
+
const createdJobEvent = contractLogs.find(
|
|
6231
|
+
(log) => log.eventName === "JobCreated" && log.args.client.toLowerCase() === clientAddress.toLowerCase() && log.args.provider.toLowerCase() === providerAddress.toLowerCase()
|
|
6232
|
+
);
|
|
6233
|
+
if (!createdJobEvent) {
|
|
6234
|
+
throw new acpError_default("Failed to find created job event");
|
|
6235
|
+
}
|
|
6236
|
+
return Number(createdJobEvent.args.jobId);
|
|
6057
6237
|
}
|
|
6058
|
-
updateJobX402Nonce(jobId, nonce) {
|
|
6059
|
-
return
|
|
6060
|
-
return yield this.acpX402.updateJobNonce(jobId, nonce);
|
|
6061
|
-
});
|
|
6238
|
+
async updateJobX402Nonce(jobId, nonce) {
|
|
6239
|
+
return await this.acpX402.updateJobNonce(jobId, nonce);
|
|
6062
6240
|
}
|
|
6063
|
-
generateX402Payment(payableRequest, requirements) {
|
|
6064
|
-
return
|
|
6065
|
-
return yield this.acpX402.generatePayment(payableRequest, requirements);
|
|
6066
|
-
});
|
|
6241
|
+
async generateX402Payment(payableRequest, requirements) {
|
|
6242
|
+
return await this.acpX402.generatePayment(payableRequest, requirements);
|
|
6067
6243
|
}
|
|
6068
|
-
performX402Request(url, version2, budget, signature) {
|
|
6069
|
-
return
|
|
6070
|
-
return yield this.acpX402.performRequest(url, version2, budget, signature);
|
|
6071
|
-
});
|
|
6244
|
+
async performX402Request(url, version2, budget, signature) {
|
|
6245
|
+
return await this.acpX402.performRequest(url, version2, budget, signature);
|
|
6072
6246
|
}
|
|
6073
|
-
getX402PaymentDetails(jobId) {
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
|
|
6086
|
-
|
|
6087
|
-
|
|
6088
|
-
}
|
|
6089
|
-
});
|
|
6247
|
+
async getX402PaymentDetails(jobId) {
|
|
6248
|
+
try {
|
|
6249
|
+
const result = await this.publicClient.readContract({
|
|
6250
|
+
address: this.jobManagerAddress,
|
|
6251
|
+
abi: jobManagerAbi_default,
|
|
6252
|
+
functionName: "x402PaymentDetails",
|
|
6253
|
+
args: [BigInt(jobId)]
|
|
6254
|
+
});
|
|
6255
|
+
return {
|
|
6256
|
+
isX402: result[0],
|
|
6257
|
+
isBudgetReceived: result[1]
|
|
6258
|
+
};
|
|
6259
|
+
} catch (error) {
|
|
6260
|
+
throw new acpError_default("Failed to get X402 payment details", error);
|
|
6261
|
+
}
|
|
6090
6262
|
}
|
|
6091
6263
|
getAcpVersion() {
|
|
6092
6264
|
return "2";
|