@virtuals-protocol/acp-node 0.3.0-beta.22 → 0.3.0-beta.24

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,7 +35,7 @@ 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.22",
38
+ version: "0.3.0-beta.24",
39
39
  main: "./dist/index.js",
40
40
  module: "./dist/index.mjs",
41
41
  types: "./dist/index.d.ts",
@@ -68,6 +68,8 @@ var require_package = __commonJS({
68
68
  "@account-kit/smart-contracts": "^4.73.0",
69
69
  "@virtuals-protocol/acp-node": "^0.3.0-beta.10",
70
70
  ajv: "^8.17.1",
71
+ axios: "^1.13.2",
72
+ "jwt-decode": "^4.0.0",
71
73
  "socket.io-client": "^4.8.1",
72
74
  tsup: "^8.5.0",
73
75
  viem: "^2.28.2"
@@ -83,6 +85,7 @@ var require_package = __commonJS({
83
85
  var index_exports = {};
84
86
  __export(index_exports, {
85
87
  ACP_ABI: () => acpAbi_default,
88
+ AcpAgent: () => acpAgent_default,
86
89
  AcpAgentSort: () => AcpAgentSort,
87
90
  AcpContractClient: () => acpContractClient_default,
88
91
  AcpContractClientV2: () => acpContractClientV2_default,
@@ -99,8 +102,6 @@ __export(index_exports, {
99
102
  FareAmount: () => FareAmount,
100
103
  FareBigInt: () => FareBigInt,
101
104
  MemoType: () => MemoType,
102
- PayloadType: () => PayloadType,
103
- PositionDirection: () => PositionDirection,
104
105
  baseAcpConfig: () => baseAcpConfig,
105
106
  baseAcpConfigV2: () => baseAcpConfigV2,
106
107
  baseAcpX402Config: () => baseAcpX402Config,
@@ -1287,6 +1288,7 @@ var acpAbi_default = ACP_ABI;
1287
1288
  // src/acpClient.ts
1288
1289
  var import_viem4 = require("viem");
1289
1290
  var import_socket = require("socket.io-client");
1291
+ var import_jwt_decode = require("jwt-decode");
1290
1292
 
1291
1293
  // src/contractClients/baseAcpContractClient.ts
1292
1294
  var import_viem2 = require("viem");
@@ -3842,23 +3844,6 @@ var AcpOnlineStatus = /* @__PURE__ */ ((AcpOnlineStatus2) => {
3842
3844
  AcpOnlineStatus2["OFFLINE"] = "offline";
3843
3845
  return AcpOnlineStatus2;
3844
3846
  })(AcpOnlineStatus || {});
3845
- var PayloadType = /* @__PURE__ */ ((PayloadType2) => {
3846
- PayloadType2["FUND_RESPONSE"] = "fund_response";
3847
- PayloadType2["OPEN_POSITION"] = "open_position";
3848
- PayloadType2["SWAP_TOKEN"] = "swap_token";
3849
- PayloadType2["RESPONSE_SWAP_TOKEN"] = "response_swap_token";
3850
- PayloadType2["CLOSE_PARTIAL_POSITION"] = "close_partial_position";
3851
- PayloadType2["CLOSE_POSITION"] = "close_position";
3852
- PayloadType2["POSITION_FULFILLED"] = "position_fulfilled";
3853
- PayloadType2["CLOSE_JOB_AND_WITHDRAW"] = "close_job_and_withdraw";
3854
- PayloadType2["UNFULFILLED_POSITION"] = "unfulfilled_position";
3855
- return PayloadType2;
3856
- })(PayloadType || {});
3857
- var PositionDirection = /* @__PURE__ */ ((PositionDirection2) => {
3858
- PositionDirection2["LONG"] = "long";
3859
- PositionDirection2["SHORT"] = "short";
3860
- return PositionDirection2;
3861
- })(PositionDirection || {});
3862
3847
 
3863
3848
  // src/utils.ts
3864
3849
  function tryParseJson(content) {
@@ -3893,6 +3878,11 @@ var AcpJobOffering = class {
3893
3878
  this.ajv = new import_ajv.default({ allErrors: true });
3894
3879
  }
3895
3880
  async initiateJob(serviceRequirement, evaluatorAddress, expiredAt = new Date(Date.now() + 1e3 * 60 * 60 * 24)) {
3881
+ if (this.providerAddress === this.acpClient.walletAddress) {
3882
+ throw new acpError_default(
3883
+ "Provider address cannot be the same as the client address"
3884
+ );
3885
+ }
3896
3886
  if (this.requirement && typeof this.requirement === "object") {
3897
3887
  const validator = this.ajv.compile(this.requirement);
3898
3888
  const valid = validator(serviceRequirement);
@@ -4206,8 +4196,8 @@ var AcpJob = class {
4206
4196
  return await this.acpContractClient.handleOperation(operations);
4207
4197
  }
4208
4198
  async deliver(deliverable) {
4209
- if (this.latestMemo?.nextPhase !== 3 /* EVALUATION */) {
4210
- throw new acpError_default("No transaction memo found");
4199
+ if (this.phase !== 2 /* TRANSACTION */) {
4200
+ throw new acpError_default("Job is not in transaction phase");
4211
4201
  }
4212
4202
  const operations = [];
4213
4203
  operations.push(
@@ -4237,6 +4227,7 @@ var AcpJob = class {
4237
4227
  operations.push(
4238
4228
  this.acpContractClient.createPayableMemo(
4239
4229
  this.id,
4230
+ // memoContent.url,
4240
4231
  preparePayload(deliverable),
4241
4232
  amount.amount,
4242
4233
  this.clientAddress,
@@ -4395,16 +4386,9 @@ var AcpMemo = class {
4395
4386
  this.payableDetails.amount = BigInt(this.payableDetails.amount);
4396
4387
  this.payableDetails.feeAmount = BigInt(this.payableDetails.feeAmount);
4397
4388
  }
4398
- this.structuredContent = tryParseJson(this.content) || void 0;
4399
- }
4400
- get payloadType() {
4401
- return this.structuredContent?.type;
4402
- }
4403
- getStructuredContent() {
4404
- return this.structuredContent;
4405
4389
  }
4406
4390
  async create(jobId, isSecured = true) {
4407
- return await this.contractClient.createMemo(
4391
+ return this.contractClient.createMemo(
4408
4392
  jobId,
4409
4393
  this.content,
4410
4394
  this.type,
@@ -4452,10 +4436,31 @@ var AcpAccount = class {
4452
4436
  }
4453
4437
  };
4454
4438
 
4439
+ // src/acpClient.ts
4440
+ var import_axios = __toESM(require("axios"));
4441
+
4442
+ // src/acpAgent.ts
4443
+ var AcpAgent = class {
4444
+ constructor(args) {
4445
+ this.id = String(args.id);
4446
+ this.name = args.name;
4447
+ this.contractAddress = args.contractAddress;
4448
+ this.walletAddress = args.walletAddress;
4449
+ this.jobOfferings = Object.freeze([...args.jobOfferings]);
4450
+ this.description = args.description;
4451
+ this.twitterHandle = args.twitterHandle;
4452
+ this.metrics = args.metrics;
4453
+ this.resources = args.resources;
4454
+ }
4455
+ };
4456
+ var acpAgent_default = AcpAgent;
4457
+
4455
4458
  // src/acpClient.ts
4456
4459
  var { version } = require_package();
4457
4460
  var AcpClient = class {
4458
4461
  constructor(options) {
4462
+ this.accessToken = null;
4463
+ this.accessTokenInflight = null;
4459
4464
  this.contractClients = Array.isArray(options.acpContractClient) ? options.acpContractClient : [options.acpContractClient];
4460
4465
  if (this.contractClients.length === 0) {
4461
4466
  throw new acpError_default("ACP contract client is required");
@@ -4467,10 +4472,86 @@ var AcpClient = class {
4467
4472
  );
4468
4473
  }
4469
4474
  });
4475
+ this.acpClient = import_axios.default.create({
4476
+ baseURL: `${this.acpUrl}/api`,
4477
+ headers: {
4478
+ "wallet-address": this.walletAddress
4479
+ }
4480
+ });
4481
+ this.noAuthAcpClient = this.acpClient.create({
4482
+ baseURL: `${this.acpUrl}/api`
4483
+ });
4484
+ this.acpClient.interceptors.request.use(async (config) => {
4485
+ const accessToken = await this.getAccessToken();
4486
+ config.headers["authorization"] = `Bearer ${accessToken}`;
4487
+ return config;
4488
+ });
4470
4489
  this.onNewTask = options.onNewTask;
4471
4490
  this.onEvaluate = options.onEvaluate || this.defaultOnEvaluate;
4472
4491
  this.init(options.skipSocketConnection);
4473
4492
  }
4493
+ async getAccessToken() {
4494
+ if (this.accessTokenInflight) {
4495
+ return await this.accessTokenInflight;
4496
+ }
4497
+ let refreshToken = this.accessToken ? false : true;
4498
+ if (this.accessToken) {
4499
+ const decodedToken = (0, import_jwt_decode.jwtDecode)(this.accessToken);
4500
+ if (decodedToken.exp && decodedToken.exp - 60 * 5 < Math.floor(Date.now() / 1e3)) {
4501
+ refreshToken = true;
4502
+ }
4503
+ }
4504
+ if (!refreshToken) {
4505
+ return this.accessToken;
4506
+ }
4507
+ this.accessTokenInflight = (async () => {
4508
+ this.accessToken = await this.refreshToken();
4509
+ return this.accessToken;
4510
+ })().finally(() => {
4511
+ this.accessTokenInflight = null;
4512
+ });
4513
+ return await this.accessTokenInflight;
4514
+ }
4515
+ async refreshToken() {
4516
+ const challenge = await this.getAuthChallenge();
4517
+ const signature = await this.acpContractClient.signTypedData(challenge);
4518
+ const verified = await this.verifyAuthChallenge(
4519
+ challenge.message["walletAddress"],
4520
+ challenge.message["nonce"],
4521
+ challenge.message["expiresAt"],
4522
+ signature
4523
+ );
4524
+ return verified.accessToken;
4525
+ }
4526
+ async getAuthChallenge() {
4527
+ try {
4528
+ const response = await this.noAuthAcpClient.get("/auth/challenge", {
4529
+ params: {
4530
+ walletAddress: this.walletAddress
4531
+ }
4532
+ });
4533
+ return response.data.data;
4534
+ } catch (err) {
4535
+ console.error(
4536
+ "Failed to get auth challenge",
4537
+ err.response?.data
4538
+ );
4539
+ throw new acpError_default("Failed to get auth challenge", err);
4540
+ }
4541
+ }
4542
+ async verifyAuthChallenge(walletAddress, nonce, expiresAt, signature) {
4543
+ try {
4544
+ const response = await this.noAuthAcpClient.post("/auth/verify-typed-signature", {
4545
+ walletAddress,
4546
+ nonce,
4547
+ expiresAt,
4548
+ signature
4549
+ });
4550
+ return response.data.data;
4551
+ } catch (err) {
4552
+ throw new acpError_default("Failed to verify auth challenge", err);
4553
+ }
4554
+ }
4474
4555
  contractClientByAddress(address) {
4475
4556
  if (!address) {
4476
4557
  return this.contractClients[0];
@@ -4499,9 +4580,13 @@ var AcpClient = class {
4499
4580
  if (skipSocketConnection) {
4500
4581
  return;
4501
4582
  }
4583
+ console.log("Initializing socket");
4502
4584
  const socket = (0, import_socket.io)(this.acpUrl, {
4503
- auth: {
4504
- walletAddress: this.walletAddress
4585
+ auth: async (cb) => {
4586
+ cb({
4587
+ walletAddress: this.walletAddress,
4588
+ accessToken: await this.getAccessToken()
4589
+ });
4505
4590
  },
4506
4591
  extraHeaders: {
4507
4592
  "x-sdk-version": version,
@@ -4515,85 +4600,23 @@ var AcpClient = class {
4515
4600
  console.log("Joined ACP Room");
4516
4601
  callback(true);
4517
4602
  });
4518
- socket.on(
4519
- "onEvaluate" /* ON_EVALUATE */,
4520
- async (data, callback) => {
4521
- callback(true);
4522
- if (this.onEvaluate) {
4523
- const job = new acpJob_default(
4524
- this,
4525
- data.id,
4526
- data.clientAddress,
4527
- data.providerAddress,
4528
- data.evaluatorAddress,
4529
- data.price,
4530
- data.priceTokenAddress,
4531
- data.memos.map((memo) => {
4532
- return new acpMemo_default(
4533
- this.contractClientByAddress(data.contractAddress),
4534
- memo.id,
4535
- memo.memoType,
4536
- memo.content,
4537
- memo.nextPhase,
4538
- memo.status,
4539
- memo.senderAddress,
4540
- memo.signedReason,
4541
- memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4542
- memo.payableDetails,
4543
- memo.txHash,
4544
- memo.signedTxHash
4545
- );
4546
- }),
4547
- data.phase,
4548
- data.context,
4549
- data.contractAddress,
4550
- data.netPayableAmount
4551
- );
4552
- this.onEvaluate(job);
4553
- }
4603
+ socket.on("onEvaluate" /* ON_EVALUATE */, async (data, callback) => {
4604
+ callback(true);
4605
+ if (this.onEvaluate) {
4606
+ const job = this._hydrateJob(data);
4607
+ this.onEvaluate(job);
4554
4608
  }
4555
- );
4556
- socket.on(
4557
- "onNewTask" /* ON_NEW_TASK */,
4558
- async (data, callback) => {
4559
- callback(true);
4560
- if (this.onNewTask) {
4561
- const job = new acpJob_default(
4562
- this,
4563
- data.id,
4564
- data.clientAddress,
4565
- data.providerAddress,
4566
- data.evaluatorAddress,
4567
- data.price,
4568
- data.priceTokenAddress,
4569
- data.memos.map((memo) => {
4570
- return new acpMemo_default(
4571
- this.contractClientByAddress(data.contractAddress),
4572
- memo.id,
4573
- memo.memoType,
4574
- memo.content,
4575
- memo.nextPhase,
4576
- memo.status,
4577
- memo.senderAddress,
4578
- memo.signedReason,
4579
- memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4580
- memo.payableDetails,
4581
- memo.txHash,
4582
- memo.signedTxHash
4583
- );
4584
- }),
4585
- data.phase,
4586
- data.context,
4587
- data.contractAddress,
4588
- data.netPayableAmount
4589
- );
4590
- this.onNewTask(
4591
- job,
4592
- job.memos.find((m) => m.id == data.memoToSign)
4593
- );
4594
- }
4609
+ });
4610
+ socket.on("onNewTask" /* ON_NEW_TASK */, async (data, callback) => {
4611
+ callback(true);
4612
+ if (this.onNewTask) {
4613
+ const job = this._hydrateJob(data);
4614
+ this.onNewTask(
4615
+ job,
4616
+ job.memos.find((m) => m.id == data.memoToSign)
4617
+ );
4595
4618
  }
4596
- );
4619
+ });
4597
4620
  const cleanup = async () => {
4598
4621
  if (socket) {
4599
4622
  socket.disconnect();
@@ -4603,70 +4626,156 @@ var AcpClient = class {
4603
4626
  process.on("SIGINT", cleanup);
4604
4627
  process.on("SIGTERM", cleanup);
4605
4628
  }
4606
- async browseAgents(keyword, options) {
4607
- let { cluster, sort_by, top_k, graduationStatus, onlineStatus, showHiddenOfferings } = options;
4608
- top_k = top_k ?? 5;
4609
- let url = `${this.acpUrl}/api/agents/v4/search?search=${keyword}`;
4610
- if (sort_by && sort_by.length > 0) {
4611
- url += `&sortBy=${sort_by.map((s) => s).join(",")}`;
4629
+ async _fetch(url, method = "GET", params, data, errCallback) {
4630
+ try {
4631
+ const response = await this.acpClient.request({
4632
+ url,
4633
+ method,
4634
+ params,
4635
+ data
4636
+ });
4637
+ return response.data.data;
4638
+ } catch (err) {
4639
+ if (err instanceof import_axios.AxiosError) {
4640
+ if (errCallback) {
4641
+ errCallback(err);
4642
+ } else if (err.response?.data.error?.message) {
4643
+ throw new acpError_default(err.response?.data.error.message);
4644
+ }
4645
+ } else {
4646
+ throw new acpError_default(
4647
+ `Failed to fetch ACP Endpoint: ${url} (network error)`,
4648
+ err
4649
+ );
4650
+ }
4651
+ }
4652
+ }
4653
+ _hydrateMemo(memo, contractClient) {
4654
+ try {
4655
+ return new acpMemo_default(
4656
+ contractClient,
4657
+ memo.id,
4658
+ memo.memoType,
4659
+ memo.content,
4660
+ memo.nextPhase,
4661
+ memo.status,
4662
+ memo.senderAddress,
4663
+ memo.signedReason,
4664
+ memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4665
+ memo.payableDetails,
4666
+ memo.txHash,
4667
+ memo.signedTxHash
4668
+ );
4669
+ } catch (err) {
4670
+ throw new acpError_default(`Failed to hydrate memo ${memo.id}`, err);
4612
4671
  }
4613
- if (top_k) {
4614
- url += `&top_k=${top_k}`;
4672
+ }
4673
+ _hydrateJob(job) {
4674
+ try {
4675
+ return new acpJob_default(
4676
+ this,
4677
+ job.id,
4678
+ job.clientAddress,
4679
+ job.providerAddress,
4680
+ job.evaluatorAddress,
4681
+ job.price,
4682
+ job.priceTokenAddress,
4683
+ job.memos.map(
4684
+ (memo) => this._hydrateMemo(
4685
+ memo,
4686
+ this.contractClientByAddress(job.contractAddress)
4687
+ )
4688
+ ),
4689
+ job.phase,
4690
+ job.context,
4691
+ job.contractAddress,
4692
+ job.netPayableAmount
4693
+ );
4694
+ } catch (err) {
4695
+ throw new acpError_default(`Failed to hydrate job ${job.id}`, err);
4696
+ }
4697
+ }
4698
+ _hydrateJobs(rawJobs, options) {
4699
+ const jobs = rawJobs.map((job) => {
4700
+ try {
4701
+ return this._hydrateJob(job);
4702
+ } catch (err) {
4703
+ console.warn(`${options?.logPrefix ?? "Skipped"}`, err);
4704
+ return null;
4705
+ }
4706
+ });
4707
+ return jobs.filter((job) => !!job);
4708
+ }
4709
+ _hydrateAgent(agent) {
4710
+ const acpContractClient = this.contractClients.find(
4711
+ (client) => client.contractAddress.toLowerCase() === agent.contractAddress.toLowerCase()
4712
+ );
4713
+ if (!acpContractClient) {
4714
+ throw new acpError_default("ACP contract client not found");
4615
4715
  }
4616
- if (this.walletAddress) {
4617
- url += `&walletAddressesToExclude=${this.walletAddress}`;
4716
+ return new acpAgent_default({
4717
+ id: agent.id,
4718
+ name: agent.name,
4719
+ description: agent.description,
4720
+ jobOfferings: agent.jobs.map((jobs) => {
4721
+ return new acpJobOffering_default(
4722
+ this,
4723
+ acpContractClient,
4724
+ agent.walletAddress,
4725
+ jobs.name,
4726
+ jobs.priceV2.value,
4727
+ jobs.priceV2.type,
4728
+ jobs.requirement
4729
+ );
4730
+ }),
4731
+ contractAddress: agent.contractAddress,
4732
+ twitterHandle: agent.twitterHandle,
4733
+ walletAddress: agent.walletAddress,
4734
+ metrics: agent.metrics,
4735
+ resources: agent.resources
4736
+ });
4737
+ }
4738
+ async browseAgents(keyword, options = {}) {
4739
+ const {
4740
+ cluster,
4741
+ sortBy,
4742
+ topK = 5,
4743
+ graduationStatus,
4744
+ onlineStatus,
4745
+ showHiddenOfferings
4746
+ } = options;
4747
+ const params = {
4748
+ search: keyword
4749
+ };
4750
+ params.top_k = topK;
4751
+ params.walletAddressesToExclude = this.walletAddress;
4752
+ if (sortBy && sortBy.length > 0) {
4753
+ params.sortBy = sortBy.join(",");
4618
4754
  }
4619
4755
  if (cluster) {
4620
- url += `&cluster=${cluster}`;
4756
+ params.cluster = cluster;
4621
4757
  }
4622
4758
  if (graduationStatus) {
4623
- url += `&graduationStatus=${graduationStatus}`;
4759
+ params.graduationStatus = graduationStatus;
4624
4760
  }
4625
4761
  if (onlineStatus) {
4626
- url += `&onlineStatus=${onlineStatus}`;
4762
+ params.onlineStatus = onlineStatus;
4627
4763
  }
4628
4764
  if (showHiddenOfferings) {
4629
- url += `&showHiddenOfferings=${showHiddenOfferings}`;
4765
+ params.showHiddenOfferings = true;
4630
4766
  }
4631
- const response = await fetch(url);
4632
- const data = await response.json();
4767
+ const agents = await this._fetch("/agents/v4/search", "GET", params) || [];
4633
4768
  const availableContractClientAddresses = this.contractClients.map(
4634
4769
  (client) => client.contractAddress.toLowerCase()
4635
4770
  );
4636
- return data.data.filter(
4771
+ return agents.filter(
4637
4772
  (agent) => agent.walletAddress.toLowerCase() !== this.walletAddress.toLowerCase()
4638
4773
  ).filter(
4639
4774
  (agent) => availableContractClientAddresses.includes(
4640
4775
  agent.contractAddress.toLowerCase()
4641
4776
  )
4642
4777
  ).map((agent) => {
4643
- const acpContractClient = this.contractClients.find(
4644
- (client) => client.contractAddress.toLowerCase() === agent.contractAddress.toLowerCase()
4645
- );
4646
- if (!acpContractClient) {
4647
- throw new acpError_default("ACP contract client not found");
4648
- }
4649
- return {
4650
- id: agent.id,
4651
- name: agent.name,
4652
- description: agent.description,
4653
- jobOfferings: agent.jobs.map((jobs) => {
4654
- return new acpJobOffering_default(
4655
- this,
4656
- acpContractClient,
4657
- agent.walletAddress,
4658
- jobs.name,
4659
- jobs.priceV2.value,
4660
- jobs.priceV2.type,
4661
- jobs.requirement
4662
- );
4663
- }),
4664
- contractAddress: agent.contractAddress,
4665
- twitterHandle: agent.twitterHandle,
4666
- walletAddress: agent.walletAddress,
4667
- metrics: agent.metrics,
4668
- resources: agent.resources
4669
- };
4778
+ return this._hydrateAgent(agent);
4670
4779
  });
4671
4780
  }
4672
4781
  async initiateJob(providerAddress, serviceRequirement, fareAmount, evaluatorAddress, expiredAt = new Date(Date.now() + 1e3 * 60 * 60 * 24)) {
@@ -4736,254 +4845,136 @@ var AcpClient = class {
4736
4845
  return jobId;
4737
4846
  }
4738
4847
  async getActiveJobs(page = 1, pageSize = 10) {
4739
- const url = `${this.acpUrl}/api/jobs/active?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
4740
- const rawJobs = await this._fetchJobList(url);
4741
- return this._hydrateJobs(rawJobs, { logPrefix: "Active jobs" });
4848
+ const rawJobs = await this._fetch("/jobs/active", "GET", {
4849
+ pagination: {
4850
+ page,
4851
+ pageSize
4852
+ }
4853
+ });
4854
+ return this._hydrateJobs(rawJobs ?? [], { logPrefix: "Active jobs" });
4742
4855
  }
4743
4856
  async getPendingMemoJobs(page = 1, pageSize = 10) {
4744
- const url = `${this.acpUrl}/api/jobs/pending-memos?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
4745
- const rawJobs = await this._fetchJobList(url);
4746
- return this._hydrateJobs(rawJobs, { logPrefix: "Pending memo jobs" });
4857
+ const rawJobs = await this._fetch("/jobs/pending-memos", "GET", {
4858
+ pagination: {
4859
+ page,
4860
+ pageSize
4861
+ }
4862
+ });
4863
+ return this._hydrateJobs(rawJobs ?? [], { logPrefix: "Pending memo jobs" });
4747
4864
  }
4748
4865
  async getCompletedJobs(page = 1, pageSize = 10) {
4749
- const url = `${this.acpUrl}/api/jobs/completed?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
4750
- const rawJobs = await this._fetchJobList(url);
4751
- return this._hydrateJobs(rawJobs, { logPrefix: "Completed jobs" });
4866
+ const rawJobs = await this._fetch("/jobs/completed", "GET", {
4867
+ pagination: {
4868
+ page,
4869
+ pageSize
4870
+ }
4871
+ });
4872
+ return this._hydrateJobs(rawJobs ?? [], { logPrefix: "Completed jobs" });
4752
4873
  }
4753
4874
  async getCancelledJobs(page = 1, pageSize = 10) {
4754
- const url = `${this.acpUrl}/api/jobs/cancelled?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
4755
- const rawJobs = await this._fetchJobList(url);
4756
- return this._hydrateJobs(rawJobs, { logPrefix: "Cancelled jobs" });
4757
- }
4758
- async _fetchJobList(url) {
4759
- let response;
4760
- try {
4761
- response = await fetch(url, {
4762
- headers: {
4763
- "wallet-address": this.walletAddress
4764
- }
4765
- });
4766
- } catch (err) {
4767
- throw new acpError_default("Failed to fetch ACP jobs (network error)", err);
4768
- }
4769
- let data;
4770
- try {
4771
- data = await response.json();
4772
- } catch (err) {
4773
- throw new acpError_default("Failed to parse ACP jobs response", err);
4774
- }
4775
- if (data.error) {
4776
- throw new acpError_default(data.error.message);
4777
- }
4778
- return data.data;
4779
- }
4780
- _hydrateJobs(rawJobs, options) {
4781
- const jobs = [];
4782
- const errors = [];
4783
- for (const job of rawJobs) {
4784
- try {
4785
- const memos = job.memos.map(
4786
- (memo) => new acpMemo_default(
4787
- this.contractClientByAddress(job.contractAddress),
4788
- memo.id,
4789
- memo.memoType,
4790
- memo.content,
4791
- memo.nextPhase,
4792
- memo.status,
4793
- memo.senderAddress,
4794
- memo.signedReason,
4795
- memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4796
- memo.payableDetails,
4797
- memo.txHash,
4798
- memo.signedTxHash
4799
- )
4800
- );
4801
- jobs.push(
4802
- new acpJob_default(
4803
- this,
4804
- job.id,
4805
- job.clientAddress,
4806
- job.providerAddress,
4807
- job.evaluatorAddress,
4808
- job.price,
4809
- job.priceTokenAddress,
4810
- memos,
4811
- job.phase,
4812
- job.context,
4813
- job.contractAddress,
4814
- job.netPayableAmount
4815
- )
4816
- );
4817
- } catch (err) {
4818
- errors.push({ jobId: job.id, error: err });
4875
+ const rawJobs = await this._fetch("/jobs/cancelled", "GET", {
4876
+ pagination: {
4877
+ page,
4878
+ pageSize
4819
4879
  }
4820
- }
4821
- if (errors.length > 0) {
4822
- console.warn(
4823
- `${options?.logPrefix ?? "Skipped"} ${errors.length} malformed job(s)
4824
- ` + JSON.stringify(
4825
- errors.map((e) => ({ jobId: e.jobId, message: e.error.message })),
4826
- null,
4827
- 2
4828
- )
4829
- );
4830
- }
4831
- return jobs;
4880
+ });
4881
+ return this._hydrateJobs(rawJobs ?? [], { logPrefix: "Cancelled jobs" });
4832
4882
  }
4833
4883
  async getJobById(jobId) {
4834
- const url = `${this.acpUrl}/api/jobs/${jobId}`;
4835
- let response;
4836
- try {
4837
- response = await fetch(url, {
4838
- headers: {
4839
- "wallet-address": this.acpContractClient.walletAddress
4840
- }
4841
- });
4842
- } catch (err) {
4843
- throw new acpError_default("Failed to fetch job by id (network error)", err);
4844
- }
4845
- let data;
4846
- try {
4847
- data = await response.json();
4848
- } catch (err) {
4849
- throw new acpError_default("Failed to parse job by id response", err);
4850
- }
4851
- if (data.error) {
4852
- throw new acpError_default(data.error.message);
4853
- }
4854
- const job = data.data;
4884
+ const job = await this._fetch(`/jobs/${jobId}`);
4855
4885
  if (!job) {
4856
- return void 0;
4857
- }
4858
- try {
4859
- const memos = job.memos.map(
4860
- (memo) => new acpMemo_default(
4861
- this.contractClientByAddress(job.contractAddress),
4862
- memo.id,
4863
- memo.memoType,
4864
- memo.content,
4865
- memo.nextPhase,
4866
- memo.status,
4867
- memo.senderAddress,
4868
- memo.signedReason,
4869
- memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4870
- memo.payableDetails,
4871
- memo.txHash,
4872
- memo.signedTxHash
4873
- )
4874
- );
4875
- return new acpJob_default(
4876
- this,
4877
- job.id,
4878
- job.clientAddress,
4879
- job.providerAddress,
4880
- job.evaluatorAddress,
4881
- job.price,
4882
- job.priceTokenAddress,
4883
- memos,
4884
- job.phase,
4885
- job.context,
4886
- job.contractAddress,
4887
- job.netPayableAmount
4888
- );
4889
- } catch (err) {
4890
- throw new acpError_default(`Failed to hydrate job ${jobId}`, err);
4886
+ return null;
4891
4887
  }
4888
+ return this._hydrateJob(job);
4892
4889
  }
4893
4890
  async getMemoById(jobId, memoId) {
4894
- const url = `${this.acpUrl}/api/jobs/${jobId}/memos/${memoId}`;
4895
- let response;
4896
- try {
4897
- response = await fetch(url, {
4898
- headers: {
4899
- "wallet-address": this.walletAddress
4900
- }
4901
- });
4902
- } catch (err) {
4903
- throw new acpError_default("Failed to fetch memo by id (network error)", err);
4904
- }
4905
- let data;
4906
- try {
4907
- data = await response.json();
4908
- } catch (err) {
4909
- throw new acpError_default("Failed to parse memo by id response", err);
4910
- }
4911
- if (data.error) {
4912
- throw new acpError_default(data.error.message);
4913
- }
4914
- const memo = data.data;
4891
+ const memo = await this._fetch(
4892
+ `/jobs/${jobId}/memos/${memoId}`
4893
+ );
4915
4894
  if (!memo) {
4916
- return void 0;
4917
- }
4918
- try {
4919
- return new acpMemo_default(
4920
- this.contractClientByAddress(memo.contractAddress),
4921
- memo.id,
4922
- memo.memoType,
4923
- memo.content,
4924
- memo.nextPhase,
4925
- memo.status,
4926
- memo.senderAddress,
4927
- memo.signedReason,
4928
- memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4929
- memo.payableDetails,
4930
- memo.txHash,
4931
- memo.signedTxHash
4932
- );
4933
- } catch (err) {
4934
- throw new acpError_default(
4935
- `Failed to hydrate memo ${memoId} for job ${jobId}`,
4936
- err
4937
- );
4895
+ return null;
4938
4896
  }
4897
+ return this._hydrateMemo(
4898
+ memo,
4899
+ this.contractClientByAddress(memo.contractAddress)
4900
+ );
4939
4901
  }
4940
- async getAgent(walletAddress) {
4941
- const url = `${this.acpUrl}/api/agents?filters[walletAddress]=${walletAddress}`;
4942
- const response = await fetch(url);
4943
- const data = await response.json();
4944
- const agents = data.data || [];
4945
- if (agents.length === 0) {
4946
- return;
4902
+ async getAgent(walletAddress, options = {}) {
4903
+ const params = {
4904
+ "filters[walletAddress]": walletAddress
4905
+ };
4906
+ const { showHiddenOfferings } = options;
4907
+ if (showHiddenOfferings) {
4908
+ params.showHiddenOfferings = true;
4909
+ }
4910
+ const agents = await this._fetch("/agents", "GET", params) || [];
4911
+ if (!agents) {
4912
+ return null;
4947
4913
  }
4948
- return agents[0];
4914
+ const agent = agents[0];
4915
+ return this._hydrateAgent(agent);
4949
4916
  }
4950
4917
  async getAccountByJobId(jobId, acpContractClient) {
4951
- try {
4952
- const url = `${this.acpUrl}/api/accounts/job/${jobId}`;
4953
- const response = await fetch(url);
4954
- const data = await response.json();
4955
- if (!data.data) {
4956
- return null;
4957
- }
4958
- return new AcpAccount(
4959
- acpContractClient || this.contractClients[0],
4960
- data.data.id,
4961
- data.data.clientAddress,
4962
- data.data.providerAddress,
4963
- data.data.metadata
4964
- );
4965
- } catch (error) {
4966
- throw new acpError_default("Failed to get account by job id", error);
4918
+ const account = await this._fetch(`/accounts/job/${jobId}`);
4919
+ if (!account) {
4920
+ return null;
4967
4921
  }
4922
+ return new AcpAccount(
4923
+ acpContractClient || this.contractClients[0],
4924
+ account.id,
4925
+ account.clientAddress,
4926
+ account.providerAddress,
4927
+ account.metadata
4928
+ );
4968
4929
  }
4969
4930
  async getByClientAndProvider(clientAddress, providerAddress, acpContractClient) {
4970
- try {
4971
- const url = `${this.acpUrl}/api/accounts/client/${clientAddress}/provider/${providerAddress}`;
4972
- const response = await fetch(url);
4973
- const data = await response.json();
4974
- if (!data.data) {
4975
- return null;
4931
+ const response = await this._fetch(
4932
+ `/accounts/client/${clientAddress}/provider/${providerAddress}`,
4933
+ "GET",
4934
+ {},
4935
+ {},
4936
+ (err) => {
4937
+ if (err.response?.status === 404) {
4938
+ console.warn("Account not found by client and provider");
4939
+ return;
4940
+ }
4941
+ throw new acpError_default("Failed to get account by client and provider", err);
4976
4942
  }
4977
- return new AcpAccount(
4978
- acpContractClient || this.contractClients[0],
4979
- data.data.id,
4980
- data.data.clientAddress,
4981
- data.data.providerAddress,
4982
- data.data.metadata
4983
- );
4984
- } catch (error) {
4985
- throw new acpError_default("Failed to get account by client and provider", error);
4943
+ );
4944
+ if (!response) {
4945
+ return null;
4946
+ }
4947
+ return new AcpAccount(
4948
+ acpContractClient || this.contractClients[0],
4949
+ response.id,
4950
+ response.clientAddress,
4951
+ response.providerAddress,
4952
+ response.metadata
4953
+ );
4954
+ }
4955
+ async createMemoContent(jobId, content) {
4956
+ const response = await this._fetch(
4957
+ `/memo-contents`,
4958
+ "POST",
4959
+ {},
4960
+ {
4961
+ data: {
4962
+ onChainJobId: jobId,
4963
+ content
4964
+ }
4965
+ }
4966
+ );
4967
+ if (!response) {
4968
+ throw new acpError_default("Failed to create memo content");
4986
4969
  }
4970
+ return response;
4971
+ }
4972
+ async getTokenBalances() {
4973
+ const response = await this._fetch(
4974
+ `/chains/token-balances`,
4975
+ "GET"
4976
+ );
4977
+ return response;
4987
4978
  }
4988
4979
  };
4989
4980
  var acpClient_default = AcpClient;
@@ -5365,6 +5356,9 @@ var AcpContractClient = class _AcpContractClient extends baseAcpContractClient_d
5365
5356
  getAcpVersion() {
5366
5357
  return "1";
5367
5358
  }
5359
+ signTypedData(typedData) {
5360
+ return this.sessionKeyClient.signTypedData({ typedData });
5361
+ }
5368
5362
  };
5369
5363
  var acpContractClient_default = AcpContractClient;
5370
5364
 
@@ -6290,6 +6284,9 @@ var AcpContractClientV2 = class _AcpContractClientV2 extends baseAcpContractClie
6290
6284
  getAcpVersion() {
6291
6285
  return "2";
6292
6286
  }
6287
+ async signTypedData(typedData) {
6288
+ return await this.sessionKeyClient.signTypedData({ typedData });
6289
+ }
6293
6290
  };
6294
6291
  var acpContractClientV2_default = AcpContractClientV2;
6295
6292
 
@@ -6298,6 +6295,7 @@ var index_default = acpClient_default;
6298
6295
  // Annotate the CommonJS export names for ESM import in node:
6299
6296
  0 && (module.exports = {
6300
6297
  ACP_ABI,
6298
+ AcpAgent,
6301
6299
  AcpAgentSort,
6302
6300
  AcpContractClient,
6303
6301
  AcpContractClientV2,
@@ -6314,8 +6312,6 @@ var index_default = acpClient_default;
6314
6312
  FareAmount,
6315
6313
  FareBigInt,
6316
6314
  MemoType,
6317
- PayloadType,
6318
- PositionDirection,
6319
6315
  baseAcpConfig,
6320
6316
  baseAcpConfigV2,
6321
6317
  baseAcpX402Config,