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