@continuumdao/ctm-mpc-defi 0.2.55 → 0.2.57

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.
Files changed (61) hide show
  1. package/dist/agent/catalog.cjs +692 -310
  2. package/dist/agent/catalog.cjs.map +1 -1
  3. package/dist/agent/catalog.d.ts +279 -99
  4. package/dist/agent/catalog.js +687 -312
  5. package/dist/agent/catalog.js.map +1 -1
  6. package/dist/agent/skills/aave-v4/SKILL.md +26 -3
  7. package/dist/agent/skills/aerodrome/SKILL.md +3 -1
  8. package/dist/agent/skills/circle-cctp/SKILL.md +5 -4
  9. package/dist/agent/skills/continuum-dao-marketplace/SKILL.md +4 -4
  10. package/dist/agent/skills/curve-dao/SKILL.md +2 -2
  11. package/dist/agent/skills/uniswap-v4/SKILL.md +2 -2
  12. package/dist/index.cjs +165 -19
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.js +166 -20
  15. package/dist/index.js.map +1 -1
  16. package/dist/protocols/evm/aave-v4/index.cjs +198 -15
  17. package/dist/protocols/evm/aave-v4/index.cjs.map +1 -1
  18. package/dist/protocols/evm/aave-v4/index.d.ts +62 -7
  19. package/dist/protocols/evm/aave-v4/index.js +189 -16
  20. package/dist/protocols/evm/aave-v4/index.js.map +1 -1
  21. package/dist/protocols/evm/aerodrome/index.cjs +152 -63
  22. package/dist/protocols/evm/aerodrome/index.cjs.map +1 -1
  23. package/dist/protocols/evm/aerodrome/index.d.ts +30 -58
  24. package/dist/protocols/evm/aerodrome/index.js +151 -64
  25. package/dist/protocols/evm/aerodrome/index.js.map +1 -1
  26. package/dist/protocols/evm/circle-cctp/index.cjs +77 -19
  27. package/dist/protocols/evm/circle-cctp/index.cjs.map +1 -1
  28. package/dist/protocols/evm/circle-cctp/index.d.ts +53 -3
  29. package/dist/protocols/evm/circle-cctp/index.js +76 -20
  30. package/dist/protocols/evm/circle-cctp/index.js.map +1 -1
  31. package/dist/protocols/evm/compound-v3/index.cjs +115 -2
  32. package/dist/protocols/evm/compound-v3/index.cjs.map +1 -1
  33. package/dist/protocols/evm/compound-v3/index.js +116 -3
  34. package/dist/protocols/evm/compound-v3/index.js.map +1 -1
  35. package/dist/protocols/evm/continuum-dao/index.cjs +288 -32
  36. package/dist/protocols/evm/continuum-dao/index.cjs.map +1 -1
  37. package/dist/protocols/evm/continuum-dao/index.d.ts +14 -1
  38. package/dist/protocols/evm/continuum-dao/index.js +287 -33
  39. package/dist/protocols/evm/continuum-dao/index.js.map +1 -1
  40. package/dist/protocols/evm/curve-dao/index.cjs +120 -5
  41. package/dist/protocols/evm/curve-dao/index.cjs.map +1 -1
  42. package/dist/protocols/evm/curve-dao/index.js +120 -5
  43. package/dist/protocols/evm/curve-dao/index.js.map +1 -1
  44. package/dist/protocols/evm/euler-v2/index.cjs +121 -6
  45. package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
  46. package/dist/protocols/evm/euler-v2/index.js +121 -6
  47. package/dist/protocols/evm/euler-v2/index.js.map +1 -1
  48. package/dist/protocols/evm/morpho/index.cjs +129 -57
  49. package/dist/protocols/evm/morpho/index.cjs.map +1 -1
  50. package/dist/protocols/evm/morpho/index.d.ts +2 -1
  51. package/dist/protocols/evm/morpho/index.js +129 -58
  52. package/dist/protocols/evm/morpho/index.js.map +1 -1
  53. package/dist/protocols/evm/pendle/index.cjs +129 -10
  54. package/dist/protocols/evm/pendle/index.cjs.map +1 -1
  55. package/dist/protocols/evm/pendle/index.js +129 -10
  56. package/dist/protocols/evm/pendle/index.js.map +1 -1
  57. package/dist/protocols/evm/uniswap-v4/index.cjs +164 -17
  58. package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -1
  59. package/dist/protocols/evm/uniswap-v4/index.js +165 -18
  60. package/dist/protocols/evm/uniswap-v4/index.js.map +1 -1
  61. package/package.json +1 -1
@@ -191,10 +191,10 @@ function docsBaseUrl() {
191
191
  return raw.replace(/\/+$/, "");
192
192
  }
