@bountyagents/bountyagents-task 2026.2.2715 → 2026.3.9

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
@@ -9841,14 +9841,14 @@ var require_util = __commonJS((exports, module) => {
9841
9841
  }
9842
9842
  const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
9843
9843
  let origin = url.origin != null ? url.origin : `${url.protocol || ""}//${url.hostname || ""}:${port}`;
9844
- let path = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
9844
+ let path2 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
9845
9845
  if (origin[origin.length - 1] === "/") {
9846
9846
  origin = origin.slice(0, origin.length - 1);
9847
9847
  }
9848
- if (path && path[0] !== "/") {
9849
- path = `/${path}`;
9848
+ if (path2 && path2[0] !== "/") {
9849
+ path2 = `/${path2}`;
9850
9850
  }
9851
- return new URL(`${origin}${path}`);
9851
+ return new URL(`${origin}${path2}`);
9852
9852
  }
9853
9853
  if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
9854
9854
  throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
@@ -10602,9 +10602,9 @@ var require_diagnostics = __commonJS((exports, module) => {
10602
10602
  });
10603
10603
  diagnosticsChannel.subscribe("undici:client:sendHeaders", (evt) => {
10604
10604
  const {
10605
- request: { method, path, origin }
10605
+ request: { method, path: path2, origin }
10606
10606
  } = evt;
10607
- debugLog("sending request to %s %s%s", method, origin, path);
10607
+ debugLog("sending request to %s %s%s", method, origin, path2);
10608
10608
  });
10609
10609
  }
10610
10610
  var isTrackingRequestEvents = false;
