@virtuals-protocol/acp-node 0.3.0-beta.17 → 0.3.0-beta.18

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.js CHANGED
@@ -35,12 +35,13 @@ var require_package = __commonJS({
35
35
  "package.json"(exports2, module2) {
36
36
  module2.exports = {
37
37
  name: "@virtuals-protocol/acp-node",
38
- version: "0.3.0-beta.17",
38
+ version: "0.3.0-beta.18",
39
39
  main: "./dist/index.js",
40
40
  module: "./dist/index.mjs",
41
41
  types: "./dist/index.d.ts",
42
42
  scripts: {
43
43
  test: "jest",
44
+ "test:ci": "jest --ci --reporters=default --reporters=jest-junit",
44
45
  "test:watch": "jest --watch",
45
46
  "test:coverage": "jest --coverage",
46
47
  tsup: "tsup src/index.ts --dts --format cjs,esm --out-dir dist"
@@ -56,6 +57,7 @@ var require_package = __commonJS({
56
57
  "babel-jest": "^30.2.0",
57
58
  dotenv: "^17.2.3",
58
59
  jest: "^30.2.0",
60
+ "jest-junit": "^16.0.0",
59
61
  "ts-jest": "^29.4.5",
60
62
  typescript: "^5.8.3"
61
63
  },
@@ -89,6 +91,7 @@ __export(index_exports, {
89
91
  AcpJob: () => acpJob_default,
90
92
  AcpJobPhases: () => AcpJobPhases,
91
93
  AcpMemo: () => acpMemo_default,
94
+ AcpMemoState: () => AcpMemoState,
92
95
  AcpMemoStatus: () => AcpMemoStatus,
93
96
  AcpOnlineStatus: () => AcpOnlineStatus,
94
97
  BaseAcpContractClient: () => baseAcpContractClient_default,
@@ -1282,7 +1285,7 @@ var ACP_ABI = [
1282
1285
  var acpAbi_default = ACP_ABI;
1283
1286
 
1284
1287
  // src/acpClient.ts
1285
- var import_viem4 = require("viem");
1288
+ var import_viem6 = require("viem");
1286
1289
  var import_socket = require("socket.io-client");
1287
1290
 
1288
1291
  // src/contractClients/baseAcpContractClient.ts
@@ -1311,27 +1314,42 @@ var acpError_default = AcpError;
1311
1314
 
1312
1315
  // src/acpFare.ts
1313
1316
  var Fare = class _Fare {
1314
- constructor(contractAddress, decimals) {
1317
+ constructor(contractAddress, decimals, chainId) {
1315
1318
  this.contractAddress = contractAddress;
1316
1319
  this.decimals = decimals;
1320
+ this.chainId = chainId;
1317
1321
  }
1318
1322
  formatAmount(amount) {
1319
1323
  return (0, import_viem.parseUnits)(amount.toString(), this.decimals);
1320
1324
  }
1321
- static async fromContractAddress(contractAddress, config = baseAcpConfig) {
1325
+ static async fromContractAddress(contractAddress, config = baseAcpConfig, chainId = config.chain.id) {
1322
1326
  if (contractAddress === config.baseFare.contractAddress) {
1323
1327
  return config.baseFare;
1324
1328
  }
1329
+ let chainConfig = config.chain;
1330
+ let rpcUrl = config.rpcEndpoint;
1331
+ if (chainId !== config.chain.id) {
1332
+ const selectedConfig = config.chains?.find(
1333
+ (chain) => chain.chain.id === chainId
1334
+ );
1335
+ if (!selectedConfig) {
1336
+ throw new acpError_default(
1337
+ `Chain configuration for chainId ${chainId} not found.`
1338
+ );
1339
+ }
1340
+ chainConfig = selectedConfig.chain;
1341
+ rpcUrl = selectedConfig.rpcUrl;
1342
+ }
1325
1343
  const publicClient = (0, import_viem.createPublicClient)({
1326
- chain: config.chain,
1327
- transport: (0, import_viem.http)(config.rpcEndpoint)
1344
+ chain: chainConfig,
1345
+ transport: (0, import_viem.http)(rpcUrl)
1328
1346
  });
1329
1347
  const decimals = await publicClient.readContract({
1330
1348
  address: contractAddress,
1331
1349
  abi: import_viem.erc20Abi,
1332
1350
  functionName: "decimals"
1333
1351
  });
1334
- return new _Fare(contractAddress, decimals);
1352
+ return new _Fare(contractAddress, decimals, chainId);
1335
1353
  }
1336
1354
  };
1337
1355
  var FareAmountBase = class {
@@ -1750,6 +1768,34 @@ var ACP_V2_ABI = [
1750
1768
  stateMutability: "nonpayable",
1751
1769
  type: "function"
1752
1770
  },
1771
+ {
1772
+ inputs: [
1773
+ { internalType: "uint256", name: "jobId", type: "uint256" },
1774
+ { internalType: "string", name: "content", type: "string" },
1775
+ { internalType: "address", name: "token", type: "address" },
1776
+ { internalType: "uint256", name: "amount", type: "uint256" },
1777
+ { internalType: "address", name: "recipient", type: "address" },
1778
+ { internalType: "uint256", name: "feeAmount", type: "uint256" },
1779
+ { internalType: "enum ACPTypes.FeeType", name: "feeType", type: "uint8" },
1780
+ {
1781
+ internalType: "enum ACPTypes.MemoType",
1782
+ name: "memoType",
1783
+ type: "uint8"
1784
+ },
1785
+ { internalType: "uint256", name: "expiredAt", type: "uint256" },
1786
+ { internalType: "bool", name: "isSecured", type: "bool" },
1787
+ {
1788
+ internalType: "enum ACPTypes.JobPhase",
1789
+ name: "nextPhase",
1790
+ type: "uint8"
1791
+ },
1792
+ { internalType: "uint32", name: "lzDstEid", type: "uint32" }
1793
+ ],
1794
+ name: "createCrossChainPayableMemo",
1795
+ outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
1796
+ stateMutability: "nonpayable",
1797
+ type: "function"
1798
+ },
1753
1799
  {
1754
1800
  inputs: [
1755
1801
  { internalType: "address", name: "provider", type: "address" },
@@ -1934,7 +1980,12 @@ var ACP_V2_ABI = [
1934
1980
  name: "nextPhase",
1935
1981
  type: "uint8"
1936
1982
  },
1937
- { internalType: "uint256", name: "expiredAt", type: "uint256" }
1983
+ { internalType: "uint256", name: "expiredAt", type: "uint256" },
1984
+ {
1985
+ internalType: "enum ACPTypes.MemoState",
1986
+ name: "state",
1987
+ type: "uint8"
1988
+ }
1938
1989
  ],
1939
1990
  internalType: "struct ACPTypes.Memo[]",
1940
1991
  name: "memos",
@@ -1981,7 +2032,12 @@ var ACP_V2_ABI = [
1981
2032
  name: "nextPhase",
1982
2033
  type: "uint8"
1983
2034
  },
1984
- { internalType: "uint256", name: "expiredAt", type: "uint256" }
2035
+ { internalType: "uint256", name: "expiredAt", type: "uint256" },
2036
+ {
2037
+ internalType: "enum ACPTypes.MemoState",
2038
+ name: "state",
2039
+ type: "uint8"
2040
+ }
1985
2041
  ],
1986
2042
  internalType: "struct ACPTypes.Memo[]",
1987
2043
  name: "memos",
@@ -2024,7 +2080,12 @@ var ACP_V2_ABI = [
2024
2080
  name: "nextPhase",
2025
2081
  type: "uint8"
2026
2082
  },
2027
- { internalType: "uint256", name: "expiredAt", type: "uint256" }
2083
+ { internalType: "uint256", name: "expiredAt", type: "uint256" },
2084
+ {
2085
+ internalType: "enum ACPTypes.MemoState",
2086
+ name: "state",
2087
+ type: "uint8"
2088
+ }
2028
2089
  ],
2029
2090
  internalType: "struct ACPTypes.Memo[]",
2030
2091
  name: "memos",
@@ -2280,7 +2341,7 @@ var acpAbiV2_default = ACP_V2_ABI;
2280
2341
  var V1_MAX_RETRIES = 10;
2281
2342
  var V2_MAX_RETRIES = 3;
2282
2343
  var AcpContractConfig2 = class {
2283
- constructor(chain, contractAddress, baseFare, alchemyRpcUrl, acpUrl, abi, maxRetries, rpcEndpoint, x402Config) {
2344
+ constructor(chain, contractAddress, baseFare, alchemyRpcUrl, acpUrl, abi, maxRetries, rpcEndpoint, x402Config, chains = []) {
2284
2345
  this.chain = chain;
2285
2346
  this.contractAddress = contractAddress;
2286
2347
  this.baseFare = baseFare;
@@ -2290,6 +2351,7 @@ var AcpContractConfig2 = class {
2290
2351
  this.maxRetries = maxRetries;
2291
2352
  this.rpcEndpoint = rpcEndpoint;
2292
2353
  this.x402Config = x402Config;
2354
+ this.chains = chains;
2293
2355
  }
2294
2356
  };
2295
2357
  var baseSepoliaAcpConfig = new AcpContractConfig2(
@@ -3535,6 +3597,16 @@ var HTTP_STATUS_CODES = {
3535
3597
  PAYMENT_REQUIRED: 402
3536
3598
  };
3537
3599
  var SINGLE_SIGNER_VALIDATION_MODULE_ADDRESS = "0x00000000000099DE0BF6fA90dEB851E2A2df7d83";
3600
+ var ASSET_MANAGER_ADDRESSES = {
3601
+ [import_chains.bscTestnet.id]: "0xfCf52B02936623852dd5132007E9414f9060168b",
3602
+ [import_chains.bsc.id]: "",
3603
+ [import_chains.polygonAmoy.id]: "0xfCf52B02936623852dd5132007E9414f9060168b",
3604
+ [import_chains.polygon.id]: "",
3605
+ [import_chains.arbitrum.id]: "",
3606
+ [import_chains.arbitrumSepolia.id]: "0xfCf52B02936623852dd5132007E9414f9060168b",
3607
+ [import_chains.sepolia.id]: "0xfCf52B02936623852dd5132007E9414f9060168b",
3608
+ [import_chains.mainnet.id]: ""
3609
+ };
3538
3610
 
3539
3611
  // src/contractClients/baseAcpContractClient.ts
3540
3612
  var MemoType = /* @__PURE__ */ ((MemoType3) => {
@@ -3549,6 +3621,7 @@ var MemoType = /* @__PURE__ */ ((MemoType3) => {
3549
3621
  MemoType3[MemoType3["PAYABLE_TRANSFER_ESCROW"] = 8] = "PAYABLE_TRANSFER_ESCROW";
3550
3622
  MemoType3[MemoType3["NOTIFICATION"] = 9] = "NOTIFICATION";
3551
3623
  MemoType3[MemoType3["PAYABLE_NOTIFICATION"] = 10] = "PAYABLE_NOTIFICATION";
3624
+ MemoType3[MemoType3["TRANSFER_EVENT"] = 11] = "TRANSFER_EVENT";
3552
3625
  return MemoType3;
3553
3626
  })(MemoType || {});
3554
3627
  var AcpJobPhases = /* @__PURE__ */ ((AcpJobPhases3) => {
@@ -3565,6 +3638,7 @@ var BaseAcpContractClient = class {
3565
3638
  constructor(agentWalletAddress, config = baseAcpConfig) {
3566
3639
  this.agentWalletAddress = agentWalletAddress;
3567
3640
  this.config = config;
3641
+ this.publicClients = {};
3568
3642
  this.chain = config.chain;
3569
3643
  this.abi = config.abi;
3570
3644
  this.contractAddress = config.contractAddress;
@@ -3664,12 +3738,12 @@ ${JSON.stringify(
3664
3738
  throw new acpError_default("Failed to create job", error);
3665
3739
  }
3666
3740
  }
3667
- approveAllowance(amountBaseUnit, paymentTokenAddress = this.config.baseFare.contractAddress) {
3741
+ approveAllowance(amountBaseUnit, paymentTokenAddress = this.config.baseFare.contractAddress, targetAddress) {
3668
3742
  try {
3669
3743
  const data = (0, import_viem2.encodeFunctionData)({
3670
3744
  abi: import_viem2.erc20Abi,
3671
3745
  functionName: "approve",
3672
- args: [this.contractAddress, amountBaseUnit]
3746
+ args: [targetAddress ?? this.contractAddress, amountBaseUnit]
3673
3747
  });
3674
3748
  const payload = {
3675
3749
  data,
@@ -3708,6 +3782,35 @@ ${JSON.stringify(
3708
3782
  throw new acpError_default("Failed to create payable memo", error);
3709
3783
  }
3710
3784
  }
3785
+ createCrossChainPayableMemo(jobId, content, token, amountBaseUnit, recipient, feeAmountBaseUnit, feeType, type, expiredAt, nextPhase, destinationEid, secured = true) {
3786
+ try {
3787
+ const data = (0, import_viem2.encodeFunctionData)({
3788
+ abi: this.abi,
3789
+ functionName: "createCrossChainPayableMemo",
3790
+ args: [
3791
+ jobId,
3792
+ content,
3793
+ token,
3794
+ amountBaseUnit,
3795
+ recipient,
3796
+ feeAmountBaseUnit,
3797
+ feeType,
3798
+ type,
3799
+ expiredAt,
3800
+ secured,
3801
+ nextPhase,
3802
+ destinationEid
3803
+ ]
3804
+ });
3805
+ const payload = {
3806
+ data,
3807
+ contractAddress: this.contractAddress
3808
+ };
3809
+ return payload;
3810
+ } catch (error) {
3811
+ throw new acpError_default("Failed to create cross chain payable memo", error);
3812
+ }
3813
+ }
3711
3814
  createMemo(jobId, content, type, isSecured, nextPhase) {
3712
3815
  try {
3713
3816
  const data = (0, import_viem2.encodeFunctionData)({
@@ -3724,6 +3827,22 @@ ${JSON.stringify(
3724
3827
  throw new acpError_default("Failed to create memo", error);
3725
3828
  }
3726
3829
  }
3830
+ createMemoWithMetadata(jobId, content, type, isSecured, nextPhase, metadata) {
3831
+ try {
3832
+ const data = (0, import_viem2.encodeFunctionData)({
3833
+ abi: this.abi,
3834
+ functionName: "createMemoWithMetadata",
3835
+ args: [jobId, content, type, isSecured, nextPhase, metadata]
3836
+ });
3837
+ const payload = {
3838
+ data,
3839
+ contractAddress: this.contractAddress
3840
+ };
3841
+ return payload;
3842
+ } catch (error) {
3843
+ throw new acpError_default("Failed to create memo with metadata", error);
3844
+ }
3845
+ }
3727
3846
  signMemo(memoId, isApproved, reason) {
3728
3847
  try {
3729
3848
  const data = (0, import_viem2.encodeFunctionData)({
@@ -3809,9 +3928,47 @@ ${JSON.stringify(
3809
3928
  throw new acpError_default("Failed to submit TransferWithAuthorization", error);
3810
3929
  }
3811
3930
  }
3931
+ async getERC20Balance(chainId, tokenAddress, walletAddress) {
3932
+ const publicClient = this.publicClients[chainId];
3933
+ if (!publicClient) {
3934
+ throw new acpError_default(`Public client for chainId ${chainId} not found`);
3935
+ }
3936
+ return await publicClient.readContract({
3937
+ address: tokenAddress,
3938
+ abi: import_viem2.erc20Abi,
3939
+ functionName: "balanceOf",
3940
+ args: [walletAddress]
3941
+ });
3942
+ }
3943
+ async getERC20Allowance(chainId, tokenAddress, walletAddress, spenderAddress) {
3944
+ const publicClient = this.publicClients[chainId];
3945
+ if (!publicClient) {
3946
+ throw new acpError_default(`Public client for chainId ${chainId} not found`);
3947
+ }
3948
+ return await publicClient.readContract({
3949
+ address: tokenAddress,
3950
+ abi: import_viem2.erc20Abi,
3951
+ functionName: "allowance",
3952
+ args: [walletAddress, spenderAddress]
3953
+ });
3954
+ }
3955
+ async getERC20Symbol(chainId, tokenAddress) {
3956
+ const publicClient = this.publicClients[chainId];
3957
+ if (!publicClient) {
3958
+ throw new acpError_default(`Public client for chainId ${chainId} not found`);
3959
+ }
3960
+ return await publicClient.readContract({
3961
+ address: tokenAddress,
3962
+ abi: import_viem2.erc20Abi,
3963
+ functionName: "symbol"
3964
+ });
3965
+ }
3812
3966
  };
3813
3967
  var baseAcpContractClient_default = BaseAcpContractClient;
3814
3968
 
3969
+ // src/acpJob.ts
3970
+ var import_viem5 = require("viem");
3971
+
3815
3972
  // src/interfaces.ts
3816
3973
  var AcpMemoStatus = /* @__PURE__ */ ((AcpMemoStatus2) => {
3817
3974
  AcpMemoStatus2["PENDING"] = "PENDING";
@@ -3819,6 +3976,15 @@ var AcpMemoStatus = /* @__PURE__ */ ((AcpMemoStatus2) => {
3819
3976
  AcpMemoStatus2["REJECTED"] = "REJECTED";
3820
3977
  return AcpMemoStatus2;
3821
3978
  })(AcpMemoStatus || {});
3979
+ var AcpMemoState = /* @__PURE__ */ ((AcpMemoState2) => {
3980
+ AcpMemoState2["NONE"] = "NONE";
3981
+ AcpMemoState2["PENDING"] = "PENDING";
3982
+ AcpMemoState2["IN_PROGRESS"] = "IN_PROGRESS";
3983
+ AcpMemoState2["READY"] = "READY";
3984
+ AcpMemoState2["COMPLETED"] = "COMPLETED";
3985
+ AcpMemoState2["REJECTED"] = "REJECTED";
3986
+ return AcpMemoState2;
3987
+ })(AcpMemoState || {});
3822
3988
  var AcpAgentSort = /* @__PURE__ */ ((AcpAgentSort2) => {
3823
3989
  AcpAgentSort2["SUCCESSFUL_JOB_COUNT"] = "successfulJobCount";
3824
3990
  AcpAgentSort2["SUCCESS_RATE"] = "successRate";
@@ -3857,6 +4023,8 @@ var PositionDirection = /* @__PURE__ */ ((PositionDirection2) => {
3857
4023
  })(PositionDirection || {});
3858
4024
 
3859
4025
  // src/utils.ts
4026
+ var import_viem3 = require("viem");
4027
+ var import_chains2 = require("viem/chains");
3860
4028
  function tryParseJson(content) {
3861
4029
  try {
3862
4030
  return JSON.parse(content);
@@ -3873,9 +4041,34 @@ function safeBase64Encode(data) {
3873
4041
  }
3874
4042
  return Buffer.from(data).toString("base64");
3875
4043
  }
4044
+ function getDestinationEndpointId(chainId) {
4045
+ switch (chainId) {
4046
+ case import_chains2.baseSepolia.id:
4047
+ return 40245;
4048
+ case import_chains2.sepolia.id:
4049
+ return 40161;
4050
+ case import_chains2.polygonAmoy.id:
4051
+ return 40267;
4052
+ case import_chains2.arbitrumSepolia.id:
4053
+ return 40231;
4054
+ case import_chains2.bscTestnet.id:
4055
+ return 40102;
4056
+ case import_chains2.base.id:
4057
+ return 30184;
4058
+ case import_chains2.mainnet.id:
4059
+ return 30101;
4060
+ case import_chains2.polygon.id:
4061
+ return 30109;
4062
+ case import_chains2.arbitrum.id:
4063
+ return 30110;
4064
+ case import_chains2.bsc.id:
4065
+ return 30102;
4066
+ }
4067
+ throw new Error(`Unsupported chain ID: ${chainId}`);
4068
+ }
3876
4069
 
3877
4070
  // src/acpJobOffering.ts
3878
- var import_viem3 = require("viem");
4071
+ var import_viem4 = require("viem");
3879
4072
  var import_ajv = __toESM(require("ajv"));
3880
4073
  var AcpJobOffering = class {
3881
4074
  constructor(acpClient, acpContractClient, providerAddress, name, price, priceType = "fixed" /* FIXED */, requirement) {
@@ -3934,7 +4127,7 @@ var AcpJobOffering = class {
3934
4127
  } else {
3935
4128
  createJobPayload = this.acpContractClient.createJobWithAccount(
3936
4129
  account.id,
3937
- evaluatorAddress || import_viem3.zeroAddress,
4130
+ evaluatorAddress || import_viem4.zeroAddress,
3938
4131
  fareAmount.amount,
3939
4132
  fareAmount.fare.contractAddress,
3940
4133
  expiredAt,
@@ -4075,20 +4268,38 @@ var AcpJob = class {
4075
4268
  }
4076
4269
  const feeAmount = new FareAmount(0, this.acpContractClient.config.baseFare);
4077
4270
  const isPercentagePricing = this.priceType === "percentage" /* PERCENTAGE */;
4078
- operations.push(
4079
- this.acpContractClient.createPayableMemo(
4080
- this.id,
4081
- content,
4082
- amount.amount,
4083
- recipient,
4084
- isPercentagePricing ? BigInt(Math.round(this.priceValue * 1e4)) : feeAmount.amount,
4085
- isPercentagePricing ? 3 /* PERCENTAGE_FEE */ : 0 /* NO_FEE */,
4086
- 2 /* TRANSACTION */,
4087
- type,
4088
- expiredAt,
4089
- amount.fare.contractAddress
4090
- )
4091
- );
4271
+ if (amount.fare.chainId && amount.fare.chainId !== this.acpContractClient.config.chain.id) {
4272
+ operations.push(
4273
+ this.acpContractClient.createCrossChainPayableMemo(
4274
+ this.id,
4275
+ content,
4276
+ amount.fare.contractAddress,
4277
+ amount.amount,
4278
+ recipient,
4279
+ isPercentagePricing ? BigInt(Math.round(this.priceValue * 1e4)) : feeAmount.amount,
4280
+ isPercentagePricing ? 3 /* PERCENTAGE_FEE */ : 0 /* NO_FEE */,
4281
+ type,
4282
+ expiredAt,
4283
+ 2 /* TRANSACTION */,
4284
+ getDestinationEndpointId(amount.fare.chainId)
4285
+ )
4286
+ );
4287
+ } else {
4288
+ operations.push(
4289
+ this.acpContractClient.createPayableMemo(
4290
+ this.id,
4291
+ content,
4292
+ amount.amount,
4293
+ recipient,
4294
+ isPercentagePricing ? BigInt(Math.round(this.priceValue * 1e4)) : feeAmount.amount,
4295
+ isPercentagePricing ? 3 /* PERCENTAGE_FEE */ : 0 /* NO_FEE */,
4296
+ 2 /* TRANSACTION */,
4297
+ type,
4298
+ expiredAt,
4299
+ amount.fare.contractAddress
4300
+ )
4301
+ );
4302
+ }
4092
4303
  return await this.acpContractClient.handleOperation(operations);
4093
4304
  }
4094
4305
  async payAndAcceptRequirement(reason) {
@@ -4221,6 +4432,9 @@ var AcpJob = class {
4221
4432
  if (this.latestMemo?.nextPhase !== 3 /* EVALUATION */) {
4222
4433
  throw new acpError_default("No transaction memo found");
4223
4434
  }
4435
+ if (amount.fare.chainId !== this.acpContractClient.config.chain.id) {
4436
+ return await this.deliverCrossChainPayable(this.clientAddress, amount);
4437
+ }
4224
4438
  const operations = [];
4225
4439
  operations.push(
4226
4440
  this.acpContractClient.approveAllowance(
@@ -4351,6 +4565,56 @@ var AcpJob = class {
4351
4565
  waitMs = Math.min(waitMs * 2, maxWaitMs);
4352
4566
  }
4353
4567
  }
4568
+ async deliverCrossChainPayable(recipient, amount) {
4569
+ if (!amount.fare.chainId) {
4570
+ throw new acpError_default("Chain ID is required for cross chain payable");
4571
+ }
4572
+ const chainId = amount.fare.chainId;
4573
+ const tokenBalance = await this.acpContractClient.getERC20Balance(
4574
+ chainId,
4575
+ amount.fare.contractAddress,
4576
+ this.acpContractClient.agentWalletAddress
4577
+ );
4578
+ if (tokenBalance < amount.amount) {
4579
+ throw new acpError_default("Insufficient token balance for cross chain payable");
4580
+ }
4581
+ const currentAllowance = await this.acpContractClient.getERC20Allowance(
4582
+ chainId,
4583
+ amount.fare.contractAddress,
4584
+ this.acpContractClient.agentWalletAddress,
4585
+ ASSET_MANAGER_ADDRESSES[chainId]
4586
+ );
4587
+ const approveAllowanceOperation = this.acpContractClient.approveAllowance(
4588
+ amount.amount + currentAllowance,
4589
+ amount.fare.contractAddress,
4590
+ ASSET_MANAGER_ADDRESSES[chainId]
4591
+ );
4592
+ await this.acpContractClient.handleOperation(
4593
+ [approveAllowanceOperation],
4594
+ chainId
4595
+ );
4596
+ const tokenSymbol = await this.acpContractClient.getERC20Symbol(
4597
+ chainId,
4598
+ amount.fare.contractAddress
4599
+ );
4600
+ const createMemoOperation = this.acpContractClient.createCrossChainPayableMemo(
4601
+ this.id,
4602
+ `Performing cross chain payable transfer of ${(0, import_viem5.formatUnits)(
4603
+ amount.amount,
4604
+ amount.fare.decimals
4605
+ )} ${tokenSymbol} to ${recipient}`,
4606
+ amount.fare.contractAddress,
4607
+ amount.amount,
4608
+ recipient,
4609
+ BigInt(0),
4610
+ 0 /* NO_FEE */,
4611
+ 7 /* PAYABLE_TRANSFER */,
4612
+ new Date(Date.now() + 1e3 * 60 * 5),
4613
+ 4 /* COMPLETED */,
4614
+ getDestinationEndpointId(chainId)
4615
+ );
4616
+ await this.acpContractClient.handleOperation([createMemoOperation]);
4617
+ }
4354
4618
  [util.inspect.custom]() {
4355
4619
  return {
4356
4620
  id: this.id,
@@ -4374,7 +4638,7 @@ var acpJob_default = AcpJob;
4374
4638
  // src/acpMemo.ts
4375
4639
  var import_util = __toESM(require("util"));
4376
4640
  var AcpMemo = class {
4377
- constructor(contractClient, id, type, content, nextPhase, status, senderAddress, signedReason, expiry, payableDetails, txHash, signedTxHash) {
4641
+ constructor(contractClient, id, type, content, nextPhase, status, senderAddress, signedReason, expiry, payableDetails, txHash, signedTxHash, state) {
4378
4642
  this.contractClient = contractClient;
4379
4643
  this.id = id;
4380
4644
  this.type = type;
@@ -4387,6 +4651,7 @@ var AcpMemo = class {
4387
4651
  this.payableDetails = payableDetails;
4388
4652
  this.txHash = txHash;
4389
4653
  this.signedTxHash = signedTxHash;
4654
+ this.state = state;
4390
4655
  if (this.payableDetails) {
4391
4656
  this.payableDetails.amount = BigInt(this.payableDetails.amount);
4392
4657
  this.payableDetails.feeAmount = BigInt(this.payableDetails.feeAmount);
@@ -4537,7 +4802,8 @@ var AcpClient = class {
4537
4802
  memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4538
4803
  memo.payableDetails,
4539
4804
  memo.txHash,
4540
- memo.signedTxHash
4805
+ memo.signedTxHash,
4806
+ memo.state
4541
4807
  );
4542
4808
  }),
4543
4809
  data.phase,
@@ -4575,7 +4841,8 @@ var AcpClient = class {
4575
4841
  memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4576
4842
  memo.payableDetails,
4577
4843
  memo.txHash,
4578
- memo.signedTxHash
4844
+ memo.signedTxHash,
4845
+ memo.state
4579
4846
  );
4580
4847
  }),
4581
4848
  data.phase,
@@ -4600,7 +4867,14 @@ var AcpClient = class {
4600
4867
  process.on("SIGTERM", cleanup);
4601
4868
  }
4602
4869
  async browseAgents(keyword, options) {
4603
- let { cluster, sort_by, top_k, graduationStatus, onlineStatus, showHiddenOfferings } = options;
4870
+ let {
4871
+ cluster,
4872
+ sort_by,
4873
+ top_k,
4874
+ graduationStatus,
4875
+ onlineStatus,
4876
+ showHiddenOfferings
4877
+ } = options;
4604
4878
  top_k = top_k ?? 5;
4605
4879
  let url = `${this.acpUrl}/api/agents/v4/search?search=${keyword}`;
4606
4880
  if (sort_by && sort_by.length > 0) {
@@ -4682,7 +4956,7 @@ var AcpClient = class {
4682
4956
  baseAcpConfig.contractAddress,
4683
4957
  baseAcpX402Config.contractAddress
4684
4958
  ].includes(this.acpContractClient.config.contractAddress);
4685
- const defaultEvaluatorAddress = isV1 && !evaluatorAddress ? this.walletAddress : import_viem4.zeroAddress;
4959
+ const defaultEvaluatorAddress = isV1 && !evaluatorAddress ? this.walletAddress : import_viem6.zeroAddress;
4686
4960
  const chainId = this.acpContractClient.config.chain.id;
4687
4961
  const isUsdcPaymentToken = USDC_TOKEN_ADDRESS[chainId].toLowerCase() === fareAmount.fare.contractAddress.toLowerCase();
4688
4962
  const isX402Job = this.acpContractClient.config.x402Config && isUsdcPaymentToken;
@@ -4791,7 +5065,8 @@ var AcpClient = class {
4791
5065
  memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4792
5066
  memo.payableDetails,
4793
5067
  memo.txHash,
4794
- memo.signedTxHash
5068
+ memo.signedTxHash,
5069
+ memo.state
4795
5070
  )
4796
5071
  );
4797
5072
  jobs.push(
@@ -4865,7 +5140,8 @@ var AcpClient = class {
4865
5140
  memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4866
5141
  memo.payableDetails,
4867
5142
  memo.txHash,
4868
- memo.signedTxHash
5143
+ memo.signedTxHash,
5144
+ memo.state
4869
5145
  )
4870
5146
  );
4871
5147
  return new acpJob_default(
@@ -4924,7 +5200,8 @@ var AcpClient = class {
4924
5200
  memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4925
5201
  memo.payableDetails,
4926
5202
  memo.txHash,
4927
- memo.signedTxHash
5203
+ memo.signedTxHash,
5204
+ memo.state
4928
5205
  );
4929
5206
  } catch (err) {
4930
5207
  throw new acpError_default(
@@ -4988,10 +5265,10 @@ var acpClient_default = AcpClient;
4988
5265
  var import_core = require("@aa-sdk/core");
4989
5266
  var import_infra2 = require("@account-kit/infra");
4990
5267
  var import_smart_contracts = require("@account-kit/smart-contracts");
4991
- var import_viem6 = require("viem");
5268
+ var import_viem8 = require("viem");
4992
5269
 
4993
5270
  // src/acpX402.ts
4994
- var import_viem5 = require("viem");
5271
+ var import_viem7 = require("viem");
4995
5272
  var import_crypto = require("crypto");
4996
5273
  var AcpX402 = class {
4997
5274
  constructor(config, sessionKeyClient, publicClient) {
@@ -5033,6 +5310,9 @@ var AcpX402 = class {
5033
5310
  const acpJob = await response.json();
5034
5311
  return acpJob;
5035
5312
  } catch (error) {
5313
+ if (error instanceof acpError_default) {
5314
+ throw error;
5315
+ }
5036
5316
  throw new acpError_default("Failed to update job X402 nonce", error);
5037
5317
  }
5038
5318
  }
@@ -5046,7 +5326,7 @@ var AcpX402 = class {
5046
5326
  contracts: [
5047
5327
  {
5048
5328
  address: USDC_CONTRACT,
5049
- abi: import_viem5.erc20Abi,
5329
+ abi: import_viem7.erc20Abi,
5050
5330
  functionName: "name"
5051
5331
  },
5052
5332
  {
@@ -5121,6 +5401,9 @@ var AcpX402 = class {
5121
5401
  data
5122
5402
  };
5123
5403
  } catch (error) {
5404
+ if (error instanceof acpError_default) {
5405
+ throw error;
5406
+ }
5124
5407
  throw new acpError_default("Failed to perform X402 request", error);
5125
5408
  }
5126
5409
  }
@@ -5246,7 +5529,7 @@ var AcpContractClient = class _AcpContractClient extends baseAcpContractClient_d
5246
5529
  const contractLogs = result.logs.filter((log) => {
5247
5530
  return log.address.toLowerCase() === this.contractAddress.toLowerCase();
5248
5531
  }).map(
5249
- (log) => (0, import_viem6.decodeEventLog)({
5532
+ (log) => (0, import_viem8.decodeEventLog)({
5250
5533
  abi: this.abi,
5251
5534
  data: log.data,
5252
5535
  topics: log.topics
@@ -5262,7 +5545,7 @@ var AcpContractClient = class _AcpContractClient extends baseAcpContractClient_d
5262
5545
  }
5263
5546
  createJob(providerAddress, evaluatorAddress, expireAt, paymentTokenAddress, budgetBaseUnit, metadata, isX402Job) {
5264
5547
  try {
5265
- const data = (0, import_viem6.encodeFunctionData)({
5548
+ const data = (0, import_viem8.encodeFunctionData)({
5266
5549
  abi: this.abi,
5267
5550
  functionName: isX402Job ? "createJobWithX402" : "createJob",
5268
5551
  args: [
@@ -5282,7 +5565,7 @@ var AcpContractClient = class _AcpContractClient extends baseAcpContractClient_d
5282
5565
  }
5283
5566
  setBudgetWithPaymentToken(jobId, budgetBaseUnit, paymentTokenAddress = this.config.baseFare.contractAddress) {
5284
5567
  try {
5285
- const data = (0, import_viem6.encodeFunctionData)({
5568
+ const data = (0, import_viem8.encodeFunctionData)({
5286
5569
  abi: this.abi,
5287
5570
  functionName: "setBudgetWithPaymentToken",
5288
5571
  args: [jobId, budgetBaseUnit, paymentTokenAddress]
@@ -5298,7 +5581,7 @@ var AcpContractClient = class _AcpContractClient extends baseAcpContractClient_d
5298
5581
  }
5299
5582
  createPayableMemo(jobId, content, amountBaseUnit, recipient, feeAmountBaseUnit, feeType, nextPhase, type, expiredAt, token = this.config.baseFare.contractAddress, secured = true) {
5300
5583
  try {
5301
- const data = (0, import_viem6.encodeFunctionData)({
5584
+ const data = (0, import_viem8.encodeFunctionData)({
5302
5585
  abi: this.abi,
5303
5586
  functionName: "createPayableMemo",
5304
5587
  args: [
@@ -5348,7 +5631,7 @@ var acpContractClient_default = AcpContractClient;
5348
5631
  var import_core2 = require("@aa-sdk/core");
5349
5632
  var import_infra3 = require("@account-kit/infra");
5350
5633
  var import_smart_contracts2 = require("@account-kit/smart-contracts");
5351
- var import_viem7 = require("viem");
5634
+ var import_viem9 = require("viem");
5352
5635
 
5353
5636
  // src/abis/jobManagerAbi.ts
5354
5637
  var JOB_MANAGER_ABI = [
@@ -6052,6 +6335,7 @@ var JOB_MANAGER_ABI = [
6052
6335
  var jobManagerAbi_default = JOB_MANAGER_ABI;
6053
6336
 
6054
6337
  // src/contractClients/acpContractClientV2.ts
6338
+ var import_chains3 = require("viem/chains");
6055
6339
  var AcpContractClientV2 = class _AcpContractClientV2 extends baseAcpContractClient_default {
6056
6340
  constructor(jobManagerAddress, memoManagerAddress, accountManagerAddress, agentWalletAddress, config = baseAcpConfigV2) {
6057
6341
  super(agentWalletAddress, config);
@@ -6061,11 +6345,20 @@ var AcpContractClientV2 = class _AcpContractClientV2 extends baseAcpContractClie
6061
6345
  this.PRIORITY_FEE_MULTIPLIER = 2;
6062
6346
  this.MAX_FEE_PER_GAS = 2e7;
6063
6347
  this.MAX_PRIORITY_FEE_PER_GAS = 21e6;
6348
+ this.GAS_FEE_MULTIPLIER = 0.5;
6349
+ this._sessionKeyClients = {};
6064
6350
  }
6065
6351
  static async build(walletPrivateKey, sessionEntityKeyId, agentWalletAddress, config = baseAcpConfigV2) {
6066
- const publicClient = (0, import_viem7.createPublicClient)({
6352
+ const publicClients = {};
6353
+ for (const chain of config.chains) {
6354
+ publicClients[chain.chain.id] = (0, import_viem9.createPublicClient)({
6355
+ chain: chain.chain,
6356
+ transport: (0, import_viem9.http)(chain.rpcUrl)
6357
+ });
6358
+ }
6359
+ const publicClient = (0, import_viem9.createPublicClient)({
6067
6360
  chain: config.chain,
6068
- transport: (0, import_viem7.http)(config.rpcEndpoint)
6361
+ transport: (0, import_viem9.http)(config.rpcEndpoint)
6069
6362
  });
6070
6363
  const [jobManagerAddress, memoManagerAddress, accountManagerAddress] = await publicClient.multicall({
6071
6364
  contracts: [
@@ -6098,6 +6391,7 @@ var AcpContractClientV2 = class _AcpContractClientV2 extends baseAcpContractClie
6098
6391
  agentWalletAddress,
6099
6392
  config
6100
6393
  );
6394
+ acpContractClient.publicClients = publicClients;
6101
6395
  await acpContractClient.init(walletPrivateKey, sessionEntityKeyId);
6102
6396
  return acpContractClient;
6103
6397
  }
@@ -6116,6 +6410,21 @@ var AcpContractClientV2 = class _AcpContractClientV2 extends baseAcpContractClie
6116
6410
  isGlobalValidation: true
6117
6411
  }
6118
6412
  });
6413
+ for (const chain of this.config.chains) {
6414
+ this._sessionKeyClients[chain.chain.id] = await (0, import_smart_contracts2.createModularAccountV2Client)({
6415
+ chain: chain.chain,
6416
+ transport: (0, import_infra3.alchemy)({
6417
+ rpcUrl: `${this.config.alchemyRpcUrl}?chainId=${chain.chain.id}`
6418
+ }),
6419
+ signer: sessionKeySigner,
6420
+ policyId: "186aaa4a-5f57-4156-83fb-e456365a8820",
6421
+ accountAddress: this.agentWalletAddress,
6422
+ signerEntity: {
6423
+ entityId: sessionEntityKeyId,
6424
+ isGlobalValidation: true
6425
+ }
6426
+ });
6427
+ }
6119
6428
  this._acpX402 = new AcpX402(
6120
6429
  this.config,
6121
6430
  this.sessionKeyClient,
@@ -6128,7 +6437,10 @@ var AcpContractClientV2 = class _AcpContractClientV2 extends baseAcpContractClie
6128
6437
  `ACP Contract Client validation failed: agent account ${this.agentWalletAddress} is not deployed on-chain`
6129
6438
  );
6130
6439
  }
6131
- await this.validateSessionKeyOnChain(sessionSignerAddress, sessionEntityKeyId);
6440
+ await this.validateSessionKeyOnChain(
6441
+ sessionSignerAddress,
6442
+ sessionEntityKeyId
6443
+ );
6132
6444
  console.log("Connected to ACP:", {
6133
6445
  agentWalletAddress: this.agentWalletAddress,
6134
6446
  whitelistedWalletAddress: sessionSignerAddress,
@@ -6156,11 +6468,20 @@ var AcpContractClientV2 = class _AcpContractClientV2 extends baseAcpContractClie
6156
6468
  }
6157
6469
  return this._acpX402;
6158
6470
  }
6159
- async calculateGasFees() {
6471
+ async calculateGasFees(chainId) {
6472
+ if (chainId) {
6473
+ const { maxFeePerGas } = await this.publicClients[chainId].estimateFeesPerGas();
6474
+ const increasedMaxFeePerGas = BigInt(maxFeePerGas) + BigInt(maxFeePerGas) * BigInt(this.GAS_FEE_MULTIPLIER * 100) / BigInt(100);
6475
+ return increasedMaxFeePerGas;
6476
+ }
6160
6477
  const finalMaxFeePerGas = BigInt(this.MAX_FEE_PER_GAS) + BigInt(this.MAX_PRIORITY_FEE_PER_GAS) * BigInt(Math.max(0, this.PRIORITY_FEE_MULTIPLIER - 1));
6161
6478
  return finalMaxFeePerGas;
6162
6479
  }
6163
- async handleOperation(operations) {
6480
+ async handleOperation(operations, chainId) {
6481
+ const sessionKeyClient = chainId ? this._sessionKeyClients[chainId] : this.sessionKeyClient;
6482
+ if (!sessionKeyClient) {
6483
+ throw new acpError_default("Session key client not initialized");
6484
+ }
6164
6485
  const payload = {
6165
6486
  uo: operations.map((operation) => ({
6166
6487
  target: operation.contractAddress,
@@ -6181,16 +6502,21 @@ var AcpContractClientV2 = class _AcpContractClientV2 extends baseAcpContractClie
6181
6502
  maxFeePerGas: `0x${gasFees.toString(16)}`
6182
6503
  };
6183
6504
  }
6184
- const { hash } = await this.sessionKeyClient.sendUserOperation(payload);
6185
- const txnHash = await this.sessionKeyClient.waitForUserOperationTransaction({
6505
+ const { hash } = await sessionKeyClient.sendUserOperation(payload);
6506
+ const checkTransactionConfig = {
6186
6507
  hash,
6187
- tag: "pending",
6188
6508
  retries: {
6189
6509
  intervalMs: 200,
6190
6510
  multiplier: 1.1,
6191
6511
  maxRetries: 10
6192
6512
  }
6193
- });
6513
+ };
6514
+ if (!chainId || chainId === import_chains3.baseSepolia.id || chainId === import_chains3.base.id) {
6515
+ checkTransactionConfig["tag"] = "pending";
6516
+ }
6517
+ const txnHash = await sessionKeyClient.waitForUserOperationTransaction(
6518
+ checkTransactionConfig
6519
+ );
6194
6520
  return { userOpHash: hash, txnHash };
6195
6521
  } catch (error) {
6196
6522
  retries -= 1;
@@ -6214,7 +6540,7 @@ var AcpContractClientV2 = class _AcpContractClientV2 extends baseAcpContractClie
6214
6540
  const contractLogs = result.logs.filter((log) => {
6215
6541
  return log.address.toLowerCase() === this.jobManagerAddress.toLowerCase();
6216
6542
  }).map(
6217
- (log) => (0, import_viem7.decodeEventLog)({
6543
+ (log) => (0, import_viem9.decodeEventLog)({
6218
6544
  abi: jobManagerAbi_default,
6219
6545
  data: log.data,
6220
6546
  topics: log.topics
@@ -6273,6 +6599,7 @@ var index_default = acpClient_default;
6273
6599
  AcpJob,
6274
6600
  AcpJobPhases,
6275
6601
  AcpMemo,
6602
+ AcpMemoState,
6276
6603
  AcpMemoStatus,
6277
6604
  AcpOnlineStatus,
6278
6605
  BaseAcpContractClient,