@continuumdao/ctm-mpc-defi 0.2.54 → 0.2.56
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/agent/catalog.cjs +398 -180
- package/dist/agent/catalog.cjs.map +1 -1
- package/dist/agent/catalog.d.ts +118 -58
- package/dist/agent/catalog.js +395 -182
- package/dist/agent/catalog.js.map +1 -1
- package/dist/agent/skills/circle-cctp/SKILL.md +5 -4
- package/dist/agent/skills/continuum-dao/SKILL.md +2 -2
- package/dist/agent/skills/continuum-dao-marketplace/SKILL.md +4 -4
- package/dist/protocols/evm/circle-cctp/index.cjs +77 -19
- package/dist/protocols/evm/circle-cctp/index.cjs.map +1 -1
- package/dist/protocols/evm/circle-cctp/index.d.ts +53 -3
- package/dist/protocols/evm/circle-cctp/index.js +76 -20
- package/dist/protocols/evm/circle-cctp/index.js.map +1 -1
- package/dist/protocols/evm/continuum-dao/index.cjs +304 -35
- package/dist/protocols/evm/continuum-dao/index.cjs.map +1 -1
- package/dist/protocols/evm/continuum-dao/index.d.ts +14 -1
- package/dist/protocols/evm/continuum-dao/index.js +303 -36
- package/dist/protocols/evm/continuum-dao/index.js.map +1 -1
- 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
|
|
195
|
-
const start =
|
|
194
|
+
const text2 = String(markdown || "");
|
|
195
|
+
const start = text2.search(/^### Committee List\s*$/m);
|
|
196
196
|
if (start < 0) return [];
|
|
197
|
-
const lines =
|
|
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] ?? "";
|
|
@@ -260,9 +260,10 @@ function checksumOrEmpty(value) {
|
|
|
260
260
|
if (!raw) return "";
|
|
261
261
|
return viem.getAddress(raw);
|
|
262
262
|
}
|
|
263
|
-
function normalizeInput(inp) {
|
|
263
|
+
function normalizeInput(inp, index) {
|
|
264
|
+
const explicit = String(inp?.name || "").trim();
|
|
264
265
|
return {
|
|
265
|
-
name:
|
|
266
|
+
name: explicit || `arg${index}`,
|
|
266
267
|
type: String(inp?.type || ""),
|
|
267
268
|
value: String(inp?.value ?? "")
|
|
268
269
|
};
|
|
@@ -279,7 +280,7 @@ function normalizeAction(action) {
|
|
|
279
280
|
target: checksumOrEmpty(action.target),
|
|
280
281
|
value: String(action.value || "0"),
|
|
281
282
|
signature: String(action.signature || ""),
|
|
282
|
-
inputs: (action.inputs || []).map(normalizeInput)
|
|
283
|
+
inputs: (action.inputs || []).map((inp, index) => normalizeInput(inp, index))
|
|
283
284
|
};
|
|
284
285
|
}
|
|
285
286
|
function assertProposalCatalogConstants() {
|
|
@@ -351,11 +352,11 @@ var init_defiEvmClient = __esm({
|
|
|
351
352
|
// src/core/purpose.ts
|
|
352
353
|
function mergePurposeText(purposeText, purposeSuffix) {
|
|
353
354
|
const t = (purposeText ?? "").trim();
|
|
354
|
-
const
|
|
355
|
-
if (!
|
|
355
|
+
const suffix2 = (purposeSuffix ?? "").trim();
|
|
356
|
+
if (!suffix2) return t;
|
|
356
357
|
return t ? `${t}
|
|
357
358
|
|
|
358
|
-
${
|
|
359
|
+
${suffix2}` : suffix2;
|
|
359
360
|
}
|
|
360
361
|
var init_purpose = __esm({
|
|
361
362
|
"src/core/purpose.ts"() {
|
|
@@ -929,8 +930,8 @@ async function continuumDaoForumUnread(args) {
|
|
|
929
930
|
if (args.filter?.trim()) qs2.set("filter", args.filter.trim());
|
|
930
931
|
if (args.start != null) qs2.set("start", String(args.start));
|
|
931
932
|
if (args.limit != null) qs2.set("limit", String(args.limit));
|
|
932
|
-
const
|
|
933
|
-
return forumFetch(`/api/continuum/forum/unread${
|
|
933
|
+
const suffix2 = qs2.toString() ? `?${qs2}` : "";
|
|
934
|
+
return forumFetch(`/api/continuum/forum/unread${suffix2}`, {
|
|
934
935
|
forumUrl: args.forumUrl,
|
|
935
936
|
ticket: args.ticket
|
|
936
937
|
});
|
|
@@ -1453,8 +1454,8 @@ function buildFoundryProposalSimulatePlan(args) {
|
|
|
1453
1454
|
)
|
|
1454
1455
|
});
|
|
1455
1456
|
args.batches.forEach((batch, bi) => {
|
|
1456
|
-
const
|
|
1457
|
-
const contractName = `ContinuumDaoSimulateExecute${
|
|
1457
|
+
const suffix2 = batch.label != null ? solIdent(batch.label, `Option${(batch.optionIndex ?? bi) + 1}`) : "Bravo";
|
|
1458
|
+
const contractName = `ContinuumDaoSimulateExecute${suffix2}`;
|
|
1458
1459
|
const path = `script/${contractName}.s.sol`;
|
|
1459
1460
|
const body = [
|
|
1460
1461
|
" function run() external {",
|
|
@@ -2684,13 +2685,25 @@ async function buildEvmMultisignBodyContinuumDaoCastVoteBravoFromMcp(args) {
|
|
|
2684
2685
|
}
|
|
2685
2686
|
async function continuumDaoRegisterProposal(payload) {
|
|
2686
2687
|
assertContinuumDaoForumTopicKey(payload.forumKey);
|
|
2688
|
+
const body = JSON.stringify(payload);
|
|
2687
2689
|
const res = await fetch(`${exports.CONTINUUM_DAO_GOVERNANCE_API}/proposals/create`, {
|
|
2688
2690
|
method: "POST",
|
|
2689
2691
|
headers: { "Content-Type": "application/json" },
|
|
2690
|
-
body
|
|
2692
|
+
body
|
|
2691
2693
|
});
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
+
const text2 = await res.text();
|
|
2695
|
+
if (res.status === 409) {
|
|
2696
|
+
const repair = await fetch(`${exports.CONTINUUM_DAO_GOVERNANCE_API}/proposals/repair`, {
|
|
2697
|
+
method: "POST",
|
|
2698
|
+
headers: { "Content-Type": "application/json" },
|
|
2699
|
+
body
|
|
2700
|
+
});
|
|
2701
|
+
const repairText = await repair.text();
|
|
2702
|
+
if (!repair.ok) throw new Error(`proposals/repair: ${repair.status} ${repairText}`);
|
|
2703
|
+
return { ok: true, result: JSON.parse(repairText) };
|
|
2704
|
+
}
|
|
2705
|
+
if (!res.ok) throw new Error(`proposals/create: ${res.status} ${text2}`);
|
|
2706
|
+
return { ok: true, result: JSON.parse(text2) };
|
|
2694
2707
|
}
|
|
2695
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;
|
|
2696
2709
|
var init_governance = __esm({
|
|
@@ -5286,10 +5299,20 @@ function foldMarketplaceEvents(events, initial) {
|
|
|
5286
5299
|
for (const ev of events) applyMarketplaceEvent(book, ev);
|
|
5287
5300
|
return book;
|
|
5288
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
|
+
}
|
|
5289
5311
|
function deriveAuctionStatus(auction, nowUnix) {
|
|
5290
|
-
const deadline =
|
|
5312
|
+
const deadline = auctionDeadlineUnix(auction);
|
|
5291
5313
|
if (auction.storedStatus === "Pending" && Number.isFinite(deadline) && nowUnix >= deadline) return "Expired";
|
|
5292
5314
|
if (auction.storedStatus === "Active" && Number.isFinite(deadline) && nowUnix >= deadline) return "Complete";
|
|
5315
|
+
if (auction.storedStatus === "Pending") return "Active";
|
|
5293
5316
|
return auction.derivedStatus || auction.storedStatus;
|
|
5294
5317
|
}
|
|
5295
5318
|
function applyDerivedStatuses(book, nowUnix) {
|
|
@@ -5399,7 +5422,11 @@ function keyGenOwnsVeCtm(snap, seller) {
|
|
|
5399
5422
|
return false;
|
|
5400
5423
|
}
|
|
5401
5424
|
function assertNotOwn(snap, seller, tokenId) {
|
|
5402
|
-
|
|
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) {
|
|
5403
5430
|
throw new Error(`This KeyGen already owns veCTM #${tokenId.toString()} and cannot buy or bid on it.`);
|
|
5404
5431
|
}
|
|
5405
5432
|
}
|
|
@@ -5471,6 +5498,7 @@ function planMarketplaceSteps(input, snap) {
|
|
|
5471
5498
|
const m = snap.marketplace;
|
|
5472
5499
|
switch (input.action) {
|
|
5473
5500
|
case "createListing": {
|
|
5501
|
+
assertNotAttached(snap, input.tokenId);
|
|
5474
5502
|
assertPayment(snap);
|
|
5475
5503
|
assertDeadline(snap, input.deadline);
|
|
5476
5504
|
if (!same2(snap.owner, snap.executor)) throw new Error("Only the veCTM owner can create a listing.");
|
|
@@ -5497,7 +5525,9 @@ function planMarketplaceSteps(input, snap) {
|
|
|
5497
5525
|
]);
|
|
5498
5526
|
}
|
|
5499
5527
|
case "delist": {
|
|
5500
|
-
|
|
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.");
|
|
5501
5531
|
return [
|
|
5502
5532
|
{
|
|
5503
5533
|
to: m,
|
|
@@ -5542,6 +5572,7 @@ function planMarketplaceSteps(input, snap) {
|
|
|
5542
5572
|
]);
|
|
5543
5573
|
}
|
|
5544
5574
|
case "createOffering": {
|
|
5575
|
+
assertNotAttached(snap, input.tokenId);
|
|
5545
5576
|
assertNotOwn(snap, void 0, input.tokenId);
|
|
5546
5577
|
assertPayment(snap);
|
|
5547
5578
|
assertDeadline(snap, input.deadline);
|
|
@@ -6232,8 +6263,8 @@ async function getJson(url) {
|
|
|
6232
6263
|
try {
|
|
6233
6264
|
const res = await fetch(url);
|
|
6234
6265
|
if (!res.ok) {
|
|
6235
|
-
const
|
|
6236
|
-
return { ok: false, status: res.status, error: new Error(`${url}: ${res.status} ${
|
|
6266
|
+
const text2 = await res.text().catch(() => "");
|
|
6267
|
+
return { ok: false, status: res.status, error: new Error(`${url}: ${res.status} ${text2}`.trim()) };
|
|
6237
6268
|
}
|
|
6238
6269
|
return { ok: true, body: await res.json() };
|
|
6239
6270
|
} catch (err) {
|
|
@@ -6273,6 +6304,37 @@ function matchAuction(row, args, includeInactive) {
|
|
|
6273
6304
|
if (args.seller && row.seller.toLowerCase() !== args.seller.toLowerCase()) return false;
|
|
6274
6305
|
return true;
|
|
6275
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
|
+
}
|
|
6276
6338
|
function listFrom(items, source) {
|
|
6277
6339
|
return { items, nextCursor: null, source };
|
|
6278
6340
|
}
|
|
@@ -6302,11 +6364,18 @@ async function fetchContinuumDaoMarketplaceListings(args = {}) {
|
|
|
6302
6364
|
const res = await getJson(url);
|
|
6303
6365
|
if (res.ok) {
|
|
6304
6366
|
const body = res.body;
|
|
6305
|
-
return {
|
|
6367
|
+
return {
|
|
6368
|
+
items: annotateListingViewer(body.items ?? [], args.viewer),
|
|
6369
|
+
nextCursor: body.nextCursor ?? null,
|
|
6370
|
+
source: "api"
|
|
6371
|
+
};
|
|
6306
6372
|
}
|
|
6307
6373
|
if (args.cursor || !isOffline(res.status)) throw res.error;
|
|
6308
6374
|
const book = await logsBook(args);
|
|
6309
|
-
return listFrom(
|
|
6375
|
+
return listFrom(
|
|
6376
|
+
annotateListingViewer(book.listings.filter((row) => matchOrder(row, args, includeInactive)), args.viewer),
|
|
6377
|
+
"logs"
|
|
6378
|
+
);
|
|
6310
6379
|
}
|
|
6311
6380
|
async function fetchContinuumDaoMarketplaceOfferings(args = {}) {
|
|
6312
6381
|
const includeInactive = Boolean(args.includeInactive);
|
|
@@ -6343,20 +6412,30 @@ async function fetchContinuumDaoMarketplaceAuctions(args = {}) {
|
|
|
6343
6412
|
if (res.ok) {
|
|
6344
6413
|
const body = res.body;
|
|
6345
6414
|
return {
|
|
6346
|
-
items: (body.items ?? []).map((row) => (
|
|
6415
|
+
items: (body.items ?? []).map((row) => presentAuction(row)).filter((row) => includeInactive || isLiveAuctionStatus(row.derivedStatus)),
|
|
6347
6416
|
nextCursor: body.nextCursor ?? null,
|
|
6348
6417
|
source: "api"
|
|
6349
6418
|
};
|
|
6350
6419
|
}
|
|
6351
6420
|
if (args.cursor || !isOffline(res.status)) throw res.error;
|
|
6352
6421
|
const book = await logsBook(args);
|
|
6353
|
-
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");
|
|
6354
6423
|
}
|
|
6355
6424
|
async function fetchContinuumDaoMarketplaceToken(args) {
|
|
6356
6425
|
const url = `${apiBase(args)}/marketplace/tokens/${encodeURIComponent(args.tokenId)}${qs({ viewer: args.viewer })}`;
|
|
6357
6426
|
const res = await getJson(url);
|
|
6358
6427
|
if (res.ok && res.body && typeof res.body === "object") {
|
|
6359
|
-
|
|
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
|
+
};
|
|
6360
6439
|
}
|
|
6361
6440
|
if (!res.ok && !isOffline(res.status)) throw res.error;
|
|
6362
6441
|
const book = await logsBook(args);
|
|
@@ -6367,11 +6446,14 @@ async function fetchContinuumDaoMarketplaceToken(args) {
|
|
|
6367
6446
|
token: { tokenId: args.tokenId },
|
|
6368
6447
|
listing: listings.find((row) => isOpenOrder(row)) ?? null,
|
|
6369
6448
|
offerings: offerings.filter((row) => isOpenOrder(row)),
|
|
6370
|
-
auction:
|
|
6449
|
+
auction: (() => {
|
|
6450
|
+
const live = auctions.find((row) => isLiveAuctionStatus(row.derivedStatus));
|
|
6451
|
+
return live ? presentAuction(live) : null;
|
|
6452
|
+
})(),
|
|
6371
6453
|
history: {
|
|
6372
6454
|
listings: listings.filter((row) => !isOpenOrder(row)),
|
|
6373
6455
|
offerings: offerings.filter((row) => !isOpenOrder(row)),
|
|
6374
|
-
auctions: auctions.filter((row) => !isLiveAuctionStatus(row.derivedStatus))
|
|
6456
|
+
auctions: auctions.filter((row) => !isLiveAuctionStatus(row.derivedStatus)).map((row) => presentAuction(row))
|
|
6375
6457
|
},
|
|
6376
6458
|
source: "logs"
|
|
6377
6459
|
};
|
|
@@ -6398,7 +6480,7 @@ async function fetchContinuumDaoMarketplaceActivity(args) {
|
|
|
6398
6480
|
return {
|
|
6399
6481
|
address: args.address,
|
|
6400
6482
|
orders: body.orders ?? [],
|
|
6401
|
-
auctions: (body.auctions ?? []).map((row) => (
|
|
6483
|
+
auctions: (body.auctions ?? []).map((row) => presentAuction(row)),
|
|
6402
6484
|
source: "api"
|
|
6403
6485
|
};
|
|
6404
6486
|
}
|
|
@@ -6411,7 +6493,7 @@ async function fetchContinuumDaoMarketplaceActivity(args) {
|
|
|
6411
6493
|
const auctions = book.auctions.filter((row) => {
|
|
6412
6494
|
return row.seller.toLowerCase() === address || (row.buyer ?? "").toLowerCase() === address || (row.highestBidder ?? "").toLowerCase() === address || row.bids.some((bid) => bid.bidder.toLowerCase() === address);
|
|
6413
6495
|
});
|
|
6414
|
-
return { address: args.address, orders, auctions, source: "logs" };
|
|
6496
|
+
return { address: args.address, orders, auctions: auctions.map((row) => presentAuction(row)), source: "logs" };
|
|
6415
6497
|
}
|
|
6416
6498
|
|
|
6417
6499
|
// src/protocols/evm/continuum-dao/marketplaceSearch.ts
|
|
@@ -6483,6 +6565,13 @@ function positive(value) {
|
|
|
6483
6565
|
const trimmed = (value ?? "").trim();
|
|
6484
6566
|
return trimmed && trimmed !== "0" ? trimmed : "";
|
|
6485
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
|
+
}
|
|
6486
6575
|
function unlockUnixFrom(row) {
|
|
6487
6576
|
const iso2 = positive(row.unlockTimeAt);
|
|
6488
6577
|
if (iso2) {
|
|
@@ -6502,7 +6591,7 @@ function listingCandidate(row) {
|
|
|
6502
6591
|
kind: "listing",
|
|
6503
6592
|
tokenId: row.tokenId,
|
|
6504
6593
|
onchainIndex: row.onchainIndex,
|
|
6505
|
-
seller: row.seller
|
|
6594
|
+
seller: party(row.seller, row.creator, row.currentOwner),
|
|
6506
6595
|
paymentToken: row.paymentToken,
|
|
6507
6596
|
price: asBig(row.price),
|
|
6508
6597
|
priceBasis: "ask",
|
|
@@ -6560,7 +6649,7 @@ function rankMarketplaceSearchHits(rows, query, nowUnix = Math.floor(Date.now()
|
|
|
6560
6649
|
const excludeOwned = query.excludeOwned !== false && Boolean(executor);
|
|
6561
6650
|
let matched = rows.filter((row) => {
|
|
6562
6651
|
if (query.paymentToken && !same3(row.paymentToken, query.paymentToken)) return false;
|
|
6563
|
-
if (excludeOwned && same3(row.seller, executor)) return false;
|
|
6652
|
+
if (excludeOwned && row.kind !== "listing" && same3(row.seller, executor)) return false;
|
|
6564
6653
|
if (minLocked != null && row.locked < minLocked) return false;
|
|
6565
6654
|
if (maxLocked != null && row.locked > maxLocked) return false;
|
|
6566
6655
|
if (unlockAfter != null && row.unlockUnix < unlockAfter) return false;
|
|
@@ -6568,6 +6657,10 @@ function rankMarketplaceSearchHits(rows, query, nowUnix = Math.floor(Date.now()
|
|
|
6568
6657
|
if (monthCap != null && (row.unlockUnix <= nowUnix || row.unlockUnix > monthCap)) return false;
|
|
6569
6658
|
return true;
|
|
6570
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
|
+
});
|
|
6571
6664
|
const priceSort = sort === "price" || sort === "pricePerLockedCtm";
|
|
6572
6665
|
if (priceSort && !query.paymentToken) {
|
|
6573
6666
|
const tokens = new Set(matched.map((row) => row.paymentToken.toLowerCase()));
|
|
@@ -6592,9 +6685,16 @@ function rankMarketplaceSearchHits(rows, query, nowUnix = Math.floor(Date.now()
|
|
|
6592
6685
|
return a.tokenId.localeCompare(b.tokenId);
|
|
6593
6686
|
});
|
|
6594
6687
|
const limit = Math.min(MAX_LIMIT, Math.max(1, query.limit ?? DEFAULT_LIMIT));
|
|
6595
|
-
return matched.slice(0, limit).map((row) =>
|
|
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
|
+
});
|
|
6596
6696
|
}
|
|
6597
|
-
function toHit(row, nowUnix) {
|
|
6697
|
+
function toHit(row, nowUnix, action) {
|
|
6598
6698
|
const meta4 = paymentMeta(row.paymentToken);
|
|
6599
6699
|
const perCtm = row.locked > 0n ? row.price * 10n ** 18n / row.locked : 0n;
|
|
6600
6700
|
const months = row.unlockUnix > nowUnix ? ((row.unlockUnix - nowUnix) / MONTH_SECONDS).toFixed(1) : row.unlockUnix > 0 ? "0" : "";
|
|
@@ -6615,7 +6715,8 @@ function toHit(row, nowUnix) {
|
|
|
6615
6715
|
pricePerLockedCtm: row.locked > 0n ? humanAmount(perCtm, meta4.decimals) : "",
|
|
6616
6716
|
deadlineAt: row.deadlineUnix > 0 ? new Date(row.deadlineUnix * 1e3).toISOString() : "",
|
|
6617
6717
|
attached: row.attached,
|
|
6618
|
-
fillable: row.fillable
|
|
6718
|
+
fillable: row.fillable,
|
|
6719
|
+
action
|
|
6619
6720
|
};
|
|
6620
6721
|
}
|
|
6621
6722
|
async function fillMissingLocks(rows, rpcUrl, chainId) {
|
|
@@ -7156,6 +7257,172 @@ function marketplaceVeCtmReceivedBy(detail, executor) {
|
|
|
7156
7257
|
return null;
|
|
7157
7258
|
}
|
|
7158
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
|
+
|
|
7159
7426
|
// src/protocols/evm/continuum-dao/index.ts
|
|
7160
7427
|
registerProtocolModule(continuumDaoMarketplaceProtocolModule);
|
|
7161
7428
|
var continuumDaoProtocolModule = {
|
|
@@ -7268,6 +7535,7 @@ exports.auctionStatusName = auctionStatusName;
|
|
|
7268
7535
|
exports.bravoSupportLabel = bravoSupportLabel;
|
|
7269
7536
|
exports.bucketGovernorState = bucketGovernorState;
|
|
7270
7537
|
exports.buildBravoProposalArgs = buildBravoProposalArgs;
|
|
7538
|
+
exports.buildContinuumDaoMcpPurpose = buildContinuumDaoMcpPurpose;
|
|
7271
7539
|
exports.buildDeltaProposalArgs = buildDeltaProposalArgs;
|
|
7272
7540
|
exports.buildEvmMultisignBodyContinuumDaoAttachVeCtm = buildEvmMultisignBodyContinuumDaoAttachVeCtm;
|
|
7273
7541
|
exports.buildEvmMultisignBodyContinuumDaoAttachVeCtmFromMcp = buildEvmMultisignBodyContinuumDaoAttachVeCtmFromMcp;
|
|
@@ -7424,6 +7692,7 @@ exports.preflightSplit = preflightSplit;
|
|
|
7424
7692
|
exports.preflightTransfer = preflightTransfer;
|
|
7425
7693
|
exports.preflightUndelegate = preflightUndelegate;
|
|
7426
7694
|
exports.preflightWithdraw = preflightWithdraw;
|
|
7695
|
+
exports.preprocessContinuumDaoPurpose = preprocessContinuumDaoPurpose;
|
|
7427
7696
|
exports.proposalCatalogCanonical = proposalCatalogCanonical;
|
|
7428
7697
|
exports.proposalCatalogDocument = proposalCatalogDocument;
|
|
7429
7698
|
exports.proposalDescriptionHash = proposalDescriptionHash;
|