@@ -10619,23 +10619,23 @@ var require_diagnostics = __commonJS((exports, module) => {
10619
10619
  isTrackingRequestEvents = true;
10620
10620
  diagnosticsChannel.subscribe("undici:request:headers", (evt) => {
10621
10621
  const {
10622
- request: { method, path, origin },
10622
+ request: { method, path: path2, origin },
10623
10623
  response: { statusCode }
10624
10624
  } = evt;
10625
- debugLog("received response to %s %s%s - HTTP %d", method, origin, path, statusCode);
10625
+ debugLog("received response to %s %s%s - HTTP %d", method, origin, path2, statusCode);
10626
10626
  });
10627
10627
  diagnosticsChannel.subscribe("undici:request:trailers", (evt) => {
10628
10628
  const {
10629
- request: { method, path, origin }
10629
+ request: { method, path: path2, origin }
10630
10630
  } = evt;
10631
- debugLog("trailers received from %s %s%s", method, origin, path);
10631
+ debugLog("trailers received from %s %s%s", method, origin, path2);
10632
10632
  });
10633
10633
  diagnosticsChannel.subscribe("undici:request:error", (evt) => {
10634
10634
  const {
10635
- request: { method, path, origin },
10635
+ request: { method, path: path2, origin },
10636
10636
  error
10637
10637
  } = evt;
10638
- debugLog("request to %s %s%s errored - %s", method, origin, path, error.message);
10638
+ debugLog("request to %s %s%s errored - %s", method, origin, path2, error.message);
10639
10639
  });
10640
10640
  }
10641
10641
  var isTrackingWebSocketEvents = false;
@@ -10710,7 +10710,7 @@ var require_request = __commonJS((exports, module) => {
10710
10710
 
10711
10711
  class Request2 {
10712
10712
  constructor(origin, {
10713
- path,
10713
+ path: path2,
10714
10714
  method,
10715
10715
  body,
10716
10716
  headers,
@@ -10726,11 +10726,11 @@ var require_request = __commonJS((exports, module) => {
10726
10726
  throwOnError,
10727
10727
  maxRedirections
10728
10728
  }, handler) {
10729
- if (typeof path !== "string") {
10729
+ if (typeof path2 !== "string") {
10730
10730
  throw new InvalidArgumentError("path must be a string");
10731
- } else if (path[0] !== "/" && !(path.startsWith("http://") || path.startsWith("https://")) && method !== "CONNECT") {
10731
+ } else if (path2[0] !== "/" && !(path2.startsWith("http://") || path2.startsWith("https://")) && method !== "CONNECT") {
10732
10732
  throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
10733
- } else if (invalidPathRegex.test(path)) {
10733
+ } else if (invalidPathRegex.test(path2)) {
10734
10734
  throw new InvalidArgumentError("invalid request path");
10735
10735
  }
10736
10736
  if (typeof method !== "string") {
@@ -10798,7 +10798,7 @@ var require_request = __commonJS((exports, module) => {
10798
10798
  this.completed = false;
10799
10799
  this.aborted = false;
10800
10800
  this.upgrade = upgrade || null;
10801
- this.path = query ? serializePathWithQuery(path, query) : path;
10801
+ this.path = query ? serializePathWithQuery(path2, query) : path2;
10802
10802
  this.origin = origin;
10803
10803
  this.protocol = getProtocolFromUrlString(origin);
10804
10804
  this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
@@ -15332,7 +15332,7 @@ var require_client_h1 = __commonJS((exports, module) => {
15332
15332
  return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
15333
15333
  }
15334
15334
  function writeH1(client, request) {
15335
- const { method, path, host, upgrade, blocking, reset } = request;
15335
+ const { method, path: path2, host, upgrade, blocking, reset } = request;
15336
15336
  let { body, headers, contentLength } = request;
15337
15337
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
15338
15338
  if (util.isFormDataLike(body)) {
@@ -15398,7 +15398,7 @@ var require_client_h1 = __commonJS((exports, module) => {
15398
15398
  if (blocking) {
15399
15399
  socket[kBlocking] = true;
15400
15400
  }
15401
- let header = `${method} ${path} HTTP/1.1\r
15401
+ let header = `${method} ${path2} HTTP/1.1\r
15402
15402
  `;
15403
15403
  if (typeof host === "string") {
15404
15404
  header += `host: ${host}\r
@@ -16015,7 +16015,7 @@ var require_client_h2 = __commonJS((exports, module) => {
16015
16015
  function writeH2(client, request) {
16016
16016
  const requestTimeout = request.bodyTimeout ?? client[kBodyTimeout];
16017
16017
  const session = client[kHTTP2Session];
16018
- const { method, path, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request;
16018
+ const { method, path: path2, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request;
16019
16019
  let { body } = request;
16020
16020
  if (upgrade != null && upgrade !== "websocket") {
16021
16021
  util.errorRequest(client, request, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
@@ -16083,7 +16083,7 @@ var require_client_h2 = __commonJS((exports, module) => {
16083
16083
  }
16084
16084
  headers[HTTP2_HEADER_METHOD] = "CONNECT";
16085
16085
  headers[HTTP2_HEADER_PROTOCOL] = "websocket";
16086
- headers[HTTP2_HEADER_PATH] = path;
16086
+ headers[HTTP2_HEADER_PATH] = path2;
16087
16087
  if (protocol === "ws:" || protocol === "wss:") {
16088
16088
  headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
16089
16089
  } else {
@@ -16126,7 +16126,7 @@ var require_client_h2 = __commonJS((exports, module) => {
16126
16126
  stream.setTimeout(requestTimeout);
16127
16127
  return true;
16128
16128
  }
16129
- headers[HTTP2_HEADER_PATH] = path;
16129
+ headers[HTTP2_HEADER_PATH] = path2;
16130
16130
  headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
16131
16131
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
16132
16132
  if (body && typeof body.read === "function") {
@@ -17654,10 +17654,10 @@ var require_proxy_agent = __commonJS((exports, module) => {
17654
17654
  };
17655
17655
  const {
17656
17656
  origin,
17657
- path = "/",
17657
+ path: path2 = "/",
17658
17658
  headers = {}
17659
17659
  } = opts;
17660
- opts.path = origin + path;
17660
+ opts.path = origin + path2;
17661
17661
  if (!("host" in headers) && !("Host" in headers)) {
17662
17662
  const { host } = new URL(origin);
17663
17663
  headers.host = host;
@@ -19519,20 +19519,20 @@ var require_mock_utils = __commonJS((exports, module) => {
19519
19519
  }
19520
19520
  return normalizedQp;
19521
19521
  }
19522
- function safeUrl(path) {
19523
- if (typeof path !== "string") {
19524
- return path;
19522
+ function safeUrl(path2) {
19523
+ if (typeof path2 !== "string") {
19524
+ return path2;
19525
19525
  }
19526
- const pathSegments = path.split("?", 3);
19526
+ const pathSegments = path2.split("?", 3);
19527
19527
  if (pathSegments.length !== 2) {
19528
- return path;
19528
+ return path2;
19529
19529
  }
19530
19530
  const qp = new URLSearchParams(pathSegments.pop());
19531
19531
  qp.sort();
19532
19532
  return [...pathSegments, qp.toString()].join("?");
19533
19533
  }
19534
- function matchKey(mockDispatch2, { path, method, body, headers }) {
19535
- const pathMatch = matchValue(mockDispatch2.path, path);
19534
+ function matchKey(mockDispatch2, { path: path2, method, body, headers }) {
19535
+ const pathMatch = matchValue(mockDispatch2.path, path2);
19536
19536
  const methodMatch = matchValue(mockDispatch2.method, method);
19537
19537
  const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
19538
19538
  const headersMatch = matchHeaders(mockDispatch2, headers);
@@ -19557,8 +19557,8 @@ var require_mock_utils = __commonJS((exports, module) => {
19557
19557
  const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
19558
19558
  const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
19559
19559
  const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
19560
- let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path, ignoreTrailingSlash }) => {
19561
- return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path), resolvedPath);
19560
+ let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path2, ignoreTrailingSlash }) => {
19561
+ return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path2)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path2), resolvedPath);
19562
19562
  });
19563
19563
  if (matchedMockDispatches.length === 0) {
19564
19564
  throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
@@ -19596,19 +19596,19 @@ var require_mock_utils = __commonJS((exports, module) => {
19596
19596
  mockDispatches.splice(index2, 1);
19597
19597
  }
19598
19598
  }
19599
- function removeTrailingSlash(path) {
19600
- while (path.endsWith("/")) {
19601
- path = path.slice(0, -1);
19599
+ function removeTrailingSlash(path2) {
19600
+ while (path2.endsWith("/")) {
19601
+ path2 = path2.slice(0, -1);
19602
19602
  }
19603
- if (path.length === 0) {
19604
- path = "/";
19603
+ if (path2.length === 0) {
19604
+ path2 = "/";
19605
19605
  }
19606
- return path;
19606
+ return path2;
19607
19607
  }
19608
19608
  function buildKey(opts) {
19609
- const { path, method, body, headers, query } = opts;
19609
+ const { path: path2, method, body, headers, query } = opts;
19610
19610
  return {
19611
- path,
19611
+ path: path2,
19612
19612
  method,
19613
19613
  body,
19614
19614
  headers,
@@ -20246,10 +20246,10 @@ var require_pending_interceptors_formatter = __commonJS((exports, module) => {
20246
20246
  });
20247
20247
  }
20248
20248
  format(pendingInterceptors) {
20249
- const withPrettyHeaders = pendingInterceptors.map(({ method, path, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
20249
+ const withPrettyHeaders = pendingInterceptors.map(({ method, path: path2, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
20250
20250
  Method: method,
20251
20251
  Origin: origin,
20252
- Path: path,
20252
+ Path: path2,
20253
20253
  "Status code": statusCode,
20254
20254
  Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
20255
20255
  Invocations: timesInvoked,
@@ -20328,9 +20328,9 @@ var require_mock_agent = __commonJS((exports, module) => {
20328
20328
  const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
20329
20329
  const dispatchOpts = { ...opts };
20330
20330
  if (acceptNonStandardSearchParameters && dispatchOpts.path) {
20331
- const [path, searchParams] = dispatchOpts.path.split("?");
20331
+ const [path2, searchParams] = dispatchOpts.path.split("?");
20332
20332
  const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
20333
- dispatchOpts.path = `${path}?${normalizedSearchParams}`;
20333
+ dispatchOpts.path = `${path2}?${normalizedSearchParams}`;
20334
20334
  }
20335
20335
  return this[kAgent].dispatch(dispatchOpts, handler);
20336
20336
  }
@@ -20689,12 +20689,12 @@ var require_snapshot_recorder = __commonJS((exports, module) => {
20689
20689
  };
20690
20690
  }
20691
20691
  async loadSnapshots(filePath) {
20692
- const path = filePath || this.#snapshotPath;
20693
- if (!path) {
20692
+ const path2 = filePath || this.#snapshotPath;
20693
+ if (!path2) {
20694
20694
  throw new InvalidArgumentError("Snapshot path is required");
20695
20695
  }
20696
20696
  try {
20697
- const data = await readFile(resolve(path), "utf8");
20697
+ const data = await readFile(resolve(path2), "utf8");
20698
20698
  const parsed = JSON.parse(data);
20699
20699
  if (Array.isArray(parsed)) {
20700
20700
  this.#snapshots.clear();
@@ -20708,16 +20708,16 @@ var require_snapshot_recorder = __commonJS((exports, module) => {
20708
20708
  if (error.code === "ENOENT") {
20709
20709
  this.#snapshots.clear();
20710
20710
  } else {
20711
- throw new UndiciError(`Failed to load snapshots from ${path}`, { cause: error });
20711
+ throw new UndiciError(`Failed to load snapshots from ${path2}`, { cause: error });
20712
20712
  }
20713
20713
  }
20714
20714
  }
20715
20715
  async saveSnapshots(filePath) {
20716
- const path = filePath || this.#snapshotPath;
20717
- if (!path) {
20716
+ const path2 = filePath || this.#snapshotPath;
20717
+ if (!path2) {
20718
20718
  throw new InvalidArgumentError("Snapshot path is required");
20719
20719
  }
20720
- const resolvedPath = resolve(path);
20720
+ const resolvedPath = resolve(path2);
20721
20721
  await mkdir(dirname(resolvedPath), { recursive: true });
20722
20722
  const data = Array.from(this.#snapshots.entries()).map(([hash3, snapshot]) => ({
20723
20723
  hash: hash3,
@@ -21195,15 +21195,15 @@ var require_redirect_handler = __commonJS((exports, module) => {
21195
21195
  return;
21196
21196
  }
21197
21197
  const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
21198
- const path = search ? `${pathname}${search}` : pathname;
21199
- const redirectUrlString = `${origin}${path}`;
21198
+ const path2 = search ? `${pathname}${search}` : pathname;
21199
+ const redirectUrlString = `${origin}${path2}`;
21200
21200
  for (const historyUrl of this.history) {
21201
21201
  if (historyUrl.toString() === redirectUrlString) {
21202
21202
  throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`);
21203
21203
  }
21204
21204
  }
21205
21205
  this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
21206
- this.opts.path = path;
21206
+ this.opts.path = path2;
21207
21207
  this.opts.origin = origin;
21208
21208
  this.opts.query = null;
21209
21209
  }
@@ -27251,9 +27251,9 @@ var require_util4 = __commonJS((exports, module) => {
27251
27251
  }
27252
27252
  }
27253
27253
  }
27254
- function validateCookiePath(path) {
27255
- for (let i = 0;i < path.length; ++i) {
27256
- const code = path.charCodeAt(i);
27254
+ function validateCookiePath(path2) {
27255
+ for (let i = 0;i < path2.length; ++i) {
27256
+ const code = path2.charCodeAt(i);
27257
27257
  if (code < 32 || code === 127 || code === 59) {
27258
27258
  throw new Error("Invalid cookie path");
27259
27259
  }
@@ -30026,6 +30026,27 @@ var require_eventsource = __commonJS((exports, module) => {
30026
30026
  };
30027
30027
  });
30028
30028
 
30029
+ // src/helper.ts
30030
+ import * as fs from "fs";
30031
+ import * as path from "path";
30032
+ import * as os from "os";
30033
+ function json(data) {
30034
+ return {
30035
+ content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
30036
+ details: data
30037
+ };
30038
+ }
30039
+ var KEY_PATH = path.join(os.homedir(), ".bountyagents_key");
30040
+ function getPrivateKey() {
30041
+ if (fs.existsSync(KEY_PATH)) {
30042
+ const key = fs.readFileSync(KEY_PATH, "utf-8").trim();
30043
+ if (key.startsWith("0x")) {
30044
+ return key;
30045
+ }
30046
+ }
30047
+ return "0x289f92dd30c36ff24b75b48623c70dea2b428dabac7a52c5ca810bcda64d861b";
30048
+ }
30049
+
30029
30050
  // ../node_modules/.pnpm/@sinclair+typebox@0.34.48/node_modules/@sinclair/typebox/build/esm/type/guard/value.mjs
30030
30051
  var exports_value = {};
30031
30052
  __export(exports_value, {
@@ -41198,6 +41219,12 @@ init_getAddress();
41198
41219
  init_isAddress();
41199
41220
  init_toBytes();
41200
41221
  init_keccak256();
41222
+ // ../node_modules/.pnpm/viem@2.46.2_typescript@5.9.3_zod@4.3.6/node_modules/viem/_esm/accounts/generatePrivateKey.js
41223
+ init_secp256k1();
41224
+ init_toHex();
41225
+ function generatePrivateKey() {
41226
+ return toHex(secp256k1.utils.randomPrivateKey());
41227
+ }
41201
41228
  // ../node_modules/.pnpm/viem@2.46.2_typescript@5.9.3_zod@4.3.6/node_modules/viem/_esm/accounts/privateKeyToAccount.js
41202
41229
  init_secp256k1();
41203
41230
  init_toHex();
@@ -41376,14 +41403,6 @@ var buildSettleDataHash = (contractAddress, key, owner, token, worker, amount) =
41376
41403
  ]));
41377
41404
  };
41378
41405
 
41379
- // src/helper.ts
41380
- function json(data) {
41381
- return {
41382
- content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
41383
- details: data
41384
- };
41385
- }
41386
-
41387
41406
  // node_modules/undici/index.js
41388
41407
  var __filename = "/Users/amigo/Develop/mizu/bountyagents/plugin/node_modules/undici/index.js";
41389
41408
  var Client = require_client();
@@ -41447,11 +41466,11 @@ function makeDispatcher(fn) {
41447
41466
  if (typeof opts.path !== "string") {
41448
41467
  throw new InvalidArgumentError("invalid opts.path");
41449
41468
  }
41450
- let path = opts.path;
41469
+ let path2 = opts.path;
41451
41470
  if (!opts.path.startsWith("/")) {
41452
- path = `/${path}`;
41471
+ path2 = `/${path2}`;
41453
41472
  }
41454
- url = new URL(util.parseOrigin(url).origin + path);
41473
+ url = new URL(util.parseOrigin(url).origin + path2);
41455
41474
  } else {
41456
41475
  if (!opts) {
41457
41476
  opts = typeof url === "object" ? url : {};
@@ -42288,10 +42307,10 @@ function mergeDefs(...defs) {
42288
42307
  function cloneDef(schema) {
42289
42308
  return mergeDefs(schema._zod.def);
42290
42309
  }
42291
- function getElementAtPath(obj, path) {
42292
- if (!path)
42310
+ function getElementAtPath(obj, path2) {
42311
+ if (!path2)
42293
42312
  return obj;
42294
- return path.reduce((acc, key) => acc?.[key], obj);
42313
+ return path2.reduce((acc, key) => acc?.[key], obj);
42295
42314
  }
42296
42315
  function promiseAllObject(promisesObj) {
42297
42316
  const keys = Object.keys(promisesObj);
@@ -42672,11 +42691,11 @@ function aborted(x, startIndex = 0) {
42672
42691
  }
42673
42692
  return false;
42674
42693
  }
42675
- function prefixIssues(path, issues) {
42694
+ function prefixIssues(path2, issues) {
42676
42695
  return issues.map((iss) => {
42677
42696
  var _a;
42678
42697
  (_a = iss).path ?? (_a.path = []);
42679
- iss.path.unshift(path);
42698
+ iss.path.unshift(path2);
42680
42699
  return iss;
42681
42700
  });
42682
42701
  }
@@ -42859,7 +42878,7 @@ function formatError(error, mapper = (issue2) => issue2.message) {
42859
42878
  }
42860
42879
  function treeifyError(error, mapper = (issue2) => issue2.message) {
42861
42880
  const result = { errors: [] };
42862
- const processError = (error2, path = []) => {
42881
+ const processError = (error2, path2 = []) => {
42863
42882
  var _a, _b;
42864
42883
  for (const issue2 of error2.issues) {
42865
42884
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -42869,7 +42888,7 @@ function treeifyError(error, mapper = (issue2) => issue2.message) {
42869
42888
  } else if (issue2.code === "invalid_element") {
42870
42889
  processError({ issues: issue2.issues }, issue2.path);
42871
42890
  } else {
42872
- const fullpath = [...path, ...issue2.path];
42891
+ const fullpath = [...path2, ...issue2.path];
42873
42892
  if (fullpath.length === 0) {
42874
42893
  result.errors.push(mapper(issue2));
42875
42894
  continue;
@@ -42901,8 +42920,8 @@ function treeifyError(error, mapper = (issue2) => issue2.message) {
42901
42920
  }
42902
42921
  function toDotPath(_path) {
42903
42922
  const segs = [];
42904
- const path = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
42905
- for (const seg of path) {
42923
+ const path2 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
42924
+ for (const seg of path2) {
42906
42925
  if (typeof seg === "number")
42907
42926
  segs.push(`[${seg}]`);
42908
42927
  else if (typeof seg === "symbol")
@@ -54649,13 +54668,13 @@ function resolveRef(ref, ctx) {
54649
54668
  if (!ref.startsWith("#")) {
54650
54669
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
54651
54670
  }
54652
- const path = ref.slice(1).split("/").filter(Boolean);
54653
- if (path.length === 0) {
54671
+ const path2 = ref.slice(1).split("/").filter(Boolean);
54672
+ if (path2.length === 0) {
54654
54673
  return ctx.rootSchema;
54655
54674
  }
54656
54675
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
54657
- if (path[0] === defsKey) {
54658
- const key = path[1];
54676
+ if (path2[0] === defsKey) {
54677
+ const key = path2[1];
54659
54678
  if (!key || !ctx.defs[key]) {
54660
54679
  throw new Error(`Reference not found: ${ref}`);
54661
54680
  }
@@ -55056,7 +55075,7 @@ function date4(params) {
55056
55075
  // ../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/external.js
55057
55076
  config(en_default());
55058
55077
  // src/task-db-types.ts
55059
- var taskStatusSchema = exports_external.enum(["finished", "draft", "active", "closed"]);
55078
+ var taskStatusSchema = exports_external.enum(["finished", "draft", "active", "closed", "pending_review"]);
55060
55079
  var responseStatusSchema = exports_external.enum(["pending", "approved", "rejected"]);
55061
55080
  var taskRecordSchema = exports_external.object({
55062
55081
  id: exports_external.string().uuid(),
@@ -55111,8 +55130,6 @@ var decisionPayloadSchema = exports_external.object({
55111
55130
  settlementSignature: signatureSchema.optional()
55112
55131
  }).refine((value) => value.status !== "pending", {
55113
55132
  message: "Status must be approved or rejected"
55114
- }).refine((value) => value.status === "approved" ? Boolean(value.settlementSignature) : true, {
55115
- message: "settlementSignature required when approving"
55116
55133
  });
55117
55134
  var cancelTaskPayloadSchema = exports_external.object({
55118
55135
  taskId: exports_external.string().uuid()
@@ -55269,8 +55286,8 @@ class BaseBountyPlugin {
55269
55286
  execute: (rawInput) => executor(schema.parse(rawInput))
55270
55287
  });
55271
55288
  }
55272
- async request(path, body, method = "POST") {
55273
- const response = await $fetch(`${this.baseUrl}${path}`, {
55289
+ async request(path2, body, method = "POST") {
55290
+ const response = await $fetch(`${this.baseUrl}${path2}`, {
55274
55291
  method,
55275
55292
  headers: {
55276
55293
  "content-type": "application/json"
@@ -55335,25 +55352,29 @@ class BountyAgentsPublisherPlugin extends BaseBountyPlugin {
55335
55352
  if (!task.token || task.price === "0") {
55336
55353
  throw new Error("Task is not funded yet");
55337
55354
  }
55338
- if (payload.price !== task.price) {
55339
- throw new Error("Price does not match funded amount");
55355
+ const taskPrice = task.price;
55356
+ if (payload.price !== taskPrice) {
55357
+ throw new Error(`Price mismatch: payload price ${payload.price} does not match task price ${taskPrice}`);
55340
55358
  }
55341
55359
  const workerAddress = getAddress(payload.workerAddress);
55342
55360
  if (workerAddress !== getAddress(responseRecord.worker)) {
55343
55361
  throw new Error("Worker address mismatch");
55344
55362
  }
55345
- const settlementSignature = payload.status === "approved" ? await this.createSettlementSignature(responseRecord.task_id, workerAddress, payload.price, task.token) : undefined;
55346
- const canonicalPayload = {
55363
+ const settlementSignature = payload.status === "approved" ? await this.createSettlementSignature(responseRecord.task_id, workerAddress, taskPrice, task.token) : undefined;
55364
+ const body = {
55347
55365
  responseId: payload.responseId,
55348
55366
  workerAddress,
55349
55367
  price: payload.price,
55350
55368
  status: payload.status,
55351
- settlementSignature
55352
- };
55353
- const body = {
55354
- ...canonicalPayload,
55369
+ settlementSignature,
55355
55370
  ownerAddress: this.signer.address,
55356
- signature: await this.signPayload(decisionSignaturePayload(canonicalPayload))
55371
+ signature: await this.signPayload(decisionSignaturePayload({
55372
+ responseId: payload.responseId,
55373
+ workerAddress,
55374
+ price: payload.price,
55375
+ status: payload.status,
55376
+ settlementSignature
55377
+ }))
55357
55378
  };
55358
55379
  const response = await this.request(`/responses/${payload.responseId}/decision`, body);
55359
55380
  return submissionResponseSchema.parse(response).response;
@@ -55495,7 +55516,6 @@ class PrivateKeySigner {
55495
55516
  // src/publisher.ts
55496
55517
  var SERVICE_URL = "http://localhost:3000";
55497
55518
  var CONTRACT_ADDRESS = "0x55D45aFA265d0381C8A81328FfeA408D2Dd45F40";
55498
- var PRIVATE_KEY = "0x289f92dd30c36ff24b75b48623c70dea2b428dabac7a52c5ca810bcda64d861b";
55499
55519
  var TEST_TOKEN_ADDRESS = "0x56DA32693A4e6dDd0eDC932b295cb00372f37f8b";
55500
55520
  var AGENT_ESCROW_ABI = [
55501
55521
  {
@@ -55548,7 +55568,7 @@ var ERC20_ABI = [
55548
55568
  }
55549
55569
  ];
55550
55570
  async function createBountyTask(params) {
55551
- const signer = new PrivateKeySigner(PRIVATE_KEY);
55571
+ const signer = new PrivateKeySigner(getPrivateKey());
55552
55572
  const plugin = new BountyAgentsPublisherPlugin(signer, {
55553
55573
  serviceUrl: SERVICE_URL,
55554
55574
  contractAddress: CONTRACT_ADDRESS
@@ -55561,7 +55581,7 @@ async function createBountyTask(params) {
55561
55581
  return task;
55562
55582
  }
55563
55583
  async function fundBountyTask(params) {
55564
- const signer = new PrivateKeySigner(PRIVATE_KEY);
55584
+ const signer = new PrivateKeySigner(getPrivateKey());
55565
55585
  const plugin = new BountyAgentsPublisherPlugin(signer, {
55566
55586
  serviceUrl: SERVICE_URL,
55567
55587
  contractAddress: CONTRACT_ADDRESS
@@ -55573,7 +55593,7 @@ async function fundBountyTask(params) {
55573
55593
  return task;
55574
55594
  }
55575
55595
  async function depositToken(params) {
55576
- const account = privateKeyToAccount(PRIVATE_KEY);
55596
+ const account = privateKeyToAccount(getPrivateKey());
55577
55597
  const chain = bscTestnet;
55578
55598
  const transport = http();
55579
55599
  const walletClient = createWalletClient({
@@ -55630,6 +55650,15 @@ async function depositToken(params) {
55630
55650
  rawLockedAmount: depositInfo.amountLocked.toString()
55631
55651
  };
55632
55652
  }
55653
+ async function decideOnResponse(params) {
55654
+ const signer = new PrivateKeySigner(getPrivateKey());
55655
+ const plugin = new BountyAgentsPublisherPlugin(signer, {
55656
+ serviceUrl: SERVICE_URL,
55657
+ contractAddress: CONTRACT_ADDRESS
55658
+ });
55659
+ const response = await plugin.executeTool("bountyagents.publisher.task.decision", params);
55660
+ return response;
55661
+ }
55633
55662
  function registerPublisherTools(api3) {
55634
55663
  api3.registerTool({
55635
55664
  name: "create_bounty_task",
@@ -55686,14 +55715,36 @@ function registerPublisherTools(api3) {
55686
55715
  }
55687
55716
  }
55688
55717
  });
55718
+ api3.registerTool({
55719
+ name: "decide_on_response",
55720
+ description: "Approve or reject a task response.",
55721
+ parameters: Type.Object({
55722
+ responseId: Type.String(),
55723
+ workerAddress: Type.String(),
55724
+ price: Type.String(),
55725
+ status: Type.Union([
55726
+ Type.Literal("approved"),
55727
+ Type.Literal("rejected")
55728
+ ])
55729
+ }),
55730
+ async execute(_id, params) {
55731
+ try {
55732
+ const result = await decideOnResponse(params);
55733
+ return json(result);
55734
+ } catch (error48) {
55735
+ return json({
55736
+ error: error48 instanceof Error ? error48.message : String(error48)
55737
+ });
55738
+ }
55739
+ }
55740
+ });
55689
55741
  }
55690
55742
 
55691
55743
  // src/worker.ts
55692
55744
  var SERVICE_URL2 = "http://localhost:3000";
55693
55745
  var CONTRACT_ADDRESS2 = "0x55D45aFA265d0381C8A81328FfeA408D2Dd45F40";
55694
- var PRIVATE_KEY2 = "0x289f92dd30c36ff24b75b48623c70dea2b428dabac7a52c5ca810bcda64d861b";
55695
55746
  async function getAvailableTask(params) {
55696
- const signer = new PrivateKeySigner(PRIVATE_KEY2);
55747
+ const signer = new PrivateKeySigner(getPrivateKey());
55697
55748
  const plugin = new BountyAgentsWorkerPlugin(signer, {
55698
55749
  serviceUrl: SERVICE_URL2,
55699
55750
  contractAddress: CONTRACT_ADDRESS2
@@ -55710,6 +55761,18 @@ async function getAvailableTask(params) {
55710
55761
  }
55711
55762
  return tasks[0];
55712
55763
  }
55764
+ async function submitResponse(params) {
55765
+ const signer = new PrivateKeySigner(getPrivateKey());
55766
+ const plugin = new BountyAgentsWorkerPlugin(signer, {
55767
+ serviceUrl: SERVICE_URL2,
55768
+ contractAddress: CONTRACT_ADDRESS2
55769
+ });
55770
+ const response = await plugin.executeTool("bountyagents.worker.task.respond", {
55771
+ taskId: params.taskId,
55772
+ payload: params.payload
55773
+ });
55774
+ return response;
55775
+ }
55713
55776
  function registerWorkerTools(api3) {
55714
55777
  api3.registerTool({
55715
55778
  name: "get_available_task",
@@ -55732,10 +55795,66 @@ function registerWorkerTools(api3) {
55732
55795
  }
55733
55796
  }
55734
55797
  });
55798
+ api3.registerTool({
55799
+ name: "submit_task_response",
55800
+ description: "Submit a response for an active bounty task.",
55801
+ parameters: Type.Object({
55802
+ taskId: Type.String(),
55803
+ content: Type.String()
55804
+ }),
55805
+ async execute(_id, params) {
55806
+ try {
55807
+ const result = await submitResponse({
55808
+ taskId: params.taskId,
55809
+ payload: params.content
55810
+ });
55811
+ return json(result);
55812
+ } catch (error48) {
55813
+ return json({
55814
+ error: error48 instanceof Error ? error48.message : String(error48)
55815
+ });
55816
+ }
55817
+ }
55818
+ });
55735
55819
  }
55736
55820
 
55737
55821
  // index.ts
55822
+ import * as fs2 from "fs";
55738
55823
  function register(api3) {
55824
+ api3.registerCommand({
55825
+ name: "upclaw",
55826
+ description: "UpClaw Bounty Agents Task commands",
55827
+ acceptsArgs: true,
55828
+ handler: async (ctx) => {
55829
+ const args = ctx.args?.trim() ?? "";
55830
+ const tokens = args.split(/\s+/).filter(Boolean);
55831
+ const action = (tokens[0] ?? "status").toLowerCase();
55832
+ if (action === "init") {
55833
+ try {
55834
+ if (!fs2.existsSync(KEY_PATH)) {
55835
+ const pk = generatePrivateKey();
55836
+ fs2.writeFileSync(KEY_PATH, pk, "utf-8");
55837
+ return json({
55838
+ text: `Initialized new EVM private key and saved to ${KEY_PATH}`
55839
+ });
55840
+ } else {
55841
+ return json({
55842
+ text: `EVM private key already exists at ${KEY_PATH}`
55843
+ });
55844
+ }
55845
+ } catch (error48) {
55846
+ return json({
55847
+ text: "Failed to initialize key:",
55848
+ error: error48.message
55849
+ });
55850
+ }
55851
+ }
55852
+ return json({
55853
+ text: ["UpClaw Bounty Agents Task commands:", "", "/upclaw init"].join(`
55854
+ `)
55855
+ });
55856
+ }
55857
+ });
55739
55858
  registerPublisherTools(api3);
55740
55859
  registerWorkerTools(api3);
55741
55860
  }
package/index.ts CHANGED
@@ -1,52 +1,45 @@
1
+ import { json, KEY_PATH } from "./src/helper.js";
1
2
  import { registerPublisherTools } from "./src/publisher.js";
2
3
  import { registerWorkerTools } from "./src/worker.js";
4
+ import { generatePrivateKey } from "viem/accounts";
5
+ import * as fs from "fs";
3
6
 
4
7
  export default function register(api: any) {
5
- // api.registerCommand({
6
- // name: "task",
7
- // description: "Bounty Agents Task commands",
8
- // acceptsArgs: true,
9
- // handler: async (ctx: any) => {
10
- // const args = ctx.args?.trim() ?? "";
11
- // const tokens = args.split(/\s+/).filter(Boolean);
12
- // const action = (tokens[0] ?? "status").toLowerCase();
8
+ api.registerCommand({
9
+ name: "upclaw",
10
+ description: "UpClaw Bounty Agents Task commands",
11
+ acceptsArgs: true,
12
+ handler: async (ctx: any) => {
13
+ const args = ctx.args?.trim() ?? "";
14
+ const tokens = args.split(/\s+/).filter(Boolean);
15
+ const action = (tokens[0] ?? "status").toLowerCase();
13
16
 
14
- // if (action === "create") {
15
- // const signer = new PrivateKeySigner(
16
- // "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
17
- // );
18
- // const plugin = new BountyAgentsPublisherPlugin(signer, {
19
- // serviceUrl: "http://localhost:3000",
20
- // contractAddress: "0x55D45aFA265d0381C8A81328FfeA408D2Dd45F40",
21
- // });
17
+ if (action === "init") {
18
+ try {
19
+ if (!fs.existsSync(KEY_PATH)) {
20
+ const pk = generatePrivateKey();
21
+ fs.writeFileSync(KEY_PATH, pk, "utf-8");
22
+ return json({
23
+ text: `Initialized new EVM private key and saved to ${KEY_PATH}`,
24
+ });
25
+ } else {
26
+ return json({
27
+ text: `EVM private key already exists at ${KEY_PATH}`,
28
+ });
29
+ }
30
+ } catch (error: any) {
31
+ return json({
32
+ text: "Failed to initialize key:",
33
+ error: error.message,
34
+ });
35
+ }
36
+ }
22
37
 
23
- // try {
24
- // const task = (await plugin.executeTool(
25
- // "bountyagents.publisher.task.create",
26
- // {
27
- // id: crypto.randomUUID(),
28
- // title: "Test Task from CLI",
29
- // content: "This is a test task created via the CLI tool.",
30
- // }
31
- // )) as any;
32
- // console.log("Task created successfully:", task);
33
- // return {
34
- // text: `Task created successfully: ${task.id}`,
35
- // };
36
- // } catch (error) {
37
- // console.error("Failed to create task:", error);
38
- // return {
39
- // text: "Failed to create task:",
40
- // error: error,
41
- // };
42
- // }
43
- // }
44
-
45
- // return {
46
- // text: ["Bounty Agents Task commands:", "", "/task create"].join("\n"),
47
- // };
48
- // },
49
- // });
38
+ return json({
39
+ text: ["UpClaw Bounty Agents Task commands:", "", "/upclaw init"].join("\n"),
40
+ });
41
+ },
42
+ });
50
43
 
51
44
  registerPublisherTools(api);
52
45
  registerWorkerTools(api);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bountyagents/bountyagents-task",
3
- "version": "2026.2.2715",
3
+ "version": "2026.3.9",
4
4
  "description": "BountyAgents Task Plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/helper.ts CHANGED
@@ -1,6 +1,23 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import * as os from "os";
4
+
1
5
  export function json(data: unknown) {
2
6
  return {
3
7
  content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }],
4
8
  details: data,
5
9
  };
6
10
  }
11
+
12
+ export const KEY_PATH = path.join(os.homedir(), ".bountyagents_key");
13
+
14
+ export function getPrivateKey(): `0x${string}` {
15
+ if (fs.existsSync(KEY_PATH)) {
16
+ const key = fs.readFileSync(KEY_PATH, "utf-8").trim();
17
+ if (key.startsWith("0x")) {
18
+ return key as `0x${string}`;
19
+ }
20
+ }
21
+ // Fallback to the default one if the file doesn't exist to not break existing functionality directly, but throw error if user wants to use init
22
+ return "0x289f92dd30c36ff24b75b48623c70dea2b428dabac7a52c5ca810bcda64d861b";
23
+ }
package/src/index.ts CHANGED
@@ -214,8 +214,12 @@ export class BountyAgentsPublisherPlugin extends BaseBountyPlugin {
214
214
  if (!task.token || task.price === "0") {
215
215
  throw new Error("Task is not funded yet");
216
216
  }
217
- if (payload.price !== task.price) {
218
- throw new Error("Price does not match funded amount");
217
+
218
+ // Use the price from the task record for the settlement signature
219
+ const taskPrice = task.price;
220
+
221
+ if (payload.price !== taskPrice) {
222
+ throw new Error(`Price mismatch: payload price ${payload.price} does not match task price ${taskPrice}`);
219
223
  }
220
224
  const workerAddress = getAddress(payload.workerAddress as `0x${string}`);
221
225
  if (workerAddress !== getAddress(responseRecord.worker as `0x${string}`)) {
@@ -227,23 +231,26 @@ export class BountyAgentsPublisherPlugin extends BaseBountyPlugin {
227
231
  ? await this.createSettlementSignature(
228
232
  responseRecord.task_id,
229
233
  workerAddress,
230
- payload.price,
234
+ taskPrice,
231
235
  task.token
232
236
  )
233
237
  : undefined;
234
238
 
235
- const canonicalPayload: DecisionPayload = {
239
+ const body = {
236
240
  responseId: payload.responseId,
237
241
  workerAddress,
238
242
  price: payload.price,
239
243
  status: payload.status,
240
244
  settlementSignature,
241
- };
242
- const body = {
243
- ...canonicalPayload,
244
245
  ownerAddress: this.signer.address,
245
246
  signature: await this.signPayload(
246
- decisionSignaturePayload(canonicalPayload)
247
+ decisionSignaturePayload({
248
+ responseId: payload.responseId,
249
+ workerAddress,
250
+ price: payload.price,
251
+ status: payload.status,
252
+ settlementSignature,
253
+ })
247
254
  ),
248
255
  };
249
256
  const response = await this.request(
package/src/publisher.ts CHANGED
@@ -3,14 +3,12 @@ import { createPublicClient, createWalletClient, http, parseUnits } from "viem";
3
3
  import { privateKeyToAccount } from "viem/accounts";
4
4
  import { bscTestnet } from "viem/chains";
5
5
  import { taskDepositKey } from "./escrow.js";
6
- import { json } from "./helper.js";
6
+ import { json, getPrivateKey } from "./helper.js";
7
7
  import { BountyAgentsPublisherPlugin } from "./index.js";
8
8
  import { PrivateKeySigner } from "./signers.js";
9
9
 
10
10
  const SERVICE_URL = "http://localhost:3000";
11
11
  const CONTRACT_ADDRESS = "0x55D45aFA265d0381C8A81328FfeA408D2Dd45F40";
12
- const PRIVATE_KEY =
13
- "0x289f92dd30c36ff24b75b48623c70dea2b428dabac7a52c5ca810bcda64d861b";
14
12
  const TEST_TOKEN_ADDRESS = "0x56DA32693A4e6dDd0eDC932b295cb00372f37f8b";
15
13
 
16
14
  const AGENT_ESCROW_ABI = [
@@ -69,7 +67,7 @@ export async function createBountyTask(params: {
69
67
  title: string;
70
68
  content: string;
71
69
  }) {
72
- const signer = new PrivateKeySigner(PRIVATE_KEY);
70
+ const signer = new PrivateKeySigner(getPrivateKey());
73
71
  const plugin = new BountyAgentsPublisherPlugin(signer, {
74
72
  serviceUrl: SERVICE_URL,
75
73
  contractAddress: CONTRACT_ADDRESS,
@@ -87,7 +85,7 @@ export async function fundBountyTask(params: {
87
85
  taskId: string;
88
86
  token: string;
89
87
  }) {
90
- const signer = new PrivateKeySigner(PRIVATE_KEY);
88
+ const signer = new PrivateKeySigner(getPrivateKey());
91
89
  const plugin = new BountyAgentsPublisherPlugin(signer, {
92
90
  serviceUrl: SERVICE_URL,
93
91
  contractAddress: CONTRACT_ADDRESS,
@@ -104,7 +102,7 @@ export async function depositToken(params: {
104
102
  taskId: string;
105
103
  amount?: string;
106
104
  }) {
107
- const account = privateKeyToAccount(PRIVATE_KEY);
105
+ const account = privateKeyToAccount(getPrivateKey());
108
106
  const chain = bscTestnet;
109
107
  const transport = http();
110
108
 
@@ -175,6 +173,25 @@ export async function depositToken(params: {
175
173
  };
176
174
  }
177
175
 
176
+ export async function decideOnResponse(params: {
177
+ responseId: string;
178
+ workerAddress: string;
179
+ price: string;
180
+ status: "approved" | "rejected";
181
+ }) {
182
+ const signer = new PrivateKeySigner(getPrivateKey());
183
+ const plugin = new BountyAgentsPublisherPlugin(signer, {
184
+ serviceUrl: SERVICE_URL,
185
+ contractAddress: CONTRACT_ADDRESS,
186
+ });
187
+
188
+ const response = (await plugin.executeTool(
189
+ "bountyagents.publisher.task.decision",
190
+ params
191
+ )) as any;
192
+ return response;
193
+ }
194
+
178
195
  export function registerPublisherTools(api: any) {
179
196
  api.registerTool({
180
197
  name: "create_bounty_task",
@@ -236,4 +253,28 @@ export function registerPublisherTools(api: any) {
236
253
  }
237
254
  },
238
255
  });
256
+
257
+ api.registerTool({
258
+ name: "decide_on_response",
259
+ description: "Approve or reject a task response.",
260
+ parameters: Type.Object({
261
+ responseId: Type.String(),
262
+ workerAddress: Type.String(),
263
+ price: Type.String(),
264
+ status: Type.Union([
265
+ Type.Literal("approved"),
266
+ Type.Literal("rejected"),
267
+ ]),
268
+ }),
269
+ async execute(_id: string, params: any) {
270
+ try {
271
+ const result = await decideOnResponse(params);
272
+ return json(result);
273
+ } catch (error: any) {
274
+ return json({
275
+ error: error instanceof Error ? error.message : String(error),
276
+ });
277
+ }
278
+ },
279
+ });
239
280
  }
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
 
3
- export const taskStatusSchema = z.enum(["finished", "draft", "active", "closed"]);
3
+ export const taskStatusSchema = z.enum(["finished", "draft", "active", "closed", "pending_review"]);
4
4
  export type TaskStatus = z.infer<typeof taskStatusSchema>;
5
5
 
6
6
  export const responseStatusSchema = z.enum(["pending", "approved", "rejected"]);
package/src/types.ts CHANGED
@@ -44,9 +44,6 @@ export const decisionPayloadSchema = z
44
44
  })
45
45
  .refine((value) => value.status !== 'pending', {
46
46
  message: 'Status must be approved or rejected'
47
- })
48
- .refine((value) => (value.status === 'approved' ? Boolean(value.settlementSignature) : true), {
49
- message: 'settlementSignature required when approving'
50
47
  });
51
48
 
52
49
  export const cancelTaskPayloadSchema = z.object({
package/src/worker.ts CHANGED
@@ -1,19 +1,17 @@
1
1
  import { Type } from "@sinclair/typebox";
2
2
  import { PrivateKeySigner } from "./signers.js";
3
3
  import { BountyAgentsWorkerPlugin } from "./index.js";
4
- import { json } from "./helper.js";
4
+ import { json, getPrivateKey } from "./helper.js";
5
5
 
6
6
  const SERVICE_URL = "http://localhost:3000";
7
7
  const CONTRACT_ADDRESS = "0x55D45aFA265d0381C8A81328FfeA408D2Dd45F40";
8
- const PRIVATE_KEY =
9
- "0x289f92dd30c36ff24b75b48623c70dea2b428dabac7a52c5ca810bcda64d861b";
10
8
 
11
9
  export async function getAvailableTask(params: {
12
10
  keyword?: string;
13
11
  pageSize?: number;
14
12
  pageNum?: number;
15
13
  }) {
16
- const signer = new PrivateKeySigner(PRIVATE_KEY);
14
+ const signer = new PrivateKeySigner(getPrivateKey());
17
15
  const plugin = new BountyAgentsWorkerPlugin(signer, {
18
16
  serviceUrl: SERVICE_URL,
19
17
  contractAddress: CONTRACT_ADDRESS,
@@ -32,6 +30,23 @@ export async function getAvailableTask(params: {
32
30
  return tasks[0];
33
31
  }
34
32
 
33
+ export async function submitResponse(params: {
34
+ taskId: string;
35
+ payload: string;
36
+ }) {
37
+ const signer = new PrivateKeySigner(getPrivateKey());
38
+ const plugin = new BountyAgentsWorkerPlugin(signer, {
39
+ serviceUrl: SERVICE_URL,
40
+ contractAddress: CONTRACT_ADDRESS,
41
+ });
42
+
43
+ const response = (await plugin.executeTool("bountyagents.worker.task.respond", {
44
+ taskId: params.taskId,
45
+ payload: params.payload,
46
+ })) as any;
47
+ return response;
48
+ }
49
+
35
50
  export function registerWorkerTools(api: any) {
36
51
  api.registerTool({
37
52
  name: "get_available_task",
@@ -55,4 +70,26 @@ export function registerWorkerTools(api: any) {
55
70
  }
56
71
  },
57
72
  });
73
+
74
+ api.registerTool({
75
+ name: "submit_task_response",
76
+ description: "Submit a response for an active bounty task.",
77
+ parameters: Type.Object({
78
+ taskId: Type.String(),
79
+ content: Type.String(),
80
+ }),
81
+ async execute(_id: string, params: any) {
82
+ try {
83
+ const result = await submitResponse({
84
+ taskId: params.taskId,
85
+ payload: params.content,
86
+ });
87
+ return json(result);
88
+ } catch (error: any) {
89
+ return json({
90
+ error: error instanceof Error ? error.message : String(error),
91
+ });
92
+ }
93
+ },
94
+ });
58
95
  }
@@ -0,0 +1,43 @@
1
+ import { submitResponse } from "./src/worker.js";
2
+ import { decideOnResponse } from "./src/publisher.js";
3
+
4
+ async function testResponseFlow() {
5
+ const taskId = "c5fc8fd0-e7db-4ec8-8fb9-86314cb6a5e7";
6
+ console.log(`\n--- Testing Response Flow for taskId: ${taskId} ---`);
7
+
8
+ try {
9
+ // 1. Submit Response
10
+ console.log("\n1. Submitting response as worker...");
11
+ const responseResult = await submitResponse({
12
+ taskId,
13
+ payload: "This is a test response content submitted via standalone function."
14
+ });
15
+ console.log("Response submission successful!");
16
+ console.log(JSON.stringify(responseResult, null, 2));
17
+
18
+ const responseId = responseResult.id;
19
+ const workerAddress = responseResult.worker;
20
+ // Note: In a real scenario, we might need to fetch the task to get the price,
21
+ // but for testing we'll assume a value or use what's in the response if available.
22
+ // Based on the schema, price is on the task, not the response.
23
+
24
+ // 2. Decide on Response (Approve)
25
+ console.log(`\n2. Deciding on response (approving) as publisher...`);
26
+ // We'll use the price from the task. Since the task was funded with 100 tokens,
27
+ // we use the same value.
28
+ const decisionResult = await decideOnResponse({
29
+ responseId,
30
+ workerAddress,
31
+ price: "142500000",
32
+ status: "approved"
33
+ });
34
+ console.log("Decision (approval) successful!");
35
+ console.log(JSON.stringify(decisionResult, null, 2));
36
+
37
+ } catch (error) {
38
+ console.error("Test flow failed:");
39
+ console.error(error);
40
+ }
41
+ }
42
+
43
+ testResponseFlow();