@continuumdao/ctm-mpc-defi 0.2.47 → 0.2.48

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.
@@ -1,4 +1,4 @@
1
- import { parseAbi, getAddress, zeroAddress, encodeFunctionData, keccak256, encodePacked, padHex, toHex, createPublicClient, defineChain, parseUnits, isAddress, hashTypedData, http, stringToHex, parseGwei, serializeTransaction } from 'viem';
1
+ import { parseAbi, parseAbiItem, getAddress, zeroAddress, encodeFunctionData, keccak256, encodePacked, padHex, toHex, createPublicClient, defineChain, parseUnits, isAddress, formatUnits, hashTypedData, http, stringToHex, parseGwei, serializeTransaction } from 'viem';
2
2
  import { getClientIdFromKeyGenResult, fetchChainFeeParams, gasLimitFromEstimateAndChainConfig, gweiToDecimalString, proposalTxParamsToFeeSnapshot, alignEip1559FeesWithLatestBase } from '@continuumdao/continuum-node-sdk';
3
3
 
4
4
  var __defProp = Object.defineProperty;
@@ -2304,7 +2304,7 @@ function summarizeLiveProposals(result) {
2304
2304
  const label = (p) => `#${p.id ?? "\u2014"} ${p.title}${p.committeeProposer ? " [Committee]" : ""}`;
2305
2305
  const liveTitles = result.live.map(label).join("; ") || "none";
2306
2306
  const execTitles = result.readyToExecute.map(label).join("; ") || "none";
2307
- return `Live (Active, voting now): ${result.live.length} (${liveTitles}). Pending: ${result.pending.length}. Passed, ready to execute (Succeeded): ${result.readyToExecute.length} (${execTitles}). Recently completed in this scan: ${result.recentlyCompleted.length}. Queue is not implemented.`;
2307
+ return `Live (Active, voting now): ${result.live.length} (${liveTitles}). Pending: ${result.pending.length}. Passed, ready to execute (Succeeded): ${result.readyToExecute.length} (${execTitles}). Recently completed in this scan: ${result.recentlyCompleted.length}. Queue is not implemented. After naming a proposal, offer ctm_continuum_dao_fetch_proposal_votes so the operator can see who voted and how.`;
2308
2308
  }
