@spectratools/assembly-cli 0.11.7 → 0.13.0

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 (3) hide show
  1. package/dist/cli.js +1090 -772
  2. package/dist/index.js +1090 -772
  3. package/package.json +3 -3
package/dist/cli.js CHANGED
@@ -7,9 +7,9 @@ import { fileURLToPath } from "url";
7
7
  import {
8
8
  initTelemetry,
9
9
  shutdownTelemetry,
10
- withCommandSpan
10
+ withCommandSpan as withCommandSpan2
11
11
  } from "@spectratools/cli-shared/telemetry";
12
- import { Cli as Cli6, z as z7 } from "incur";
12
+ import { Cli as Cli6, z as z9 } from "incur";
13
13
 
14
14
  // src/commands/_common.ts
15
15
  import { checksumAddress, weiToEth } from "@spectratools/cli-shared";
@@ -5246,41 +5246,11 @@ council.command("withdraw-refund", {
5246
5246
  }
5247
5247
  });
5248
5248
 
5249
- // src/commands/forum.ts
5250
- import { TxError } from "@spectratools/tx-shared";
5251
- import { Cli as Cli2, z as z3 } from "incur";
5252
- var env2 = z3.object({
5253
- ABSTRACT_RPC_URL: z3.string().optional().describe("Abstract RPC URL override")
5254
- });
5255
- var commentEnv = env2.extend({
5256
- PRIVATE_KEY: z3.string().optional().describe("Private key (required only when posting a comment via --body)")
5257
- });
5258
- var timestampOutput2 = z3.union([z3.number(), z3.string()]);
5259
- var txResultOutput2 = z3.union([
5260
- z3.object({
5261
- status: z3.literal("success"),
5262
- hash: z3.string(),
5263
- blockNumber: z3.number(),
5264
- gasUsed: z3.string(),
5265
- from: z3.string(),
5266
- to: z3.string().nullable(),
5267
- effectiveGasPrice: z3.string().optional()
5268
- }),
5269
- z3.object({
5270
- status: z3.literal("reverted"),
5271
- hash: z3.string(),
5272
- blockNumber: z3.number(),
5273
- gasUsed: z3.string(),
5274
- from: z3.string(),
5275
- to: z3.string().nullable(),
5276
- effectiveGasPrice: z3.string().optional()
5277
- }),
5278
- z3.object({
5279
- status: z3.literal("dry-run"),
5280
- estimatedGas: z3.string(),
5281
- simulationResult: z3.unknown()
5282
- })
5283
- ]);
5249
+ // src/commands/digest.ts
5250
+ import { withCommandSpan } from "@spectratools/cli-shared/telemetry";
5251
+ import { z as z4 } from "incur";
5252
+
5253
+ // src/services/forum.ts
5284
5254
  function decodeThread(value) {
5285
5255
  const [id, kind, author, createdAt, category, title, body, proposalId, petitionId] = value;
5286
5256
  return {
@@ -5332,45 +5302,762 @@ function decodePetition(value) {
5332
5302
  proposalInput: jsonSafe(proposalInput)
5333
5303
  };
5334
5304
  }
5305
+ async function fetchAllThreads(client) {
5306
+ const count = await client.readContract({
5307
+ abi: forumAbi,
5308
+ address: ABSTRACT_MAINNET_ADDRESSES.forum,
5309
+ functionName: "threadCount"
5310
+ });
5311
+ const ids = Array.from({ length: Number(count) }, (_, i) => BigInt(i + 1));
5312
+ if (ids.length === 0) return [];
5313
+ const threadTuples = await client.multicall({
5314
+ allowFailure: false,
5315
+ contracts: ids.map((id) => ({
5316
+ abi: forumAbi,
5317
+ address: ABSTRACT_MAINNET_ADDRESSES.forum,
5318
+ functionName: "threads",
5319
+ args: [id]
5320
+ }))
5321
+ });
5322
+ return threadTuples.map(decodeThread);
5323
+ }
5324
+ async function fetchAllComments(client) {
5325
+ const count = await client.readContract({
5326
+ abi: forumAbi,
5327
+ address: ABSTRACT_MAINNET_ADDRESSES.forum,
5328
+ functionName: "commentCount"
5329
+ });
5330
+ const ids = Array.from({ length: Number(count) }, (_, i) => BigInt(i + 1));
5331
+ if (ids.length === 0) return [];
5332
+ const commentTuples = await client.multicall({
5333
+ allowFailure: false,
5334
+ contracts: ids.map((id) => ({
5335
+ abi: forumAbi,
5336
+ address: ABSTRACT_MAINNET_ADDRESSES.forum,
5337
+ functionName: "comments",
5338
+ args: [id]
5339
+ }))
5340
+ });
5341
+ return commentTuples.map(decodeComment);
5342
+ }
5343
+ async function fetchAllPetitions(client) {
5344
+ const count = await client.readContract({
5345
+ abi: forumAbi,
5346
+ address: ABSTRACT_MAINNET_ADDRESSES.forum,
5347
+ functionName: "petitionCount"
5348
+ });
5349
+ const ids = Array.from({ length: Number(count) }, (_, i) => BigInt(i + 1));
5350
+ if (ids.length === 0) return [];
5351
+ const petitionTuples = await client.multicall({
5352
+ allowFailure: false,
5353
+ contracts: ids.map((id) => ({
5354
+ abi: forumAbi,
5355
+ address: ABSTRACT_MAINNET_ADDRESSES.forum,
5356
+ functionName: "petitions",
5357
+ args: [id]
5358
+ }))
5359
+ });
5360
+ return petitionTuples.map(decodePetition);
5361
+ }
5362
+ async function fetchForumStats(client) {
5363
+ const [threadCount, commentCount, petitionCount, petitionThresholdBps] = await Promise.all([
5364
+ client.readContract({
5365
+ abi: forumAbi,
5366
+ address: ABSTRACT_MAINNET_ADDRESSES.forum,
5367
+ functionName: "threadCount"
5368
+ }),
5369
+ client.readContract({
5370
+ abi: forumAbi,
5371
+ address: ABSTRACT_MAINNET_ADDRESSES.forum,
5372
+ functionName: "commentCount"
5373
+ }),
5374
+ client.readContract({
5375
+ abi: forumAbi,
5376
+ address: ABSTRACT_MAINNET_ADDRESSES.forum,
5377
+ functionName: "petitionCount"
5378
+ }),
5379
+ client.readContract({
5380
+ abi: forumAbi,
5381
+ address: ABSTRACT_MAINNET_ADDRESSES.forum,
5382
+ functionName: "petitionThresholdBps"
5383
+ })
5384
+ ]);
5385
+ return {
5386
+ threadCount: asNum(threadCount),
5387
+ commentCount: asNum(commentCount),
5388
+ petitionCount: asNum(petitionCount),
5389
+ petitionThresholdBps: asNum(petitionThresholdBps)
5390
+ };
5391
+ }
5392
+ async function fetchHasSignedBatch(client, address, petitionIds) {
5393
+ if (petitionIds.length === 0) return /* @__PURE__ */ new Map();
5394
+ const results = await client.multicall({
5395
+ allowFailure: false,
5396
+ contracts: petitionIds.map((id) => ({
5397
+ abi: forumAbi,
5398
+ address: ABSTRACT_MAINNET_ADDRESSES.forum,
5399
+ functionName: "hasSignedPetition",
5400
+ args: [BigInt(id), address]
5401
+ }))
5402
+ });
5403
+ const map = /* @__PURE__ */ new Map();
5404
+ for (let i = 0; i < petitionIds.length; i++) {
5405
+ map.set(petitionIds[i], results[i]);
5406
+ }
5407
+ return map;
5408
+ }
5409
+
5410
+ // src/services/governance.ts
5411
+ var proposalStatusLabels = {
5412
+ 0: "pending",
5413
+ 1: "active",
5414
+ 2: "passed",
5415
+ 3: "executed",
5416
+ 4: "defeated",
5417
+ 5: "cancelled"
5418
+ };
5419
+ function proposalStatus(status) {
5420
+ const statusCode = asNum(status);
5421
+ return {
5422
+ status: proposalStatusLabels[statusCode] ?? `unknown-${statusCode}`,
5423
+ statusCode
5424
+ };
5425
+ }
5426
+ function decodeProposal(value) {
5427
+ const [
5428
+ kind,
5429
+ configRiskTier,
5430
+ origin,
5431
+ status,
5432
+ proposer,
5433
+ threadId,
5434
+ petitionId,
5435
+ createdAt,
5436
+ deliberationEndsAt,
5437
+ voteStartAt,
5438
+ voteEndAt,
5439
+ timelockEndsAt,
5440
+ activeSeatsSnapshot,
5441
+ forVotes,
5442
+ againstVotes,
5443
+ abstainVotes,
5444
+ amount,
5445
+ snapshotAssetBalance,
5446
+ transferIntent,
5447
+ intentDeadline,
5448
+ intentMaxRiskTier,
5449
+ title,
5450
+ description
5451
+ ] = value;
5452
+ return {
5453
+ kind,
5454
+ configRiskTier,
5455
+ origin,
5456
+ status,
5457
+ proposer: toChecksum(proposer),
5458
+ threadId,
5459
+ petitionId,
5460
+ createdAt,
5461
+ deliberationEndsAt,
5462
+ voteStartAt,
5463
+ voteEndAt,
5464
+ timelockEndsAt,
5465
+ activeSeatsSnapshot,
5466
+ forVotes,
5467
+ againstVotes,
5468
+ abstainVotes,
5469
+ amount,
5470
+ snapshotAssetBalance,
5471
+ transferIntent,
5472
+ intentDeadline,
5473
+ intentMaxRiskTier,
5474
+ title,
5475
+ description
5476
+ };
5477
+ }
5478
+ function serializeProposal(proposal) {
5479
+ const status = proposalStatus(proposal.status);
5480
+ return {
5481
+ kind: asNum(proposal.kind),
5482
+ configRiskTier: asNum(proposal.configRiskTier),
5483
+ origin: asNum(proposal.origin),
5484
+ status: status.status,
5485
+ statusCode: status.statusCode,
5486
+ proposer: proposal.proposer,
5487
+ threadId: asNum(proposal.threadId),
5488
+ petitionId: asNum(proposal.petitionId),
5489
+ createdAt: asNum(proposal.createdAt),
5490
+ deliberationEndsAt: asNum(proposal.deliberationEndsAt),
5491
+ voteStartAt: asNum(proposal.voteStartAt),
5492
+ voteEndAt: asNum(proposal.voteEndAt),
5493
+ timelockEndsAt: asNum(proposal.timelockEndsAt),
5494
+ activeSeatsSnapshot: asNum(proposal.activeSeatsSnapshot),
5495
+ forVotes: proposal.forVotes.toString(),
5496
+ againstVotes: proposal.againstVotes.toString(),
5497
+ abstainVotes: proposal.abstainVotes.toString(),
5498
+ amount: proposal.amount.toString(),
5499
+ snapshotAssetBalance: proposal.snapshotAssetBalance.toString(),
5500
+ transferIntent: proposal.transferIntent,
5501
+ intentDeadline: asNum(proposal.intentDeadline),
5502
+ intentMaxRiskTier: asNum(proposal.intentMaxRiskTier),
5503
+ title: proposal.title,
5504
+ description: proposal.description
5505
+ };
5506
+ }
5507
+ async function fetchProposalCount(client) {
5508
+ return await client.readContract({
5509
+ abi: governanceAbi,
5510
+ address: ABSTRACT_MAINNET_ADDRESSES.governance,
5511
+ functionName: "proposalCount"
5512
+ });
5513
+ }
5514
+ async function fetchProposalById(client, id) {
5515
+ return decodeProposal(
5516
+ await client.readContract({
5517
+ abi: governanceAbi,
5518
+ address: ABSTRACT_MAINNET_ADDRESSES.governance,
5519
+ functionName: "proposals",
5520
+ args: [BigInt(id)]
5521
+ })
5522
+ );
5523
+ }
5524
+ async function fetchAllProposals(client) {
5525
+ const count = await fetchProposalCount(client);
5526
+ const ids = Array.from({ length: Number(count) }, (_, i) => BigInt(i + 1));
5527
+ if (ids.length === 0) return [];
5528
+ const proposalTuples = await client.multicall({
5529
+ allowFailure: false,
5530
+ contracts: ids.map((id) => ({
5531
+ abi: governanceAbi,
5532
+ address: ABSTRACT_MAINNET_ADDRESSES.governance,
5533
+ functionName: "proposals",
5534
+ args: [id]
5535
+ }))
5536
+ });
5537
+ return proposalTuples.map(decodeProposal);
5538
+ }
5539
+ async function fetchHasVotedBatch(client, address, proposalIds) {
5540
+ if (proposalIds.length === 0) return /* @__PURE__ */ new Map();
5541
+ const results = await client.multicall({
5542
+ allowFailure: false,
5543
+ contracts: proposalIds.map((id) => ({
5544
+ abi: governanceAbi,
5545
+ address: ABSTRACT_MAINNET_ADDRESSES.governance,
5546
+ functionName: "hasVoted",
5547
+ args: [BigInt(id), address]
5548
+ }))
5549
+ });
5550
+ const map = /* @__PURE__ */ new Map();
5551
+ for (let i = 0; i < proposalIds.length; i++) {
5552
+ map.set(proposalIds[i], results[i]);
5553
+ }
5554
+ return map;
5555
+ }
5556
+
5557
+ // src/services/members.ts
5558
+ import { z as z3 } from "incur";
5559
+ var DEFAULT_MEMBER_SNAPSHOT_URL = "https://www.theaiassembly.org/api/indexer/members";
5560
+ var REGISTERED_EVENT_SCAN_STEP = 100000n;
5561
+ var REGISTERED_EVENT_SCAN_TIMEOUT_MS = 2e4;
5562
+ var memberSnapshotEntrySchema = z3.union([
5563
+ z3.string(),
5564
+ z3.object({
5565
+ address: z3.string(),
5566
+ ens: z3.string().optional(),
5567
+ name: z3.string().optional()
5568
+ })
5569
+ ]);
5570
+ var memberSnapshotSchema = z3.array(memberSnapshotEntrySchema);
5571
+ var AssemblyApiValidationError = class extends Error {
5572
+ constructor(details) {
5573
+ super("Assembly API response validation failed");
5574
+ this.details = details;
5575
+ this.name = "AssemblyApiValidationError";
5576
+ }
5577
+ };
5578
+ var AssemblyIndexerUnavailableError = class extends Error {
5579
+ constructor(details) {
5580
+ super("Assembly indexer unavailable");
5581
+ this.details = details;
5582
+ this.name = "AssemblyIndexerUnavailableError";
5583
+ }
5584
+ };
5585
+ function memberSnapshotEntryToIdentity(entry) {
5586
+ if (typeof entry === "string") return { address: entry };
5587
+ const identity = { address: entry.address };
5588
+ if (entry.ens !== void 0) identity.ens = entry.ens;
5589
+ if (entry.name !== void 0) identity.name = entry.name;
5590
+ return identity;
5591
+ }
5592
+ function mergeMemberIdentities(entries) {
5593
+ const byAddress = /* @__PURE__ */ new Map();
5594
+ for (const entry of entries) {
5595
+ const key = entry.address.toLowerCase();
5596
+ const existing = byAddress.get(key);
5597
+ if (!existing) {
5598
+ byAddress.set(key, entry);
5599
+ continue;
5600
+ }
5601
+ const merged = { address: existing.address };
5602
+ const ens = existing.ens ?? entry.ens;
5603
+ const name = existing.name ?? entry.name;
5604
+ if (ens !== void 0) merged.ens = ens;
5605
+ if (name !== void 0) merged.name = name;
5606
+ byAddress.set(key, merged);
5607
+ }
5608
+ return [...byAddress.values()];
5609
+ }
5610
+ async function memberSnapshot(url) {
5611
+ let res;
5612
+ try {
5613
+ res = await fetch(url);
5614
+ } catch (error) {
5615
+ throw new AssemblyIndexerUnavailableError({
5616
+ code: "ASSEMBLY_INDEXER_UNAVAILABLE",
5617
+ url,
5618
+ reason: error instanceof Error ? error.message : String(error)
5619
+ });
5620
+ }
5621
+ if (!res.ok) {
5622
+ throw new AssemblyIndexerUnavailableError({
5623
+ code: "ASSEMBLY_INDEXER_UNAVAILABLE",
5624
+ url,
5625
+ status: res.status,
5626
+ statusText: res.statusText
5627
+ });
5628
+ }
5629
+ const json = await res.json();
5630
+ const parsed = memberSnapshotSchema.safeParse(json);
5631
+ if (parsed.success) {
5632
+ return mergeMemberIdentities(parsed.data.map(memberSnapshotEntryToIdentity));
5633
+ }
5634
+ throw new AssemblyApiValidationError({
5635
+ code: "INVALID_ASSEMBLY_API_RESPONSE",
5636
+ url,
5637
+ issues: parsed.error.issues,
5638
+ response: json
5639
+ });
5640
+ }
5641
+ async function withTimeout(promise, timeoutMs, timeoutMessage) {
5642
+ let timer;
5643
+ try {
5644
+ return await Promise.race([
5645
+ promise,
5646
+ new Promise((_, reject) => {
5647
+ timer = setTimeout(() => {
5648
+ reject(new Error(timeoutMessage));
5649
+ }, timeoutMs);
5650
+ })
5651
+ ]);
5652
+ } finally {
5653
+ if (timer) clearTimeout(timer);
5654
+ }
5655
+ }
5656
+ async function membersFromRegisteredEvents(client) {
5657
+ const latestBlock = await client.getBlockNumber();
5658
+ const addresses = /* @__PURE__ */ new Set();
5659
+ for (let fromBlock = ABSTRACT_MAINNET_DEPLOYMENT_BLOCKS.registry; fromBlock <= latestBlock; fromBlock += REGISTERED_EVENT_SCAN_STEP) {
5660
+ const toBlock = fromBlock + REGISTERED_EVENT_SCAN_STEP - 1n > latestBlock ? latestBlock : fromBlock + REGISTERED_EVENT_SCAN_STEP - 1n;
5661
+ const events = await client.getContractEvents({
5662
+ abi: registryAbi,
5663
+ address: ABSTRACT_MAINNET_ADDRESSES.registry,
5664
+ eventName: "Registered",
5665
+ fromBlock,
5666
+ toBlock,
5667
+ strict: true
5668
+ });
5669
+ for (const event of events) {
5670
+ const member = event.args.member;
5671
+ if (typeof member === "string") {
5672
+ addresses.add(member);
5673
+ }
5674
+ }
5675
+ }
5676
+ return [...addresses].map((address) => ({ address }));
5677
+ }
5678
+ async function fetchMemberList(client, snapshotUrl) {
5679
+ const url = snapshotUrl ?? DEFAULT_MEMBER_SNAPSHOT_URL;
5680
+ try {
5681
+ return { members: await memberSnapshot(url) };
5682
+ } catch (error) {
5683
+ if (error instanceof AssemblyApiValidationError) {
5684
+ throw error;
5685
+ }
5686
+ if (!(error instanceof AssemblyIndexerUnavailableError)) {
5687
+ throw error;
5688
+ }
5689
+ const fallbackMembers = await withTimeout(
5690
+ membersFromRegisteredEvents(client),
5691
+ REGISTERED_EVENT_SCAN_TIMEOUT_MS,
5692
+ `Registered event fallback scan timed out after ${REGISTERED_EVENT_SCAN_TIMEOUT_MS}ms`
5693
+ );
5694
+ return {
5695
+ members: mergeMemberIdentities(fallbackMembers),
5696
+ fallbackReason: error.details
5697
+ };
5698
+ }
5699
+ }
5700
+ async function fetchMemberOnchainState(client, addresses) {
5701
+ if (addresses.length === 0) return [];
5702
+ const calls = addresses.flatMap((address) => [
5703
+ {
5704
+ abi: registryAbi,
5705
+ address: ABSTRACT_MAINNET_ADDRESSES.registry,
5706
+ functionName: "isActive",
5707
+ args: [address]
5708
+ },
5709
+ {
5710
+ abi: registryAbi,
5711
+ address: ABSTRACT_MAINNET_ADDRESSES.registry,
5712
+ functionName: "members",
5713
+ args: [address]
5714
+ }
5715
+ ]);
5716
+ const values = await client.multicall({ allowFailure: false, contracts: calls });
5717
+ return addresses.map((address, i) => {
5718
+ const active = values[i * 2];
5719
+ const info = values[i * 2 + 1];
5720
+ return {
5721
+ address: toChecksum(address),
5722
+ active,
5723
+ registered: info.registered,
5724
+ activeUntil: info.activeUntil,
5725
+ lastHeartbeatAt: info.lastHeartbeatAt
5726
+ };
5727
+ });
5728
+ }
5729
+
5730
+ // src/commands/digest.ts
5731
+ var digestEnv = z4.object({
5732
+ ABSTRACT_RPC_URL: z4.string().optional().describe("Abstract RPC URL override"),
5733
+ ASSEMBLY_INDEXER_URL: z4.string().optional().describe("Optional members snapshot endpoint (default: theaiassembly.org indexer)")
5734
+ });
5735
+ var memberItemSchema = z4.object({
5736
+ address: z4.string(),
5737
+ active: z4.boolean(),
5738
+ registered: z4.boolean(),
5739
+ activeUntil: z4.string(),
5740
+ lastHeartbeatAt: z4.string()
5741
+ });
5742
+ var proposalDigestSchema = z4.object({
5743
+ id: z4.number(),
5744
+ kind: z4.number(),
5745
+ configRiskTier: z4.number(),
5746
+ origin: z4.number(),
5747
+ status: z4.string(),
5748
+ statusCode: z4.number(),
5749
+ proposer: z4.string(),
5750
+ threadId: z4.number(),
5751
+ petitionId: z4.number(),
5752
+ createdAt: z4.number(),
5753
+ deliberationEndsAt: z4.number(),
5754
+ voteStartAt: z4.number(),
5755
+ voteEndAt: z4.number(),
5756
+ timelockEndsAt: z4.number(),
5757
+ activeSeatsSnapshot: z4.number(),
5758
+ forVotes: z4.string(),
5759
+ againstVotes: z4.string(),
5760
+ abstainVotes: z4.string(),
5761
+ amount: z4.string(),
5762
+ snapshotAssetBalance: z4.string(),
5763
+ transferIntent: z4.boolean(),
5764
+ intentDeadline: z4.number(),
5765
+ intentMaxRiskTier: z4.number(),
5766
+ title: z4.string(),
5767
+ description: z4.string(),
5768
+ hasVoted: z4.boolean().optional()
5769
+ });
5770
+ var threadDigestSchema = z4.object({
5771
+ id: z4.number(),
5772
+ kind: z4.number(),
5773
+ author: z4.string(),
5774
+ createdAt: z4.number(),
5775
+ category: z4.string(),
5776
+ title: z4.string(),
5777
+ proposalId: z4.number(),
5778
+ petitionId: z4.number()
5779
+ });
5780
+ var commentDigestSchema = z4.object({
5781
+ id: z4.number(),
5782
+ threadId: z4.number(),
5783
+ parentId: z4.number(),
5784
+ author: z4.string(),
5785
+ createdAt: z4.number(),
5786
+ body: z4.string()
5787
+ });
5788
+ var petitionDigestSchema = z4.object({
5789
+ id: z4.number(),
5790
+ proposer: z4.string(),
5791
+ createdAt: z4.number(),
5792
+ category: z4.string(),
5793
+ title: z4.string(),
5794
+ body: z4.string(),
5795
+ signatures: z4.number(),
5796
+ promoted: z4.boolean(),
5797
+ threadId: z4.number(),
5798
+ hasSigned: z4.boolean().optional()
5799
+ });
5800
+ var digestOutputSchema = z4.object({
5801
+ meta: z4.object({
5802
+ chainId: z4.number(),
5803
+ fetchedAt: z4.string(),
5804
+ address: z4.string().optional()
5805
+ }),
5806
+ proposals: z4.array(proposalDigestSchema),
5807
+ threads: z4.array(threadDigestSchema),
5808
+ comments: z4.array(commentDigestSchema),
5809
+ petitions: z4.array(petitionDigestSchema),
5810
+ members: z4.object({
5811
+ count: z4.number(),
5812
+ items: z4.array(memberItemSchema)
5813
+ }),
5814
+ errors: z4.array(z4.string())
5815
+ });
5816
+ function registerDigestCommand(cli2) {
5817
+ cli2.command("digest", {
5818
+ description: "Aggregate proposals, threads, comments, petitions, and members into a single governance snapshot.",
5819
+ options: z4.object({
5820
+ address: z4.string().optional().describe("Wallet address to enrich proposals (hasVoted) and petitions (hasSigned)")
5821
+ }),
5822
+ env: digestEnv,
5823
+ output: digestOutputSchema,
5824
+ examples: [
5825
+ { description: "Fetch a full governance digest" },
5826
+ {
5827
+ options: { address: "0x230Ccc765765d729fFb1897D538f773b92005Aa2" },
5828
+ description: "Fetch digest with wallet-relative enrichment"
5829
+ }
5830
+ ],
5831
+ async run(c) {
5832
+ return withCommandSpan("assembly digest", { address: c.options.address }, async () => {
5833
+ const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
5834
+ const errors = [];
5835
+ const address = c.options.address ? toChecksum(c.options.address) : void 0;
5836
+ const [proposalsResult, threadsResult, commentsResult, petitionsResult, membersResult] = await Promise.allSettled([
5837
+ fetchAllProposals(client),
5838
+ fetchAllThreads(client),
5839
+ fetchAllComments(client),
5840
+ fetchAllPetitions(client),
5841
+ fetchMemberList(client, c.env.ASSEMBLY_INDEXER_URL)
5842
+ ]);
5843
+ let proposals = [];
5844
+ if (proposalsResult.status === "fulfilled") {
5845
+ proposals = proposalsResult.value;
5846
+ } else {
5847
+ errors.push(`proposals: ${proposalsResult.reason}`);
5848
+ }
5849
+ let threads = [];
5850
+ if (threadsResult.status === "fulfilled") {
5851
+ threads = threadsResult.value;
5852
+ } else {
5853
+ errors.push(`threads: ${threadsResult.reason}`);
5854
+ }
5855
+ let comments = [];
5856
+ if (commentsResult.status === "fulfilled") {
5857
+ comments = commentsResult.value;
5858
+ } else {
5859
+ errors.push(`comments: ${commentsResult.reason}`);
5860
+ }
5861
+ let petitions = [];
5862
+ if (petitionsResult.status === "fulfilled") {
5863
+ petitions = petitionsResult.value;
5864
+ } else {
5865
+ errors.push(`petitions: ${petitionsResult.reason}`);
5866
+ }
5867
+ let memberIdentities = [];
5868
+ if (membersResult.status === "fulfilled") {
5869
+ const loaded = membersResult.value;
5870
+ memberIdentities = loaded.members;
5871
+ if (loaded.fallbackReason) {
5872
+ process.stderr.write(
5873
+ `${JSON.stringify({
5874
+ level: "warn",
5875
+ code: loaded.fallbackReason.code,
5876
+ message: "Member snapshot indexer is unavailable. Falling back to on-chain Registered events.",
5877
+ url: loaded.fallbackReason.url
5878
+ })}
5879
+ `
5880
+ );
5881
+ }
5882
+ } else {
5883
+ const err = membersResult.reason;
5884
+ if (err instanceof AssemblyApiValidationError) {
5885
+ errors.push(`members: ${err.details.code}`);
5886
+ } else {
5887
+ errors.push(`members: ${err}`);
5888
+ }
5889
+ }
5890
+ let memberItems = [];
5891
+ if (memberIdentities.length > 0) {
5892
+ try {
5893
+ const onchainStates = await fetchMemberOnchainState(
5894
+ client,
5895
+ memberIdentities.map((m) => m.address)
5896
+ );
5897
+ memberItems = onchainStates.map((s) => ({
5898
+ address: s.address,
5899
+ active: s.active,
5900
+ registered: s.registered,
5901
+ activeUntil: isoTime(s.activeUntil),
5902
+ lastHeartbeatAt: isoTime(s.lastHeartbeatAt)
5903
+ }));
5904
+ } catch (err) {
5905
+ errors.push(`members onchain state: ${err}`);
5906
+ }
5907
+ }
5908
+ let hasVotedMap = /* @__PURE__ */ new Map();
5909
+ let hasSignedMap = /* @__PURE__ */ new Map();
5910
+ if (address) {
5911
+ const [votedResult, signedResult] = await Promise.allSettled([
5912
+ fetchHasVotedBatch(
5913
+ client,
5914
+ address,
5915
+ proposals.map((_, i) => i + 1)
5916
+ ),
5917
+ fetchHasSignedBatch(
5918
+ client,
5919
+ address,
5920
+ petitions.map((p) => p.id)
5921
+ )
5922
+ ]);
5923
+ if (votedResult.status === "fulfilled") {
5924
+ hasVotedMap = votedResult.value;
5925
+ } else {
5926
+ errors.push(`hasVoted enrichment: ${votedResult.reason}`);
5927
+ }
5928
+ if (signedResult.status === "fulfilled") {
5929
+ hasSignedMap = signedResult.value;
5930
+ } else {
5931
+ errors.push(`hasSigned enrichment: ${signedResult.reason}`);
5932
+ }
5933
+ }
5934
+ const serializedProposals = proposals.map((p, i) => {
5935
+ const serialized = serializeProposal(p);
5936
+ const entry = {
5937
+ id: i + 1,
5938
+ ...serialized
5939
+ };
5940
+ if (address) {
5941
+ entry.hasVoted = hasVotedMap.get(i + 1) ?? false;
5942
+ }
5943
+ return entry;
5944
+ });
5945
+ const serializedThreads = threads.map((t) => ({
5946
+ id: t.id,
5947
+ kind: t.kind,
5948
+ author: t.author,
5949
+ createdAt: t.createdAt,
5950
+ category: t.category,
5951
+ title: t.title,
5952
+ proposalId: t.proposalId,
5953
+ petitionId: t.petitionId
5954
+ }));
5955
+ const serializedComments = comments.map((cm) => ({
5956
+ id: cm.id,
5957
+ threadId: cm.threadId,
5958
+ parentId: cm.parentId,
5959
+ author: cm.author,
5960
+ createdAt: cm.createdAt,
5961
+ body: cm.body
5962
+ }));
5963
+ const serializedPetitions = petitions.map((p) => {
5964
+ const entry = {
5965
+ id: p.id,
5966
+ proposer: p.proposer,
5967
+ createdAt: p.createdAt,
5968
+ category: p.category,
5969
+ title: p.title,
5970
+ body: p.body,
5971
+ signatures: p.signatures,
5972
+ promoted: p.promoted,
5973
+ threadId: p.threadId
5974
+ };
5975
+ if (address) {
5976
+ entry.hasSigned = hasSignedMap.get(p.id) ?? false;
5977
+ }
5978
+ return entry;
5979
+ });
5980
+ const output = {
5981
+ meta: {
5982
+ chainId: 2741,
5983
+ fetchedAt: (/* @__PURE__ */ new Date()).toISOString().replace(".000Z", "Z"),
5984
+ ...address ? { address } : {}
5985
+ },
5986
+ proposals: serializedProposals,
5987
+ threads: serializedThreads,
5988
+ comments: serializedComments,
5989
+ petitions: serializedPetitions,
5990
+ members: {
5991
+ count: memberItems.length,
5992
+ items: memberItems
5993
+ },
5994
+ errors
5995
+ };
5996
+ return c.ok(output);
5997
+ });
5998
+ }
5999
+ });
6000
+ }
6001
+
6002
+ // src/commands/forum.ts
6003
+ import { TxError } from "@spectratools/tx-shared";
6004
+ import { Cli as Cli2, z as z5 } from "incur";
6005
+ var env2 = z5.object({
6006
+ ABSTRACT_RPC_URL: z5.string().optional().describe("Abstract RPC URL override")
6007
+ });
6008
+ var commentEnv = env2.extend({
6009
+ PRIVATE_KEY: z5.string().optional().describe("Private key (required only when posting a comment via --body)")
6010
+ });
6011
+ var timestampOutput2 = z5.union([z5.number(), z5.string()]);
6012
+ var txResultOutput2 = z5.union([
6013
+ z5.object({
6014
+ status: z5.literal("success"),
6015
+ hash: z5.string(),
6016
+ blockNumber: z5.number(),
6017
+ gasUsed: z5.string(),
6018
+ from: z5.string(),
6019
+ to: z5.string().nullable(),
6020
+ effectiveGasPrice: z5.string().optional()
6021
+ }),
6022
+ z5.object({
6023
+ status: z5.literal("reverted"),
6024
+ hash: z5.string(),
6025
+ blockNumber: z5.number(),
6026
+ gasUsed: z5.string(),
6027
+ from: z5.string(),
6028
+ to: z5.string().nullable(),
6029
+ effectiveGasPrice: z5.string().optional()
6030
+ }),
6031
+ z5.object({
6032
+ status: z5.literal("dry-run"),
6033
+ estimatedGas: z5.string(),
6034
+ simulationResult: z5.unknown()
6035
+ })
6036
+ ]);
5335
6037
  var forum = Cli2.create("forum", {
5336
6038
  description: "Browse Assembly forum threads, comments, and petitions."
5337
6039
  });
5338
6040
  forum.command("threads", {
5339
6041
  description: "List forum threads with author and creation metadata.",
5340
6042
  env: env2,
5341
- output: z3.object({
5342
- threads: z3.array(
5343
- z3.object({
5344
- id: z3.number(),
5345
- kind: z3.number(),
5346
- author: z3.string(),
6043
+ output: z5.object({
6044
+ threads: z5.array(
6045
+ z5.object({
6046
+ id: z5.number(),
6047
+ kind: z5.number(),
6048
+ author: z5.string(),
5347
6049
  createdAt: timestampOutput2,
5348
- createdAtRelative: z3.string(),
5349
- category: z3.string().nullable().optional(),
5350
- title: z3.string().nullable().optional()
6050
+ createdAtRelative: z5.string(),
6051
+ category: z5.string().nullable().optional(),
6052
+ title: z5.string().nullable().optional()
5351
6053
  })
5352
6054
  ),
5353
- count: z3.number()
6055
+ count: z5.number()
5354
6056
  }),
5355
6057
  examples: [{ description: "List all forum threads" }],
5356
6058
  async run(c) {
5357
6059
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
5358
- const count = await client.readContract({
5359
- abi: forumAbi,
5360
- address: ABSTRACT_MAINNET_ADDRESSES.forum,
5361
- functionName: "threadCount"
5362
- });
5363
- const ids = Array.from({ length: Number(count) }, (_, i) => BigInt(i + 1));
5364
- const threadTuples = ids.length ? await client.multicall({
5365
- allowFailure: false,
5366
- contracts: ids.map((id) => ({
5367
- abi: forumAbi,
5368
- address: ABSTRACT_MAINNET_ADDRESSES.forum,
5369
- functionName: "threads",
5370
- args: [id]
5371
- }))
5372
- }) : [];
5373
- const items = threadTuples.map(decodeThread);
6060
+ const items = await fetchAllThreads(client);
5374
6061
  const threads = items.map((x) => ({
5375
6062
  id: x.id,
5376
6063
  kind: x.kind,
@@ -5399,13 +6086,13 @@ forum.command("threads", {
5399
6086
  });
5400
6087
  forum.command("thread", {
5401
6088
  description: "Get one thread and all comments associated with it.",
5402
- args: z3.object({
5403
- id: z3.coerce.number().int().positive().describe("Thread id (1-indexed)")
6089
+ args: z5.object({
6090
+ id: z5.coerce.number().int().positive().describe("Thread id (1-indexed)")
5404
6091
  }),
5405
6092
  env: env2,
5406
- output: z3.object({
5407
- thread: z3.record(z3.string(), z3.unknown()),
5408
- comments: z3.array(z3.record(z3.string(), z3.unknown()))
6093
+ output: z5.object({
6094
+ thread: z5.record(z5.string(), z5.unknown()),
6095
+ comments: z5.array(z5.record(z5.string(), z5.unknown()))
5409
6096
  }),
5410
6097
  examples: [{ args: { id: 1 }, description: "Fetch thread #1 and its comments" }],
5411
6098
  async run(c) {
@@ -5422,31 +6109,14 @@ forum.command("thread", {
5422
6109
  retryable: false
5423
6110
  });
5424
6111
  }
5425
- const [threadTuple, commentCount] = await Promise.all([
5426
- client.readContract({
5427
- abi: forumAbi,
5428
- address: ABSTRACT_MAINNET_ADDRESSES.forum,
5429
- functionName: "threads",
5430
- args: [BigInt(c.args.id)]
5431
- }),
5432
- client.readContract({
5433
- abi: forumAbi,
5434
- address: ABSTRACT_MAINNET_ADDRESSES.forum,
5435
- functionName: "commentCount"
5436
- })
5437
- ]);
6112
+ const threadTuple = await client.readContract({
6113
+ abi: forumAbi,
6114
+ address: ABSTRACT_MAINNET_ADDRESSES.forum,
6115
+ functionName: "threads",
6116
+ args: [BigInt(c.args.id)]
6117
+ });
5438
6118
  const thread = decodeThread(threadTuple);
5439
- const ids = Array.from({ length: Number(commentCount) }, (_, i) => BigInt(i + 1));
5440
- const commentTuples = ids.length ? await client.multicall({
5441
- allowFailure: false,
5442
- contracts: ids.map((id) => ({
5443
- abi: forumAbi,
5444
- address: ABSTRACT_MAINNET_ADDRESSES.forum,
5445
- functionName: "comments",
5446
- args: [id]
5447
- }))
5448
- }) : [];
5449
- const comments = commentTuples.map(decodeComment);
6119
+ const comments = await fetchAllComments(client);
5450
6120
  return c.ok({
5451
6121
  thread: jsonSafe(thread),
5452
6122
  comments: comments.filter((x) => x.threadId === c.args.id).map((comment) => jsonSafe(comment))
@@ -5455,30 +6125,15 @@ forum.command("thread", {
5455
6125
  });
5456
6126
  forum.command("comments", {
5457
6127
  description: "List comments for a thread id.",
5458
- args: z3.object({
5459
- threadId: z3.coerce.number().int().positive().describe("Thread id to filter comments by")
6128
+ args: z5.object({
6129
+ threadId: z5.coerce.number().int().positive().describe("Thread id to filter comments by")
5460
6130
  }),
5461
6131
  env: env2,
5462
- output: z3.array(z3.record(z3.string(), z3.unknown())),
6132
+ output: z5.array(z5.record(z5.string(), z5.unknown())),
5463
6133
  examples: [{ args: { threadId: 1 }, description: "List comments for thread #1" }],
5464
6134
  async run(c) {
5465
6135
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
5466
- const count = await client.readContract({
5467
- abi: forumAbi,
5468
- address: ABSTRACT_MAINNET_ADDRESSES.forum,
5469
- functionName: "commentCount"
5470
- });
5471
- const ids = Array.from({ length: Number(count) }, (_, i) => BigInt(i + 1));
5472
- const commentTuples = ids.length ? await client.multicall({
5473
- allowFailure: false,
5474
- contracts: ids.map((id) => ({
5475
- abi: forumAbi,
5476
- address: ABSTRACT_MAINNET_ADDRESSES.forum,
5477
- functionName: "comments",
5478
- args: [id]
5479
- }))
5480
- }) : [];
5481
- const comments = commentTuples.map(decodeComment);
6136
+ const comments = await fetchAllComments(client);
5482
6137
  return c.ok(
5483
6138
  comments.filter((x) => x.threadId === c.args.threadId).map((comment) => jsonSafe(comment))
5484
6139
  );
@@ -5486,15 +6141,15 @@ forum.command("comments", {
5486
6141
  });
5487
6142
  forum.command("comment", {
5488
6143
  description: "Get one comment by id, or post to a thread when --body is provided.",
5489
- args: z3.object({
5490
- id: z3.coerce.number().int().positive().describe("Comment id (read) or thread id (write)")
6144
+ args: z5.object({
6145
+ id: z5.coerce.number().int().positive().describe("Comment id (read) or thread id (write)")
5491
6146
  }),
5492
6147
  options: writeOptions.extend({
5493
- body: z3.string().min(1).optional().describe("Comment body (write mode)"),
5494
- "parent-id": z3.coerce.number().int().nonnegative().default(0).describe("Optional parent comment id for threaded replies (write mode)")
6148
+ body: z5.string().min(1).optional().describe("Comment body (write mode)"),
6149
+ "parent-id": z5.coerce.number().int().nonnegative().default(0).describe("Optional parent comment id for threaded replies (write mode)")
5495
6150
  }),
5496
6151
  env: commentEnv,
5497
- output: z3.record(z3.string(), z3.unknown()),
6152
+ output: z5.record(z5.string(), z5.unknown()),
5498
6153
  examples: [
5499
6154
  { args: { id: 1 }, description: "Fetch comment #1" },
5500
6155
  {
@@ -5609,16 +6264,16 @@ forum.command("post", {
5609
6264
  description: "Create a new discussion thread in the forum.",
5610
6265
  hint: "Requires PRIVATE_KEY environment variable for signing.",
5611
6266
  options: writeOptions.extend({
5612
- category: z3.string().min(1).describe("Thread category label (e.g., general, governance)"),
5613
- title: z3.string().min(1).describe("Thread title"),
5614
- body: z3.string().min(1).describe("Thread body")
6267
+ category: z5.string().min(1).describe("Thread category label (e.g., general, governance)"),
6268
+ title: z5.string().min(1).describe("Thread title"),
6269
+ body: z5.string().min(1).describe("Thread body")
5615
6270
  }),
5616
6271
  env: writeEnv,
5617
- output: z3.object({
5618
- author: z3.string(),
5619
- category: z3.string(),
5620
- title: z3.string(),
5621
- expectedThreadId: z3.number(),
6272
+ output: z5.object({
6273
+ author: z5.string(),
6274
+ category: z5.string(),
6275
+ title: z5.string(),
6276
+ expectedThreadId: z5.number(),
5622
6277
  tx: txResultOutput2
5623
6278
  }),
5624
6279
  examples: [
@@ -5686,19 +6341,19 @@ forum.command("post", {
5686
6341
  forum.command("post-comment", {
5687
6342
  description: "Post a comment to a forum thread.",
5688
6343
  hint: "Requires PRIVATE_KEY environment variable for signing.",
5689
- args: z3.object({
5690
- threadId: z3.coerce.number().int().positive().describe("Thread id to comment on")
6344
+ args: z5.object({
6345
+ threadId: z5.coerce.number().int().positive().describe("Thread id to comment on")
5691
6346
  }),
5692
6347
  options: writeOptions.extend({
5693
- body: z3.string().min(1).describe("Comment body"),
5694
- "parent-id": z3.coerce.number().int().nonnegative().default(0).describe("Optional parent comment id for threaded replies")
6348
+ body: z5.string().min(1).describe("Comment body"),
6349
+ "parent-id": z5.coerce.number().int().nonnegative().default(0).describe("Optional parent comment id for threaded replies")
5695
6350
  }),
5696
6351
  env: writeEnv,
5697
- output: z3.object({
5698
- author: z3.string(),
5699
- threadId: z3.number(),
5700
- parentId: z3.number(),
5701
- expectedCommentId: z3.number(),
6352
+ output: z5.object({
6353
+ author: z5.string(),
6354
+ threadId: z5.number(),
6355
+ parentId: z5.number(),
6356
+ expectedCommentId: z5.number(),
5702
6357
  tx: txResultOutput2
5703
6358
  }),
5704
6359
  examples: [
@@ -5785,20 +6440,20 @@ forum.command("create-petition", {
5785
6440
  description: "Create a new petition for community-initiated proposals.",
5786
6441
  hint: "Requires PRIVATE_KEY environment variable for signing.",
5787
6442
  options: writeOptions.extend({
5788
- title: z3.string().min(1).describe("Petition title"),
5789
- description: z3.string().min(1).describe("Petition description"),
5790
- kind: z3.coerce.number().int().nonnegative().max(255).describe("Proposal kind enum value"),
5791
- category: z3.string().default("governance").describe("Forum category label for the petition")
6443
+ title: z5.string().min(1).describe("Petition title"),
6444
+ description: z5.string().min(1).describe("Petition description"),
6445
+ kind: z5.coerce.number().int().nonnegative().max(255).describe("Proposal kind enum value"),
6446
+ category: z5.string().default("governance").describe("Forum category label for the petition")
5792
6447
  }),
5793
6448
  env: writeEnv,
5794
- output: z3.object({
5795
- proposer: z3.string(),
5796
- category: z3.string(),
5797
- kind: z3.number(),
5798
- title: z3.string(),
5799
- description: z3.string(),
5800
- expectedPetitionId: z3.number(),
5801
- expectedThreadId: z3.number(),
6449
+ output: z5.object({
6450
+ proposer: z5.string(),
6451
+ category: z5.string(),
6452
+ kind: z5.number(),
6453
+ title: z5.string(),
6454
+ description: z5.string(),
6455
+ expectedPetitionId: z5.number(),
6456
+ expectedThreadId: z5.number(),
5802
6457
  tx: txResultOutput2
5803
6458
  }),
5804
6459
  examples: [
@@ -5901,15 +6556,15 @@ forum.command("create-petition", {
5901
6556
  forum.command("sign-petition", {
5902
6557
  description: "Sign an existing petition as an active member.",
5903
6558
  hint: "Requires PRIVATE_KEY environment variable for signing.",
5904
- args: z3.object({
5905
- petitionId: z3.coerce.number().int().positive().describe("Petition id (1-indexed)")
6559
+ args: z5.object({
6560
+ petitionId: z5.coerce.number().int().positive().describe("Petition id (1-indexed)")
5906
6561
  }),
5907
6562
  options: writeOptions,
5908
6563
  env: writeEnv,
5909
- output: z3.object({
5910
- signer: z3.string(),
5911
- petitionId: z3.number(),
5912
- expectedSignatures: z3.number(),
6564
+ output: z5.object({
6565
+ signer: z5.string(),
6566
+ petitionId: z5.number(),
6567
+ expectedSignatures: z5.number(),
5913
6568
  tx: txResultOutput2
5914
6569
  }),
5915
6570
  examples: [{ args: { petitionId: 1 }, description: "Sign petition #1" }],
@@ -5996,36 +6651,21 @@ forum.command("sign-petition", {
5996
6651
  forum.command("petitions", {
5997
6652
  description: "List petitions submitted in the forum contract.",
5998
6653
  env: env2,
5999
- output: z3.array(z3.record(z3.string(), z3.unknown())),
6654
+ output: z5.array(z5.record(z5.string(), z5.unknown())),
6000
6655
  examples: [{ description: "List all petitions" }],
6001
6656
  async run(c) {
6002
6657
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
6003
- const count = await client.readContract({
6004
- abi: forumAbi,
6005
- address: ABSTRACT_MAINNET_ADDRESSES.forum,
6006
- functionName: "petitionCount"
6007
- });
6008
- const ids = Array.from({ length: Number(count) }, (_, i) => BigInt(i + 1));
6009
- const petitionTuples = ids.length ? await client.multicall({
6010
- allowFailure: false,
6011
- contracts: ids.map((id) => ({
6012
- abi: forumAbi,
6013
- address: ABSTRACT_MAINNET_ADDRESSES.forum,
6014
- functionName: "petitions",
6015
- args: [id]
6016
- }))
6017
- }) : [];
6018
- const petitions = petitionTuples.map(decodePetition);
6658
+ const petitions = await fetchAllPetitions(client);
6019
6659
  return c.ok(petitions.map((petition) => jsonSafe(petition)));
6020
6660
  }
6021
6661
  });
6022
6662
  forum.command("petition", {
6023
6663
  description: "Get one petition plus whether proposer already signed it.",
6024
- args: z3.object({
6025
- id: z3.coerce.number().int().positive().describe("Petition id (1-indexed)")
6664
+ args: z5.object({
6665
+ id: z5.coerce.number().int().positive().describe("Petition id (1-indexed)")
6026
6666
  }),
6027
6667
  env: env2,
6028
- output: z3.object({ proposerSigned: z3.boolean() }).passthrough(),
6668
+ output: z5.object({ proposerSigned: z5.boolean() }).passthrough(),
6029
6669
  examples: [{ args: { id: 1 }, description: "Fetch petition #1" }],
6030
6670
  async run(c) {
6031
6671
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
@@ -6060,15 +6700,15 @@ forum.command("petition", {
6060
6700
  });
6061
6701
  forum.command("has-signed", {
6062
6702
  description: "Check whether an address signed a petition.",
6063
- args: z3.object({
6064
- petitionId: z3.coerce.number().int().positive().describe("Petition id (1-indexed)"),
6065
- address: z3.string().describe("Signer address to check")
6703
+ args: z5.object({
6704
+ petitionId: z5.coerce.number().int().positive().describe("Petition id (1-indexed)"),
6705
+ address: z5.string().describe("Signer address to check")
6066
6706
  }),
6067
6707
  env: env2,
6068
- output: z3.object({
6069
- petitionId: z3.number(),
6070
- address: z3.string(),
6071
- hasSigned: z3.boolean()
6708
+ output: z5.object({
6709
+ petitionId: z5.number(),
6710
+ address: z5.string(),
6711
+ hasSigned: z5.boolean()
6072
6712
  }),
6073
6713
  examples: [
6074
6714
  {
@@ -6093,61 +6733,26 @@ forum.command("has-signed", {
6093
6733
  forum.command("stats", {
6094
6734
  description: "Read top-level forum counters and petition threshold.",
6095
6735
  env: env2,
6096
- output: z3.object({
6097
- threadCount: z3.number(),
6098
- commentCount: z3.number(),
6099
- petitionCount: z3.number(),
6100
- petitionThresholdBps: z3.number()
6736
+ output: z5.object({
6737
+ threadCount: z5.number(),
6738
+ commentCount: z5.number(),
6739
+ petitionCount: z5.number(),
6740
+ petitionThresholdBps: z5.number()
6101
6741
  }),
6102
6742
  examples: [{ description: "Get forum counts and petition threshold" }],
6103
6743
  async run(c) {
6104
6744
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
6105
- const [threadCount, commentCount, petitionCount, petitionThresholdBps] = await Promise.all([
6106
- client.readContract({
6107
- abi: forumAbi,
6108
- address: ABSTRACT_MAINNET_ADDRESSES.forum,
6109
- functionName: "threadCount"
6110
- }),
6111
- client.readContract({
6112
- abi: forumAbi,
6113
- address: ABSTRACT_MAINNET_ADDRESSES.forum,
6114
- functionName: "commentCount"
6115
- }),
6116
- client.readContract({
6117
- abi: forumAbi,
6118
- address: ABSTRACT_MAINNET_ADDRESSES.forum,
6119
- functionName: "petitionCount"
6120
- }),
6121
- client.readContract({
6122
- abi: forumAbi,
6123
- address: ABSTRACT_MAINNET_ADDRESSES.forum,
6124
- functionName: "petitionThresholdBps"
6125
- })
6126
- ]);
6127
- return c.ok({
6128
- threadCount: asNum(threadCount),
6129
- commentCount: asNum(commentCount),
6130
- petitionCount: asNum(petitionCount),
6131
- petitionThresholdBps: asNum(petitionThresholdBps)
6132
- });
6745
+ return c.ok(await fetchForumStats(client));
6133
6746
  }
6134
6747
  });
6135
6748
 
6136
6749
  // src/commands/governance.ts
6137
6750
  import { TxError as TxError2 } from "@spectratools/tx-shared";
6138
- import { Cli as Cli3, z as z4 } from "incur";
6139
- var env3 = z4.object({
6140
- ABSTRACT_RPC_URL: z4.string().optional().describe("Abstract RPC URL override")
6751
+ import { Cli as Cli3, z as z6 } from "incur";
6752
+ var env3 = z6.object({
6753
+ ABSTRACT_RPC_URL: z6.string().optional().describe("Abstract RPC URL override")
6141
6754
  });
6142
- var timestampOutput3 = z4.union([z4.number(), z4.string()]);
6143
- var proposalStatusLabels = {
6144
- 0: "pending",
6145
- 1: "active",
6146
- 2: "passed",
6147
- 3: "executed",
6148
- 4: "defeated",
6149
- 5: "cancelled"
6150
- };
6755
+ var timestampOutput3 = z6.union([z6.number(), z6.string()]);
6151
6756
  var PROPOSAL_STATUS_PENDING = 0;
6152
6757
  var PROPOSAL_STATUS_ACTIVE = 1;
6153
6758
  var PROPOSAL_STATUS_PASSED = 2;
@@ -6156,176 +6761,56 @@ var supportChoiceToValue = {
6156
6761
  for: 1,
6157
6762
  abstain: 2
6158
6763
  };
6159
- function proposalStatus(status) {
6160
- const statusCode = asNum(status);
6161
- return {
6162
- status: proposalStatusLabels[statusCode] ?? `unknown-${statusCode}`,
6163
- statusCode
6164
- };
6165
- }
6166
- var proposalOutputSchema = z4.object({
6167
- kind: z4.number(),
6168
- configRiskTier: z4.number(),
6169
- origin: z4.number(),
6170
- status: z4.string(),
6171
- statusCode: z4.number(),
6172
- proposer: z4.string(),
6173
- threadId: z4.number(),
6174
- petitionId: z4.number(),
6175
- createdAt: z4.number(),
6176
- deliberationEndsAt: z4.number(),
6177
- voteStartAt: z4.number(),
6178
- voteEndAt: z4.number(),
6179
- timelockEndsAt: z4.number(),
6180
- activeSeatsSnapshot: z4.number(),
6181
- forVotes: z4.string(),
6182
- againstVotes: z4.string(),
6183
- abstainVotes: z4.string(),
6184
- amount: z4.string(),
6185
- snapshotAssetBalance: z4.string(),
6186
- transferIntent: z4.boolean(),
6187
- intentDeadline: z4.number(),
6188
- intentMaxRiskTier: z4.number(),
6189
- title: z4.string(),
6190
- description: z4.string()
6764
+ var proposalOutputSchema = z6.object({
6765
+ kind: z6.number(),
6766
+ configRiskTier: z6.number(),
6767
+ origin: z6.number(),
6768
+ status: z6.string(),
6769
+ statusCode: z6.number(),
6770
+ proposer: z6.string(),
6771
+ threadId: z6.number(),
6772
+ petitionId: z6.number(),
6773
+ createdAt: z6.number(),
6774
+ deliberationEndsAt: z6.number(),
6775
+ voteStartAt: z6.number(),
6776
+ voteEndAt: z6.number(),
6777
+ timelockEndsAt: z6.number(),
6778
+ activeSeatsSnapshot: z6.number(),
6779
+ forVotes: z6.string(),
6780
+ againstVotes: z6.string(),
6781
+ abstainVotes: z6.string(),
6782
+ amount: z6.string(),
6783
+ snapshotAssetBalance: z6.string(),
6784
+ transferIntent: z6.boolean(),
6785
+ intentDeadline: z6.number(),
6786
+ intentMaxRiskTier: z6.number(),
6787
+ title: z6.string(),
6788
+ description: z6.string()
6191
6789
  });
6192
- function decodeProposal(value) {
6193
- const [
6194
- kind,
6195
- configRiskTier,
6196
- origin,
6197
- status,
6198
- proposer,
6199
- threadId,
6200
- petitionId,
6201
- createdAt,
6202
- deliberationEndsAt,
6203
- voteStartAt,
6204
- voteEndAt,
6205
- timelockEndsAt,
6206
- activeSeatsSnapshot,
6207
- forVotes,
6208
- againstVotes,
6209
- abstainVotes,
6210
- amount,
6211
- snapshotAssetBalance,
6212
- transferIntent,
6213
- intentDeadline,
6214
- intentMaxRiskTier,
6215
- title,
6216
- description
6217
- ] = value;
6218
- return {
6219
- kind,
6220
- configRiskTier,
6221
- origin,
6222
- status,
6223
- proposer: toChecksum(proposer),
6224
- threadId,
6225
- petitionId,
6226
- createdAt,
6227
- deliberationEndsAt,
6228
- voteStartAt,
6229
- voteEndAt,
6230
- timelockEndsAt,
6231
- activeSeatsSnapshot,
6232
- forVotes,
6233
- againstVotes,
6234
- abstainVotes,
6235
- amount,
6236
- snapshotAssetBalance,
6237
- transferIntent,
6238
- intentDeadline,
6239
- intentMaxRiskTier,
6240
- title,
6241
- description
6242
- };
6243
- }
6244
- function serializeProposal(proposal) {
6245
- const status = proposalStatus(proposal.status);
6246
- return {
6247
- kind: asNum(proposal.kind),
6248
- configRiskTier: asNum(proposal.configRiskTier),
6249
- origin: asNum(proposal.origin),
6250
- status: status.status,
6251
- statusCode: status.statusCode,
6252
- proposer: proposal.proposer,
6253
- threadId: asNum(proposal.threadId),
6254
- petitionId: asNum(proposal.petitionId),
6255
- createdAt: asNum(proposal.createdAt),
6256
- deliberationEndsAt: asNum(proposal.deliberationEndsAt),
6257
- voteStartAt: asNum(proposal.voteStartAt),
6258
- voteEndAt: asNum(proposal.voteEndAt),
6259
- timelockEndsAt: asNum(proposal.timelockEndsAt),
6260
- activeSeatsSnapshot: asNum(proposal.activeSeatsSnapshot),
6261
- forVotes: proposal.forVotes.toString(),
6262
- againstVotes: proposal.againstVotes.toString(),
6263
- abstainVotes: proposal.abstainVotes.toString(),
6264
- amount: proposal.amount.toString(),
6265
- snapshotAssetBalance: proposal.snapshotAssetBalance.toString(),
6266
- transferIntent: proposal.transferIntent,
6267
- intentDeadline: asNum(proposal.intentDeadline),
6268
- intentMaxRiskTier: asNum(proposal.intentMaxRiskTier),
6269
- title: proposal.title,
6270
- description: proposal.description
6271
- };
6272
- }
6273
- async function readProposalCount(client) {
6274
- return await client.readContract({
6275
- abi: governanceAbi,
6276
- address: ABSTRACT_MAINNET_ADDRESSES.governance,
6277
- functionName: "proposalCount"
6278
- });
6279
- }
6280
- async function readProposalById(client, proposalId) {
6281
- return decodeProposal(
6282
- await client.readContract({
6283
- abi: governanceAbi,
6284
- address: ABSTRACT_MAINNET_ADDRESSES.governance,
6285
- functionName: "proposals",
6286
- args: [BigInt(proposalId)]
6287
- })
6288
- );
6289
- }
6290
6790
  var governance = Cli3.create("governance", {
6291
6791
  description: "Inspect Assembly governance proposals, votes, and parameters."
6292
6792
  });
6293
6793
  governance.command("proposals", {
6294
6794
  description: "List governance proposals with status and vote end time.",
6295
6795
  env: env3,
6296
- output: z4.object({
6297
- proposals: z4.array(
6298
- z4.object({
6299
- id: z4.number(),
6300
- kind: z4.number(),
6301
- status: z4.string(),
6302
- statusCode: z4.number(),
6303
- title: z4.string().nullable().optional(),
6796
+ output: z6.object({
6797
+ proposals: z6.array(
6798
+ z6.object({
6799
+ id: z6.number(),
6800
+ kind: z6.number(),
6801
+ status: z6.string(),
6802
+ statusCode: z6.number(),
6803
+ title: z6.string().nullable().optional(),
6304
6804
  voteEndAt: timestampOutput3,
6305
- voteEndRelative: z4.string()
6805
+ voteEndRelative: z6.string()
6306
6806
  })
6307
- ),
6308
- count: z4.number()
6309
- }),
6310
- examples: [{ description: "List all proposals" }],
6311
- async run(c) {
6312
- const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
6313
- const count = await client.readContract({
6314
- abi: governanceAbi,
6315
- address: ABSTRACT_MAINNET_ADDRESSES.governance,
6316
- functionName: "proposalCount"
6317
- });
6318
- const ids = Array.from({ length: Number(count) }, (_, i) => BigInt(i + 1));
6319
- const proposalTuples = ids.length ? await client.multicall({
6320
- allowFailure: false,
6321
- contracts: ids.map((id) => ({
6322
- abi: governanceAbi,
6323
- address: ABSTRACT_MAINNET_ADDRESSES.governance,
6324
- functionName: "proposals",
6325
- args: [id]
6326
- }))
6327
- }) : [];
6328
- const proposals = proposalTuples.map(decodeProposal);
6807
+ ),
6808
+ count: z6.number()
6809
+ }),
6810
+ examples: [{ description: "List all proposals" }],
6811
+ async run(c) {
6812
+ const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
6813
+ const proposals = await fetchAllProposals(client);
6329
6814
  const items = proposals.map((p, i) => ({
6330
6815
  ...proposalStatus(p.status),
6331
6816
  id: i + 1,
@@ -6356,19 +6841,15 @@ governance.command("proposals", {
6356
6841
  });
6357
6842
  governance.command("proposal", {
6358
6843
  description: "Get full raw proposal details by proposal id.",
6359
- args: z4.object({
6360
- id: z4.coerce.number().int().positive().describe("Proposal id (1-indexed)")
6844
+ args: z6.object({
6845
+ id: z6.coerce.number().int().positive().describe("Proposal id (1-indexed)")
6361
6846
  }),
6362
6847
  env: env3,
6363
6848
  output: proposalOutputSchema,
6364
6849
  examples: [{ args: { id: 1 }, description: "Fetch proposal #1" }],
6365
6850
  async run(c) {
6366
6851
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
6367
- const proposalCount = await client.readContract({
6368
- abi: governanceAbi,
6369
- address: ABSTRACT_MAINNET_ADDRESSES.governance,
6370
- functionName: "proposalCount"
6371
- });
6852
+ const proposalCount = await fetchProposalCount(client);
6372
6853
  if (c.args.id > Number(proposalCount)) {
6373
6854
  return c.error({
6374
6855
  code: "OUT_OF_RANGE",
@@ -6376,28 +6857,21 @@ governance.command("proposal", {
6376
6857
  retryable: false
6377
6858
  });
6378
6859
  }
6379
- const proposal = decodeProposal(
6380
- await client.readContract({
6381
- abi: governanceAbi,
6382
- address: ABSTRACT_MAINNET_ADDRESSES.governance,
6383
- functionName: "proposals",
6384
- args: [BigInt(c.args.id)]
6385
- })
6386
- );
6860
+ const proposal = await fetchProposalById(client, c.args.id);
6387
6861
  return c.ok(serializeProposal(proposal));
6388
6862
  }
6389
6863
  });
6390
6864
  governance.command("has-voted", {
6391
6865
  description: "Check if an address has voted on a proposal.",
6392
- args: z4.object({
6393
- proposalId: z4.coerce.number().int().positive().describe("Proposal id (1-indexed)"),
6394
- address: z4.string().describe("Voter address")
6866
+ args: z6.object({
6867
+ proposalId: z6.coerce.number().int().positive().describe("Proposal id (1-indexed)"),
6868
+ address: z6.string().describe("Voter address")
6395
6869
  }),
6396
6870
  env: env3,
6397
- output: z4.object({
6398
- proposalId: z4.number(),
6399
- address: z4.string(),
6400
- hasVoted: z4.boolean()
6871
+ output: z6.object({
6872
+ proposalId: z6.number(),
6873
+ address: z6.string(),
6874
+ hasVoted: z6.boolean()
6401
6875
  }),
6402
6876
  examples: [
6403
6877
  {
@@ -6426,19 +6900,19 @@ governance.command("has-voted", {
6426
6900
  governance.command("params", {
6427
6901
  description: "Read governance threshold and timing parameters.",
6428
6902
  env: env3,
6429
- output: z4.object({
6430
- deliberationPeriod: z4.number(),
6431
- votePeriod: z4.number(),
6432
- quorumBps: z4.number(),
6433
- constitutionalDeliberationPeriod: z4.number(),
6434
- constitutionalVotePeriod: z4.number(),
6435
- constitutionalPassBps: z4.number(),
6436
- majorPassBps: z4.number(),
6437
- parameterPassBps: z4.number(),
6438
- significantPassBps: z4.number(),
6439
- significantThresholdBps: z4.number(),
6440
- routineThresholdBps: z4.number(),
6441
- timelockPeriod: z4.number()
6903
+ output: z6.object({
6904
+ deliberationPeriod: z6.number(),
6905
+ votePeriod: z6.number(),
6906
+ quorumBps: z6.number(),
6907
+ constitutionalDeliberationPeriod: z6.number(),
6908
+ constitutionalVotePeriod: z6.number(),
6909
+ constitutionalPassBps: z6.number(),
6910
+ majorPassBps: z6.number(),
6911
+ parameterPassBps: z6.number(),
6912
+ significantPassBps: z6.number(),
6913
+ significantThresholdBps: z6.number(),
6914
+ routineThresholdBps: z6.number(),
6915
+ timelockPeriod: z6.number()
6442
6916
  }),
6443
6917
  examples: [{ description: "Inspect governance timing and pass thresholds" }],
6444
6918
  async run(c) {
@@ -6481,36 +6955,36 @@ governance.command("params", {
6481
6955
  });
6482
6956
  }
6483
6957
  });
6484
- var txResultOutput3 = z4.union([
6485
- z4.object({
6486
- status: z4.enum(["success", "reverted"]),
6487
- hash: z4.string(),
6488
- blockNumber: z4.number(),
6489
- gasUsed: z4.string(),
6490
- from: z4.string(),
6491
- to: z4.string().nullable(),
6492
- effectiveGasPrice: z4.string().optional()
6958
+ var txResultOutput3 = z6.union([
6959
+ z6.object({
6960
+ status: z6.enum(["success", "reverted"]),
6961
+ hash: z6.string(),
6962
+ blockNumber: z6.number(),
6963
+ gasUsed: z6.string(),
6964
+ from: z6.string(),
6965
+ to: z6.string().nullable(),
6966
+ effectiveGasPrice: z6.string().optional()
6493
6967
  }),
6494
- z4.object({
6495
- status: z4.literal("dry-run"),
6496
- estimatedGas: z4.string(),
6497
- simulationResult: z4.unknown()
6968
+ z6.object({
6969
+ status: z6.literal("dry-run"),
6970
+ estimatedGas: z6.string(),
6971
+ simulationResult: z6.unknown()
6498
6972
  })
6499
6973
  ]);
6500
6974
  governance.command("vote", {
6501
6975
  description: "Cast a governance vote on a proposal.",
6502
6976
  hint: "Requires PRIVATE_KEY environment variable for signing.",
6503
- args: z4.object({
6504
- proposalId: z4.coerce.number().int().positive().describe("Proposal id (1-indexed)"),
6505
- support: z4.enum(["for", "against", "abstain"]).describe("Vote support: for, against, or abstain")
6977
+ args: z6.object({
6978
+ proposalId: z6.coerce.number().int().positive().describe("Proposal id (1-indexed)"),
6979
+ support: z6.enum(["for", "against", "abstain"]).describe("Vote support: for, against, or abstain")
6506
6980
  }),
6507
6981
  options: writeOptions,
6508
6982
  env: writeEnv,
6509
- output: z4.object({
6510
- proposalId: z4.number(),
6511
- proposalTitle: z4.string(),
6512
- support: z4.enum(["for", "against", "abstain"]),
6513
- supportValue: z4.number(),
6983
+ output: z6.object({
6984
+ proposalId: z6.number(),
6985
+ proposalTitle: z6.string(),
6986
+ support: z6.enum(["for", "against", "abstain"]),
6987
+ supportValue: z6.number(),
6514
6988
  tx: txResultOutput3
6515
6989
  }),
6516
6990
  examples: [
@@ -6527,7 +7001,7 @@ governance.command("vote", {
6527
7001
  async run(c) {
6528
7002
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
6529
7003
  const account = resolveAccount(c.env);
6530
- const proposalCount = await readProposalCount(client);
7004
+ const proposalCount = await fetchProposalCount(client);
6531
7005
  if (c.args.proposalId > Number(proposalCount)) {
6532
7006
  return c.error({
6533
7007
  code: "OUT_OF_RANGE",
@@ -6535,7 +7009,7 @@ governance.command("vote", {
6535
7009
  retryable: false
6536
7010
  });
6537
7011
  }
6538
- const proposal = await readProposalById(client, c.args.proposalId);
7012
+ const proposal = await fetchProposalById(client, c.args.proposalId);
6539
7013
  const status = proposalStatus(proposal.status);
6540
7014
  if (status.statusCode !== PROPOSAL_STATUS_ACTIVE) {
6541
7015
  return c.error({
@@ -6590,22 +7064,22 @@ governance.command("propose", {
6590
7064
  description: "Create a new council-originated governance proposal.",
6591
7065
  hint: "Requires PRIVATE_KEY environment variable for signing.",
6592
7066
  options: writeOptions.extend({
6593
- title: z4.string().min(1).describe("Proposal title"),
6594
- description: z4.string().min(1).describe("Proposal description"),
6595
- kind: z4.coerce.number().int().nonnegative().max(255).describe("Proposal kind enum value"),
6596
- category: z4.string().default("governance").describe("Forum category label for the proposal"),
6597
- "risk-tier": z4.coerce.number().int().nonnegative().max(255).optional().describe("Optional max allowed intent risk tier (default: 0)"),
6598
- amount: z4.string().optional().describe("Optional treasury amount hint (currently unsupported for intent encoding)"),
6599
- recipient: z4.string().optional().describe("Optional treasury recipient hint (currently unsupported for intent encoding)")
7067
+ title: z6.string().min(1).describe("Proposal title"),
7068
+ description: z6.string().min(1).describe("Proposal description"),
7069
+ kind: z6.coerce.number().int().nonnegative().max(255).describe("Proposal kind enum value"),
7070
+ category: z6.string().default("governance").describe("Forum category label for the proposal"),
7071
+ "risk-tier": z6.coerce.number().int().nonnegative().max(255).optional().describe("Optional max allowed intent risk tier (default: 0)"),
7072
+ amount: z6.string().optional().describe("Optional treasury amount hint (currently unsupported for intent encoding)"),
7073
+ recipient: z6.string().optional().describe("Optional treasury recipient hint (currently unsupported for intent encoding)")
6600
7074
  }),
6601
7075
  env: writeEnv,
6602
- output: z4.object({
6603
- proposer: z4.string(),
6604
- category: z4.string(),
6605
- kind: z4.number(),
6606
- title: z4.string(),
6607
- description: z4.string(),
6608
- expectedProposalId: z4.number(),
7076
+ output: z6.object({
7077
+ proposer: z6.string(),
7078
+ category: z6.string(),
7079
+ kind: z6.number(),
7080
+ title: z6.string(),
7081
+ description: z6.string(),
7082
+ expectedProposalId: z6.number(),
6609
7083
  tx: txResultOutput3
6610
7084
  }),
6611
7085
  examples: [
@@ -6648,7 +7122,7 @@ governance.command("propose", {
6648
7122
  retryable: false
6649
7123
  });
6650
7124
  }
6651
- const proposalCountBefore = await readProposalCount(client);
7125
+ const proposalCountBefore = await fetchProposalCount(client);
6652
7126
  const expectedProposalId = Number(proposalCountBefore) + 1;
6653
7127
  const proposalInput = {
6654
7128
  kind: c.options.kind,
@@ -6694,15 +7168,15 @@ governance.command("propose", {
6694
7168
  governance.command("queue", {
6695
7169
  description: "Finalize voting and queue an eligible proposal into timelock.",
6696
7170
  hint: "Requires PRIVATE_KEY environment variable for signing.",
6697
- args: z4.object({
6698
- proposalId: z4.coerce.number().int().positive().describe("Proposal id (1-indexed)")
7171
+ args: z6.object({
7172
+ proposalId: z6.coerce.number().int().positive().describe("Proposal id (1-indexed)")
6699
7173
  }),
6700
7174
  options: writeOptions,
6701
7175
  env: writeEnv,
6702
- output: z4.object({
6703
- proposalId: z4.number(),
6704
- proposalTitle: z4.string(),
6705
- statusBefore: z4.string(),
7176
+ output: z6.object({
7177
+ proposalId: z6.number(),
7178
+ proposalTitle: z6.string(),
7179
+ statusBefore: z6.string(),
6706
7180
  tx: txResultOutput3
6707
7181
  }),
6708
7182
  examples: [
@@ -6713,7 +7187,7 @@ governance.command("queue", {
6713
7187
  ],
6714
7188
  async run(c) {
6715
7189
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
6716
- const proposalCount = await readProposalCount(client);
7190
+ const proposalCount = await fetchProposalCount(client);
6717
7191
  if (c.args.proposalId > Number(proposalCount)) {
6718
7192
  return c.error({
6719
7193
  code: "OUT_OF_RANGE",
@@ -6721,7 +7195,7 @@ governance.command("queue", {
6721
7195
  retryable: false
6722
7196
  });
6723
7197
  }
6724
- const proposal = await readProposalById(client, c.args.proposalId);
7198
+ const proposal = await fetchProposalById(client, c.args.proposalId);
6725
7199
  const status = proposalStatus(proposal.status);
6726
7200
  if (status.statusCode === PROPOSAL_STATUS_PASSED) {
6727
7201
  return c.error({
@@ -6782,14 +7256,14 @@ governance.command("queue", {
6782
7256
  governance.command("execute", {
6783
7257
  description: "Execute a queued governance proposal after timelock expiry.",
6784
7258
  hint: "Requires PRIVATE_KEY environment variable for signing.",
6785
- args: z4.object({
6786
- proposalId: z4.coerce.number().int().positive().describe("Proposal id (1-indexed)")
7259
+ args: z6.object({
7260
+ proposalId: z6.coerce.number().int().positive().describe("Proposal id (1-indexed)")
6787
7261
  }),
6788
7262
  options: writeOptions,
6789
7263
  env: writeEnv,
6790
- output: z4.object({
6791
- proposalId: z4.number(),
6792
- proposalTitle: z4.string(),
7264
+ output: z6.object({
7265
+ proposalId: z6.number(),
7266
+ proposalTitle: z6.string(),
6793
7267
  timelockEndsAt: timestampOutput3,
6794
7268
  tx: txResultOutput3
6795
7269
  }),
@@ -6801,7 +7275,7 @@ governance.command("execute", {
6801
7275
  ],
6802
7276
  async run(c) {
6803
7277
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
6804
- const proposalCount = await readProposalCount(client);
7278
+ const proposalCount = await fetchProposalCount(client);
6805
7279
  if (c.args.proposalId > Number(proposalCount)) {
6806
7280
  return c.error({
6807
7281
  code: "OUT_OF_RANGE",
@@ -6809,7 +7283,7 @@ governance.command("execute", {
6809
7283
  retryable: false
6810
7284
  });
6811
7285
  }
6812
- const proposal = await readProposalById(client, c.args.proposalId);
7286
+ const proposal = await fetchProposalById(client, c.args.proposalId);
6813
7287
  const status = proposalStatus(proposal.status);
6814
7288
  if (status.statusCode !== PROPOSAL_STATUS_PASSED) {
6815
7289
  return c.error({
@@ -6856,64 +7330,14 @@ governance.command("execute", {
6856
7330
 
6857
7331
  // src/commands/members.ts
6858
7332
  import { TxError as TxError3 } from "@spectratools/tx-shared";
6859
- import { Cli as Cli4, z as z5 } from "incur";
6860
- var DEFAULT_MEMBER_SNAPSHOT_URL = "https://www.theaiassembly.org/api/indexer/members";
6861
- var REGISTERED_EVENT_SCAN_STEP = 100000n;
6862
- var REGISTERED_EVENT_SCAN_TIMEOUT_MS = 2e4;
7333
+ import { Cli as Cli4, z as z7 } from "incur";
7334
+ var DEFAULT_MEMBER_SNAPSHOT_URL2 = "https://www.theaiassembly.org/api/indexer/members";
6863
7335
  var MAX_MEMBER_LOOKUP_SUGGESTIONS = 5;
6864
- var env4 = z5.object({
6865
- ABSTRACT_RPC_URL: z5.string().optional().describe("Abstract RPC URL override"),
6866
- ASSEMBLY_INDEXER_URL: z5.string().optional().describe("Optional members snapshot endpoint (default: theaiassembly.org indexer)")
7336
+ var env4 = z7.object({
7337
+ ABSTRACT_RPC_URL: z7.string().optional().describe("Abstract RPC URL override"),
7338
+ ASSEMBLY_INDEXER_URL: z7.string().optional().describe("Optional members snapshot endpoint (default: theaiassembly.org indexer)")
6867
7339
  });
6868
- var timestampOutput4 = z5.union([z5.number(), z5.string()]);
6869
- var memberSnapshotEntrySchema = z5.union([
6870
- z5.string(),
6871
- z5.object({
6872
- address: z5.string(),
6873
- ens: z5.string().optional(),
6874
- name: z5.string().optional()
6875
- })
6876
- ]);
6877
- var memberSnapshotSchema = z5.array(memberSnapshotEntrySchema);
6878
- var AssemblyApiValidationError = class extends Error {
6879
- constructor(details) {
6880
- super("Assembly API response validation failed");
6881
- this.details = details;
6882
- this.name = "AssemblyApiValidationError";
6883
- }
6884
- };
6885
- var AssemblyIndexerUnavailableError = class extends Error {
6886
- constructor(details) {
6887
- super("Assembly indexer unavailable");
6888
- this.details = details;
6889
- this.name = "AssemblyIndexerUnavailableError";
6890
- }
6891
- };
6892
- function mergeMemberIdentities(entries) {
6893
- const byAddress = /* @__PURE__ */ new Map();
6894
- for (const entry of entries) {
6895
- const key = entry.address.toLowerCase();
6896
- const existing = byAddress.get(key);
6897
- if (!existing) {
6898
- byAddress.set(key, entry);
6899
- continue;
6900
- }
6901
- const merged = { address: existing.address };
6902
- const ens = existing.ens ?? entry.ens;
6903
- const name = existing.name ?? entry.name;
6904
- if (ens !== void 0) merged.ens = ens;
6905
- if (name !== void 0) merged.name = name;
6906
- byAddress.set(key, merged);
6907
- }
6908
- return [...byAddress.values()];
6909
- }
6910
- function memberSnapshotEntryToIdentity(entry) {
6911
- if (typeof entry === "string") return { address: entry };
6912
- const identity = { address: entry.address };
6913
- if (entry.ens !== void 0) identity.ens = entry.ens;
6914
- if (entry.name !== void 0) identity.name = entry.name;
6915
- return identity;
6916
- }
7340
+ var timestampOutput4 = z7.union([z7.number(), z7.string()]);
6917
7341
  function matchableAddressInput(query) {
6918
7342
  return query.startsWith("0x") && query.length === 42;
6919
7343
  }
@@ -6928,95 +7352,6 @@ function searchMemberIdentities(query, members2) {
6928
7352
  return member.address.toLowerCase().includes(needle) || member.ens?.toLowerCase().includes(needle) || member.name?.toLowerCase().includes(needle);
6929
7353
  });
6930
7354
  }
6931
- async function memberSnapshot(url) {
6932
- let res;
6933
- try {
6934
- res = await fetch(url);
6935
- } catch (error) {
6936
- throw new AssemblyIndexerUnavailableError({
6937
- code: "ASSEMBLY_INDEXER_UNAVAILABLE",
6938
- url,
6939
- reason: error instanceof Error ? error.message : String(error)
6940
- });
6941
- }
6942
- if (!res.ok) {
6943
- throw new AssemblyIndexerUnavailableError({
6944
- code: "ASSEMBLY_INDEXER_UNAVAILABLE",
6945
- url,
6946
- status: res.status,
6947
- statusText: res.statusText
6948
- });
6949
- }
6950
- const json = await res.json();
6951
- const parsed = memberSnapshotSchema.safeParse(json);
6952
- if (parsed.success) {
6953
- return mergeMemberIdentities(parsed.data.map(memberSnapshotEntryToIdentity));
6954
- }
6955
- throw new AssemblyApiValidationError({
6956
- code: "INVALID_ASSEMBLY_API_RESPONSE",
6957
- url,
6958
- issues: parsed.error.issues,
6959
- response: json
6960
- });
6961
- }
6962
- async function withTimeout(promise, timeoutMs, timeoutMessage) {
6963
- let timer;
6964
- try {
6965
- return await Promise.race([
6966
- promise,
6967
- new Promise((_, reject) => {
6968
- timer = setTimeout(() => {
6969
- reject(new Error(timeoutMessage));
6970
- }, timeoutMs);
6971
- })
6972
- ]);
6973
- } finally {
6974
- if (timer) clearTimeout(timer);
6975
- }
6976
- }
6977
- async function membersFromRegisteredEvents(client) {
6978
- const latestBlock = await client.getBlockNumber();
6979
- const addresses = /* @__PURE__ */ new Set();
6980
- for (let fromBlock = ABSTRACT_MAINNET_DEPLOYMENT_BLOCKS.registry; fromBlock <= latestBlock; fromBlock += REGISTERED_EVENT_SCAN_STEP) {
6981
- const toBlock = fromBlock + REGISTERED_EVENT_SCAN_STEP - 1n > latestBlock ? latestBlock : fromBlock + REGISTERED_EVENT_SCAN_STEP - 1n;
6982
- const events = await client.getContractEvents({
6983
- abi: registryAbi,
6984
- address: ABSTRACT_MAINNET_ADDRESSES.registry,
6985
- eventName: "Registered",
6986
- fromBlock,
6987
- toBlock,
6988
- strict: true
6989
- });
6990
- for (const event of events) {
6991
- const member = event.args.member;
6992
- if (typeof member === "string") {
6993
- addresses.add(member);
6994
- }
6995
- }
6996
- }
6997
- return [...addresses].map((address) => ({ address }));
6998
- }
6999
- async function loadMemberIdentities(client, snapshotUrl) {
7000
- try {
7001
- return { members: await memberSnapshot(snapshotUrl) };
7002
- } catch (error) {
7003
- if (error instanceof AssemblyApiValidationError) {
7004
- throw error;
7005
- }
7006
- if (!(error instanceof AssemblyIndexerUnavailableError)) {
7007
- throw error;
7008
- }
7009
- const fallbackMembers = await withTimeout(
7010
- membersFromRegisteredEvents(client),
7011
- REGISTERED_EVENT_SCAN_TIMEOUT_MS,
7012
- `Registered event fallback scan timed out after ${REGISTERED_EVENT_SCAN_TIMEOUT_MS}ms`
7013
- );
7014
- return {
7015
- members: mergeMemberIdentities(fallbackMembers),
7016
- fallbackReason: error.details
7017
- };
7018
- }
7019
- }
7020
7355
  function indexerIssue(details) {
7021
7356
  if (typeof details.status === "number") {
7022
7357
  return `${details.status}${details.statusText ? ` ${details.statusText}` : ""}`;
@@ -7048,19 +7383,19 @@ var members = Cli4.create("members", {
7048
7383
  members.command("list", {
7049
7384
  description: "List members from an indexer snapshot (or Registered event fallback) plus on-chain active state.",
7050
7385
  env: env4,
7051
- output: z5.object({
7052
- members: z5.array(
7053
- z5.object({
7054
- address: z5.string(),
7055
- active: z5.boolean(),
7056
- registered: z5.boolean(),
7386
+ output: z7.object({
7387
+ members: z7.array(
7388
+ z7.object({
7389
+ address: z7.string(),
7390
+ active: z7.boolean(),
7391
+ registered: z7.boolean(),
7057
7392
  activeUntil: timestampOutput4,
7058
- activeUntilRelative: z5.string(),
7393
+ activeUntilRelative: z7.string(),
7059
7394
  lastHeartbeatAt: timestampOutput4,
7060
- lastHeartbeatRelative: z5.string()
7395
+ lastHeartbeatRelative: z7.string()
7061
7396
  })
7062
7397
  ),
7063
- count: z5.number()
7398
+ count: z7.number()
7064
7399
  }),
7065
7400
  examples: [
7066
7401
  { description: "List members using default indexer snapshot" },
@@ -7068,11 +7403,11 @@ members.command("list", {
7068
7403
  ],
7069
7404
  async run(c) {
7070
7405
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
7071
- const snapshotUrl = c.env.ASSEMBLY_INDEXER_URL ?? DEFAULT_MEMBER_SNAPSHOT_URL;
7406
+ const snapshotUrl = c.env.ASSEMBLY_INDEXER_URL ?? DEFAULT_MEMBER_SNAPSHOT_URL2;
7072
7407
  let memberIdentities;
7073
7408
  let fallbackReason;
7074
7409
  try {
7075
- const loaded = await loadMemberIdentities(client, snapshotUrl);
7410
+ const loaded = await fetchMemberList(client, snapshotUrl);
7076
7411
  memberIdentities = loaded.members;
7077
7412
  fallbackReason = loaded.fallbackReason;
7078
7413
  } catch (error) {
@@ -7096,34 +7431,16 @@ members.command("list", {
7096
7431
  emitIndexerFallbackWarning(fallbackReason);
7097
7432
  }
7098
7433
  const addresses = memberIdentities.map((member) => member.address);
7099
- const calls = addresses.flatMap((address) => [
7100
- {
7101
- abi: registryAbi,
7102
- address: ABSTRACT_MAINNET_ADDRESSES.registry,
7103
- functionName: "isActive",
7104
- args: [address]
7105
- },
7106
- {
7107
- abi: registryAbi,
7108
- address: ABSTRACT_MAINNET_ADDRESSES.registry,
7109
- functionName: "members",
7110
- args: [address]
7111
- }
7112
- ]);
7113
- const values = calls.length > 0 ? await client.multicall({ allowFailure: false, contracts: calls }) : [];
7114
- const rows = addresses.map((address, i) => {
7115
- const active = values[i * 2];
7116
- const info = values[i * 2 + 1];
7117
- return {
7118
- address: toChecksum(address),
7119
- active,
7120
- registered: info.registered,
7121
- activeUntil: timeValue(info.activeUntil, c.format),
7122
- activeUntilRelative: relTime(info.activeUntil),
7123
- lastHeartbeatAt: timeValue(info.lastHeartbeatAt, c.format),
7124
- lastHeartbeatRelative: relTime(info.lastHeartbeatAt)
7125
- };
7126
- });
7434
+ const onchainStates = await fetchMemberOnchainState(client, addresses);
7435
+ const rows = onchainStates.map((state) => ({
7436
+ address: state.address,
7437
+ active: state.active,
7438
+ registered: state.registered,
7439
+ activeUntil: timeValue(state.activeUntil, c.format),
7440
+ activeUntilRelative: relTime(state.activeUntil),
7441
+ lastHeartbeatAt: timeValue(state.lastHeartbeatAt, c.format),
7442
+ lastHeartbeatRelative: relTime(state.lastHeartbeatAt)
7443
+ }));
7127
7444
  return c.ok({
7128
7445
  members: rows,
7129
7446
  count: rows.length
@@ -7132,17 +7449,17 @@ members.command("list", {
7132
7449
  });
7133
7450
  members.command("info", {
7134
7451
  description: "Get member registry record and active status by full address, partial address, ENS, or name.",
7135
- args: z5.object({
7136
- address: z5.string().describe("Member lookup query (full/partial address, ENS, or name metadata)")
7452
+ args: z7.object({
7453
+ address: z7.string().describe("Member lookup query (full/partial address, ENS, or name metadata)")
7137
7454
  }),
7138
7455
  env: env4,
7139
- output: z5.object({
7140
- address: z5.string(),
7141
- active: z5.boolean(),
7456
+ output: z7.object({
7457
+ address: z7.string(),
7458
+ active: z7.boolean(),
7142
7459
  activeUntil: timestampOutput4,
7143
7460
  lastHeartbeatAt: timestampOutput4,
7144
- activeUntilRelative: z5.string(),
7145
- lastHeartbeatRelative: z5.string()
7461
+ activeUntilRelative: z7.string(),
7462
+ lastHeartbeatRelative: z7.string()
7146
7463
  }),
7147
7464
  examples: [
7148
7465
  {
@@ -7156,13 +7473,13 @@ members.command("info", {
7156
7473
  ],
7157
7474
  async run(c) {
7158
7475
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
7159
- const snapshotUrl = c.env.ASSEMBLY_INDEXER_URL ?? DEFAULT_MEMBER_SNAPSHOT_URL;
7476
+ const snapshotUrl = c.env.ASSEMBLY_INDEXER_URL ?? DEFAULT_MEMBER_SNAPSHOT_URL2;
7160
7477
  let lookupAddress = c.args.address;
7161
7478
  if (!matchableAddressInput(c.args.address)) {
7162
7479
  let loadedMembers;
7163
7480
  let fallbackReason;
7164
7481
  try {
7165
- const loaded = await loadMemberIdentities(client, snapshotUrl);
7482
+ const loaded = await fetchMemberList(client, snapshotUrl);
7166
7483
  loadedMembers = loaded.members;
7167
7484
  fallbackReason = loaded.fallbackReason;
7168
7485
  } catch (error) {
@@ -7227,9 +7544,9 @@ members.command("info", {
7227
7544
  members.command("count", {
7228
7545
  description: "Get active and total-known member counts from Registry.",
7229
7546
  env: env4,
7230
- output: z5.object({
7231
- active: z5.number(),
7232
- total: z5.number()
7547
+ output: z7.object({
7548
+ active: z7.number(),
7549
+ total: z7.number()
7233
7550
  }),
7234
7551
  examples: [{ description: "Count active and known members" }],
7235
7552
  async run(c) {
@@ -7252,12 +7569,12 @@ members.command("count", {
7252
7569
  members.command("fees", {
7253
7570
  description: "Get registration and heartbeat fee settings.",
7254
7571
  env: env4,
7255
- output: z5.object({
7256
- registrationFeeWei: z5.string(),
7257
- registrationFee: z5.string(),
7258
- heartbeatFeeWei: z5.string(),
7259
- heartbeatFee: z5.string(),
7260
- heartbeatGracePeriodSeconds: z5.number()
7572
+ output: z7.object({
7573
+ registrationFeeWei: z7.string(),
7574
+ registrationFee: z7.string(),
7575
+ heartbeatFeeWei: z7.string(),
7576
+ heartbeatFee: z7.string(),
7577
+ heartbeatGracePeriodSeconds: z7.number()
7261
7578
  }),
7262
7579
  examples: [{ description: "Inspect current registry fee configuration" }],
7263
7580
  async run(c) {
@@ -7288,24 +7605,24 @@ members.command("fees", {
7288
7605
  });
7289
7606
  }
7290
7607
  });
7291
- var txOutputSchema = z5.union([
7292
- z5.object({
7293
- status: z5.enum(["success", "reverted"]),
7294
- hash: z5.string(),
7295
- blockNumber: z5.number(),
7296
- gasUsed: z5.string(),
7297
- from: z5.string(),
7298
- to: z5.string().nullable(),
7299
- effectiveGasPrice: z5.string().optional(),
7300
- fee: z5.string(),
7301
- feeEth: z5.string()
7608
+ var txOutputSchema = z7.union([
7609
+ z7.object({
7610
+ status: z7.enum(["success", "reverted"]),
7611
+ hash: z7.string(),
7612
+ blockNumber: z7.number(),
7613
+ gasUsed: z7.string(),
7614
+ from: z7.string(),
7615
+ to: z7.string().nullable(),
7616
+ effectiveGasPrice: z7.string().optional(),
7617
+ fee: z7.string(),
7618
+ feeEth: z7.string()
7302
7619
  }),
7303
- z5.object({
7304
- status: z5.literal("dry-run"),
7305
- estimatedGas: z5.string(),
7306
- simulationResult: z5.unknown(),
7307
- fee: z5.string(),
7308
- feeEth: z5.string()
7620
+ z7.object({
7621
+ status: z7.literal("dry-run"),
7622
+ estimatedGas: z7.string(),
7623
+ simulationResult: z7.unknown(),
7624
+ fee: z7.string(),
7625
+ feeEth: z7.string()
7309
7626
  })
7310
7627
  ]);
7311
7628
  members.command("register", {
@@ -7464,35 +7781,35 @@ members.command("renew", {
7464
7781
 
7465
7782
  // src/commands/treasury.ts
7466
7783
  import { TxError as TxError4 } from "@spectratools/tx-shared";
7467
- import { Cli as Cli5, z as z6 } from "incur";
7784
+ import { Cli as Cli5, z as z8 } from "incur";
7468
7785
  import { encodeAbiParameters, parseUnits, zeroAddress } from "viem";
7469
- var env5 = z6.object({
7470
- ABSTRACT_RPC_URL: z6.string().optional().describe("Abstract RPC URL override")
7786
+ var env5 = z8.object({
7787
+ ABSTRACT_RPC_URL: z8.string().optional().describe("Abstract RPC URL override")
7471
7788
  });
7472
- var timestampOutput5 = z6.union([z6.number(), z6.string()]);
7473
- var txResultOutput4 = z6.union([
7474
- z6.object({
7475
- status: z6.literal("success"),
7476
- hash: z6.string(),
7477
- blockNumber: z6.number(),
7478
- gasUsed: z6.string(),
7479
- from: z6.string(),
7480
- to: z6.string().nullable(),
7481
- effectiveGasPrice: z6.string().optional()
7789
+ var timestampOutput5 = z8.union([z8.number(), z8.string()]);
7790
+ var txResultOutput4 = z8.union([
7791
+ z8.object({
7792
+ status: z8.literal("success"),
7793
+ hash: z8.string(),
7794
+ blockNumber: z8.number(),
7795
+ gasUsed: z8.string(),
7796
+ from: z8.string(),
7797
+ to: z8.string().nullable(),
7798
+ effectiveGasPrice: z8.string().optional()
7482
7799
  }),
7483
- z6.object({
7484
- status: z6.literal("reverted"),
7485
- hash: z6.string(),
7486
- blockNumber: z6.number(),
7487
- gasUsed: z6.string(),
7488
- from: z6.string(),
7489
- to: z6.string().nullable(),
7490
- effectiveGasPrice: z6.string().optional()
7800
+ z8.object({
7801
+ status: z8.literal("reverted"),
7802
+ hash: z8.string(),
7803
+ blockNumber: z8.number(),
7804
+ gasUsed: z8.string(),
7805
+ from: z8.string(),
7806
+ to: z8.string().nullable(),
7807
+ effectiveGasPrice: z8.string().optional()
7491
7808
  }),
7492
- z6.object({
7493
- status: z6.literal("dry-run"),
7494
- estimatedGas: z6.string(),
7495
- simulationResult: z6.unknown()
7809
+ z8.object({
7810
+ status: z8.literal("dry-run"),
7811
+ estimatedGas: z8.string(),
7812
+ simulationResult: z8.unknown()
7496
7813
  })
7497
7814
  ]);
7498
7815
  var treasury = Cli5.create("treasury", {
@@ -7501,10 +7818,10 @@ var treasury = Cli5.create("treasury", {
7501
7818
  treasury.command("balance", {
7502
7819
  description: "Get current native token balance for the treasury contract.",
7503
7820
  env: env5,
7504
- output: z6.object({
7505
- address: z6.string(),
7506
- balanceWei: z6.string(),
7507
- balance: z6.string()
7821
+ output: z8.object({
7822
+ address: z8.string(),
7823
+ balanceWei: z8.string(),
7824
+ balance: z8.string()
7508
7825
  }),
7509
7826
  examples: [{ description: "Check treasury balance" }],
7510
7827
  async run(c) {
@@ -7519,13 +7836,13 @@ treasury.command("balance", {
7519
7836
  });
7520
7837
  treasury.command("whitelist", {
7521
7838
  description: "Check whether an asset address is treasury-whitelisted.",
7522
- args: z6.object({
7523
- asset: z6.string().describe("Token/asset contract address")
7839
+ args: z8.object({
7840
+ asset: z8.string().describe("Token/asset contract address")
7524
7841
  }),
7525
7842
  env: env5,
7526
- output: z6.object({
7527
- asset: z6.string(),
7528
- whitelisted: z6.boolean()
7843
+ output: z8.object({
7844
+ asset: z8.string(),
7845
+ whitelisted: z8.boolean()
7529
7846
  }),
7530
7847
  examples: [
7531
7848
  {
@@ -7547,11 +7864,11 @@ treasury.command("whitelist", {
7547
7864
  treasury.command("major-spend-status", {
7548
7865
  description: "Read major-spend cooldown status for the treasury contract.",
7549
7866
  env: env5,
7550
- output: z6.object({
7551
- majorSpendCooldownSeconds: z6.number(),
7867
+ output: z8.object({
7868
+ majorSpendCooldownSeconds: z8.number(),
7552
7869
  lastMajorSpendAt: timestampOutput5,
7553
- lastMajorSpendRelative: z6.string(),
7554
- isMajorSpendAllowed: z6.boolean()
7870
+ lastMajorSpendRelative: z8.string(),
7871
+ isMajorSpendAllowed: z8.boolean()
7555
7872
  }),
7556
7873
  examples: [{ description: "Inspect treasury major-spend guardrails" }],
7557
7874
  async run(c) {
@@ -7585,13 +7902,13 @@ treasury.command("major-spend-status", {
7585
7902
  });
7586
7903
  treasury.command("executed", {
7587
7904
  description: "Check whether a treasury action for a proposal has executed.",
7588
- args: z6.object({
7589
- proposalId: z6.coerce.number().int().positive().describe("Governance proposal id")
7905
+ args: z8.object({
7906
+ proposalId: z8.coerce.number().int().positive().describe("Governance proposal id")
7590
7907
  }),
7591
7908
  env: env5,
7592
- output: z6.object({
7593
- proposalId: z6.number(),
7594
- executed: z6.boolean()
7909
+ output: z8.object({
7910
+ proposalId: z8.number(),
7911
+ executed: z8.boolean()
7595
7912
  }),
7596
7913
  examples: [{ args: { proposalId: 1 }, description: "Check execution status for proposal #1" }],
7597
7914
  async run(c) {
@@ -7621,25 +7938,25 @@ treasury.command("propose-spend", {
7621
7938
  description: "Create a council proposal that spends treasury funds via TreasuryTransferIntentModule.",
7622
7939
  hint: "Requires PRIVATE_KEY environment variable for signing.",
7623
7940
  options: writeOptions.extend({
7624
- token: z6.string().describe("Token address to spend (use 0x0000000000000000000000000000000000000000 for ETH)"),
7625
- recipient: z6.string().describe("Recipient address"),
7626
- amount: z6.string().describe("Token amount as decimal string (human units)"),
7627
- decimals: z6.coerce.number().int().min(0).max(36).default(18).describe("Token decimals used to parse --amount (default: 18)"),
7628
- title: z6.string().min(1).describe("Proposal title"),
7629
- description: z6.string().min(1).describe("Proposal description"),
7630
- category: z6.string().default("treasury").describe("Forum category label for this proposal"),
7631
- "risk-tier": z6.coerce.number().int().min(0).max(3).default(3).describe("Max allowed risk tier in intent constraints (0-3, default: 3)")
7941
+ token: z8.string().describe("Token address to spend (use 0x0000000000000000000000000000000000000000 for ETH)"),
7942
+ recipient: z8.string().describe("Recipient address"),
7943
+ amount: z8.string().describe("Token amount as decimal string (human units)"),
7944
+ decimals: z8.coerce.number().int().min(0).max(36).default(18).describe("Token decimals used to parse --amount (default: 18)"),
7945
+ title: z8.string().min(1).describe("Proposal title"),
7946
+ description: z8.string().min(1).describe("Proposal description"),
7947
+ category: z8.string().default("treasury").describe("Forum category label for this proposal"),
7948
+ "risk-tier": z8.coerce.number().int().min(0).max(3).default(3).describe("Max allowed risk tier in intent constraints (0-3, default: 3)")
7632
7949
  }),
7633
7950
  env: writeEnv,
7634
- output: z6.object({
7635
- proposer: z6.string(),
7636
- category: z6.string(),
7637
- token: z6.string(),
7638
- recipient: z6.string(),
7639
- amount: z6.string(),
7640
- amountWei: z6.string(),
7641
- expectedProposalId: z6.number(),
7642
- expectedThreadId: z6.number(),
7951
+ output: z8.object({
7952
+ proposer: z8.string(),
7953
+ category: z8.string(),
7954
+ token: z8.string(),
7955
+ recipient: z8.string(),
7956
+ amount: z8.string(),
7957
+ amountWei: z8.string(),
7958
+ expectedProposalId: z8.number(),
7959
+ expectedThreadId: z8.number(),
7643
7960
  tx: txResultOutput4
7644
7961
  }),
7645
7962
  examples: [
@@ -7943,24 +8260,25 @@ cli.command(council);
7943
8260
  cli.command(forum);
7944
8261
  cli.command(governance);
7945
8262
  cli.command(treasury);
7946
- var rootEnv = z7.object({
7947
- ABSTRACT_RPC_URL: z7.string().optional().describe("Abstract RPC URL override")
8263
+ registerDigestCommand(cli);
8264
+ var rootEnv = z9.object({
8265
+ ABSTRACT_RPC_URL: z9.string().optional().describe("Abstract RPC URL override")
7948
8266
  });
7949
- var timestampOutput6 = z7.union([z7.number(), z7.string()]);
8267
+ var timestampOutput6 = z9.union([z9.number(), z9.string()]);
7950
8268
  cli.command("status", {
7951
8269
  description: "Get a cross-contract Assembly snapshot (members, council, governance, treasury).",
7952
8270
  env: rootEnv,
7953
- output: z7.object({
7954
- activeMemberCount: z7.number(),
7955
- seatCount: z7.number(),
7956
- proposalCount: z7.number(),
7957
- currentAuctionDay: z7.number(),
7958
- currentAuctionSlot: z7.number(),
7959
- treasuryBalance: z7.string()
8271
+ output: z9.object({
8272
+ activeMemberCount: z9.number(),
8273
+ seatCount: z9.number(),
8274
+ proposalCount: z9.number(),
8275
+ currentAuctionDay: z9.number(),
8276
+ currentAuctionSlot: z9.number(),
8277
+ treasuryBalance: z9.string()
7960
8278
  }),
7961
8279
  examples: [{ description: "Fetch the current Assembly system status" }],
7962
8280
  async run(c) {
7963
- return withCommandSpan("assembly status", {}, async () => {
8281
+ return withCommandSpan2("assembly status", {}, async () => {
7964
8282
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
7965
8283
  const [
7966
8284
  activeMemberCount,
@@ -8010,18 +8328,18 @@ cli.command("status", {
8010
8328
  });
8011
8329
  cli.command("health", {
8012
8330
  description: "Check cross-contract health for one address (membership, council, refunds, power).",
8013
- args: z7.object({
8014
- address: z7.string().describe("Member or wallet address to inspect")
8331
+ args: z9.object({
8332
+ address: z9.string().describe("Member or wallet address to inspect")
8015
8333
  }),
8016
8334
  env: rootEnv,
8017
- output: z7.object({
8018
- address: z7.string(),
8019
- isActive: z7.boolean(),
8335
+ output: z9.object({
8336
+ address: z9.string(),
8337
+ isActive: z9.boolean(),
8020
8338
  activeUntil: timestampOutput6,
8021
- activeUntilRelative: z7.string(),
8022
- isCouncilMember: z7.boolean(),
8023
- pendingReturnsWei: z7.string(),
8024
- votingPower: z7.number()
8339
+ activeUntilRelative: z9.string(),
8340
+ isCouncilMember: z9.boolean(),
8341
+ pendingReturnsWei: z9.string(),
8342
+ votingPower: z9.number()
8025
8343
  }),
8026
8344
  examples: [
8027
8345
  {
@@ -8030,7 +8348,7 @@ cli.command("health", {
8030
8348
  }
8031
8349
  ],
8032
8350
  async run(c) {
8033
- return withCommandSpan("assembly health", { address: c.args.address }, async () => {
8351
+ return withCommandSpan2("assembly health", { address: c.args.address }, async () => {
8034
8352
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
8035
8353
  const [isActive, member, isCouncilMember, pendingReturns, votingPower] = await Promise.all([
8036
8354
  client.readContract({