@virtuals-protocol/acp-node 0.3.0-beta.13 → 0.3.0-beta.14
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 +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1544 -1391
- package/dist/index.mjs +1548 -1394
- 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.14",
|
|
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
|
-
return yield this.reject(memoContent);
|
|
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);
|
|
3923
4145
|
}
|
|
3924
|
-
accept(reason) {
|
|
3925
|
-
|
|
3926
|
-
|
|
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);
|
|
4153
|
+
}
|
|
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
|
|
|
@@ -4253,10 +4449,8 @@ 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
4456
|
if (Array.isArray(this.acpContractClient)) {
|
|
@@ -4264,271 +4458,39 @@ var AcpClient = class {
|
|
|
4264
4458
|
}
|
|
4265
4459
|
return this.acpContractClient.walletAddress;
|
|
4266
4460
|
}
|
|
4267
|
-
init() {
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
transports: ["websocket"]
|
|
4280
|
-
});
|
|
4281
|
-
socket.on("roomJoined" /* ROOM_JOINED */, (_, callback) => {
|
|
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
|
-
});
|
|
4461
|
+
async init() {
|
|
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,268 @@ 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
|
+
throw new acpError_default("Failed to get active jobs", error);
|
|
4740
|
+
}
|
|
4741
|
+
}
|
|
4742
|
+
async getPendingMemoJobs(page = 1, pageSize = 10) {
|
|
4743
|
+
let url = `${this.acpUrl}/api/jobs/pending-memos?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
|
|
4744
|
+
try {
|
|
4745
|
+
const response = await fetch(url, {
|
|
4746
|
+
headers: {
|
|
4747
|
+
"wallet-address": this.acpContractClient.walletAddress
|
|
4748
|
+
}
|
|
4749
|
+
});
|
|
4750
|
+
const data = await response.json();
|
|
4751
|
+
if (data.error) {
|
|
4752
|
+
throw new acpError_default(data.error.message);
|
|
4753
|
+
}
|
|
4754
|
+
return data.data.map((job) => {
|
|
4755
|
+
return new acpJob_default(
|
|
4756
|
+
this,
|
|
4757
|
+
job.id,
|
|
4758
|
+
job.clientAddress,
|
|
4759
|
+
job.providerAddress,
|
|
4760
|
+
job.evaluatorAddress,
|
|
4761
|
+
job.price,
|
|
4762
|
+
job.priceTokenAddress,
|
|
4763
|
+
job.memos.map((memo) => {
|
|
4764
|
+
return new acpMemo_default(
|
|
4765
|
+
this.contractClientByAddress(job.contractAddress),
|
|
4766
|
+
memo.id,
|
|
4767
|
+
memo.memoType,
|
|
4768
|
+
memo.content,
|
|
4769
|
+
memo.nextPhase,
|
|
4770
|
+
memo.status,
|
|
4771
|
+
memo.senderAddress,
|
|
4772
|
+
memo.signedReason,
|
|
4773
|
+
memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
|
|
4774
|
+
typeof memo.payableDetails === "string" ? tryParseJson(memo.payableDetails) || void 0 : memo.payableDetails,
|
|
4775
|
+
memo.txHash,
|
|
4776
|
+
memo.signedTxHash
|
|
4777
|
+
);
|
|
4778
|
+
}),
|
|
4779
|
+
job.phase,
|
|
4780
|
+
job.context,
|
|
4781
|
+
job.contractAddress,
|
|
4782
|
+
job.netPayableAmount
|
|
4783
|
+
);
|
|
4784
|
+
});
|
|
4785
|
+
} catch (error) {
|
|
4786
|
+
throw new acpError_default("Failed to get pending memo jobs", error);
|
|
4787
|
+
}
|
|
4702
4788
|
}
|
|
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;
|
|
4789
|
+
async getCompletedJobs(page = 1, pageSize = 10) {
|
|
4790
|
+
let url = `${this.acpUrl}/api/jobs/completed?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
|
|
4791
|
+
try {
|
|
4792
|
+
const response = await fetch(url, {
|
|
4793
|
+
headers: {
|
|
4794
|
+
"wallet-address": this.acpContractClient.walletAddress
|
|
4719
4795
|
}
|
|
4796
|
+
});
|
|
4797
|
+
const data = await response.json();
|
|
4798
|
+
if (data.error) {
|
|
4799
|
+
throw new acpError_default(data.error.message);
|
|
4800
|
+
}
|
|
4801
|
+
return data.data.map((job) => {
|
|
4720
4802
|
return new acpJob_default(
|
|
4721
4803
|
this,
|
|
4722
4804
|
job.id,
|
|
@@ -4746,100 +4828,188 @@ var AcpClient = class {
|
|
|
4746
4828
|
job.contractAddress,
|
|
4747
4829
|
job.netPayableAmount
|
|
4748
4830
|
);
|
|
4749
|
-
}
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
}
|
|
4831
|
+
});
|
|
4832
|
+
} catch (error) {
|
|
4833
|
+
throw new acpError_default("Failed to get completed jobs", error);
|
|
4834
|
+
}
|
|
4753
4835
|
}
|
|
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;
|
|
4836
|
+
async getCancelledJobs(page = 1, pageSize = 10) {
|
|
4837
|
+
let url = `${this.acpUrl}/api/jobs/cancelled?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
|
|
4838
|
+
try {
|
|
4839
|
+
const response = await fetch(url, {
|
|
4840
|
+
headers: {
|
|
4841
|
+
"wallet-address": this.walletAddress
|
|
4770
4842
|
}
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
memo.content,
|
|
4776
|
-
memo.nextPhase,
|
|
4777
|
-
memo.status,
|
|
4778
|
-
memo.senderAddress,
|
|
4779
|
-
memo.signedReason,
|
|
4780
|
-
memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
|
|
4781
|
-
memo.payableDetails,
|
|
4782
|
-
memo.txHash,
|
|
4783
|
-
memo.signedTxHash
|
|
4784
|
-
);
|
|
4785
|
-
} catch (error) {
|
|
4786
|
-
throw new acpError_default("Failed to get memo by id", error);
|
|
4843
|
+
});
|
|
4844
|
+
const data = await response.json();
|
|
4845
|
+
if (data.error) {
|
|
4846
|
+
throw new acpError_default(data.error.message);
|
|
4787
4847
|
}
|
|
4788
|
-
|
|
4848
|
+
return data.data.map((job) => {
|
|
4849
|
+
return new acpJob_default(
|
|
4850
|
+
this,
|
|
4851
|
+
job.id,
|
|
4852
|
+
job.clientAddress,
|
|
4853
|
+
job.providerAddress,
|
|
4854
|
+
job.evaluatorAddress,
|
|
4855
|
+
job.price,
|
|
4856
|
+
job.priceTokenAddress,
|
|
4857
|
+
job.memos.map((memo) => {
|
|
4858
|
+
return new acpMemo_default(
|
|
4859
|
+
this.contractClientByAddress(job.contractAddress),
|
|
4860
|
+
memo.id,
|
|
4861
|
+
memo.memoType,
|
|
4862
|
+
memo.content,
|
|
4863
|
+
memo.nextPhase,
|
|
4864
|
+
memo.status,
|
|
4865
|
+
memo.senderAddress,
|
|
4866
|
+
memo.signedReason,
|
|
4867
|
+
memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
|
|
4868
|
+
memo.payableDetails,
|
|
4869
|
+
memo.txHash,
|
|
4870
|
+
memo.signedTxHash
|
|
4871
|
+
);
|
|
4872
|
+
}),
|
|
4873
|
+
job.phase,
|
|
4874
|
+
job.context,
|
|
4875
|
+
job.contractAddress,
|
|
4876
|
+
job.netPayableAmount
|
|
4877
|
+
);
|
|
4878
|
+
});
|
|
4879
|
+
} catch (error) {
|
|
4880
|
+
throw new acpError_default("Failed to get cancelled jobs", error);
|
|
4881
|
+
}
|
|
4789
4882
|
}
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
const response =
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4883
|
+
async getJobById(jobId) {
|
|
4884
|
+
let url = `${this.acpUrl}/api/jobs/${jobId}`;
|
|
4885
|
+
try {
|
|
4886
|
+
const response = await fetch(url, {
|
|
4887
|
+
headers: {
|
|
4888
|
+
"wallet-address": this.acpContractClient.walletAddress
|
|
4889
|
+
}
|
|
4890
|
+
});
|
|
4891
|
+
const data = await response.json();
|
|
4892
|
+
if (data.error) {
|
|
4893
|
+
throw new acpError_default(data.error.message);
|
|
4894
|
+
}
|
|
4895
|
+
const job = data.data;
|
|
4896
|
+
if (!job) {
|
|
4797
4897
|
return;
|
|
4798
4898
|
}
|
|
4799
|
-
return
|
|
4800
|
-
|
|
4899
|
+
return new acpJob_default(
|
|
4900
|
+
this,
|
|
4901
|
+
job.id,
|
|
4902
|
+
job.clientAddress,
|
|
4903
|
+
job.providerAddress,
|
|
4904
|
+
job.evaluatorAddress,
|
|
4905
|
+
job.price,
|
|
4906
|
+
job.priceTokenAddress,
|
|
4907
|
+
job.memos.map((memo) => {
|
|
4908
|
+
return new acpMemo_default(
|
|
4909
|
+
this.contractClientByAddress(job.contractAddress),
|
|
4910
|
+
memo.id,
|
|
4911
|
+
memo.memoType,
|
|
4912
|
+
memo.content,
|
|
4913
|
+
memo.nextPhase,
|
|
4914
|
+
memo.status,
|
|
4915
|
+
memo.senderAddress,
|
|
4916
|
+
memo.signedReason,
|
|
4917
|
+
memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
|
|
4918
|
+
memo.payableDetails,
|
|
4919
|
+
memo.txHash,
|
|
4920
|
+
memo.signedTxHash
|
|
4921
|
+
);
|
|
4922
|
+
}),
|
|
4923
|
+
job.phase,
|
|
4924
|
+
job.context,
|
|
4925
|
+
job.contractAddress,
|
|
4926
|
+
job.netPayableAmount
|
|
4927
|
+
);
|
|
4928
|
+
} catch (error) {
|
|
4929
|
+
throw new acpError_default("Failed to get job by id", error);
|
|
4930
|
+
}
|
|
4801
4931
|
}
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
if (!data.data) {
|
|
4809
|
-
return null;
|
|
4932
|
+
async getMemoById(jobId, memoId) {
|
|
4933
|
+
let url = `${this.acpUrl}/api/jobs/${jobId}/memos/${memoId}`;
|
|
4934
|
+
try {
|
|
4935
|
+
const response = await fetch(url, {
|
|
4936
|
+
headers: {
|
|
4937
|
+
"wallet-address": this.walletAddress
|
|
4810
4938
|
}
|
|
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);
|
|
4939
|
+
});
|
|
4940
|
+
const data = await response.json();
|
|
4941
|
+
if (data.error) {
|
|
4942
|
+
throw new acpError_default(data.error.message);
|
|
4820
4943
|
}
|
|
4821
|
-
|
|
4944
|
+
const memo = data.data;
|
|
4945
|
+
if (!memo) {
|
|
4946
|
+
return;
|
|
4947
|
+
}
|
|
4948
|
+
return new acpMemo_default(
|
|
4949
|
+
this.contractClientByAddress(memo.contractAddress),
|
|
4950
|
+
memo.id,
|
|
4951
|
+
memo.memoType,
|
|
4952
|
+
memo.content,
|
|
4953
|
+
memo.nextPhase,
|
|
4954
|
+
memo.status,
|
|
4955
|
+
memo.senderAddress,
|
|
4956
|
+
memo.signedReason,
|
|
4957
|
+
memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
|
|
4958
|
+
memo.payableDetails,
|
|
4959
|
+
memo.txHash,
|
|
4960
|
+
memo.signedTxHash
|
|
4961
|
+
);
|
|
4962
|
+
} catch (error) {
|
|
4963
|
+
throw new acpError_default("Failed to get memo by id", error);
|
|
4964
|
+
}
|
|
4822
4965
|
}
|
|
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);
|
|
4966
|
+
async getAgent(walletAddress) {
|
|
4967
|
+
const url = `${this.acpUrl}/api/agents?filters[walletAddress]=${walletAddress}`;
|
|
4968
|
+
const response = await fetch(url);
|
|
4969
|
+
const data = await response.json();
|
|
4970
|
+
const agents = data.data || [];
|
|
4971
|
+
if (agents.length === 0) {
|
|
4972
|
+
return;
|
|
4973
|
+
}
|
|
4974
|
+
return agents[0];
|
|
4975
|
+
}
|
|
4976
|
+
async getAccountByJobId(jobId, acpContractClient) {
|
|
4977
|
+
try {
|
|
4978
|
+
const url = `${this.acpUrl}/api/accounts/job/${jobId}`;
|
|
4979
|
+
const response = await fetch(url);
|
|
4980
|
+
const data = await response.json();
|
|
4981
|
+
if (!data.data) {
|
|
4982
|
+
return null;
|
|
4841
4983
|
}
|
|
4842
|
-
|
|
4984
|
+
return new AcpAccount(
|
|
4985
|
+
acpContractClient || this.contractClients[0],
|
|
4986
|
+
data.data.id,
|
|
4987
|
+
data.data.clientAddress,
|
|
4988
|
+
data.data.providerAddress,
|
|
4989
|
+
data.data.metadata
|
|
4990
|
+
);
|
|
4991
|
+
} catch (error) {
|
|
4992
|
+
throw new acpError_default("Failed to get account by job id", error);
|
|
4993
|
+
}
|
|
4994
|
+
}
|
|
4995
|
+
async getByClientAndProvider(clientAddress, providerAddress, acpContractClient) {
|
|
4996
|
+
try {
|
|
4997
|
+
const url = `${this.acpUrl}/api/accounts/client/${clientAddress}/provider/${providerAddress}`;
|
|
4998
|
+
const response = await fetch(url);
|
|
4999
|
+
const data = await response.json();
|
|
5000
|
+
if (!data.data) {
|
|
5001
|
+
return null;
|
|
5002
|
+
}
|
|
5003
|
+
return new AcpAccount(
|
|
5004
|
+
acpContractClient || this.contractClients[0],
|
|
5005
|
+
data.data.id,
|
|
5006
|
+
data.data.clientAddress,
|
|
5007
|
+
data.data.providerAddress,
|
|
5008
|
+
data.data.metadata
|
|
5009
|
+
);
|
|
5010
|
+
} catch (error) {
|
|
5011
|
+
throw new acpError_default("Failed to get account by client and provider", error);
|
|
5012
|
+
}
|
|
4843
5013
|
}
|
|
4844
5014
|
};
|
|
4845
5015
|
var acpClient_default = AcpClient;
|
|
@@ -4862,136 +5032,127 @@ var AcpX402 = class {
|
|
|
4862
5032
|
this.sessionKeyClient = sessionKeyClient;
|
|
4863
5033
|
this.publicClient = publicClient;
|
|
4864
5034
|
}
|
|
4865
|
-
signUpdateJobNonceMessage(jobId, nonce) {
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
return signature;
|
|
4870
|
-
});
|
|
5035
|
+
async signUpdateJobNonceMessage(jobId, nonce) {
|
|
5036
|
+
const message = `${jobId}-${nonce}`;
|
|
5037
|
+
const signature = await this.sessionKeyClient.account.getSigner().signMessage(message);
|
|
5038
|
+
return signature;
|
|
4871
5039
|
}
|
|
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);
|
|
5040
|
+
async updateJobNonce(jobId, nonce) {
|
|
5041
|
+
try {
|
|
5042
|
+
const apiUrl = `${this.config.acpUrl}/api/jobs/${jobId}/x402-nonce`;
|
|
5043
|
+
const signature = await this.signUpdateJobNonceMessage(jobId, nonce);
|
|
5044
|
+
const response = await fetch(apiUrl, {
|
|
5045
|
+
method: "POST",
|
|
5046
|
+
headers: {
|
|
5047
|
+
"x-signature": signature,
|
|
5048
|
+
"x-nonce": nonce,
|
|
5049
|
+
"Content-Type": "application/json"
|
|
5050
|
+
},
|
|
5051
|
+
body: JSON.stringify({
|
|
5052
|
+
data: {
|
|
5053
|
+
nonce
|
|
5054
|
+
}
|
|
5055
|
+
})
|
|
5056
|
+
});
|
|
5057
|
+
if (!response.ok) {
|
|
5058
|
+
throw new acpError_default(
|
|
5059
|
+
"Failed to update job X402 nonce",
|
|
5060
|
+
response.statusText
|
|
5061
|
+
);
|
|
4900
5062
|
}
|
|
4901
|
-
|
|
5063
|
+
const acpJob = await response.json();
|
|
5064
|
+
return acpJob;
|
|
5065
|
+
} catch (error) {
|
|
5066
|
+
throw new acpError_default("Failed to update job X402 nonce", error);
|
|
5067
|
+
}
|
|
4902
5068
|
}
|
|
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
|
|
5069
|
+
async generatePayment(payableRequest, requirements) {
|
|
5070
|
+
try {
|
|
5071
|
+
const USDC_CONTRACT = this.config.baseFare.contractAddress;
|
|
5072
|
+
const timeNow = Math.floor(Date.now() / 1e3);
|
|
5073
|
+
const validAfter = timeNow.toString();
|
|
5074
|
+
const validBefore = (timeNow + requirements.accepts[0].maxTimeoutSeconds).toString();
|
|
5075
|
+
const [tokenName, tokenVersion] = await this.publicClient.multicall({
|
|
5076
|
+
contracts: [
|
|
5077
|
+
{
|
|
5078
|
+
address: USDC_CONTRACT,
|
|
5079
|
+
abi: import_viem5.erc20Abi,
|
|
5080
|
+
functionName: "name"
|
|
4942
5081
|
},
|
|
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
|
|
5082
|
+
{
|
|
5083
|
+
address: USDC_CONTRACT,
|
|
5084
|
+
abi: fiatTokenV2Abi_default,
|
|
5085
|
+
functionName: "version"
|
|
4956
5086
|
}
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
5087
|
+
]
|
|
5088
|
+
});
|
|
5089
|
+
const nonce = `0x${(0, import_crypto.randomBytes)(32).toString("hex")}`;
|
|
5090
|
+
const message = {
|
|
5091
|
+
from: this.sessionKeyClient.account.address,
|
|
5092
|
+
to: payableRequest.to,
|
|
5093
|
+
value: payableRequest.value.toString(),
|
|
5094
|
+
validAfter: validAfter.toString(),
|
|
5095
|
+
validBefore: validBefore.toString(),
|
|
5096
|
+
nonce
|
|
5097
|
+
};
|
|
5098
|
+
const typedData = {
|
|
5099
|
+
types: {
|
|
5100
|
+
TransferWithAuthorization: X402AuthorizationTypes
|
|
5101
|
+
},
|
|
5102
|
+
domain: {
|
|
5103
|
+
name: tokenName.result,
|
|
5104
|
+
version: tokenVersion.result,
|
|
5105
|
+
chainId: this.config.chain.id,
|
|
5106
|
+
verifyingContract: USDC_CONTRACT
|
|
5107
|
+
},
|
|
5108
|
+
primaryType: "TransferWithAuthorization",
|
|
5109
|
+
message
|
|
5110
|
+
};
|
|
5111
|
+
const signature = await this.sessionKeyClient.signTypedData({
|
|
5112
|
+
typedData
|
|
5113
|
+
});
|
|
5114
|
+
const payload = {
|
|
5115
|
+
x402Version: requirements.x402Version,
|
|
5116
|
+
scheme: requirements.accepts[0].scheme,
|
|
5117
|
+
network: requirements.accepts[0].network,
|
|
5118
|
+
payload: {
|
|
4961
5119
|
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
|
-
);
|
|
5120
|
+
authorization: message
|
|
4986
5121
|
}
|
|
4987
|
-
|
|
4988
|
-
|
|
5122
|
+
};
|
|
5123
|
+
const encodedPayment = safeBase64Encode(JSON.stringify(payload));
|
|
5124
|
+
return {
|
|
5125
|
+
encodedPayment,
|
|
5126
|
+
signature,
|
|
5127
|
+
message
|
|
5128
|
+
};
|
|
5129
|
+
} catch (error) {
|
|
5130
|
+
throw new acpError_default("Failed to generate X402 payment", error);
|
|
5131
|
+
}
|
|
5132
|
+
}
|
|
5133
|
+
async performRequest(url, version2, budget, signature) {
|
|
5134
|
+
const baseUrl = this.config.x402Config?.url;
|
|
5135
|
+
if (!baseUrl) throw new acpError_default("X402 URL not configured");
|
|
5136
|
+
try {
|
|
5137
|
+
const headers = {};
|
|
5138
|
+
if (signature) headers["x-payment"] = signature;
|
|
5139
|
+
if (budget) headers["x-budget"] = budget.toString();
|
|
5140
|
+
headers["x-acp-version"] = version2;
|
|
5141
|
+
const res = await fetch(`${baseUrl}${url}`, { method: "GET", headers });
|
|
5142
|
+
const data = await res.json();
|
|
5143
|
+
if (!res.ok && res.status !== HTTP_STATUS_CODES.PAYMENT_REQUIRED) {
|
|
5144
|
+
throw new acpError_default(
|
|
5145
|
+
"Invalid response status code for X402 request",
|
|
4989
5146
|
data
|
|
4990
|
-
|
|
4991
|
-
} catch (error) {
|
|
4992
|
-
throw new acpError_default("Failed to perform X402 request", error);
|
|
5147
|
+
);
|
|
4993
5148
|
}
|
|
4994
|
-
|
|
5149
|
+
return {
|
|
5150
|
+
isPaymentRequired: res.status === HTTP_STATUS_CODES.PAYMENT_REQUIRED,
|
|
5151
|
+
data
|
|
5152
|
+
};
|
|
5153
|
+
} catch (error) {
|
|
5154
|
+
throw new acpError_default("Failed to perform X402 request", error);
|
|
5155
|
+
}
|
|
4995
5156
|
}
|
|
4996
5157
|
};
|
|
4997
5158
|
|
|
@@ -5003,37 +5164,46 @@ var AcpContractClient = class _AcpContractClient extends baseAcpContractClient_d
|
|
|
5003
5164
|
this.MAX_FEE_PER_GAS = 2e7;
|
|
5004
5165
|
this.MAX_PRIORITY_FEE_PER_GAS = 21e6;
|
|
5005
5166
|
}
|
|
5006
|
-
static build(
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
return acpContractClient;
|
|
5014
|
-
});
|
|
5167
|
+
static async build(walletPrivateKey, sessionEntityKeyId, agentWalletAddress, config = baseAcpConfig) {
|
|
5168
|
+
const acpContractClient = new _AcpContractClient(
|
|
5169
|
+
agentWalletAddress,
|
|
5170
|
+
config
|
|
5171
|
+
);
|
|
5172
|
+
await acpContractClient.init(walletPrivateKey, sessionEntityKeyId);
|
|
5173
|
+
return acpContractClient;
|
|
5015
5174
|
}
|
|
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
|
-
|
|
5175
|
+
async init(privateKey, sessionEntityKeyId) {
|
|
5176
|
+
const sessionKeySigner = import_core.LocalAccountSigner.privateKeyToAccountSigner(privateKey);
|
|
5177
|
+
this._sessionKeyClient = await (0, import_smart_contracts.createModularAccountV2Client)({
|
|
5178
|
+
chain: this.chain,
|
|
5179
|
+
transport: (0, import_infra2.alchemy)({
|
|
5180
|
+
rpcUrl: this.config.alchemyRpcUrl
|
|
5181
|
+
}),
|
|
5182
|
+
signer: sessionKeySigner,
|
|
5183
|
+
policyId: "186aaa4a-5f57-4156-83fb-e456365a8820",
|
|
5184
|
+
accountAddress: this.agentWalletAddress,
|
|
5185
|
+
signerEntity: {
|
|
5186
|
+
entityId: sessionEntityKeyId,
|
|
5187
|
+
isGlobalValidation: true
|
|
5188
|
+
}
|
|
5189
|
+
});
|
|
5190
|
+
this._acpX402 = new AcpX402(
|
|
5191
|
+
this.config,
|
|
5192
|
+
this.sessionKeyClient,
|
|
5193
|
+
this.publicClient
|
|
5194
|
+
);
|
|
5195
|
+
const account = this.sessionKeyClient.account;
|
|
5196
|
+
const sessionSignerAddress = await account.getSigner().getAddress();
|
|
5197
|
+
if (!await account.isAccountDeployed()) {
|
|
5198
|
+
throw new acpError_default(
|
|
5199
|
+
`ACP Contract Client validation failed: agent account ${this.agentWalletAddress} is not deployed on-chain`
|
|
5036
5200
|
);
|
|
5201
|
+
}
|
|
5202
|
+
await this.validateSessionKeyOnChain(sessionSignerAddress, sessionEntityKeyId);
|
|
5203
|
+
console.log("Connected to ACP:", {
|
|
5204
|
+
agentWalletAddress: this.agentWalletAddress,
|
|
5205
|
+
whitelistedWalletAddress: sessionSignerAddress,
|
|
5206
|
+
entityId: sessionEntityKeyId
|
|
5037
5207
|
});
|
|
5038
5208
|
}
|
|
5039
5209
|
getRandomNonce(bits = 152) {
|
|
@@ -5057,74 +5227,68 @@ var AcpContractClient = class _AcpContractClient extends baseAcpContractClient_d
|
|
|
5057
5227
|
}
|
|
5058
5228
|
return this._acpX402;
|
|
5059
5229
|
}
|
|
5060
|
-
calculateGasFees() {
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
return finalMaxFeePerGas;
|
|
5064
|
-
});
|
|
5230
|
+
async calculateGasFees() {
|
|
5231
|
+
const finalMaxFeePerGas = BigInt(this.MAX_FEE_PER_GAS) + BigInt(this.MAX_PRIORITY_FEE_PER_GAS) * BigInt(Math.max(0, this.PRIORITY_FEE_MULTIPLIER - 1));
|
|
5232
|
+
return finalMaxFeePerGas;
|
|
5065
5233
|
}
|
|
5066
|
-
handleOperation(operations) {
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5234
|
+
async handleOperation(operations) {
|
|
5235
|
+
const payload = {
|
|
5236
|
+
uo: operations.map((op) => ({
|
|
5237
|
+
target: op.contractAddress,
|
|
5238
|
+
data: op.data,
|
|
5239
|
+
value: op.value
|
|
5240
|
+
})),
|
|
5241
|
+
overrides: {
|
|
5242
|
+
nonceKey: this.getRandomNonce()
|
|
5243
|
+
}
|
|
5244
|
+
};
|
|
5245
|
+
let retries = this.config.maxRetries;
|
|
5246
|
+
let finalError;
|
|
5247
|
+
while (retries > 0) {
|
|
5248
|
+
try {
|
|
5249
|
+
if (this.config.maxRetries > retries) {
|
|
5250
|
+
const gasFees = await this.calculateGasFees();
|
|
5251
|
+
payload["overrides"] = {
|
|
5252
|
+
maxFeePerGas: `0x${gasFees.toString(16)}`
|
|
5253
|
+
};
|
|
5076
5254
|
}
|
|
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));
|
|
5255
|
+
const { hash } = await this.sessionKeyClient.sendUserOperation(payload);
|
|
5256
|
+
const txnHash = await this.sessionKeyClient.waitForUserOperationTransaction({
|
|
5257
|
+
hash
|
|
5258
|
+
});
|
|
5259
|
+
return { userOpHash: hash, txnHash };
|
|
5260
|
+
} catch (error) {
|
|
5261
|
+
retries -= 1;
|
|
5262
|
+
if (retries === 0) {
|
|
5263
|
+
finalError = error;
|
|
5264
|
+
break;
|
|
5100
5265
|
}
|
|
5266
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3 * retries));
|
|
5101
5267
|
}
|
|
5102
|
-
|
|
5103
|
-
|
|
5268
|
+
}
|
|
5269
|
+
throw new acpError_default(`Failed to send user operation`, finalError);
|
|
5104
5270
|
}
|
|
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
|
-
});
|
|
5271
|
+
async getJobId(createJobUserOpHash, clientAddress, providerAddress) {
|
|
5272
|
+
const result = await this.sessionKeyClient.getUserOperationReceipt(createJobUserOpHash);
|
|
5273
|
+
if (!result) {
|
|
5274
|
+
throw new acpError_default("Failed to get user operation receipt");
|
|
5275
|
+
}
|
|
5276
|
+
const contractLogs = result.logs.filter((log) => {
|
|
5277
|
+
return log.address.toLowerCase() === this.contractAddress.toLowerCase();
|
|
5278
|
+
}).map(
|
|
5279
|
+
(log) => (0, import_viem6.decodeEventLog)({
|
|
5280
|
+
abi: this.abi,
|
|
5281
|
+
data: log.data,
|
|
5282
|
+
topics: log.topics
|
|
5283
|
+
})
|
|
5284
|
+
);
|
|
5285
|
+
const createdJobEvent = contractLogs.find(
|
|
5286
|
+
(log) => log.eventName === "JobCreated" && log.args.client.toLowerCase() === clientAddress.toLowerCase() && log.args.provider.toLowerCase() === providerAddress.toLowerCase()
|
|
5287
|
+
);
|
|
5288
|
+
if (!createdJobEvent) {
|
|
5289
|
+
throw new acpError_default("Failed to find created job event");
|
|
5290
|
+
}
|
|
5291
|
+
return Number(createdJobEvent.args.jobId);
|
|
5128
5292
|
}
|
|
5129
5293
|
createJob(providerAddress, evaluatorAddress, expireAt, paymentTokenAddress, budgetBaseUnit, metadata, isX402Job) {
|
|
5130
5294
|
try {
|
|
@@ -5195,20 +5359,14 @@ var AcpContractClient = class _AcpContractClient extends baseAcpContractClient_d
|
|
|
5195
5359
|
updateAccountMetadata(accountId, metadata) {
|
|
5196
5360
|
throw new acpError_default("Not Supported");
|
|
5197
5361
|
}
|
|
5198
|
-
updateJobX402Nonce(jobId, nonce) {
|
|
5199
|
-
return
|
|
5200
|
-
return yield this.acpX402.updateJobNonce(jobId, nonce);
|
|
5201
|
-
});
|
|
5362
|
+
async updateJobX402Nonce(jobId, nonce) {
|
|
5363
|
+
return await this.acpX402.updateJobNonce(jobId, nonce);
|
|
5202
5364
|
}
|
|
5203
|
-
generateX402Payment(payableRequest, requirements) {
|
|
5204
|
-
return
|
|
5205
|
-
return yield this.acpX402.generatePayment(payableRequest, requirements);
|
|
5206
|
-
});
|
|
5365
|
+
async generateX402Payment(payableRequest, requirements) {
|
|
5366
|
+
return await this.acpX402.generatePayment(payableRequest, requirements);
|
|
5207
5367
|
}
|
|
5208
|
-
performX402Request(url, version2, budget, signature) {
|
|
5209
|
-
return
|
|
5210
|
-
return yield this.acpX402.performRequest(url, version2, budget, signature);
|
|
5211
|
-
});
|
|
5368
|
+
async performX402Request(url, version2, budget, signature) {
|
|
5369
|
+
return await this.acpX402.performRequest(url, version2, budget, signature);
|
|
5212
5370
|
}
|
|
5213
5371
|
getAcpVersion() {
|
|
5214
5372
|
return "1";
|
|
@@ -5934,68 +6092,77 @@ var AcpContractClientV2 = class _AcpContractClientV2 extends baseAcpContractClie
|
|
|
5934
6092
|
this.MAX_FEE_PER_GAS = 2e7;
|
|
5935
6093
|
this.MAX_PRIORITY_FEE_PER_GAS = 21e6;
|
|
5936
6094
|
}
|
|
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;
|
|
6095
|
+
static async build(walletPrivateKey, sessionEntityKeyId, agentWalletAddress, config = baseAcpConfigV2) {
|
|
6096
|
+
const publicClient = (0, import_viem7.createPublicClient)({
|
|
6097
|
+
chain: config.chain,
|
|
6098
|
+
transport: (0, import_viem7.http)(config.rpcEndpoint)
|
|
5976
6099
|
});
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
6100
|
+
const [jobManagerAddress, memoManagerAddress, accountManagerAddress] = await publicClient.multicall({
|
|
6101
|
+
contracts: [
|
|
6102
|
+
{
|
|
6103
|
+
address: config.contractAddress,
|
|
6104
|
+
abi: config.abi,
|
|
6105
|
+
functionName: "jobManager"
|
|
6106
|
+
},
|
|
6107
|
+
{
|
|
6108
|
+
address: config.contractAddress,
|
|
6109
|
+
abi: config.abi,
|
|
6110
|
+
functionName: "memoManager"
|
|
6111
|
+
},
|
|
6112
|
+
{
|
|
6113
|
+
address: config.contractAddress,
|
|
6114
|
+
abi: config.abi,
|
|
6115
|
+
functionName: "accountManager"
|
|
5992
6116
|
}
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
6117
|
+
]
|
|
6118
|
+
});
|
|
6119
|
+
if (!jobManagerAddress || !memoManagerAddress || !accountManagerAddress) {
|
|
6120
|
+
throw new acpError_default(
|
|
6121
|
+
"Failed to get job manager, memo manager, or account manager address"
|
|
6122
|
+
);
|
|
6123
|
+
}
|
|
6124
|
+
const acpContractClient = new _AcpContractClientV2(
|
|
6125
|
+
jobManagerAddress.result,
|
|
6126
|
+
memoManagerAddress.result,
|
|
6127
|
+
accountManagerAddress.result,
|
|
6128
|
+
agentWalletAddress,
|
|
6129
|
+
config
|
|
6130
|
+
);
|
|
6131
|
+
await acpContractClient.init(walletPrivateKey, sessionEntityKeyId);
|
|
6132
|
+
return acpContractClient;
|
|
6133
|
+
}
|
|
6134
|
+
async init(privateKey, sessionEntityKeyId) {
|
|
6135
|
+
const sessionKeySigner = import_core2.LocalAccountSigner.privateKeyToAccountSigner(privateKey);
|
|
6136
|
+
this._sessionKeyClient = await (0, import_smart_contracts2.createModularAccountV2Client)({
|
|
6137
|
+
chain: this.chain,
|
|
6138
|
+
transport: (0, import_infra3.alchemy)({
|
|
6139
|
+
rpcUrl: this.config.alchemyRpcUrl
|
|
6140
|
+
}),
|
|
6141
|
+
signer: sessionKeySigner,
|
|
6142
|
+
policyId: "186aaa4a-5f57-4156-83fb-e456365a8820",
|
|
6143
|
+
accountAddress: this.agentWalletAddress,
|
|
6144
|
+
signerEntity: {
|
|
6145
|
+
entityId: sessionEntityKeyId,
|
|
6146
|
+
isGlobalValidation: true
|
|
6147
|
+
}
|
|
6148
|
+
});
|
|
6149
|
+
this._acpX402 = new AcpX402(
|
|
6150
|
+
this.config,
|
|
6151
|
+
this.sessionKeyClient,
|
|
6152
|
+
this.publicClient
|
|
6153
|
+
);
|
|
6154
|
+
const account = this.sessionKeyClient.account;
|
|
6155
|
+
const sessionSignerAddress = await account.getSigner().getAddress();
|
|
6156
|
+
if (!await account.isAccountDeployed()) {
|
|
6157
|
+
throw new acpError_default(
|
|
6158
|
+
`ACP Contract Client validation failed: agent account ${this.agentWalletAddress} is not deployed on-chain`
|
|
5998
6159
|
);
|
|
6160
|
+
}
|
|
6161
|
+
await this.validateSessionKeyOnChain(sessionSignerAddress, sessionEntityKeyId);
|
|
6162
|
+
console.log("Connected to ACP:", {
|
|
6163
|
+
agentWalletAddress: this.agentWalletAddress,
|
|
6164
|
+
whitelistedWalletAddress: sessionSignerAddress,
|
|
6165
|
+
entityId: sessionEntityKeyId
|
|
5999
6166
|
});
|
|
6000
6167
|
}
|
|
6001
6168
|
getRandomNonce(bits = 152) {
|
|
@@ -6019,116 +6186,102 @@ var AcpContractClientV2 = class _AcpContractClientV2 extends baseAcpContractClie
|
|
|
6019
6186
|
}
|
|
6020
6187
|
return this._acpX402;
|
|
6021
6188
|
}
|
|
6022
|
-
calculateGasFees() {
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
return finalMaxFeePerGas;
|
|
6026
|
-
});
|
|
6189
|
+
async calculateGasFees() {
|
|
6190
|
+
const finalMaxFeePerGas = BigInt(this.MAX_FEE_PER_GAS) + BigInt(this.MAX_PRIORITY_FEE_PER_GAS) * BigInt(Math.max(0, this.PRIORITY_FEE_MULTIPLIER - 1));
|
|
6191
|
+
return finalMaxFeePerGas;
|
|
6027
6192
|
}
|
|
6028
|
-
handleOperation(operations) {
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6193
|
+
async handleOperation(operations) {
|
|
6194
|
+
const payload = {
|
|
6195
|
+
uo: operations.map((operation) => ({
|
|
6196
|
+
target: operation.contractAddress,
|
|
6197
|
+
data: operation.data,
|
|
6198
|
+
value: operation.value
|
|
6199
|
+
})),
|
|
6200
|
+
overrides: {
|
|
6201
|
+
nonceKey: this.getRandomNonce()
|
|
6202
|
+
}
|
|
6203
|
+
};
|
|
6204
|
+
let retries = this.config.maxRetries;
|
|
6205
|
+
let finalError;
|
|
6206
|
+
while (retries > 0) {
|
|
6207
|
+
try {
|
|
6208
|
+
if (this.config.maxRetries > retries) {
|
|
6209
|
+
const gasFees = await this.calculateGasFees();
|
|
6210
|
+
payload["overrides"] = {
|
|
6211
|
+
maxFeePerGas: `0x${gasFees.toString(16)}`
|
|
6212
|
+
};
|
|
6038
6213
|
}
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
maxFeePerGas: `0x${gasFees.toString(16)}`
|
|
6048
|
-
};
|
|
6214
|
+
const { hash } = await this.sessionKeyClient.sendUserOperation(payload);
|
|
6215
|
+
const txnHash = await this.sessionKeyClient.waitForUserOperationTransaction({
|
|
6216
|
+
hash,
|
|
6217
|
+
tag: "pending",
|
|
6218
|
+
retries: {
|
|
6219
|
+
intervalMs: 200,
|
|
6220
|
+
multiplier: 1.1,
|
|
6221
|
+
maxRetries: 10
|
|
6049
6222
|
}
|
|
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));
|
|
6223
|
+
});
|
|
6224
|
+
return { userOpHash: hash, txnHash };
|
|
6225
|
+
} catch (error) {
|
|
6226
|
+
retries -= 1;
|
|
6227
|
+
if (retries === 0) {
|
|
6228
|
+
finalError = error;
|
|
6229
|
+
break;
|
|
6068
6230
|
}
|
|
6231
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3 * retries));
|
|
6069
6232
|
}
|
|
6070
|
-
|
|
6071
|
-
|
|
6233
|
+
}
|
|
6234
|
+
throw new acpError_default(`Failed to send user operation`, finalError);
|
|
6072
6235
|
}
|
|
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
|
-
});
|
|
6236
|
+
async getJobId(createJobUserOpHash, clientAddress, providerAddress) {
|
|
6237
|
+
const result = await this.sessionKeyClient.getUserOperationReceipt(
|
|
6238
|
+
createJobUserOpHash,
|
|
6239
|
+
"pending"
|
|
6240
|
+
);
|
|
6241
|
+
if (!result) {
|
|
6242
|
+
throw new acpError_default("Failed to get user operation receipt");
|
|
6243
|
+
}
|
|
6244
|
+
const contractLogs = result.logs.filter((log) => {
|
|
6245
|
+
return log.address.toLowerCase() === this.jobManagerAddress.toLowerCase();
|
|
6246
|
+
}).map(
|
|
6247
|
+
(log) => (0, import_viem7.decodeEventLog)({
|
|
6248
|
+
abi: jobManagerAbi_default,
|
|
6249
|
+
data: log.data,
|
|
6250
|
+
topics: log.topics
|
|
6251
|
+
})
|
|
6252
|
+
);
|
|
6253
|
+
const createdJobEvent = contractLogs.find(
|
|
6254
|
+
(log) => log.eventName === "JobCreated" && log.args.client.toLowerCase() === clientAddress.toLowerCase() && log.args.provider.toLowerCase() === providerAddress.toLowerCase()
|
|
6255
|
+
);
|
|
6256
|
+
if (!createdJobEvent) {
|
|
6257
|
+
throw new acpError_default("Failed to find created job event");
|
|
6258
|
+
}
|
|
6259
|
+
return Number(createdJobEvent.args.jobId);
|
|
6099
6260
|
}
|
|
6100
|
-
updateJobX402Nonce(jobId, nonce) {
|
|
6101
|
-
return
|
|
6102
|
-
return yield this.acpX402.updateJobNonce(jobId, nonce);
|
|
6103
|
-
});
|
|
6261
|
+
async updateJobX402Nonce(jobId, nonce) {
|
|
6262
|
+
return await this.acpX402.updateJobNonce(jobId, nonce);
|
|
6104
6263
|
}
|
|
6105
|
-
generateX402Payment(payableRequest, requirements) {
|
|
6106
|
-
return
|
|
6107
|
-
return yield this.acpX402.generatePayment(payableRequest, requirements);
|
|
6108
|
-
});
|
|
6264
|
+
async generateX402Payment(payableRequest, requirements) {
|
|
6265
|
+
return await this.acpX402.generatePayment(payableRequest, requirements);
|
|
6109
6266
|
}
|
|
6110
|
-
performX402Request(url, version2, budget, signature) {
|
|
6111
|
-
return
|
|
6112
|
-
return yield this.acpX402.performRequest(url, version2, budget, signature);
|
|
6113
|
-
});
|
|
6267
|
+
async performX402Request(url, version2, budget, signature) {
|
|
6268
|
+
return await this.acpX402.performRequest(url, version2, budget, signature);
|
|
6114
6269
|
}
|
|
6115
|
-
getX402PaymentDetails(jobId) {
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
}
|
|
6131
|
-
});
|
|
6270
|
+
async getX402PaymentDetails(jobId) {
|
|
6271
|
+
try {
|
|
6272
|
+
const result = await this.publicClient.readContract({
|
|
6273
|
+
address: this.jobManagerAddress,
|
|
6274
|
+
abi: jobManagerAbi_default,
|
|
6275
|
+
functionName: "x402PaymentDetails",
|
|
6276
|
+
args: [BigInt(jobId)]
|
|
6277
|
+
});
|
|
6278
|
+
return {
|
|
6279
|
+
isX402: result[0],
|
|
6280
|
+
isBudgetReceived: result[1]
|
|
6281
|
+
};
|
|
6282
|
+
} catch (error) {
|
|
6283
|
+
throw new acpError_default("Failed to get X402 payment details", error);
|
|
6284
|
+
}
|
|
6132
6285
|
}
|
|
6133
6286
|
getAcpVersion() {
|
|
6134
6287
|
return "2";
|