2309
2309
  async function mapPool(items, concurrency, fn) {
2310
2310
  const out = [];
@@ -4251,6 +4251,465 @@ async function continuumDaoComposeProposalAction(args) {
4251
4251
 
4252
4252
  // src/protocols/evm/continuum-dao/index.ts
4253
4253
  init_explainProposal();
4254
+
4255
+ // src/protocols/evm/continuum-dao/proposalVotes.ts
4256
+ init_constants();
4257
+ init_governance();
4258
+ var VOTE_CAST_EVENT = parseAbiItem(
4259
+ "event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason)"
4260
+ );
4261
+ var VOTE_CAST_WITH_PARAMS_EVENT = parseAbiItem(
4262
+ "event VoteCastWithParams(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason, bytes params)"
4263
+ );
4264
+ var snapshotDeadlineAbi = parseAbi([
4265
+ "function proposalSnapshot(uint256 proposalId) view returns (uint256)",
4266
+ "function proposalDeadline(uint256 proposalId) view returns (uint256)",
4267
+ "function token() view returns (address)"
4268
+ ]);
4269
+ var veNodePropertiesAbi = parseAbi(["function nodeProperties() view returns (address)"]);
4270
+ var nodePropsAttachAbi = parseAbi([
4271
+ "function attachedTokenId(address keyGen) view returns (uint256)"
4272
+ ]);
4273
+ var nodeInfoAbi = [
4274
+ {
4275
+ type: "function",
4276
+ name: "nodeInfo",
4277
+ stateMutability: "view",
4278
+ inputs: [
4279
+ { name: "_tokenId", type: "uint256" },
4280
+ { name: "_account", type: "address" }
4281
+ ],
4282
+ outputs: [
4283
+ {
4284
+ name: "",
4285
+ type: "tuple",
4286
+ components: [
4287
+ { name: "forumHandle", type: "string" },
4288
+ { name: "email", type: "string" },
4289
+ { name: "ipv4", type: "uint8[4]" },
4290
+ { name: "ipv6", type: "uint16[8]" },
4291
+ { name: "vpsProvider", type: "string" },
4292
+ { name: "ramInstalled", type: "uint256" },
4293
+ { name: "cpuCores", type: "uint256" },
4294
+ { name: "dIDType", type: "string" },
4295
+ { name: "dID", type: "string" },
4296
+ { name: "data", type: "bytes" }
4297
+ ]
4298
+ }
4299
+ ]
4300
+ }
4301
+ ];
4302
+ var BRAVO_SUPPORT_LABELS = ["Against", "For", "Abstain"];
4303
+ var LOG_CHUNK_BLOCKS = 8000n;
4304
+ var MAX_LOG_CHUNKS = 80;
4305
+ var MAX_VOTES = 2e3;
4306
+ var TIMESTAMP_FLOOR = 1600000000n;
4307
+ var LINEA_BLOCK_SECONDS = 2n;
4308
+ var RANGE_BUFFER_BLOCKS = 20000n;
4309
+ function bravoSupportLabel(support) {
4310
+ return BRAVO_SUPPORT_LABELS[support] ?? `support=${support}`;
4311
+ }
4312
+ function decodeDeltaVoteParams(params) {
4313
+ if (!params || params === "0x") return [];
4314
+ const hex = params.startsWith("0x") ? params.slice(2) : params;
4315
+ if (hex.length === 0 || hex.length % 64 !== 0) return [];
4316
+ const out = [];
4317
+ for (let i = 0; i < hex.length; i += 64) {
4318
+ out.push(BigInt(`0x${hex.slice(i, i + 64)}`).toString());
4319
+ }
4320
+ return out;
4321
+ }
4322
+ function looksLikeUnixSeconds(value) {
4323
+ return value >= TIMESTAMP_FLOOR && value < 4000000000n;
4324
+ }
4325
+ function estimateBlockAtTimestamp(timestamp, latest) {
4326
+ if (timestamp >= latest.timestamp) return latest.number;
4327
+ const deltaSec = latest.timestamp - timestamp;
4328
+ const approx = deltaSec / LINEA_BLOCK_SECONDS + RANGE_BUFFER_BLOCKS;
4329
+ return latest.number > approx ? latest.number - approx : 0n;
4330
+ }
4331
+ function explorerBase(chainId) {
4332
+ return chainId === CONTINUUM_DAO_LINEA_SEPOLIA_CHAIN_ID ? "https://sepolia.lineascan.build" : "https://lineascan.build";
4333
+ }
4334
+ function howVoted(input) {
4335
+ if (input.optionWeights && input.optionWeights.length > 0) {
4336
+ const labels = input.optionLabels ?? [];
4337
+ const parts = input.optionWeights.map((w, i) => {
4338
+ const last = i === input.optionWeights.length - 1;
4339
+ const name = last ? "NOTA" : labels[i] ?? `option ${i + 1}`;
4340
+ return `${name} ${w}`;
4341
+ });
4342
+ return parts.join(", ");
4343
+ }
4344
+ return bravoSupportLabel(input.support);
4345
+ }
4346
+ function asBigInt(value) {
4347
+ if (typeof value === "bigint") return value;
4348
+ if (typeof value === "number" && Number.isFinite(value)) return BigInt(value);
4349
+ if (typeof value === "string" && /^-?\d+$/.test(value.trim())) return BigInt(value.trim());
4350
+ return null;
4351
+ }
4352
+ function collectVotesFromLogs(logs, proposalId, chainId, optionLabels) {
4353
+ const base = explorerBase(chainId);
4354
+ const rows = [];
4355
+ for (const log of logs) {
4356
+ const args = log.args ?? {};
4357
+ const logProposal = asBigInt(args.proposalId);
4358
+ if (logProposal == null || logProposal !== proposalId) continue;
4359
+ let voter;
4360
+ try {
4361
+ voter = getAddress(String(args.voter ?? ""));
4362
+ } catch {
4363
+ continue;
4364
+ }
4365
+ const support = Number(args.support ?? 0);
4366
+ const weight = asBigInt(args.weight) ?? 0n;
4367
+ const reason = typeof args.reason === "string" ? args.reason : "";
4368
+ const params = typeof args.params === "string" && args.params.startsWith("0x") ? args.params : void 0;
4369
+ const optionWeights = log.eventName === "VoteCastWithParams" || params ? decodeDeltaVoteParams(params) : void 0;
4370
+ const how = howVoted({
4371
+ support,
4372
+ ...optionWeights && optionWeights.length > 0 ? { optionWeights, optionLabels } : {}
4373
+ });
4374
+ const txHash = log.transactionHash ?? void 0;
4375
+ rows.push({
4376
+ voter,
4377
+ explorerUrl: `${base}/address/${voter}`,
4378
+ support,
4379
+ supportLabel: bravoSupportLabel(support),
4380
+ weight: weight.toString(),
4381
+ weightCtm: formatUnits(weight, 18),
4382
+ reason,
4383
+ attached: false,
4384
+ ...optionWeights && optionWeights.length > 0 ? { optionWeights } : {},
4385
+ how,
4386
+ ...txHash ? { txHash, txExplorerUrl: `${base}/tx/${txHash}` } : {},
4387
+ ...log.blockNumber != null ? { blockNumber: log.blockNumber.toString() } : {}
4388
+ });
4389
+ }
4390
+ return rows;
4391
+ }
4392
+ function summarizeProposalVotes(votes) {
4393
+ let forW = 0n;
4394
+ let againstW = 0n;
4395
+ let abstainW = 0n;
4396
+ for (const vote of votes) {
4397
+ const w = BigInt(vote.weight);
4398
+ if (vote.support === 1) forW += w;
4399
+ else if (vote.support === 0) againstW += w;
4400
+ else if (vote.support === 2) abstainW += w;
4401
+ }
4402
+ const note = votes.length === 0 ? "No VoteCast logs for this proposal in the scanned window. If it just started, wait; if it is older than the window, pass fromBlock/toBlock or load official etherscan get_logs on the governor." : `Found ${votes.length} vote(s). Read voter + how + whether they are attached to a node. Offer this after listing or explaining a proposal.`;
4403
+ const attachedCount = votes.filter((vote) => vote.attached).length;
4404
+ const attachBit = votes.length === 0 ? "" : ` ${attachedCount} of ${votes.length} voting address(es) are attached to a node (NodeProperties.attachedTokenId after attachNodeFor).`;
4405
+ return {
4406
+ voterCount: votes.length,
4407
+ attachedVoterCount: attachedCount,
4408
+ forWeight: forW.toString(),
4409
+ againstWeight: againstW.toString(),
4410
+ abstainWeight: abstainW.toString(),
4411
+ note: `${note}${attachBit}`
4412
+ };
4413
+ }
4414
+ function asNumberList(value) {
4415
+ if (!Array.isArray(value)) return [];
4416
+ return value.map((part) => Number(part));
4417
+ }
4418
+ function formatIpv4(parts) {
4419
+ const n = asNumberList(parts);
4420
+ if (n.length !== 4 || n.every((x) => x === 0)) return void 0;
4421
+ return n.join(".");
4422
+ }
4423
+ function formatIpv6(parts) {
4424
+ const n = asNumberList(parts);
4425
+ if (n.length !== 8 || n.every((x) => x === 0)) return void 0;
4426
+ return n.map((x) => x.toString(16)).join(":");
4427
+ }
4428
+ function normalizeNodeInfo(raw) {
4429
+ if (raw == null) return void 0;
4430
+ const rec = Array.isArray(raw) ? {
4431
+ forumHandle: raw[0],
4432
+ email: raw[1],
4433
+ ipv4: raw[2],
4434
+ ipv6: raw[3],
4435
+ vpsProvider: raw[4],
4436
+ ramInstalled: raw[5],
4437
+ cpuCores: raw[6],
4438
+ dIDType: raw[7],
4439
+ dID: raw[8],
4440
+ data: raw[9]
4441
+ } : typeof raw === "object" ? raw : null;
4442
+ if (!rec) return void 0;
4443
+ const str2 = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0;
4444
+ const ram = asBigInt(rec.ramInstalled);
4445
+ const cpu = asBigInt(rec.cpuCores);
4446
+ const data = typeof rec.data === "string" && rec.data.startsWith("0x") && rec.data !== "0x" ? rec.data : void 0;
4447
+ const info = {
4448
+ ...str2(rec.forumHandle) ? { forumHandle: str2(rec.forumHandle) } : {},
4449
+ ...str2(rec.email) ? { email: str2(rec.email) } : {},
4450
+ ...formatIpv4(rec.ipv4) ? { ipv4: formatIpv4(rec.ipv4) } : {},
4451
+ ...formatIpv6(rec.ipv6) ? { ipv6: formatIpv6(rec.ipv6) } : {},
4452
+ ...str2(rec.vpsProvider) ? { vpsProvider: str2(rec.vpsProvider) } : {},
4453
+ ...ram != null && ram > 0n ? { ramInstalled: ram.toString() } : {},
4454
+ ...cpu != null && cpu > 0n ? { cpuCores: cpu.toString() } : {},
4455
+ ...str2(rec.dIDType) ? { dIDType: str2(rec.dIDType) } : {},
4456
+ ...str2(rec.dID) ? { dID: str2(rec.dID) } : {},
4457
+ ...data ? { dataHex: data } : {}
4458
+ };
4459
+ return Object.keys(info).length > 0 ? info : void 0;
4460
+ }
4461
+ function applyNodeAttachments(votes, attachments) {
4462
+ return votes.map((vote) => {
4463
+ const hit = attachments.get(vote.voter.toLowerCase());
4464
+ if (!hit) return { ...vote, attached: false };
4465
+ return {
4466
+ ...vote,
4467
+ attached: hit.attached,
4468
+ ...hit.attached && hit.attachedTokenId ? { attachedTokenId: hit.attachedTokenId } : {},
4469
+ ...hit.nodeInfo ? { nodeInfo: hit.nodeInfo } : {}
4470
+ };
4471
+ });
4472
+ }
4473
+ function backendOptionLabels(raw) {
4474
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
4475
+ const options = raw.options;
4476
+ if (!Array.isArray(options)) return void 0;
4477
+ const labels = options.map((opt) => {
4478
+ if (!opt || typeof opt !== "object" || Array.isArray(opt)) return "";
4479
+ return String(opt.label ?? "").trim();
4480
+ }).filter(Boolean);
4481
+ return labels.length > 0 ? labels : void 0;
4482
+ }
4483
+ function backendTitle(raw) {
4484
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
4485
+ const title = raw.title;
4486
+ return typeof title === "string" && title.trim() ? title.trim() : void 0;
4487
+ }
4488
+ function backendConfiguration(raw) {
4489
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
4490
+ const cfg = raw.configuration;
4491
+ if (cfg === 1 || cfg === "1" || cfg === "delta") return "delta";
4492
+ if (cfg === 0 || cfg === "0" || cfg === "bravo") return "bravo";
4493
+ return void 0;
4494
+ }
4495
+ async function readWindow(client, gov, proposalId, latest, deps) {
4496
+ let snapshot;
4497
+ let deadline;
4498
+ try {
4499
+ const read = deps?.readSnapshotDeadline ? await deps.readSnapshotDeadline(gov, proposalId) : {
4500
+ snapshot: await client.readContract({
4501
+ address: gov,
4502
+ abi: snapshotDeadlineAbi,
4503
+ functionName: "proposalSnapshot",
4504
+ args: [proposalId]
4505
+ }),
4506
+ deadline: await client.readContract({
4507
+ address: gov,
4508
+ abi: snapshotDeadlineAbi,
4509
+ functionName: "proposalDeadline",
4510
+ args: [proposalId]
4511
+ })
4512
+ };
4513
+ snapshot = read.snapshot;
4514
+ deadline = read.deadline;
4515
+ } catch {
4516
+ }
4517
+ const toFromTs = (ts, fallback) => {
4518
+ if (ts == null) return fallback;
4519
+ if (looksLikeUnixSeconds(ts)) return estimateBlockAtTimestamp(ts, latest);
4520
+ return ts > latest.number ? latest.number : ts;
4521
+ };
4522
+ const fromBlock = toFromTs(snapshot, latest.number > 200000n ? latest.number - 200000n : 0n);
4523
+ const toBlock = toFromTs(deadline, latest.number);
4524
+ return {
4525
+ fromBlock,
4526
+ toBlock: toBlock < fromBlock ? latest.number : toBlock
4527
+ };
4528
+ }
4529
+ async function resolveNodePropertiesAddress(client, chainId, gov, args, deps) {
4530
+ if (deps?.readNodeProperties) {
4531
+ return deps.readNodeProperties();
4532
+ }
4533
+ if (isConfiguredAddress(args.nodeProperties)) {
4534
+ return getAddress(args.nodeProperties);
4535
+ }
4536
+ let ve = isConfiguredAddress(args.votingEscrow) ? getAddress(args.votingEscrow) : votingEscrowAddressOnEvmChain(chainId);
4537
+ if (!ve) {
4538
+ try {
4539
+ const token = await client.readContract({
4540
+ address: gov,
4541
+ abi: snapshotDeadlineAbi,
4542
+ functionName: "token"
4543
+ });
4544
+ ve = isConfiguredAddress(token) ? getAddress(token) : null;
4545
+ } catch {
4546
+ ve = null;
4547
+ }
4548
+ }
4549
+ if (!ve) return null;
4550
+ try {
4551
+ const np = await client.readContract({
4552
+ address: ve,
4553
+ abi: veNodePropertiesAbi,
4554
+ functionName: "nodeProperties"
4555
+ });
4556
+ return isConfiguredAddress(np) ? getAddress(np) : null;
4557
+ } catch {
4558
+ return null;
4559
+ }
4560
+ }
4561
+ async function readAttachmentsForVoters(client, nodeProperties, voters, deps) {
4562
+ const out = /* @__PURE__ */ new Map();
4563
+ await Promise.all(
4564
+ voters.map(async (raw) => {
4565
+ const keyGen = getAddress(raw);
4566
+ try {
4567
+ const tokenId = deps?.readAttachedTokenId ? await deps.readAttachedTokenId(keyGen) : await client.readContract({
4568
+ address: nodeProperties,
4569
+ abi: nodePropsAttachAbi,
4570
+ functionName: "attachedTokenId",
4571
+ args: [keyGen]
4572
+ });
4573
+ if (tokenId > 0n) {
4574
+ let nodeInfo;
4575
+ try {
4576
+ const raw2 = deps?.readNodeInfo ? await deps.readNodeInfo(tokenId, keyGen) : await client.readContract({
4577
+ address: nodeProperties,
4578
+ abi: nodeInfoAbi,
4579
+ functionName: "nodeInfo",
4580
+ args: [tokenId, keyGen]
4581
+ });
4582
+ nodeInfo = normalizeNodeInfo(raw2);
4583
+ } catch {
4584
+ }
4585
+ out.set(keyGen.toLowerCase(), {
4586
+ attached: true,
4587
+ attachedTokenId: tokenId.toString(),
4588
+ ...nodeInfo ? { nodeInfo } : {}
4589
+ });
4590
+ } else {
4591
+ out.set(keyGen.toLowerCase(), { attached: false });
4592
+ }
4593
+ } catch {
4594
+ out.set(keyGen.toLowerCase(), { attached: false });
4595
+ }
4596
+ })
4597
+ );
4598
+ return out;
4599
+ }
4600
+ async function collectLogsInRange(client, gov, fromBlock, toBlock, deps) {
4601
+ const logs = [];
4602
+ let chunks = 0;
4603
+ let truncated = false;
4604
+ for (let start = fromBlock; start <= toBlock; start += LOG_CHUNK_BLOCKS) {
4605
+ if (chunks >= MAX_LOG_CHUNKS) {
4606
+ truncated = true;
4607
+ break;
4608
+ }
4609
+ const end = start + LOG_CHUNK_BLOCKS - 1n > toBlock ? toBlock : start + LOG_CHUNK_BLOCKS - 1n;
4610
+ const args = {
4611
+ address: gov,
4612
+ events: [VOTE_CAST_EVENT, VOTE_CAST_WITH_PARAMS_EVENT],
4613
+ fromBlock: start,
4614
+ toBlock: end
4615
+ };
4616
+ const chunk = deps?.getLogs ? await deps.getLogs(args) : await client.getLogs(args);
4617
+ logs.push(...chunk);
4618
+ chunks += 1;
4619
+ }
4620
+ return { logs, truncated };
4621
+ }
4622
+ async function continuumDaoFetchProposalVotes(args, deps) {
4623
+ const chainId = Number(args.chainId);
4624
+ const resolved = await resolveGovernorProposalRef(args.proposalId);
4625
+ const gov = requireGovernor(chainId, resolved.governorAddress ?? args.governor);
4626
+ const client = publicClient2(args.rpcUrl, chainId);
4627
+ const latest = deps?.getBlock ? await deps.getBlock() : await client.getBlock();
4628
+ const latestHead = { number: latest.number, timestamp: latest.timestamp };
4629
+ let fromBlock;
4630
+ let toBlock;
4631
+ if (args.fromBlock != null || args.toBlock != null) {
4632
+ fromBlock = args.fromBlock != null ? BigInt(String(args.fromBlock)) : 0n;
4633
+ toBlock = args.toBlock != null ? BigInt(String(args.toBlock)) : latestHead.number;
4634
+ } else {
4635
+ const window = await readWindow(client, gov, resolved.proposalId, latestHead, deps);
4636
+ fromBlock = window.fromBlock;
4637
+ toBlock = window.toBlock;
4638
+ }
4639
+ let optionLabels;
4640
+ let title;
4641
+ let configuration;
4642
+ if (resolved.catalogId != null) {
4643
+ try {
4644
+ const fetched = await (deps?.fetchProposal ?? continuumDaoFetchProposal)({
4645
+ id: resolved.catalogId
4646
+ });
4647
+ optionLabels = backendOptionLabels(fetched.proposal);
4648
+ title = backendTitle(fetched.proposal);
4649
+ configuration = backendConfiguration(fetched.proposal);
4650
+ } catch {
4651
+ }
4652
+ }
4653
+ let logs = [];
4654
+ let truncated = false;
4655
+ let logNote;
4656
+ try {
4657
+ const collected = await collectLogsInRange(client, gov, fromBlock, toBlock, deps);
4658
+ logs = collected.logs;
4659
+ truncated = collected.truncated;
4660
+ } catch (error) {
4661
+ const message = error instanceof Error ? error.message : String(error);
4662
+ logNote = `Could not read Governor VoteCast logs: ${message}. Load official etherscan and call get_logs on the governor if the operator chooses it.`;
4663
+ }
4664
+ let votes = collectVotesFromLogs(logs, resolved.proposalId, chainId, optionLabels).slice(
4665
+ 0,
4666
+ MAX_VOTES
4667
+ );
4668
+ if (votes.length === MAX_VOTES) truncated = true;
4669
+ let nodeProperties;
4670
+ let attachNote;
4671
+ try {
4672
+ const np = await resolveNodePropertiesAddress(client, chainId, gov, args, deps);
4673
+ if (np) {
4674
+ nodeProperties = np;
4675
+ const unique = [...new Set(votes.map((vote) => vote.voter))];
4676
+ const attachments = await readAttachmentsForVoters(client, np, unique, deps);
4677
+ votes = applyNodeAttachments(votes, attachments);
4678
+ } else {
4679
+ attachNote = "Could not resolve NodeProperties (VotingEscrow.nodeProperties after attachNodeFor). Pass nodeProperties if the operator has it.";
4680
+ }
4681
+ } catch (error) {
4682
+ const message = error instanceof Error ? error.message : String(error);
4683
+ attachNote = `Could not read NodeProperties.attachedTokenId: ${message}.`;
4684
+ }
4685
+ const summary = summarizeProposalVotes(votes);
4686
+ const note = [
4687
+ summary.note,
4688
+ logNote,
4689
+ attachNote,
4690
+ truncated ? "Result truncated; narrow fromBlock/toBlock if you need the rest." : ""
4691
+ ].filter(Boolean).join(" ");
4692
+ return {
4693
+ proposalId: resolved.proposalId.toString(),
4694
+ ...resolved.catalogId != null ? { catalogId: resolved.catalogId } : {},
4695
+ governor: gov,
4696
+ ...nodeProperties ? { nodeProperties } : {},
4697
+ ...title ? { title } : {},
4698
+ ...configuration ? { configuration } : {},
4699
+ fromBlock: fromBlock.toString(),
4700
+ toBlock: toBlock.toString(),
4701
+ truncated,
4702
+ votes,
4703
+ voterCount: summary.voterCount,
4704
+ attachedVoterCount: summary.attachedVoterCount,
4705
+ forWeight: summary.forWeight,
4706
+ againstWeight: summary.againstWeight,
4707
+ abstainWeight: summary.abstainWeight,
4708
+ note
4709
+ };
4710
+ }
4711
+
4712
+ // src/protocols/evm/continuum-dao/index.ts
4254
4713
  init_forum();
4255
4714
  var continuumDaoProtocolModule = {
4256
4715
  id: CONTINUUM_DAO_PROTOCOL_ID,
@@ -4287,6 +4746,7 @@ var continuumDaoProtocolModule = {
4287
4746
  { id: "continuum-dao.cancel", protocolId: CONTINUUM_DAO_PROTOCOL_ID, chainCategory: "evm", description: "Cancel a proposal", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: { proposalId: { type: "string", required: true, description: "Catalog id or governor proposal hash" } } },
4288
4747
  { id: "continuum-dao.fetch-live-proposals", protocolId: CONTINUUM_DAO_PROTOCOL_ID, chainCategory: "evm", description: "List live/pending/succeeded proposals with on-chain state overlay", commonParams: [], params: { chainId: { type: "number", required: false, description: "Linea chain id" }, rpcUrl: { type: "string", required: false, description: "Linea RPC for state overlay" } } },
4289
4748
  { id: "continuum-dao.explain-proposal", protocolId: CONTINUUM_DAO_PROTOCOL_ID, chainCategory: "evm", description: "Deconstruct a proposal into a readable briefing (actions, C3, no-ops, risks)", commonParams: [], params: { id: { type: "string", required: false, description: "Backend proposal id" }, onchainId: { type: "string", required: false, description: "Governor proposal id" } } },
4749
+ { id: "continuum-dao.fetch-proposal-votes", protocolId: CONTINUUM_DAO_PROTOCOL_ID, chainCategory: "evm", description: "Who voted on a proposal and how (VoteCast / VoteCastWithParams)", commonParams: [], params: { proposalId: { type: "string", required: true, description: "Catalog id or governor proposal hash" } } },
4290
4750
  { id: "continuum-dao.forum-sign-in", protocolId: CONTINUUM_DAO_PROTOCOL_ID, chainCategory: "evm", description: "EIP-712 forum login (veCTM gate first)", commonParams: ["keyGen", "purposeText"], params: { nodeKey: { type: "string", required: false, description: "Attached node key" }, username: { type: "string", required: false, description: "Username when there is no node key" } } },
4291
4751
  { id: "continuum-dao.forum-sign-in-eligible", protocolId: CONTINUUM_DAO_PROTOCOL_ID, chainCategory: "evm", description: "Check veCTM forum login eligibility", commonParams: [], params: { address: { type: "string", required: true, description: "KeyGen or wallet address" } } },
4292
4752
  { id: "continuum-dao.forum-sign-out", protocolId: CONTINUUM_DAO_PROTOCOL_ID, chainCategory: "evm", description: "Revoke forum ticket and sessions", commonParams: [], params: { ticket: { type: "string", required: true, description: "Forum write ticket" } } },
@@ -4302,6 +4762,6 @@ var continuumDaoProtocolModule = {
4302
4762
  };
4303
4763
  registerProtocolModule(continuumDaoProtocolModule);
4304
4764
 
4305
- export { ATTACH_VECTM_SIGNATURE, CONTINUUM_DAO_APPROVE_FALLBACK, CONTINUUM_DAO_ATTACH_FALLBACK, CONTINUUM_DAO_CANCEL_FALLBACK, CONTINUUM_DAO_COMMITTEE_PROPOSERS, CONTINUUM_DAO_CREATE_LOCK_FALLBACK, CONTINUUM_DAO_DELEGATE_FALLBACK, CONTINUUM_DAO_DEPLOYMENTS, CONTINUUM_DAO_DETACH_FALLBACK, CONTINUUM_DAO_ETHEREUM_CHAIN_ID, CONTINUUM_DAO_EVM_TYPES, CONTINUUM_DAO_EXECUTE_FALLBACK, CONTINUUM_DAO_GOVERNANCE_API, CONTINUUM_DAO_GOV_EVM_TYPES, CONTINUUM_DAO_INCREASE_AMOUNT_FALLBACK, CONTINUUM_DAO_INCREASE_UNLOCK_FALLBACK, CONTINUUM_DAO_LINEA_CHAIN_ID, CONTINUUM_DAO_LINEA_GOVERNOR_ADDRESS, CONTINUUM_DAO_LINEA_GOVERNOR_LEGACY_ADDRESS, CONTINUUM_DAO_LINEA_SEPOLIA_CHAIN_ID, CONTINUUM_DAO_LIQUIDATE_FALLBACK, CONTINUUM_DAO_MERGE_FALLBACK, CONTINUUM_DAO_PROPOSE_FALLBACK, CONTINUUM_DAO_PROTOCOL_ID, CONTINUUM_DAO_SPLIT_FALLBACK, CONTINUUM_DAO_TRANSFER_FALLBACK, CONTINUUM_DAO_VOTE_FALLBACK, CONTINUUM_DAO_WITHDRAW_FALLBACK, CTM_TOKEN_ADDRESS, CTM_TOKEN_DECIMALS, CTM_TOKEN_NAME, CTM_TOKEN_SYMBOL, FORUM_GOVERNANCE_SECTIONS, FORUM_IDEA_SECTION, FORUM_LOGIN_DELIVERY_KIND, FOUNDRY_PROPOSAL_REQUIRED_SERVERS, GOVERNOR_STATE, GOVERNOR_STATE_LABELS, INCREASE_UNLOCK_TIME_SIGNATURE, MAXTIME_SECONDS, PROPOSAL_TYPE_LABELS, PROPOSAL_TYPE_TO_FORUM_SECTION, VECTM_DEFAULT_MINIMUM_LOCK_WEI, VECTM_LIQ_MIN_LOCKED_WEI, VECTM_LIQ_PENALTY_DEN, VECTM_LIQ_PENALTY_NUM, VECTM_MAX_LOCK_WEEKS, VECTM_NODE_INFO_TUPLE, VECTM_TOKEN_NAME, VECTM_TOKEN_SYMBOL, VOTING_ESCROW_LINEA_ADDRESS, WEEK_SECONDS, applyForumSectionCheck, assertContinuumDaoForumDeleteInput, assertContinuumDaoForumMarkReadInput, assertContinuumDaoForumRecentInput, assertContinuumDaoForumSearchInput, assertContinuumDaoForumTopicKey, assertContinuumDaoProposalSimulation, assertCreateLockAmount, assertCtmAmountAtLeastMinimum, assertDelegatee, assertExecutorOwnsLock, assertIncreaseAmount, assertIncreaseUnlockTime, assertLiquidate, assertLockDurationSeconds, assertMerge, assertSplitExtracted, assertTransfer, assertUndelegateNotAlreadySelf, assertWithdraw, bucketGovernorState, buildBravoProposalArgs, buildDeltaProposalArgs, buildEvmMultisignBodyContinuumDaoAttachVeCtm, buildEvmMultisignBodyContinuumDaoAttachVeCtmFromMcp, buildEvmMultisignBodyContinuumDaoCancel, buildEvmMultisignBodyContinuumDaoCastVoteBravo, buildEvmMultisignBodyContinuumDaoCastVoteBravoFromMcp, buildEvmMultisignBodyContinuumDaoCastVoteDelta, buildEvmMultisignBodyContinuumDaoCreateLock, buildEvmMultisignBodyContinuumDaoDelegate, buildEvmMultisignBodyContinuumDaoExecute, buildEvmMultisignBodyContinuumDaoForumSignIn, buildEvmMultisignBodyContinuumDaoIncreaseAmount, buildEvmMultisignBodyContinuumDaoIncreaseUnlockTime, buildEvmMultisignBodyContinuumDaoLiquidate, buildEvmMultisignBodyContinuumDaoMerge, buildEvmMultisignBodyContinuumDaoProposeBravo, buildEvmMultisignBodyContinuumDaoProposeDelta, buildEvmMultisignBodyContinuumDaoProposeDeltaFromMcp, buildEvmMultisignBodyContinuumDaoRequestDetach, buildEvmMultisignBodyContinuumDaoSplit, buildEvmMultisignBodyContinuumDaoTransfer, buildEvmMultisignBodyContinuumDaoUndelegate, buildEvmMultisignBodyContinuumDaoWithdraw, buildFoundryProposalSimulatePlan, computeLiquidationAmounts, continuumDaoComposeProposalAction, continuumDaoDeployment, continuumDaoExplainProposal, continuumDaoFetchDelegates, continuumDaoFetchLiveProposals, continuumDaoFetchProposal, continuumDaoFetchProposalCount, continuumDaoFetchProposalState, continuumDaoFetchProposalVoteEligibility, continuumDaoFetchProposals, continuumDaoFetchVotingPower, continuumDaoForumCreateIdea, continuumDaoForumCreateTopic, continuumDaoForumDelete, continuumDaoForumFetchPost, continuumDaoForumFetchThread, continuumDaoForumMarkRead, continuumDaoForumMarkUnread, continuumDaoForumMe, continuumDaoForumReact, continuumDaoForumRecent, continuumDaoForumReply, continuumDaoForumReplyCount, continuumDaoForumResolve, continuumDaoForumSearch, continuumDaoForumSections, continuumDaoForumSignInEligible, continuumDaoForumSignInNonce, continuumDaoForumSignOut, continuumDaoForumUnread, continuumDaoForumUrl, continuumDaoForumUserPostIds, continuumDaoHashProposal, continuumDaoMpaFlag, continuumDaoMpaListing, continuumDaoMpaMailboxList, continuumDaoMpaMailboxOpen, continuumDaoMpaMailboxSend, continuumDaoMpaRetract, continuumDaoProtocolModule, continuumDaoRegisterProposal, continuumDaoSignatureText, continuumDaoSimulateProposal, continuumDaoTechnocoreBind, ctmTokenAddressOnEvmChain, encodeContinuumDaoNodeInfo, encodeDeltaMetadata, encodeDeltaVoteParams, encodeGovActionCalldata, executableGovBatches, expectedForumSectionForProposalType, explainGovAction, explainProposalRecord, floorUnlockTimeSeconds, formatProposalSimulationFailure, foundryPlanHasSequentialExecute, foundryScriptContainsCall, governorAddressOnEvmChain, governorWriteAbi, isConfiguredAddress, isContinuumDaoCommitteeProposer, isContinuumDaoCtmOnAssetsChain, isContinuumDaoLockChain, isContinuumDaoSupportedChainId, isContinuumDaoVeCtmOnAssetsChain, isCtmTokenSymbol, isForumIdeaSection, isGovNoOpAction, isLegacyContinuumDaoGovernor, isLineaHomeNetwork, isRemoteC3Action, isVotingEscrowContinuumName, listContinuumDaoDefaultAssets, looksLikeProposalCatalogId, maxLockDurationSeconds, normalizeGovConfiguration, preflightAttachVeCtm, preflightCreateLock, preflightDelegate, preflightIncreaseAmount, preflightIncreaseUnlockTime, preflightLiquidate, preflightMerge, preflightRequestDetach, preflightSplit, preflightTransfer, preflightUndelegate, preflightWithdraw, proposalDescriptionHash, publicClient2 as publicClient, readCtmBalanceWei, readMinimumLockWei, readVeCtmLockState, requireGovernor, resolveAttachGroupId, resolveGovernorProposalRef, resolveProposalCatalogRange, summarizeLiveProposals, throwIfProposalSimulationFailed, validateAbiParameter, votingEscrowAddressOnEvmChain, votingPowerRefuse, votingPowerWarning };
4765
+ export { ATTACH_VECTM_SIGNATURE, BRAVO_SUPPORT_LABELS, CONTINUUM_DAO_APPROVE_FALLBACK, CONTINUUM_DAO_ATTACH_FALLBACK, CONTINUUM_DAO_CANCEL_FALLBACK, CONTINUUM_DAO_COMMITTEE_PROPOSERS, CONTINUUM_DAO_CREATE_LOCK_FALLBACK, CONTINUUM_DAO_DELEGATE_FALLBACK, CONTINUUM_DAO_DEPLOYMENTS, CONTINUUM_DAO_DETACH_FALLBACK, CONTINUUM_DAO_ETHEREUM_CHAIN_ID, CONTINUUM_DAO_EVM_TYPES, CONTINUUM_DAO_EXECUTE_FALLBACK, CONTINUUM_DAO_GOVERNANCE_API, CONTINUUM_DAO_GOV_EVM_TYPES, CONTINUUM_DAO_INCREASE_AMOUNT_FALLBACK, CONTINUUM_DAO_INCREASE_UNLOCK_FALLBACK, CONTINUUM_DAO_LINEA_CHAIN_ID, CONTINUUM_DAO_LINEA_GOVERNOR_ADDRESS, CONTINUUM_DAO_LINEA_GOVERNOR_LEGACY_ADDRESS, CONTINUUM_DAO_LINEA_SEPOLIA_CHAIN_ID, CONTINUUM_DAO_LIQUIDATE_FALLBACK, CONTINUUM_DAO_MERGE_FALLBACK, CONTINUUM_DAO_PROPOSE_FALLBACK, CONTINUUM_DAO_PROTOCOL_ID, CONTINUUM_DAO_SPLIT_FALLBACK, CONTINUUM_DAO_TRANSFER_FALLBACK, CONTINUUM_DAO_VOTE_FALLBACK, CONTINUUM_DAO_WITHDRAW_FALLBACK, CTM_TOKEN_ADDRESS, CTM_TOKEN_DECIMALS, CTM_TOKEN_NAME, CTM_TOKEN_SYMBOL, FORUM_GOVERNANCE_SECTIONS, FORUM_IDEA_SECTION, FORUM_LOGIN_DELIVERY_KIND, FOUNDRY_PROPOSAL_REQUIRED_SERVERS, GOVERNOR_STATE, GOVERNOR_STATE_LABELS, INCREASE_UNLOCK_TIME_SIGNATURE, MAXTIME_SECONDS, PROPOSAL_TYPE_LABELS, PROPOSAL_TYPE_TO_FORUM_SECTION, VECTM_DEFAULT_MINIMUM_LOCK_WEI, VECTM_LIQ_MIN_LOCKED_WEI, VECTM_LIQ_PENALTY_DEN, VECTM_LIQ_PENALTY_NUM, VECTM_MAX_LOCK_WEEKS, VECTM_NODE_INFO_TUPLE, VECTM_TOKEN_NAME, VECTM_TOKEN_SYMBOL, VOTE_CAST_EVENT, VOTE_CAST_WITH_PARAMS_EVENT, VOTING_ESCROW_LINEA_ADDRESS, WEEK_SECONDS, applyForumSectionCheck, applyNodeAttachments, assertContinuumDaoForumDeleteInput, assertContinuumDaoForumMarkReadInput, assertContinuumDaoForumRecentInput, assertContinuumDaoForumSearchInput, assertContinuumDaoForumTopicKey, assertContinuumDaoProposalSimulation, assertCreateLockAmount, assertCtmAmountAtLeastMinimum, assertDelegatee, assertExecutorOwnsLock, assertIncreaseAmount, assertIncreaseUnlockTime, assertLiquidate, assertLockDurationSeconds, assertMerge, assertSplitExtracted, assertTransfer, assertUndelegateNotAlreadySelf, assertWithdraw, bravoSupportLabel, bucketGovernorState, buildBravoProposalArgs, buildDeltaProposalArgs, buildEvmMultisignBodyContinuumDaoAttachVeCtm, buildEvmMultisignBodyContinuumDaoAttachVeCtmFromMcp, buildEvmMultisignBodyContinuumDaoCancel, buildEvmMultisignBodyContinuumDaoCastVoteBravo, buildEvmMultisignBodyContinuumDaoCastVoteBravoFromMcp, buildEvmMultisignBodyContinuumDaoCastVoteDelta, buildEvmMultisignBodyContinuumDaoCreateLock, buildEvmMultisignBodyContinuumDaoDelegate, buildEvmMultisignBodyContinuumDaoExecute, buildEvmMultisignBodyContinuumDaoForumSignIn, buildEvmMultisignBodyContinuumDaoIncreaseAmount, buildEvmMultisignBodyContinuumDaoIncreaseUnlockTime, buildEvmMultisignBodyContinuumDaoLiquidate, buildEvmMultisignBodyContinuumDaoMerge, buildEvmMultisignBodyContinuumDaoProposeBravo, buildEvmMultisignBodyContinuumDaoProposeDelta, buildEvmMultisignBodyContinuumDaoProposeDeltaFromMcp, buildEvmMultisignBodyContinuumDaoRequestDetach, buildEvmMultisignBodyContinuumDaoSplit, buildEvmMultisignBodyContinuumDaoTransfer, buildEvmMultisignBodyContinuumDaoUndelegate, buildEvmMultisignBodyContinuumDaoWithdraw, buildFoundryProposalSimulatePlan, collectVotesFromLogs, computeLiquidationAmounts, continuumDaoComposeProposalAction, continuumDaoDeployment, continuumDaoExplainProposal, continuumDaoFetchDelegates, continuumDaoFetchLiveProposals, continuumDaoFetchProposal, continuumDaoFetchProposalCount, continuumDaoFetchProposalState, continuumDaoFetchProposalVoteEligibility, continuumDaoFetchProposalVotes, continuumDaoFetchProposals, continuumDaoFetchVotingPower, continuumDaoForumCreateIdea, continuumDaoForumCreateTopic, continuumDaoForumDelete, continuumDaoForumFetchPost, continuumDaoForumFetchThread, continuumDaoForumMarkRead, continuumDaoForumMarkUnread, continuumDaoForumMe, continuumDaoForumReact, continuumDaoForumRecent, continuumDaoForumReply, continuumDaoForumReplyCount, continuumDaoForumResolve, continuumDaoForumSearch, continuumDaoForumSections, continuumDaoForumSignInEligible, continuumDaoForumSignInNonce, continuumDaoForumSignOut, continuumDaoForumUnread, continuumDaoForumUrl, continuumDaoForumUserPostIds, continuumDaoHashProposal, continuumDaoMpaFlag, continuumDaoMpaListing, continuumDaoMpaMailboxList, continuumDaoMpaMailboxOpen, continuumDaoMpaMailboxSend, continuumDaoMpaRetract, continuumDaoProtocolModule, continuumDaoRegisterProposal, continuumDaoSignatureText, continuumDaoSimulateProposal, continuumDaoTechnocoreBind, ctmTokenAddressOnEvmChain, decodeDeltaVoteParams, encodeContinuumDaoNodeInfo, encodeDeltaMetadata, encodeDeltaVoteParams, encodeGovActionCalldata, estimateBlockAtTimestamp, executableGovBatches, expectedForumSectionForProposalType, explainGovAction, explainProposalRecord, explorerBase, floorUnlockTimeSeconds, formatProposalSimulationFailure, foundryPlanHasSequentialExecute, foundryScriptContainsCall, governorAddressOnEvmChain, governorWriteAbi, howVoted, isConfiguredAddress, isContinuumDaoCommitteeProposer, isContinuumDaoCtmOnAssetsChain, isContinuumDaoLockChain, isContinuumDaoSupportedChainId, isContinuumDaoVeCtmOnAssetsChain, isCtmTokenSymbol, isForumIdeaSection, isGovNoOpAction, isLegacyContinuumDaoGovernor, isLineaHomeNetwork, isRemoteC3Action, isVotingEscrowContinuumName, listContinuumDaoDefaultAssets, looksLikeProposalCatalogId, looksLikeUnixSeconds, maxLockDurationSeconds, normalizeGovConfiguration, normalizeNodeInfo, preflightAttachVeCtm, preflightCreateLock, preflightDelegate, preflightIncreaseAmount, preflightIncreaseUnlockTime, preflightLiquidate, preflightMerge, preflightRequestDetach, preflightSplit, preflightTransfer, preflightUndelegate, preflightWithdraw, proposalDescriptionHash, publicClient2 as publicClient, readCtmBalanceWei, readMinimumLockWei, readVeCtmLockState, requireGovernor, resolveAttachGroupId, resolveGovernorProposalRef, resolveProposalCatalogRange, summarizeLiveProposals, summarizeProposalVotes, throwIfProposalSimulationFailed, validateAbiParameter, votingEscrowAddressOnEvmChain, votingPowerRefuse, votingPowerWarning };
4306
4766
  //# sourceMappingURL=index.js.map
4307
4767
  //# sourceMappingURL=index.js.map