193
193
  function parseCommitteeAddressesFromConstitution(markdown) {
194
- const text = String(markdown || "");
195
- const start = text.search(/^### Committee List\s*$/m);
194
+ const text2 = String(markdown || "");
195
+ const start = text2.search(/^### Committee List\s*$/m);
196
196
  if (start < 0) return [];
197
- const lines = text.slice(start).split("\n");
197
+ const lines = text2.slice(start).split("\n");
198
198
  const addresses = [];
199
199
  for (let i = 1; i < lines.length; i += 1) {
200
200
  const line = lines[i] ?? "";
@@ -352,11 +352,11 @@ var init_defiEvmClient = __esm({
352
352
  // src/core/purpose.ts
353
353
  function mergePurposeText(purposeText, purposeSuffix) {
354
354
  const t = (purposeText ?? "").trim();
355
- const suffix = (purposeSuffix ?? "").trim();
356
- if (!suffix) return t;
355
+ const suffix2 = (purposeSuffix ?? "").trim();
356
+ if (!suffix2) return t;
357
357
  return t ? `${t}
358
358
 
359
- ${suffix}` : suffix;
359
+ ${suffix2}` : suffix2;
360
360
  }
361
361
  var init_purpose = __esm({
362
362
  "src/core/purpose.ts"() {
@@ -930,8 +930,8 @@ async function continuumDaoForumUnread(args) {
930
930
  if (args.filter?.trim()) qs2.set("filter", args.filter.trim());
931
931
  if (args.start != null) qs2.set("start", String(args.start));
932
932
  if (args.limit != null) qs2.set("limit", String(args.limit));
933
- const suffix = qs2.toString() ? `?${qs2}` : "";
934
- return forumFetch(`/api/continuum/forum/unread${suffix}`, {
933
+ const suffix2 = qs2.toString() ? `?${qs2}` : "";
934
+ return forumFetch(`/api/continuum/forum/unread${suffix2}`, {
935
935
  forumUrl: args.forumUrl,
936
936
  ticket: args.ticket
937
937
  });
@@ -1454,8 +1454,8 @@ function buildFoundryProposalSimulatePlan(args) {
1454
1454
  )
1455
1455
  });
1456
1456
  args.batches.forEach((batch, bi) => {
1457
- const suffix = batch.label != null ? solIdent(batch.label, `Option${(batch.optionIndex ?? bi) + 1}`) : "Bravo";
1458
- const contractName = `ContinuumDaoSimulateExecute${suffix}`;
1457
+ const suffix2 = batch.label != null ? solIdent(batch.label, `Option${(batch.optionIndex ?? bi) + 1}`) : "Bravo";
1458
+ const contractName = `ContinuumDaoSimulateExecute${suffix2}`;
1459
1459
  const path = `script/${contractName}.s.sol`;
1460
1460
  const body = [
1461
1461
  " function run() external {",
@@ -2691,7 +2691,7 @@ async function continuumDaoRegisterProposal(payload) {
2691
2691
  headers: { "Content-Type": "application/json" },
2692
2692
  body
2693
2693
  });
2694
- const text = await res.text();
2694
+ const text2 = await res.text();
2695
2695
  if (res.status === 409) {
2696
2696
  const repair = await fetch(`${exports.CONTINUUM_DAO_GOVERNANCE_API}/proposals/repair`, {
2697
2697
  method: "POST",
@@ -2702,8 +2702,8 @@ async function continuumDaoRegisterProposal(payload) {
2702
2702
  if (!repair.ok) throw new Error(`proposals/repair: ${repair.status} ${repairText}`);
2703
2703
  return { ok: true, result: JSON.parse(repairText) };
2704
2704
  }
2705
- if (!res.ok) throw new Error(`proposals/create: ${res.status} ${text}`);
2706
- return { ok: true, result: JSON.parse(text) };
2705
+ if (!res.ok) throw new Error(`proposals/create: ${res.status} ${text2}`);
2706
+ return { ok: true, result: JSON.parse(text2) };
2707
2707
  }
2708
2708
  exports.CONTINUUM_DAO_PROPOSE_FALLBACK = void 0; exports.CONTINUUM_DAO_VOTE_FALLBACK = void 0; exports.CONTINUUM_DAO_EXECUTE_FALLBACK = void 0; exports.CONTINUUM_DAO_CANCEL_FALLBACK = void 0; exports.CONTINUUM_DAO_GOV_EVM_TYPES = void 0; exports.governorWriteAbi = void 0; var governorReadAbi, FORUM_SECTION_TO_PROPOSAL_TYPE; exports.GOVERNOR_STATE = void 0; exports.GOVERNOR_STATE_LABELS = void 0;
2709
2709
  var init_governance = __esm({
@@ -5299,10 +5299,20 @@ function foldMarketplaceEvents(events, initial) {
5299
5299
  for (const ev of events) applyMarketplaceEvent(book, ev);
5300
5300
  return book;
5301
5301
  }
5302
+ function auctionDeadlineUnix(auction) {
5303
+ const unix = Number(auction.deadlineUnix);
5304
+ if (Number.isFinite(unix) && unix > 0) return unix;
5305
+ if (auction.deadlineAt) {
5306
+ const ms = Date.parse(auction.deadlineAt);
5307
+ if (Number.isFinite(ms) && ms > 0) return Math.floor(ms / 1e3);
5308
+ }
5309
+ return unix;
5310
+ }
5302
5311
  function deriveAuctionStatus(auction, nowUnix) {
5303
- const deadline = Number(auction.deadlineUnix);
5312
+ const deadline = auctionDeadlineUnix(auction);
5304
5313
  if (auction.storedStatus === "Pending" && Number.isFinite(deadline) && nowUnix >= deadline) return "Expired";
5305
5314
  if (auction.storedStatus === "Active" && Number.isFinite(deadline) && nowUnix >= deadline) return "Complete";
5315
+ if (auction.storedStatus === "Pending") return "Active";
5306
5316
  return auction.derivedStatus || auction.storedStatus;
5307
5317
  }
5308
5318
  function applyDerivedStatuses(book, nowUnix) {
@@ -5412,7 +5422,11 @@ function keyGenOwnsVeCtm(snap, seller) {
5412
5422
  return false;
5413
5423
  }
5414
5424
  function assertNotOwn(snap, seller, tokenId) {
5415
- if (same2(snap.owner, snap.executor) || seller && same2(seller, snap.executor) || snap.executorLiveAuction) {
5425
+ const listedByKeyGen = seller != null && same2(seller, snap.executor) || snap.listing != null && snap.listing.status === 1 && same2(snap.listing.creator, snap.executor);
5426
+ if (listedByKeyGen && !snap.executorLiveAuction) {
5427
+ throw new Error(`This KeyGen listed veCTM #${tokenId.toString()}. Delist it instead of buying it.`);
5428
+ }
5429
+ if (same2(snap.owner, snap.executor) || snap.executorLiveAuction) {
5416
5430
  throw new Error(`This KeyGen already owns veCTM #${tokenId.toString()} and cannot buy or bid on it.`);
5417
5431
  }
5418
5432
  }
@@ -5484,6 +5498,7 @@ function planMarketplaceSteps(input, snap) {
5484
5498
  const m = snap.marketplace;
5485
5499
  switch (input.action) {
5486
5500
  case "createListing": {
5501
+ assertNotAttached(snap, input.tokenId);
5487
5502
  assertPayment(snap);
5488
5503
  assertDeadline(snap, input.deadline);
5489
5504
  if (!same2(snap.owner, snap.executor)) throw new Error("Only the veCTM owner can create a listing.");
@@ -5510,7 +5525,9 @@ function planMarketplaceSteps(input, snap) {
5510
5525
  ]);
5511
5526
  }
5512
5527
  case "delist": {
5513
- if (!snap.listing || snap.listing.status !== 1) throw new Error("No open listing for this KeyGen.");
5528
+ const listing = snap.listing;
5529
+ const openForKeyGen = listing != null && listing.status === 1 && same2(listing.creator, snap.executor);
5530
+ if (!openForKeyGen) throw new Error("No open listing for this KeyGen.");
5514
5531
  return [
5515
5532
  {
5516
5533
  to: m,
@@ -5555,6 +5572,7 @@ function planMarketplaceSteps(input, snap) {
5555
5572
  ]);
5556
5573
  }
5557
5574
  case "createOffering": {
5575
+ assertNotAttached(snap, input.tokenId);
5558
5576
  assertNotOwn(snap, void 0, input.tokenId);
5559
5577
  assertPayment(snap);
5560
5578
  assertDeadline(snap, input.deadline);
@@ -6245,8 +6263,8 @@ async function getJson(url) {
6245
6263
  try {
6246
6264
  const res = await fetch(url);
6247
6265
  if (!res.ok) {
6248
- const text = await res.text().catch(() => "");
6249
- return { ok: false, status: res.status, error: new Error(`${url}: ${res.status} ${text}`.trim()) };
6266
+ const text2 = await res.text().catch(() => "");
6267
+ return { ok: false, status: res.status, error: new Error(`${url}: ${res.status} ${text2}`.trim()) };
6250
6268
  }
6251
6269
  return { ok: true, body: await res.json() };
6252
6270
  } catch (err) {
@@ -6286,6 +6304,37 @@ function matchAuction(row, args, includeInactive) {
6286
6304
  if (args.seller && row.seller.toLowerCase() !== args.seller.toLowerCase()) return false;
6287
6305
  return true;
6288
6306
  }
6307
+ function presentAddress(value) {
6308
+ const text2 = (value ?? "").trim();
6309
+ if (!text2 || /^0x0+$/i.test(text2)) return "";
6310
+ return text2;
6311
+ }
6312
+ function sameAddress(a, b) {
6313
+ const left = (a ?? "").trim();
6314
+ const right = (b ?? "").trim();
6315
+ return Boolean(left && right && left.toLowerCase() === right.toLowerCase());
6316
+ }
6317
+ function annotateListingViewer(items, viewer) {
6318
+ const who = presentAddress(viewer);
6319
+ if (!who) return items;
6320
+ return items.map((row) => {
6321
+ const seller = presentAddress(row.seller) || presentAddress(row.creator) || presentAddress(row.currentOwner);
6322
+ const closed = row.storedStatus === "Fulfilled" || row.storedStatus === "Delisted" || row.storedStatus === "DelistedOrRescinded";
6323
+ const open = !closed && (row.storedStatus === "Open" || row.protocolStatus === "Open");
6324
+ const mine = sameAddress(seller, who);
6325
+ return { ...row, viewerAction: mine && open ? "delist" : mine ? "none" : open ? "buy" : "none" };
6326
+ });
6327
+ }
6328
+ function presentAuction(row, nowUnix = Math.floor(Date.now() / 1e3)) {
6329
+ const derivedStatus = deriveAuctionStatus({ ...row, bids: row.bids ?? [] }, nowUnix);
6330
+ const closed = derivedStatus === "Complete" || derivedStatus === "Expired";
6331
+ return {
6332
+ ...row,
6333
+ bids: row.bids ?? [],
6334
+ derivedStatus,
6335
+ needsSettle: closed ? true : row.needsSettle
6336
+ };
6337
+ }
6289
6338
  function listFrom(items, source) {
6290
6339
  return { items, nextCursor: null, source };
6291
6340
  }
@@ -6315,11 +6364,18 @@ async function fetchContinuumDaoMarketplaceListings(args = {}) {
6315
6364
  const res = await getJson(url);
6316
6365
  if (res.ok) {
6317
6366
  const body = res.body;
6318
- return { items: body.items ?? [], nextCursor: body.nextCursor ?? null, source: "api" };
6367
+ return {
6368
+ items: annotateListingViewer(body.items ?? [], args.viewer),
6369
+ nextCursor: body.nextCursor ?? null,
6370
+ source: "api"
6371
+ };
6319
6372
  }
6320
6373
  if (args.cursor || !isOffline(res.status)) throw res.error;
6321
6374
  const book = await logsBook(args);
6322
- return listFrom(book.listings.filter((row) => matchOrder(row, args, includeInactive)), "logs");
6375
+ return listFrom(
6376
+ annotateListingViewer(book.listings.filter((row) => matchOrder(row, args, includeInactive)), args.viewer),
6377
+ "logs"
6378
+ );
6323
6379
  }
6324
6380
  async function fetchContinuumDaoMarketplaceOfferings(args = {}) {
6325
6381
  const includeInactive = Boolean(args.includeInactive);
@@ -6356,20 +6412,30 @@ async function fetchContinuumDaoMarketplaceAuctions(args = {}) {
6356
6412
  if (res.ok) {
6357
6413
  const body = res.body;
6358
6414
  return {
6359
- items: (body.items ?? []).map((row) => ({ ...row, bids: row.bids ?? [] })),
6415
+ items: (body.items ?? []).map((row) => presentAuction(row)).filter((row) => includeInactive || isLiveAuctionStatus(row.derivedStatus)),
6360
6416
  nextCursor: body.nextCursor ?? null,
6361
6417
  source: "api"
6362
6418
  };
6363
6419
  }
6364
6420
  if (args.cursor || !isOffline(res.status)) throw res.error;
6365
6421
  const book = await logsBook(args);
6366
- return listFrom(book.auctions.filter((row) => matchAuction(row, args, includeInactive)), "logs");
6422
+ return listFrom(book.auctions.filter((row) => matchAuction(row, args, includeInactive)).map((row) => presentAuction(row)), "logs");
6367
6423
  }
6368
6424
  async function fetchContinuumDaoMarketplaceToken(args) {
6369
6425
  const url = `${apiBase(args)}/marketplace/tokens/${encodeURIComponent(args.tokenId)}${qs({ viewer: args.viewer })}`;
6370
6426
  const res = await getJson(url);
6371
6427
  if (res.ok && res.body && typeof res.body === "object") {
6372
- return { ...res.body, source: "api" };
6428
+ const body = res.body;
6429
+ return {
6430
+ ...body,
6431
+ auction: body.auction ? presentAuction(body.auction) : null,
6432
+ history: {
6433
+ listings: body.history?.listings ?? [],
6434
+ offerings: body.history?.offerings ?? [],
6435
+ auctions: (body.history?.auctions ?? []).map((row) => presentAuction(row))
6436
+ },
6437
+ source: "api"
6438
+ };
6373
6439
  }
6374
6440
  if (!res.ok && !isOffline(res.status)) throw res.error;
6375
6441
  const book = await logsBook(args);
@@ -6380,11 +6446,14 @@ async function fetchContinuumDaoMarketplaceToken(args) {
6380
6446
  token: { tokenId: args.tokenId },
6381
6447
  listing: listings.find((row) => isOpenOrder(row)) ?? null,
6382
6448
  offerings: offerings.filter((row) => isOpenOrder(row)),
6383
- auction: auctions.find((row) => isLiveAuctionStatus(row.derivedStatus)) ?? null,
6449
+ auction: (() => {
6450
+ const live = auctions.find((row) => isLiveAuctionStatus(row.derivedStatus));
6451
+ return live ? presentAuction(live) : null;
6452
+ })(),
6384
6453
  history: {
6385
6454
  listings: listings.filter((row) => !isOpenOrder(row)),
6386
6455
  offerings: offerings.filter((row) => !isOpenOrder(row)),
6387
- auctions: auctions.filter((row) => !isLiveAuctionStatus(row.derivedStatus))
6456
+ auctions: auctions.filter((row) => !isLiveAuctionStatus(row.derivedStatus)).map((row) => presentAuction(row))
6388
6457
  },
6389
6458
  source: "logs"
6390
6459
  };
@@ -6411,7 +6480,7 @@ async function fetchContinuumDaoMarketplaceActivity(args) {
6411
6480
  return {
6412
6481
  address: args.address,
6413
6482
  orders: body.orders ?? [],
6414
- auctions: (body.auctions ?? []).map((row) => ({ ...row, bids: row.bids ?? [] })),
6483
+ auctions: (body.auctions ?? []).map((row) => presentAuction(row)),
6415
6484
  source: "api"
6416
6485
  };
6417
6486
  }
@@ -6424,7 +6493,7 @@ async function fetchContinuumDaoMarketplaceActivity(args) {
6424
6493
  const auctions = book.auctions.filter((row) => {
6425
6494
  return row.seller.toLowerCase() === address || (row.buyer ?? "").toLowerCase() === address || (row.highestBidder ?? "").toLowerCase() === address || row.bids.some((bid) => bid.bidder.toLowerCase() === address);
6426
6495
  });
6427
- return { address: args.address, orders, auctions, source: "logs" };
6496
+ return { address: args.address, orders, auctions: auctions.map((row) => presentAuction(row)), source: "logs" };
6428
6497
  }
6429
6498
 
6430
6499
  // src/protocols/evm/continuum-dao/marketplaceSearch.ts
@@ -6496,6 +6565,13 @@ function positive(value) {
6496
6565
  const trimmed = (value ?? "").trim();
6497
6566
  return trimmed && trimmed !== "0" ? trimmed : "";
6498
6567
  }
6568
+ function party(...values) {
6569
+ for (const value of values) {
6570
+ const text2 = (value ?? "").trim();
6571
+ if (text2 && !/^0x0+$/i.test(text2)) return text2;
6572
+ }
6573
+ return "";
6574
+ }
6499
6575
  function unlockUnixFrom(row) {
6500
6576
  const iso2 = positive(row.unlockTimeAt);
6501
6577
  if (iso2) {
@@ -6515,7 +6591,7 @@ function listingCandidate(row) {
6515
6591
  kind: "listing",
6516
6592
  tokenId: row.tokenId,
6517
6593
  onchainIndex: row.onchainIndex,
6518
- seller: row.seller ?? row.creator,
6594
+ seller: party(row.seller, row.creator, row.currentOwner),
6519
6595
  paymentToken: row.paymentToken,
6520
6596
  price: asBig(row.price),
6521
6597
  priceBasis: "ask",
@@ -6573,7 +6649,7 @@ function rankMarketplaceSearchHits(rows, query, nowUnix = Math.floor(Date.now()
6573
6649
  const excludeOwned = query.excludeOwned !== false && Boolean(executor);
6574
6650
  let matched = rows.filter((row) => {
6575
6651
  if (query.paymentToken && !same3(row.paymentToken, query.paymentToken)) return false;
6576
- if (excludeOwned && same3(row.seller, executor)) return false;
6652
+ if (excludeOwned && row.kind !== "listing" && same3(row.seller, executor)) return false;
6577
6653
  if (minLocked != null && row.locked < minLocked) return false;
6578
6654
  if (maxLocked != null && row.locked > maxLocked) return false;
6579
6655
  if (unlockAfter != null && row.unlockUnix < unlockAfter) return false;
@@ -6581,6 +6657,10 @@ function rankMarketplaceSearchHits(rows, query, nowUnix = Math.floor(Date.now()
6581
6657
  if (monthCap != null && (row.unlockUnix <= nowUnix || row.unlockUnix > monthCap)) return false;
6582
6658
  return true;
6583
6659
  });
6660
+ matched = matched.map((row) => {
6661
+ const ownListing = Boolean(executor && row.kind === "listing" && same3(row.seller, executor));
6662
+ return ownListing ? { ...row, fillable: false } : row;
6663
+ });
6584
6664
  const priceSort = sort === "price" || sort === "pricePerLockedCtm";
6585
6665
  if (priceSort && !query.paymentToken) {
6586
6666
  const tokens = new Set(matched.map((row) => row.paymentToken.toLowerCase()));
@@ -6605,9 +6685,16 @@ function rankMarketplaceSearchHits(rows, query, nowUnix = Math.floor(Date.now()
6605
6685
  return a.tokenId.localeCompare(b.tokenId);
6606
6686
  });
6607
6687
  const limit = Math.min(MAX_LIMIT, Math.max(1, query.limit ?? DEFAULT_LIMIT));
6608
- return matched.slice(0, limit).map((row) => toHit(row, nowUnix));
6688
+ return matched.slice(0, limit).map((row) => {
6689
+ const ownListing = Boolean(executor && row.kind === "listing" && same3(row.seller, executor));
6690
+ return toHit(
6691
+ ownListing ? { ...row, fillable: false } : row,
6692
+ nowUnix,
6693
+ ownListing ? "delist" : row.kind === "auction" ? "bid" : "buy"
6694
+ );
6695
+ });
6609
6696
  }
6610
- function toHit(row, nowUnix) {
6697
+ function toHit(row, nowUnix, action) {
6611
6698
  const meta4 = paymentMeta(row.paymentToken);
6612
6699
  const perCtm = row.locked > 0n ? row.price * 10n ** 18n / row.locked : 0n;
6613
6700
  const months = row.unlockUnix > nowUnix ? ((row.unlockUnix - nowUnix) / MONTH_SECONDS).toFixed(1) : row.unlockUnix > 0 ? "0" : "";
@@ -6628,7 +6715,8 @@ function toHit(row, nowUnix) {
6628
6715
  pricePerLockedCtm: row.locked > 0n ? humanAmount(perCtm, meta4.decimals) : "",
6629
6716
  deadlineAt: row.deadlineUnix > 0 ? new Date(row.deadlineUnix * 1e3).toISOString() : "",
6630
6717
  attached: row.attached,
6631
- fillable: row.fillable
6718
+ fillable: row.fillable,
6719
+ action
6632
6720
  };
6633
6721
  }
6634
6722
  async function fillMissingLocks(rows, rpcUrl, chainId) {
@@ -7169,6 +7257,172 @@ function marketplaceVeCtmReceivedBy(detail, executor) {
7169
7257
  return null;
7170
7258
  }
7171
7259
 
7260
+ // src/protocols/evm/continuum-dao/purpose.ts
7261
+ init_constants();
7262
+ function chainParts(chainId) {
7263
+ const n = typeof chainId === "number" ? chainId : Number.parseInt(String(chainId ?? "").trim(), 10);
7264
+ const id = Number.isFinite(n) ? n : 0;
7265
+ if (id === exports.CONTINUUM_DAO_LINEA_CHAIN_ID) return { name: "Linea Mainnet", id };
7266
+ if (id === exports.CONTINUUM_DAO_LINEA_SEPOLIA_CHAIN_ID) return { name: "Linea Sepolia", id };
7267
+ if (id === exports.CONTINUUM_DAO_ETHEREUM_CHAIN_ID) return { name: "Ethereum Mainnet", id };
7268
+ return { name: "chain", id };
7269
+ }
7270
+ function suffix(chainId) {
7271
+ const { name, id } = chainParts(chainId);
7272
+ return `on ${name} (chainId ${id})`;
7273
+ }
7274
+ function text(value) {
7275
+ return String(value ?? "").trim();
7276
+ }
7277
+ function tokenLabel(value) {
7278
+ const id = text(value);
7279
+ return id ? `#${id}` : "#\u2026";
7280
+ }
7281
+ function shortAddr(value) {
7282
+ const trimmed = text(value);
7283
+ if (!trimmed) return "\u2026";
7284
+ try {
7285
+ if (!viem.isAddress(trimmed)) return trimmed;
7286
+ const addr2 = viem.getAddress(trimmed);
7287
+ return `${addr2.slice(0, 6)}\u2026${addr2.slice(-4)}`;
7288
+ } catch {
7289
+ return trimmed;
7290
+ }
7291
+ }
7292
+ function weeksLabel(seconds) {
7293
+ const n = Number(text(seconds));
7294
+ if (!Number.isFinite(n) || n <= 0) return "\u2026 weeks";
7295
+ const weeks = Math.max(1, Math.round(n / exports.WEEK_SECONDS));
7296
+ return `${weeks} week${weeks === 1 ? "" : "s"}`;
7297
+ }
7298
+ function paymentMeta3(address) {
7299
+ const lower = text(address).toLowerCase();
7300
+ if (lower === exports.MARKETPLACE_USDC_LINEA_ADDRESS.toLowerCase()) return { symbol: "USDC", decimals: 6 };
7301
+ if (lower === exports.MARKETPLACE_WETH_LINEA_ADDRESS.toLowerCase()) return { symbol: "WETH", decimals: 18 };
7302
+ if (lower === exports.CTM_TOKEN_ADDRESS.toLowerCase()) return { symbol: "CTM", decimals: 18 };
7303
+ return { symbol: "token", decimals: 18 };
7304
+ }
7305
+ function moneyFromWei(wei, paymentToken) {
7306
+ const raw = text(wei);
7307
+ if (!raw) return "\u2026 token";
7308
+ try {
7309
+ const meta4 = paymentMeta3(paymentToken);
7310
+ const human2 = viem.formatUnits(BigInt(raw), meta4.decimals).replace(/(\.\d*?[1-9])0+$/, "$1").replace(/\.0+$/, "");
7311
+ return `${human2} ${meta4.symbol}`;
7312
+ } catch {
7313
+ return raw;
7314
+ }
7315
+ }
7316
+ function deadlineLabel(value) {
7317
+ const n = Number(text(value));
7318
+ if (!Number.isFinite(n) || n <= 0) return "\u2026";
7319
+ const date = new Date(n * 1e3);
7320
+ if (Number.isNaN(date.getTime())) return "\u2026";
7321
+ return `${date.toISOString().slice(0, 16).replace("T", " ")} UTC`;
7322
+ }
7323
+ function bravoLabel(support) {
7324
+ const raw = text(support).toLowerCase();
7325
+ if (raw === "0" || raw === "against") return "Against";
7326
+ if (raw === "1" || raw === "for") return "For";
7327
+ if (raw === "2" || raw === "abstain") return "Abstain";
7328
+ return null;
7329
+ }
7330
+ function proposalLabel(input) {
7331
+ const title = text(input.title || input.proposalTitle);
7332
+ if (title) return title;
7333
+ const id = text(input.proposalId);
7334
+ return id ? `proposal ${id}` : "proposal";
7335
+ }
7336
+ function buildContinuumDaoMcpPurpose(action, input) {
7337
+ const end = suffix(input.chainId);
7338
+ const id = tokenLabel(input.tokenId);
7339
+ switch (action) {
7340
+ case "createLock":
7341
+ return `ContinuumDAO: create lock ${text(input.amountHuman) || "\u2026"} CTM for ${weeksLabel(input.lockDurationSeconds)} ${end}`;
7342
+ case "increaseAmount":
7343
+ return `ContinuumDAO: increase lock ${id} by ${text(input.amountHuman) || "\u2026"} CTM ${end}`;
7344
+ case "increaseUnlockTime":
7345
+ return `ContinuumDAO: extend lock ${id} by ${weeksLabel(input.lockDurationSeconds)} ${end}`;
7346
+ case "split":
7347
+ return `ContinuumDAO: split lock ${id}, extract ${text(input.extractedHuman) || "\u2026"} CTM ${end}`;
7348
+ case "merge": {
7349
+ const from = tokenLabel(input.fromTokenId);
7350
+ const into = text(input.toTokenId);
7351
+ return into ? `ContinuumDAO: merge lock ${from} into #${into} ${end}` : `ContinuumDAO: merge lock ${from} into \u2026 ${end}`;
7352
+ }
7353
+ case "withdraw":
7354
+ return `ContinuumDAO: withdraw expired lock ${id} ${end}`;
7355
+ case "liquidate":
7356
+ return `ContinuumDAO: liquidate lock ${id} ${end}`;
7357
+ case "delegate":
7358
+ return text(input.delegatee) ? `ContinuumDAO: delegate voting power to ${shortAddr(input.delegatee)} ${end}` : `ContinuumDAO: delegate voting power ${end}`;
7359
+ case "undelegate":
7360
+ return `ContinuumDAO: undelegate (return voting power to this KeyGen) ${end}`;
7361
+ case "transfer":
7362
+ return text(input.to) ? `ContinuumDAO: transfer veCTM ${id} to ${shortAddr(input.to)} ${end}` : `ContinuumDAO: transfer veCTM ${id} ${end}`;
7363
+ case "attach":
7364
+ return text(input.tokenId) ? `ContinuumDAO: attach veCTM ${id} to this node ${end}` : `ContinuumDAO: attach veCTM to this node ${end}`;
7365
+ case "requestDetach":
7366
+ return `ContinuumDAO: request detach veCTM ${id} ${end}`;
7367
+ case "proposeBravo": {
7368
+ const title = text(input.title);
7369
+ return title ? `ContinuumDAO: propose "${title}" (Bravo) ${end}` : `ContinuumDAO: propose governance proposal (Bravo) ${end}`;
7370
+ }
7371
+ case "proposeDelta": {
7372
+ const title = text(input.title);
7373
+ return title ? `ContinuumDAO: propose "${title}" (Delta) ${end}` : `ContinuumDAO: propose governance proposal (Delta) ${end}`;
7374
+ }
7375
+ case "castVoteBravo": {
7376
+ const label = proposalLabel(input);
7377
+ const support = bravoLabel(input.support);
7378
+ return support ? `ContinuumDAO: vote ${support} on "${label}" ${end}` : `ContinuumDAO: vote on "${label}" ${end}`;
7379
+ }
7380
+ case "castVoteDelta":
7381
+ return `ContinuumDAO: vote on "${proposalLabel(input)}" (Delta) ${end}`;
7382
+ case "execute":
7383
+ return `ContinuumDAO: execute "${proposalLabel(input)}" ${end}`;
7384
+ case "cancel":
7385
+ return `ContinuumDAO: cancel "${proposalLabel(input)}" ${end}`;
7386
+ case "forumSignIn": {
7387
+ const who = text(input.username);
7388
+ return who ? `ContinuumDAO: sign in to the forum as ${who} ${end}` : `ContinuumDAO: sign in to the forum ${end}`;
7389
+ }
7390
+ case "marketplaceCreateListing":
7391
+ return `ContinuumDAO: list veCTM ${id} for ${moneyFromWei(input.askWei, input.paymentToken)} until ${deadlineLabel(input.deadline)} ${end}`;
7392
+ case "marketplaceDelist":
7393
+ return `ContinuumDAO: delist veCTM ${id} ${end}`;
7394
+ case "marketplaceFulfillListing":
7395
+ return `ContinuumDAO: buy veCTM ${id} for ${moneyFromWei(input.priceWei, input.paymentToken)} ${end}`;
7396
+ case "marketplaceCreateOffering":
7397
+ return `ContinuumDAO: offer ${moneyFromWei(input.bidWei, input.paymentToken)} for veCTM ${id} until ${deadlineLabel(input.deadline)} ${end}`;
7398
+ case "marketplaceRescind":
7399
+ return `ContinuumDAO: rescind offer on veCTM ${id} ${end}`;
7400
+ case "marketplaceFulfillOffering":
7401
+ return `ContinuumDAO: accept offer of ${moneyFromWei(input.priceWei, input.paymentToken)} on veCTM ${id} ${end}`;
7402
+ case "marketplaceCreateAuction":
7403
+ return `ContinuumDAO: auction veCTM ${id} reserve ${moneyFromWei(input.reserveWei, input.paymentToken)}, minimum increment ${moneyFromWei(input.minIncrementWei, input.paymentToken)}, until ${deadlineLabel(input.deadline)} ${end}`;
7404
+ case "marketplaceCancelAuction":
7405
+ return `ContinuumDAO: cancel auction for veCTM ${id} ${end}`;
7406
+ case "marketplaceAuctionBid":
7407
+ return `ContinuumDAO: bid ${moneyFromWei(input.priceWei, input.paymentToken)} on veCTM ${id} ${end}`;
7408
+ case "marketplaceSettleAuction":
7409
+ return `ContinuumDAO: settle auction for veCTM ${id} ${end}`;
7410
+ default:
7411
+ return `ContinuumDAO: ${end}`;
7412
+ }
7413
+ }
7414
+ function preprocessContinuumDaoPurpose(action, raw) {
7415
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return raw;
7416
+ const o = { ...raw };
7417
+ const supplied = text(o.purposeText ?? o.purpose);
7418
+ if (supplied) {
7419
+ o.purposeText = supplied;
7420
+ return o;
7421
+ }
7422
+ o.purposeText = buildContinuumDaoMcpPurpose(action, o);
7423
+ return o;
7424
+ }
7425
+
7172
7426
  // src/protocols/evm/continuum-dao/index.ts
7173
7427
  registerProtocolModule(continuumDaoMarketplaceProtocolModule);
7174
7428
  var continuumDaoProtocolModule = {
@@ -7281,6 +7535,7 @@ exports.auctionStatusName = auctionStatusName;
7281
7535
  exports.bravoSupportLabel = bravoSupportLabel;
7282
7536
  exports.bucketGovernorState = bucketGovernorState;
7283
7537
  exports.buildBravoProposalArgs = buildBravoProposalArgs;
7538
+ exports.buildContinuumDaoMcpPurpose = buildContinuumDaoMcpPurpose;
7284
7539
  exports.buildDeltaProposalArgs = buildDeltaProposalArgs;
7285
7540
  exports.buildEvmMultisignBodyContinuumDaoAttachVeCtm = buildEvmMultisignBodyContinuumDaoAttachVeCtm;
7286
7541
  exports.buildEvmMultisignBodyContinuumDaoAttachVeCtmFromMcp = buildEvmMultisignBodyContinuumDaoAttachVeCtmFromMcp;
@@ -7437,6 +7692,7 @@ exports.preflightSplit = preflightSplit;
7437
7692
  exports.preflightTransfer = preflightTransfer;
7438
7693
  exports.preflightUndelegate = preflightUndelegate;
7439
7694
  exports.preflightWithdraw = preflightWithdraw;
7695
+ exports.preprocessContinuumDaoPurpose = preprocessContinuumDaoPurpose;
7440
7696
  exports.proposalCatalogCanonical = proposalCatalogCanonical;
7441
7697
  exports.proposalCatalogDocument = proposalCatalogDocument;
7442
7698
  exports.proposalDescriptionHash = proposalDescriptionHash;