@spectratools/assembly-cli 0.6.0 → 0.8.1

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/README.md +23 -0
  2. package/dist/cli.js +1009 -283
  3. package/package.json +3 -3
package/dist/cli.js CHANGED
@@ -4,7 +4,7 @@
4
4
  import { readFileSync, realpathSync } from "fs";
5
5
  import { dirname, resolve } from "path";
6
6
  import { fileURLToPath } from "url";
7
- import { Cli as Cli6, z as z6 } from "incur";
7
+ import { Cli as Cli6, z as z7 } from "incur";
8
8
 
9
9
  // src/commands/_common.ts
10
10
  import { checksumAddress, weiToEth } from "@spectratools/cli-shared";
@@ -59,7 +59,8 @@ function jsonSafe(value) {
59
59
  }
60
60
 
61
61
  // src/commands/council.ts
62
- import { Cli, z } from "incur";
62
+ import { Cli, z as z2 } from "incur";
63
+ import { parseEther } from "viem";
63
64
 
64
65
  // src/contracts/CouncilSeats.abi.json
65
66
  var CouncilSeats_abi_default = [
@@ -4328,12 +4329,79 @@ function createAssemblyPublicClient(rpcUrl) {
4328
4329
  transport: http(rpcUrl ?? process.env.ABSTRACT_RPC_URL ?? "https://api.mainnet.abs.xyz")
4329
4330
  });
4330
4331
  }
4332
+ function createAssemblyWalletClient(account, rpcUrl) {
4333
+ return createWalletClient({
4334
+ account,
4335
+ chain: abstractMainnet,
4336
+ transport: http(rpcUrl ?? process.env.ABSTRACT_RPC_URL ?? "https://api.mainnet.abs.xyz")
4337
+ });
4338
+ }
4331
4339
 
4332
- // src/commands/council.ts
4333
- var env = z.object({
4340
+ // src/commands/_write-utils.ts
4341
+ import {
4342
+ createPrivateKeySigner,
4343
+ executeTx
4344
+ } from "@spectratools/tx-shared";
4345
+ import { z } from "incur";
4346
+ var writeEnv = z.object({
4347
+ PRIVATE_KEY: z.string().describe("Private key (0x-prefixed 32-byte hex) for signing transactions"),
4334
4348
  ABSTRACT_RPC_URL: z.string().optional().describe("Abstract RPC URL override")
4335
4349
  });
4336
- var timestampOutput = z.union([z.number(), z.string()]);
4350
+ var writeOptions = z.object({
4351
+ "dry-run": z.boolean().default(false).describe("Simulate the transaction without broadcasting"),
4352
+ "gas-limit": z.string().optional().describe("Gas limit override (in gas units)"),
4353
+ "max-fee": z.string().optional().describe("Max fee per gas override in wei (EIP-1559)"),
4354
+ nonce: z.number().optional().describe("Nonce override")
4355
+ });
4356
+ function resolveAccount(env6) {
4357
+ const signer = createPrivateKeySigner(env6.PRIVATE_KEY);
4358
+ return signer.account;
4359
+ }
4360
+ function formatTxResult(result) {
4361
+ if (result.status === "dry-run") {
4362
+ return {
4363
+ status: "dry-run",
4364
+ estimatedGas: result.estimatedGas.toString(),
4365
+ simulationResult: jsonSafe(result.simulationResult)
4366
+ };
4367
+ }
4368
+ return {
4369
+ status: result.status,
4370
+ hash: result.hash,
4371
+ blockNumber: Number(result.blockNumber),
4372
+ gasUsed: result.gasUsed.toString(),
4373
+ from: result.from,
4374
+ to: result.to,
4375
+ ...result.effectiveGasPrice !== void 0 ? { effectiveGasPrice: result.effectiveGasPrice.toString() } : {}
4376
+ };
4377
+ }
4378
+ async function assemblyWriteTx(opts) {
4379
+ const { env: env6, options, address, abi, functionName, args, value } = opts;
4380
+ const account = resolveAccount(env6);
4381
+ const publicClient = createAssemblyPublicClient(env6.ABSTRACT_RPC_URL);
4382
+ const walletClient = createAssemblyWalletClient(account, env6.ABSTRACT_RPC_URL);
4383
+ const result = await executeTx({
4384
+ publicClient,
4385
+ walletClient,
4386
+ account,
4387
+ address,
4388
+ abi,
4389
+ functionName,
4390
+ ...args !== void 0 ? { args } : {},
4391
+ ...value !== void 0 ? { value } : {},
4392
+ dryRun: options["dry-run"],
4393
+ ...options["gas-limit"] ? { gasLimit: BigInt(options["gas-limit"]) } : {},
4394
+ ...options["max-fee"] ? { maxFeePerGas: BigInt(options["max-fee"]) } : {},
4395
+ ...options.nonce !== void 0 ? { nonce: options.nonce } : {}
4396
+ });
4397
+ return formatTxResult(result);
4398
+ }
4399
+
4400
+ // src/commands/council.ts
4401
+ var env = z2.object({
4402
+ ABSTRACT_RPC_URL: z2.string().optional().describe("Abstract RPC URL override")
4403
+ });
4404
+ var timestampOutput = z2.union([z2.number(), z2.string()]);
4337
4405
  function decodeSeat(value) {
4338
4406
  const [owner, startAt, endAt, forfeited] = value;
4339
4407
  return { owner, startAt, endAt, forfeited };
@@ -4342,10 +4410,14 @@ function decodeAuction(value) {
4342
4410
  const [highestBidder, highestBid, settled] = value;
4343
4411
  return { highestBidder, highestBid, settled };
4344
4412
  }
4345
- function deriveAuctionStatus(params) {
4346
- if (params.settled) return "settled";
4347
- if (params.currentTimestamp < params.windowEnd) return "bidding";
4348
- return "closed";
4413
+ function deriveAuctionExecutionState(params) {
4414
+ if (params.settled) return { executionStatus: "settled", bidExecutableNow: false };
4415
+ const isCurrentAuctionSlot = params.day === Number(params.currentAuctionDay) && params.slot === Number(params.currentAuctionSlot);
4416
+ if (params.currentTimestamp < params.windowEnd) {
4417
+ if (isCurrentAuctionSlot) return { executionStatus: "open_now", bidExecutableNow: true };
4418
+ return { executionStatus: "upcoming", bidExecutableNow: false };
4419
+ }
4420
+ return { executionStatus: "closed_unsettled", bidExecutableNow: false };
4349
4421
  }
4350
4422
  var council = Cli.create("council", {
4351
4423
  description: "Inspect council seats, members, auctions, and seat parameters."
@@ -4353,15 +4425,15 @@ var council = Cli.create("council", {
4353
4425
  council.command("seats", {
4354
4426
  description: "List all council seats and their occupancy windows.",
4355
4427
  env,
4356
- output: z.array(
4357
- z.object({
4358
- id: z.number(),
4359
- owner: z.string(),
4428
+ output: z2.array(
4429
+ z2.object({
4430
+ id: z2.number(),
4431
+ owner: z2.string(),
4360
4432
  startAt: timestampOutput,
4361
- startAtRelative: z.string(),
4433
+ startAtRelative: z2.string(),
4362
4434
  endAt: timestampOutput,
4363
- endAtRelative: z.string(),
4364
- forfeited: z.boolean()
4435
+ endAtRelative: z2.string(),
4436
+ forfeited: z2.boolean()
4365
4437
  })
4366
4438
  ),
4367
4439
  examples: [{ description: "List all council seats" }],
@@ -4398,17 +4470,17 @@ council.command("seats", {
4398
4470
  });
4399
4471
  council.command("seat", {
4400
4472
  description: "Get detailed seat information for a specific seat id.",
4401
- args: z.object({
4402
- id: z.coerce.number().int().nonnegative().describe("Seat id (0-indexed)")
4473
+ args: z2.object({
4474
+ id: z2.coerce.number().int().nonnegative().describe("Seat id (0-indexed)")
4403
4475
  }),
4404
4476
  env,
4405
- output: z.object({
4406
- id: z.number(),
4407
- owner: z.string(),
4477
+ output: z2.object({
4478
+ id: z2.number(),
4479
+ owner: z2.string(),
4408
4480
  startAt: timestampOutput,
4409
4481
  endAt: timestampOutput,
4410
- forfeited: z.boolean(),
4411
- endAtRelative: z.string()
4482
+ forfeited: z2.boolean(),
4483
+ endAtRelative: z2.string()
4412
4484
  }),
4413
4485
  examples: [{ args: { id: 0 }, description: "Inspect seat #0" }],
4414
4486
  async run(c) {
@@ -4445,10 +4517,10 @@ council.command("seat", {
4445
4517
  council.command("members", {
4446
4518
  description: "List currently active council members and voting power.",
4447
4519
  env,
4448
- output: z.array(
4449
- z.object({
4450
- address: z.string(),
4451
- votingPower: z.number()
4520
+ output: z2.array(
4521
+ z2.object({
4522
+ address: z2.string(),
4523
+ votingPower: z2.number()
4452
4524
  })
4453
4525
  ),
4454
4526
  examples: [{ description: "List active council members" }],
@@ -4494,13 +4566,13 @@ council.command("members", {
4494
4566
  });
4495
4567
  council.command("is-member", {
4496
4568
  description: "Check whether an address is currently a council member.",
4497
- args: z.object({
4498
- address: z.string().describe("Address to check")
4569
+ args: z2.object({
4570
+ address: z2.string().describe("Address to check")
4499
4571
  }),
4500
4572
  env,
4501
- output: z.object({
4502
- address: z.string(),
4503
- isMember: z.boolean()
4573
+ output: z2.object({
4574
+ address: z2.string(),
4575
+ isMember: z2.boolean()
4504
4576
  }),
4505
4577
  examples: [
4506
4578
  {
@@ -4521,13 +4593,13 @@ council.command("is-member", {
4521
4593
  });
4522
4594
  council.command("voting-power", {
4523
4595
  description: "Get the current voting power for an address.",
4524
- args: z.object({
4525
- address: z.string().describe("Address to inspect")
4596
+ args: z2.object({
4597
+ address: z2.string().describe("Address to inspect")
4526
4598
  }),
4527
4599
  env,
4528
- output: z.object({
4529
- address: z.string(),
4530
- votingPower: z.number()
4600
+ output: z2.object({
4601
+ address: z2.string(),
4602
+ votingPower: z2.number()
4531
4603
  }),
4532
4604
  examples: [
4533
4605
  {
@@ -4549,19 +4621,21 @@ council.command("voting-power", {
4549
4621
  council.command("auctions", {
4550
4622
  description: "List recent and current council auction slots and leading bids.",
4551
4623
  env,
4552
- output: z.object({
4553
- currentDay: z.number(),
4554
- currentSlot: z.number(),
4555
- auctions: z.array(
4556
- z.object({
4557
- day: z.number(),
4558
- slot: z.number(),
4559
- highestBidder: z.string(),
4560
- highestBid: z.string(),
4561
- settled: z.boolean(),
4624
+ output: z2.object({
4625
+ currentDay: z2.number(),
4626
+ currentSlot: z2.number(),
4627
+ auctions: z2.array(
4628
+ z2.object({
4629
+ day: z2.number(),
4630
+ slot: z2.number(),
4631
+ highestBidder: z2.string(),
4632
+ highestBid: z2.string(),
4633
+ settled: z2.boolean(),
4562
4634
  windowEnd: timestampOutput,
4563
- windowEndRelative: z.string(),
4564
- status: z.enum(["bidding", "closed", "settled"])
4635
+ windowEndRelative: z2.string(),
4636
+ bidExecutableNow: z2.boolean(),
4637
+ executionStatus: z2.enum(["open_now", "upcoming", "closed_unsettled", "settled"]),
4638
+ status: z2.enum(["open_now", "upcoming", "closed_unsettled", "settled"])
4565
4639
  })
4566
4640
  )
4567
4641
  }),
@@ -4619,19 +4693,27 @@ council.command("auctions", {
4619
4693
  currentSlot: asNum(slot),
4620
4694
  auctions: recent.map((x, i) => {
4621
4695
  const windowEnd = windowEnds[i];
4696
+ const dayValue = Number(x.day);
4697
+ const execution = deriveAuctionExecutionState({
4698
+ day: dayValue,
4699
+ slot: x.slot,
4700
+ currentAuctionDay: day,
4701
+ currentAuctionSlot: slot,
4702
+ settled: auctions[i].settled,
4703
+ windowEnd,
4704
+ currentTimestamp
4705
+ });
4622
4706
  return {
4623
- day: Number(x.day),
4707
+ day: dayValue,
4624
4708
  slot: x.slot,
4625
4709
  highestBidder: toChecksum(auctions[i].highestBidder),
4626
4710
  highestBid: eth(auctions[i].highestBid),
4627
4711
  settled: auctions[i].settled,
4628
4712
  windowEnd: timeValue(windowEnd, c.format),
4629
4713
  windowEndRelative: relTime(windowEnd),
4630
- status: deriveAuctionStatus({
4631
- settled: auctions[i].settled,
4632
- windowEnd,
4633
- currentTimestamp
4634
- })
4714
+ bidExecutableNow: execution.bidExecutableNow,
4715
+ executionStatus: execution.executionStatus,
4716
+ status: execution.executionStatus
4635
4717
  };
4636
4718
  })
4637
4719
  },
@@ -4649,20 +4731,22 @@ council.command("auctions", {
4649
4731
  });
4650
4732
  council.command("auction", {
4651
4733
  description: "Get one auction slot by day + slot.",
4652
- args: z.object({
4653
- day: z.coerce.number().int().nonnegative().describe("Auction day index"),
4654
- slot: z.coerce.number().int().nonnegative().describe("Slot index within day")
4734
+ args: z2.object({
4735
+ day: z2.coerce.number().int().nonnegative().describe("Auction day index"),
4736
+ slot: z2.coerce.number().int().nonnegative().describe("Slot index within day")
4655
4737
  }),
4656
4738
  env,
4657
- output: z.object({
4658
- day: z.number(),
4659
- slot: z.number(),
4660
- highestBidder: z.string(),
4661
- highestBid: z.string(),
4662
- settled: z.boolean(),
4739
+ output: z2.object({
4740
+ day: z2.number(),
4741
+ slot: z2.number(),
4742
+ highestBidder: z2.string(),
4743
+ highestBid: z2.string(),
4744
+ settled: z2.boolean(),
4663
4745
  windowEnd: timestampOutput,
4664
- windowEndRelative: z.string(),
4665
- status: z.enum(["bidding", "closed", "settled"])
4746
+ windowEndRelative: z2.string(),
4747
+ bidExecutableNow: z2.boolean(),
4748
+ executionStatus: z2.enum(["open_now", "upcoming", "closed_unsettled", "settled"]),
4749
+ status: z2.enum(["open_now", "upcoming", "closed_unsettled", "settled"])
4666
4750
  }),
4667
4751
  examples: [{ args: { day: 0, slot: 0 }, description: "Inspect day 0, slot 0 auction" }],
4668
4752
  async run(c) {
@@ -4679,7 +4763,7 @@ council.command("auction", {
4679
4763
  retryable: false
4680
4764
  });
4681
4765
  }
4682
- const [auctionTuple, windowEnd, latestBlock] = await Promise.all([
4766
+ const [auctionTuple, windowEnd, latestBlock, currentAuctionDay, currentAuctionSlot] = await Promise.all([
4683
4767
  client.readContract({
4684
4768
  abi: councilSeatsAbi,
4685
4769
  address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
@@ -4692,11 +4776,30 @@ council.command("auction", {
4692
4776
  functionName: "auctionWindowEnd",
4693
4777
  args: [BigInt(c.args.day), c.args.slot]
4694
4778
  }),
4695
- client.getBlock({ blockTag: "latest" })
4779
+ client.getBlock({ blockTag: "latest" }),
4780
+ client.readContract({
4781
+ abi: councilSeatsAbi,
4782
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
4783
+ functionName: "currentAuctionDay"
4784
+ }),
4785
+ client.readContract({
4786
+ abi: councilSeatsAbi,
4787
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
4788
+ functionName: "currentAuctionSlot"
4789
+ })
4696
4790
  ]);
4697
4791
  const auction = decodeAuction(auctionTuple);
4698
4792
  const windowEndTimestamp = windowEnd;
4699
4793
  const currentTimestamp = latestBlock.timestamp;
4794
+ const execution = deriveAuctionExecutionState({
4795
+ day: c.args.day,
4796
+ slot: c.args.slot,
4797
+ currentAuctionDay,
4798
+ currentAuctionSlot,
4799
+ settled: auction.settled,
4800
+ windowEnd: windowEndTimestamp,
4801
+ currentTimestamp
4802
+ });
4700
4803
  return c.ok({
4701
4804
  day: c.args.day,
4702
4805
  slot: c.args.slot,
@@ -4705,24 +4808,22 @@ council.command("auction", {
4705
4808
  settled: auction.settled,
4706
4809
  windowEnd: timeValue(windowEndTimestamp, c.format),
4707
4810
  windowEndRelative: relTime(windowEndTimestamp),
4708
- status: deriveAuctionStatus({
4709
- settled: auction.settled,
4710
- windowEnd: windowEndTimestamp,
4711
- currentTimestamp
4712
- })
4811
+ bidExecutableNow: execution.bidExecutableNow,
4812
+ executionStatus: execution.executionStatus,
4813
+ status: execution.executionStatus
4713
4814
  });
4714
4815
  }
4715
4816
  });
4716
4817
  council.command("pending-refund", {
4717
4818
  description: "Get pending refundable bid amount for an address.",
4718
- args: z.object({
4719
- address: z.string().describe("Bidder address")
4819
+ args: z2.object({
4820
+ address: z2.string().describe("Bidder address")
4720
4821
  }),
4721
4822
  env,
4722
- output: z.object({
4723
- address: z.string(),
4724
- pendingRefund: z.string(),
4725
- pendingRefundWei: z.string()
4823
+ output: z2.object({
4824
+ address: z2.string(),
4825
+ pendingRefund: z2.string(),
4826
+ pendingRefundWei: z2.string()
4726
4827
  }),
4727
4828
  examples: [
4728
4829
  {
@@ -4748,13 +4849,13 @@ council.command("pending-refund", {
4748
4849
  council.command("params", {
4749
4850
  description: "Read council seat term and auction scheduling parameters.",
4750
4851
  env,
4751
- output: z.object({
4752
- SEAT_TERM: z.number(),
4753
- AUCTION_SLOT_DURATION: z.number(),
4754
- AUCTION_SLOTS_PER_DAY: z.number(),
4755
- auctionEpochStart: z.number(),
4756
- auctionWindowStart: z.number(),
4757
- auctionWindowEnd: z.number()
4852
+ output: z2.object({
4853
+ SEAT_TERM: z2.number(),
4854
+ AUCTION_SLOT_DURATION: z2.number(),
4855
+ AUCTION_SLOTS_PER_DAY: z2.number(),
4856
+ auctionEpochStart: z2.number(),
4857
+ auctionWindowStart: z2.number(),
4858
+ auctionWindowEnd: z2.number()
4758
4859
  }),
4759
4860
  examples: [{ description: "Inspect council seat + auction timing constants" }],
4760
4861
  async run(c) {
@@ -4805,13 +4906,347 @@ council.command("params", {
4805
4906
  });
4806
4907
  }
4807
4908
  });
4909
+ var txResultOutput = z2.union([
4910
+ z2.object({
4911
+ status: z2.enum(["success", "reverted"]),
4912
+ hash: z2.string(),
4913
+ blockNumber: z2.number(),
4914
+ gasUsed: z2.string(),
4915
+ from: z2.string(),
4916
+ to: z2.string().nullable(),
4917
+ effectiveGasPrice: z2.string().optional()
4918
+ }),
4919
+ z2.object({
4920
+ status: z2.literal("dry-run"),
4921
+ estimatedGas: z2.string(),
4922
+ simulationResult: z2.unknown()
4923
+ })
4924
+ ]);
4925
+ council.command("bid", {
4926
+ description: "Place a bid on a council seat auction (payable).",
4927
+ hint: "Requires PRIVATE_KEY environment variable for signing.",
4928
+ args: z2.object({
4929
+ day: z2.coerce.number().int().nonnegative().describe("Auction day index"),
4930
+ slot: z2.coerce.number().int().nonnegative().describe("Slot index within day")
4931
+ }),
4932
+ options: writeOptions.extend({
4933
+ amount: z2.string().describe('ETH amount to bid (e.g. "0.1")')
4934
+ }),
4935
+ env: writeEnv,
4936
+ output: z2.object({
4937
+ day: z2.number(),
4938
+ slot: z2.number(),
4939
+ bidAmount: z2.string(),
4940
+ tx: txResultOutput
4941
+ }),
4942
+ examples: [
4943
+ {
4944
+ args: { day: 0, slot: 0 },
4945
+ options: { amount: "0.1" },
4946
+ description: "Bid 0.1 ETH on day 0, slot 0"
4947
+ }
4948
+ ],
4949
+ async run(c) {
4950
+ const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
4951
+ let amountWei;
4952
+ try {
4953
+ amountWei = parseEther(c.options.amount);
4954
+ } catch {
4955
+ return c.error({
4956
+ code: "INVALID_AMOUNT",
4957
+ message: `Invalid ETH amount: "${c.options.amount}". Provide a decimal number (e.g. "0.1").`,
4958
+ retryable: false
4959
+ });
4960
+ }
4961
+ if (amountWei <= 0n) {
4962
+ return c.error({
4963
+ code: "INVALID_AMOUNT",
4964
+ message: "Bid amount must be greater than zero.",
4965
+ retryable: false
4966
+ });
4967
+ }
4968
+ const slotsPerDay = await client.readContract({
4969
+ abi: councilSeatsAbi,
4970
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
4971
+ functionName: "AUCTION_SLOTS_PER_DAY"
4972
+ });
4973
+ if (c.args.slot >= Number(slotsPerDay)) {
4974
+ return c.error({
4975
+ code: "OUT_OF_RANGE",
4976
+ message: `Slot ${c.args.slot} does not exist (max: ${Number(slotsPerDay) - 1})`,
4977
+ retryable: false
4978
+ });
4979
+ }
4980
+ const [auctionTuple, windowEnd, latestBlock, currentAuctionDay, currentAuctionSlot] = await Promise.all([
4981
+ client.readContract({
4982
+ abi: councilSeatsAbi,
4983
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
4984
+ functionName: "auctions",
4985
+ args: [BigInt(c.args.day), c.args.slot]
4986
+ }),
4987
+ client.readContract({
4988
+ abi: councilSeatsAbi,
4989
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
4990
+ functionName: "auctionWindowEnd",
4991
+ args: [BigInt(c.args.day), c.args.slot]
4992
+ }),
4993
+ client.getBlock({ blockTag: "latest" }),
4994
+ client.readContract({
4995
+ abi: councilSeatsAbi,
4996
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
4997
+ functionName: "currentAuctionDay"
4998
+ }),
4999
+ client.readContract({
5000
+ abi: councilSeatsAbi,
5001
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
5002
+ functionName: "currentAuctionSlot"
5003
+ })
5004
+ ]);
5005
+ const auction = decodeAuction(auctionTuple);
5006
+ const windowEndTimestamp = windowEnd;
5007
+ const currentTimestamp = latestBlock.timestamp;
5008
+ const execution = deriveAuctionExecutionState({
5009
+ day: c.args.day,
5010
+ slot: c.args.slot,
5011
+ currentAuctionDay,
5012
+ currentAuctionSlot,
5013
+ settled: auction.settled,
5014
+ windowEnd: windowEndTimestamp,
5015
+ currentTimestamp
5016
+ });
5017
+ if (execution.executionStatus === "settled") {
5018
+ return c.error({
5019
+ code: "AUCTION_SETTLED",
5020
+ message: `Auction (day=${c.args.day}, slot=${c.args.slot}) is already settled. Winner: ${toChecksum(auction.highestBidder)}.`,
5021
+ retryable: false
5022
+ });
5023
+ }
5024
+ if (execution.executionStatus === "upcoming") {
5025
+ return c.error({
5026
+ code: "AUCTION_NOT_ACTIVE",
5027
+ message: `Auction (day=${c.args.day}, slot=${c.args.slot}) is not the currently active slot. Current bid-executable slot is day=${Number(currentAuctionDay)}, slot=${Number(currentAuctionSlot)}.`,
5028
+ retryable: false
5029
+ });
5030
+ }
5031
+ if (execution.executionStatus === "closed_unsettled") {
5032
+ return c.error({
5033
+ code: "AUCTION_CLOSED",
5034
+ message: `Auction (day=${c.args.day}, slot=${c.args.slot}) bidding window has ended. Use "council settle" instead.`,
5035
+ retryable: false
5036
+ });
5037
+ }
5038
+ if (auction.highestBid >= amountWei) {
5039
+ return c.error({
5040
+ code: "BID_TOO_LOW",
5041
+ message: `Bid of ${c.options.amount} ETH is not higher than current highest bid of ${eth(auction.highestBid)}. Increase your bid amount.`,
5042
+ retryable: false
5043
+ });
5044
+ }
5045
+ const txResult = await assemblyWriteTx({
5046
+ env: c.env,
5047
+ options: c.options,
5048
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
5049
+ abi: councilSeatsAbi,
5050
+ functionName: "bid",
5051
+ args: [BigInt(c.args.day), c.args.slot],
5052
+ value: amountWei
5053
+ });
5054
+ return c.ok(
5055
+ {
5056
+ day: c.args.day,
5057
+ slot: c.args.slot,
5058
+ bidAmount: `${c.options.amount} ETH`,
5059
+ tx: txResult
5060
+ },
5061
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
5062
+ cta: {
5063
+ description: "Next steps:",
5064
+ commands: [
5065
+ {
5066
+ command: "council auction",
5067
+ args: { day: String(c.args.day), slot: String(c.args.slot) },
5068
+ description: "Check auction status"
5069
+ }
5070
+ ]
5071
+ }
5072
+ }
5073
+ );
5074
+ }
5075
+ });
5076
+ council.command("settle", {
5077
+ description: "Settle a completed council seat auction.",
5078
+ hint: "Requires PRIVATE_KEY environment variable for signing.",
5079
+ args: z2.object({
5080
+ day: z2.coerce.number().int().nonnegative().describe("Auction day index"),
5081
+ slot: z2.coerce.number().int().nonnegative().describe("Slot index within day")
5082
+ }),
5083
+ options: writeOptions,
5084
+ env: writeEnv,
5085
+ output: z2.object({
5086
+ day: z2.number(),
5087
+ slot: z2.number(),
5088
+ highestBidder: z2.string(),
5089
+ highestBid: z2.string(),
5090
+ tx: txResultOutput
5091
+ }),
5092
+ examples: [
5093
+ {
5094
+ args: { day: 0, slot: 0 },
5095
+ description: "Settle the auction for day 0, slot 0"
5096
+ }
5097
+ ],
5098
+ async run(c) {
5099
+ const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
5100
+ const slotsPerDay = await client.readContract({
5101
+ abi: councilSeatsAbi,
5102
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
5103
+ functionName: "AUCTION_SLOTS_PER_DAY"
5104
+ });
5105
+ if (c.args.slot >= Number(slotsPerDay)) {
5106
+ return c.error({
5107
+ code: "OUT_OF_RANGE",
5108
+ message: `Slot ${c.args.slot} does not exist (max: ${Number(slotsPerDay) - 1})`,
5109
+ retryable: false
5110
+ });
5111
+ }
5112
+ const [auctionTuple, windowEnd, latestBlock, currentAuctionDay, currentAuctionSlot] = await Promise.all([
5113
+ client.readContract({
5114
+ abi: councilSeatsAbi,
5115
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
5116
+ functionName: "auctions",
5117
+ args: [BigInt(c.args.day), c.args.slot]
5118
+ }),
5119
+ client.readContract({
5120
+ abi: councilSeatsAbi,
5121
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
5122
+ functionName: "auctionWindowEnd",
5123
+ args: [BigInt(c.args.day), c.args.slot]
5124
+ }),
5125
+ client.getBlock({ blockTag: "latest" }),
5126
+ client.readContract({
5127
+ abi: councilSeatsAbi,
5128
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
5129
+ functionName: "currentAuctionDay"
5130
+ }),
5131
+ client.readContract({
5132
+ abi: councilSeatsAbi,
5133
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
5134
+ functionName: "currentAuctionSlot"
5135
+ })
5136
+ ]);
5137
+ const auction = decodeAuction(auctionTuple);
5138
+ const windowEndTimestamp = windowEnd;
5139
+ const currentTimestamp = latestBlock.timestamp;
5140
+ const execution = deriveAuctionExecutionState({
5141
+ day: c.args.day,
5142
+ slot: c.args.slot,
5143
+ currentAuctionDay,
5144
+ currentAuctionSlot,
5145
+ settled: auction.settled,
5146
+ windowEnd: windowEndTimestamp,
5147
+ currentTimestamp
5148
+ });
5149
+ if (execution.executionStatus === "settled") {
5150
+ return c.error({
5151
+ code: "ALREADY_SETTLED",
5152
+ message: `Auction (day=${c.args.day}, slot=${c.args.slot}) is already settled.`,
5153
+ retryable: false
5154
+ });
5155
+ }
5156
+ if (execution.executionStatus === "open_now") {
5157
+ return c.error({
5158
+ code: "AUCTION_STILL_ACTIVE",
5159
+ message: `Auction (day=${c.args.day}, slot=${c.args.slot}) is still accepting bids. Window ends ${relTime(windowEndTimestamp)}.`,
5160
+ retryable: false
5161
+ });
5162
+ }
5163
+ if (execution.executionStatus === "upcoming") {
5164
+ return c.error({
5165
+ code: "AUCTION_STILL_ACTIVE",
5166
+ message: `Auction (day=${c.args.day}, slot=${c.args.slot}) is not yet the active slot. Current slot is day=${Number(currentAuctionDay)}, slot=${Number(currentAuctionSlot)}.`,
5167
+ retryable: false
5168
+ });
5169
+ }
5170
+ const txResult = await assemblyWriteTx({
5171
+ env: c.env,
5172
+ options: c.options,
5173
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
5174
+ abi: councilSeatsAbi,
5175
+ functionName: "settleAuction",
5176
+ args: [BigInt(c.args.day), c.args.slot]
5177
+ });
5178
+ return c.ok(
5179
+ {
5180
+ day: c.args.day,
5181
+ slot: c.args.slot,
5182
+ highestBidder: toChecksum(auction.highestBidder),
5183
+ highestBid: eth(auction.highestBid),
5184
+ tx: txResult
5185
+ },
5186
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
5187
+ cta: {
5188
+ description: "Next steps:",
5189
+ commands: [
5190
+ {
5191
+ command: "council seats",
5192
+ description: "View updated council seats"
5193
+ }
5194
+ ]
5195
+ }
5196
+ }
5197
+ );
5198
+ }
5199
+ });
5200
+ council.command("withdraw-refund", {
5201
+ description: "Withdraw pending bid refunds for the signer address.",
5202
+ hint: "Requires PRIVATE_KEY environment variable for signing.",
5203
+ options: writeOptions,
5204
+ env: writeEnv,
5205
+ output: z2.object({
5206
+ address: z2.string(),
5207
+ refundAmount: z2.string(),
5208
+ refundAmountWei: z2.string(),
5209
+ tx: txResultOutput.optional()
5210
+ }),
5211
+ examples: [{ description: "Withdraw all pending bid refunds" }],
5212
+ async run(c) {
5213
+ const account = resolveAccount(c.env);
5214
+ const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
5215
+ const pendingAmount = await client.readContract({
5216
+ abi: councilSeatsAbi,
5217
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
5218
+ functionName: "pendingReturns",
5219
+ args: [account.address]
5220
+ });
5221
+ if (pendingAmount === 0n) {
5222
+ return c.ok({
5223
+ address: toChecksum(account.address),
5224
+ refundAmount: "0 ETH",
5225
+ refundAmountWei: "0"
5226
+ });
5227
+ }
5228
+ const txResult = await assemblyWriteTx({
5229
+ env: c.env,
5230
+ options: c.options,
5231
+ address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
5232
+ abi: councilSeatsAbi,
5233
+ functionName: "withdrawRefund"
5234
+ });
5235
+ return c.ok({
5236
+ address: toChecksum(account.address),
5237
+ refundAmount: eth(pendingAmount),
5238
+ refundAmountWei: pendingAmount.toString(),
5239
+ tx: txResult
5240
+ });
5241
+ }
5242
+ });
4808
5243
 
4809
5244
  // src/commands/forum.ts
4810
- import { Cli as Cli2, z as z2 } from "incur";
4811
- var env2 = z2.object({
4812
- ABSTRACT_RPC_URL: z2.string().optional().describe("Abstract RPC URL override")
5245
+ import { Cli as Cli2, z as z3 } from "incur";
5246
+ var env2 = z3.object({
5247
+ ABSTRACT_RPC_URL: z3.string().optional().describe("Abstract RPC URL override")
4813
5248
  });
4814
- var timestampOutput2 = z2.union([z2.number(), z2.string()]);
5249
+ var timestampOutput2 = z3.union([z3.number(), z3.string()]);
4815
5250
  function decodeThread(value) {
4816
5251
  const [id, kind, author, createdAt, category, title, body, proposalId, petitionId] = value;
4817
5252
  return {
@@ -4869,19 +5304,19 @@ var forum = Cli2.create("forum", {
4869
5304
  forum.command("threads", {
4870
5305
  description: "List forum threads with author and creation metadata.",
4871
5306
  env: env2,
4872
- output: z2.object({
4873
- threads: z2.array(
4874
- z2.object({
4875
- id: z2.number(),
4876
- kind: z2.number(),
4877
- author: z2.string(),
5307
+ output: z3.object({
5308
+ threads: z3.array(
5309
+ z3.object({
5310
+ id: z3.number(),
5311
+ kind: z3.number(),
5312
+ author: z3.string(),
4878
5313
  createdAt: timestampOutput2,
4879
- createdAtRelative: z2.string(),
4880
- category: z2.string().nullable().optional(),
4881
- title: z2.string().nullable().optional()
5314
+ createdAtRelative: z3.string(),
5315
+ category: z3.string().nullable().optional(),
5316
+ title: z3.string().nullable().optional()
4882
5317
  })
4883
5318
  ),
4884
- count: z2.number()
5319
+ count: z3.number()
4885
5320
  }),
4886
5321
  examples: [{ description: "List all forum threads" }],
4887
5322
  async run(c) {
@@ -4930,13 +5365,13 @@ forum.command("threads", {
4930
5365
  });
4931
5366
  forum.command("thread", {
4932
5367
  description: "Get one thread and all comments associated with it.",
4933
- args: z2.object({
4934
- id: z2.coerce.number().int().positive().describe("Thread id (1-indexed)")
5368
+ args: z3.object({
5369
+ id: z3.coerce.number().int().positive().describe("Thread id (1-indexed)")
4935
5370
  }),
4936
5371
  env: env2,
4937
- output: z2.object({
4938
- thread: z2.record(z2.string(), z2.unknown()),
4939
- comments: z2.array(z2.record(z2.string(), z2.unknown()))
5372
+ output: z3.object({
5373
+ thread: z3.record(z3.string(), z3.unknown()),
5374
+ comments: z3.array(z3.record(z3.string(), z3.unknown()))
4940
5375
  }),
4941
5376
  examples: [{ args: { id: 1 }, description: "Fetch thread #1 and its comments" }],
4942
5377
  async run(c) {
@@ -4986,11 +5421,11 @@ forum.command("thread", {
4986
5421
  });
4987
5422
  forum.command("comments", {
4988
5423
  description: "List comments for a thread id.",
4989
- args: z2.object({
4990
- threadId: z2.coerce.number().int().positive().describe("Thread id to filter comments by")
5424
+ args: z3.object({
5425
+ threadId: z3.coerce.number().int().positive().describe("Thread id to filter comments by")
4991
5426
  }),
4992
5427
  env: env2,
4993
- output: z2.array(z2.record(z2.string(), z2.unknown())),
5428
+ output: z3.array(z3.record(z3.string(), z3.unknown())),
4994
5429
  examples: [{ args: { threadId: 1 }, description: "List comments for thread #1" }],
4995
5430
  async run(c) {
4996
5431
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
@@ -5017,11 +5452,11 @@ forum.command("comments", {
5017
5452
  });
5018
5453
  forum.command("comment", {
5019
5454
  description: "Get one comment by comment id.",
5020
- args: z2.object({
5021
- id: z2.coerce.number().int().positive().describe("Comment id (1-indexed)")
5455
+ args: z3.object({
5456
+ id: z3.coerce.number().int().positive().describe("Comment id (1-indexed)")
5022
5457
  }),
5023
5458
  env: env2,
5024
- output: z2.record(z2.string(), z2.unknown()),
5459
+ output: z3.record(z3.string(), z3.unknown()),
5025
5460
  examples: [{ args: { id: 1 }, description: "Fetch comment #1" }],
5026
5461
  async run(c) {
5027
5462
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
@@ -5049,7 +5484,7 @@ forum.command("comment", {
5049
5484
  forum.command("petitions", {
5050
5485
  description: "List petitions submitted in the forum contract.",
5051
5486
  env: env2,
5052
- output: z2.array(z2.record(z2.string(), z2.unknown())),
5487
+ output: z3.array(z3.record(z3.string(), z3.unknown())),
5053
5488
  examples: [{ description: "List all petitions" }],
5054
5489
  async run(c) {
5055
5490
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
@@ -5074,11 +5509,11 @@ forum.command("petitions", {
5074
5509
  });
5075
5510
  forum.command("petition", {
5076
5511
  description: "Get one petition plus whether proposer already signed it.",
5077
- args: z2.object({
5078
- id: z2.coerce.number().int().positive().describe("Petition id (1-indexed)")
5512
+ args: z3.object({
5513
+ id: z3.coerce.number().int().positive().describe("Petition id (1-indexed)")
5079
5514
  }),
5080
5515
  env: env2,
5081
- output: z2.object({ proposerSigned: z2.boolean() }).passthrough(),
5516
+ output: z3.object({ proposerSigned: z3.boolean() }).passthrough(),
5082
5517
  examples: [{ args: { id: 1 }, description: "Fetch petition #1" }],
5083
5518
  async run(c) {
5084
5519
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
@@ -5113,15 +5548,15 @@ forum.command("petition", {
5113
5548
  });
5114
5549
  forum.command("has-signed", {
5115
5550
  description: "Check whether an address signed a petition.",
5116
- args: z2.object({
5117
- petitionId: z2.coerce.number().int().positive().describe("Petition id (1-indexed)"),
5118
- address: z2.string().describe("Signer address to check")
5551
+ args: z3.object({
5552
+ petitionId: z3.coerce.number().int().positive().describe("Petition id (1-indexed)"),
5553
+ address: z3.string().describe("Signer address to check")
5119
5554
  }),
5120
5555
  env: env2,
5121
- output: z2.object({
5122
- petitionId: z2.number(),
5123
- address: z2.string(),
5124
- hasSigned: z2.boolean()
5556
+ output: z3.object({
5557
+ petitionId: z3.number(),
5558
+ address: z3.string(),
5559
+ hasSigned: z3.boolean()
5125
5560
  }),
5126
5561
  examples: [
5127
5562
  {
@@ -5146,11 +5581,11 @@ forum.command("has-signed", {
5146
5581
  forum.command("stats", {
5147
5582
  description: "Read top-level forum counters and petition threshold.",
5148
5583
  env: env2,
5149
- output: z2.object({
5150
- threadCount: z2.number(),
5151
- commentCount: z2.number(),
5152
- petitionCount: z2.number(),
5153
- petitionThresholdBps: z2.number()
5584
+ output: z3.object({
5585
+ threadCount: z3.number(),
5586
+ commentCount: z3.number(),
5587
+ petitionCount: z3.number(),
5588
+ petitionThresholdBps: z3.number()
5154
5589
  }),
5155
5590
  examples: [{ description: "Get forum counts and petition threshold" }],
5156
5591
  async run(c) {
@@ -5187,11 +5622,11 @@ forum.command("stats", {
5187
5622
  });
5188
5623
 
5189
5624
  // src/commands/governance.ts
5190
- import { Cli as Cli3, z as z3 } from "incur";
5191
- var env3 = z3.object({
5192
- ABSTRACT_RPC_URL: z3.string().optional().describe("Abstract RPC URL override")
5625
+ import { Cli as Cli3, z as z4 } from "incur";
5626
+ var env3 = z4.object({
5627
+ ABSTRACT_RPC_URL: z4.string().optional().describe("Abstract RPC URL override")
5193
5628
  });
5194
- var timestampOutput3 = z3.union([z3.number(), z3.string()]);
5629
+ var timestampOutput3 = z4.union([z4.number(), z4.string()]);
5195
5630
  var proposalStatusLabels = {
5196
5631
  0: "pending",
5197
5632
  1: "active",
@@ -5207,31 +5642,31 @@ function proposalStatus(status) {
5207
5642
  statusCode
5208
5643
  };
5209
5644
  }
5210
- var proposalOutputSchema = z3.object({
5211
- kind: z3.number(),
5212
- configRiskTier: z3.number(),
5213
- origin: z3.number(),
5214
- status: z3.string(),
5215
- statusCode: z3.number(),
5216
- proposer: z3.string(),
5217
- threadId: z3.number(),
5218
- petitionId: z3.number(),
5219
- createdAt: z3.number(),
5220
- deliberationEndsAt: z3.number(),
5221
- voteStartAt: z3.number(),
5222
- voteEndAt: z3.number(),
5223
- timelockEndsAt: z3.number(),
5224
- activeSeatsSnapshot: z3.number(),
5225
- forVotes: z3.string(),
5226
- againstVotes: z3.string(),
5227
- abstainVotes: z3.string(),
5228
- amount: z3.string(),
5229
- snapshotAssetBalance: z3.string(),
5230
- transferIntent: z3.boolean(),
5231
- intentDeadline: z3.number(),
5232
- intentMaxRiskTier: z3.number(),
5233
- title: z3.string(),
5234
- description: z3.string()
5645
+ var proposalOutputSchema = z4.object({
5646
+ kind: z4.number(),
5647
+ configRiskTier: z4.number(),
5648
+ origin: z4.number(),
5649
+ status: z4.string(),
5650
+ statusCode: z4.number(),
5651
+ proposer: z4.string(),
5652
+ threadId: z4.number(),
5653
+ petitionId: z4.number(),
5654
+ createdAt: z4.number(),
5655
+ deliberationEndsAt: z4.number(),
5656
+ voteStartAt: z4.number(),
5657
+ voteEndAt: z4.number(),
5658
+ timelockEndsAt: z4.number(),
5659
+ activeSeatsSnapshot: z4.number(),
5660
+ forVotes: z4.string(),
5661
+ againstVotes: z4.string(),
5662
+ abstainVotes: z4.string(),
5663
+ amount: z4.string(),
5664
+ snapshotAssetBalance: z4.string(),
5665
+ transferIntent: z4.boolean(),
5666
+ intentDeadline: z4.number(),
5667
+ intentMaxRiskTier: z4.number(),
5668
+ title: z4.string(),
5669
+ description: z4.string()
5235
5670
  });
5236
5671
  function decodeProposal(value) {
5237
5672
  const [
@@ -5320,19 +5755,19 @@ var governance = Cli3.create("governance", {
5320
5755
  governance.command("proposals", {
5321
5756
  description: "List governance proposals with status and vote end time.",
5322
5757
  env: env3,
5323
- output: z3.object({
5324
- proposals: z3.array(
5325
- z3.object({
5326
- id: z3.number(),
5327
- kind: z3.number(),
5328
- status: z3.string(),
5329
- statusCode: z3.number(),
5330
- title: z3.string().nullable().optional(),
5758
+ output: z4.object({
5759
+ proposals: z4.array(
5760
+ z4.object({
5761
+ id: z4.number(),
5762
+ kind: z4.number(),
5763
+ status: z4.string(),
5764
+ statusCode: z4.number(),
5765
+ title: z4.string().nullable().optional(),
5331
5766
  voteEndAt: timestampOutput3,
5332
- voteEndRelative: z3.string()
5767
+ voteEndRelative: z4.string()
5333
5768
  })
5334
5769
  ),
5335
- count: z3.number()
5770
+ count: z4.number()
5336
5771
  }),
5337
5772
  examples: [{ description: "List all proposals" }],
5338
5773
  async run(c) {
@@ -5380,8 +5815,8 @@ governance.command("proposals", {
5380
5815
  });
5381
5816
  governance.command("proposal", {
5382
5817
  description: "Get full raw proposal details by proposal id.",
5383
- args: z3.object({
5384
- id: z3.coerce.number().int().positive().describe("Proposal id (1-indexed)")
5818
+ args: z4.object({
5819
+ id: z4.coerce.number().int().positive().describe("Proposal id (1-indexed)")
5385
5820
  }),
5386
5821
  env: env3,
5387
5822
  output: proposalOutputSchema,
@@ -5413,15 +5848,15 @@ governance.command("proposal", {
5413
5848
  });
5414
5849
  governance.command("has-voted", {
5415
5850
  description: "Check if an address has voted on a proposal.",
5416
- args: z3.object({
5417
- proposalId: z3.coerce.number().int().positive().describe("Proposal id (1-indexed)"),
5418
- address: z3.string().describe("Voter address")
5851
+ args: z4.object({
5852
+ proposalId: z4.coerce.number().int().positive().describe("Proposal id (1-indexed)"),
5853
+ address: z4.string().describe("Voter address")
5419
5854
  }),
5420
5855
  env: env3,
5421
- output: z3.object({
5422
- proposalId: z3.number(),
5423
- address: z3.string(),
5424
- hasVoted: z3.boolean()
5856
+ output: z4.object({
5857
+ proposalId: z4.number(),
5858
+ address: z4.string(),
5859
+ hasVoted: z4.boolean()
5425
5860
  }),
5426
5861
  examples: [
5427
5862
  {
@@ -5450,19 +5885,19 @@ governance.command("has-voted", {
5450
5885
  governance.command("params", {
5451
5886
  description: "Read governance threshold and timing parameters.",
5452
5887
  env: env3,
5453
- output: z3.object({
5454
- deliberationPeriod: z3.number(),
5455
- votePeriod: z3.number(),
5456
- quorumBps: z3.number(),
5457
- constitutionalDeliberationPeriod: z3.number(),
5458
- constitutionalVotePeriod: z3.number(),
5459
- constitutionalPassBps: z3.number(),
5460
- majorPassBps: z3.number(),
5461
- parameterPassBps: z3.number(),
5462
- significantPassBps: z3.number(),
5463
- significantThresholdBps: z3.number(),
5464
- routineThresholdBps: z3.number(),
5465
- timelockPeriod: z3.number()
5888
+ output: z4.object({
5889
+ deliberationPeriod: z4.number(),
5890
+ votePeriod: z4.number(),
5891
+ quorumBps: z4.number(),
5892
+ constitutionalDeliberationPeriod: z4.number(),
5893
+ constitutionalVotePeriod: z4.number(),
5894
+ constitutionalPassBps: z4.number(),
5895
+ majorPassBps: z4.number(),
5896
+ parameterPassBps: z4.number(),
5897
+ significantPassBps: z4.number(),
5898
+ significantThresholdBps: z4.number(),
5899
+ routineThresholdBps: z4.number(),
5900
+ timelockPeriod: z4.number()
5466
5901
  }),
5467
5902
  examples: [{ description: "Inspect governance timing and pass thresholds" }],
5468
5903
  async run(c) {
@@ -5507,16 +5942,26 @@ governance.command("params", {
5507
5942
  });
5508
5943
 
5509
5944
  // src/commands/members.ts
5510
- import { Cli as Cli4, z as z4 } from "incur";
5945
+ import { TxError } from "@spectratools/tx-shared";
5946
+ import { Cli as Cli4, z as z5 } from "incur";
5511
5947
  var DEFAULT_MEMBER_SNAPSHOT_URL = "https://www.theaiassembly.org/api/indexer/members";
5512
5948
  var REGISTERED_EVENT_SCAN_STEP = 100000n;
5513
5949
  var REGISTERED_EVENT_SCAN_TIMEOUT_MS = 2e4;
5514
- var env4 = z4.object({
5515
- ABSTRACT_RPC_URL: z4.string().optional().describe("Abstract RPC URL override"),
5516
- ASSEMBLY_INDEXER_URL: z4.string().optional().describe("Optional members snapshot endpoint (default: theaiassembly.org indexer)")
5950
+ var MAX_MEMBER_LOOKUP_SUGGESTIONS = 5;
5951
+ var env4 = z5.object({
5952
+ ABSTRACT_RPC_URL: z5.string().optional().describe("Abstract RPC URL override"),
5953
+ ASSEMBLY_INDEXER_URL: z5.string().optional().describe("Optional members snapshot endpoint (default: theaiassembly.org indexer)")
5517
5954
  });
5518
- var timestampOutput4 = z4.union([z4.number(), z4.string()]);
5519
- var memberSnapshotSchema = z4.array(z4.string());
5955
+ var timestampOutput4 = z5.union([z5.number(), z5.string()]);
5956
+ var memberSnapshotEntrySchema = z5.union([
5957
+ z5.string(),
5958
+ z5.object({
5959
+ address: z5.string(),
5960
+ ens: z5.string().optional(),
5961
+ name: z5.string().optional()
5962
+ })
5963
+ ]);
5964
+ var memberSnapshotSchema = z5.array(memberSnapshotEntrySchema);
5520
5965
  var AssemblyApiValidationError = class extends Error {
5521
5966
  constructor(details) {
5522
5967
  super("Assembly API response validation failed");
@@ -5531,6 +5976,45 @@ var AssemblyIndexerUnavailableError = class extends Error {
5531
5976
  this.name = "AssemblyIndexerUnavailableError";
5532
5977
  }
5533
5978
  };
5979
+ function mergeMemberIdentities(entries) {
5980
+ const byAddress = /* @__PURE__ */ new Map();
5981
+ for (const entry of entries) {
5982
+ const key = entry.address.toLowerCase();
5983
+ const existing = byAddress.get(key);
5984
+ if (!existing) {
5985
+ byAddress.set(key, entry);
5986
+ continue;
5987
+ }
5988
+ const merged = { address: existing.address };
5989
+ const ens = existing.ens ?? entry.ens;
5990
+ const name = existing.name ?? entry.name;
5991
+ if (ens !== void 0) merged.ens = ens;
5992
+ if (name !== void 0) merged.name = name;
5993
+ byAddress.set(key, merged);
5994
+ }
5995
+ return [...byAddress.values()];
5996
+ }
5997
+ function memberSnapshotEntryToIdentity(entry) {
5998
+ if (typeof entry === "string") return { address: entry };
5999
+ const identity = { address: entry.address };
6000
+ if (entry.ens !== void 0) identity.ens = entry.ens;
6001
+ if (entry.name !== void 0) identity.name = entry.name;
6002
+ return identity;
6003
+ }
6004
+ function matchableAddressInput(query) {
6005
+ return query.startsWith("0x") && query.length === 42;
6006
+ }
6007
+ function searchMemberIdentities(query, members2) {
6008
+ const needle = query.trim().toLowerCase();
6009
+ if (needle.length === 0) return [];
6010
+ const exactMatches = members2.filter((member) => {
6011
+ return member.address.toLowerCase() === needle || member.ens?.toLowerCase() === needle || member.name?.toLowerCase() === needle;
6012
+ });
6013
+ if (exactMatches.length > 0) return exactMatches;
6014
+ return members2.filter((member) => {
6015
+ return member.address.toLowerCase().includes(needle) || member.ens?.toLowerCase().includes(needle) || member.name?.toLowerCase().includes(needle);
6016
+ });
6017
+ }
5534
6018
  async function memberSnapshot(url) {
5535
6019
  let res;
5536
6020
  try {
@@ -5553,7 +6037,7 @@ async function memberSnapshot(url) {
5553
6037
  const json = await res.json();
5554
6038
  const parsed = memberSnapshotSchema.safeParse(json);
5555
6039
  if (parsed.success) {
5556
- return parsed.data;
6040
+ return mergeMemberIdentities(parsed.data.map(memberSnapshotEntryToIdentity));
5557
6041
  }
5558
6042
  throw new AssemblyApiValidationError({
5559
6043
  code: "INVALID_ASSEMBLY_API_RESPONSE",
@@ -5597,7 +6081,28 @@ async function membersFromRegisteredEvents(client) {
5597
6081
  }
5598
6082
  }
5599
6083
  }
5600
- return [...addresses];
6084
+ return [...addresses].map((address) => ({ address }));
6085
+ }
6086
+ async function loadMemberIdentities(client, snapshotUrl) {
6087
+ try {
6088
+ return { members: await memberSnapshot(snapshotUrl) };
6089
+ } catch (error) {
6090
+ if (error instanceof AssemblyApiValidationError) {
6091
+ throw error;
6092
+ }
6093
+ if (!(error instanceof AssemblyIndexerUnavailableError)) {
6094
+ throw error;
6095
+ }
6096
+ const fallbackMembers = await withTimeout(
6097
+ membersFromRegisteredEvents(client),
6098
+ REGISTERED_EVENT_SCAN_TIMEOUT_MS,
6099
+ `Registered event fallback scan timed out after ${REGISTERED_EVENT_SCAN_TIMEOUT_MS}ms`
6100
+ );
6101
+ return {
6102
+ members: mergeMemberIdentities(fallbackMembers),
6103
+ fallbackReason: error.details
6104
+ };
6105
+ }
5601
6106
  }
5602
6107
  function indexerIssue(details) {
5603
6108
  if (typeof details.status === "number") {
@@ -5618,25 +6123,31 @@ function emitIndexerFallbackWarning(details) {
5618
6123
  `
5619
6124
  );
5620
6125
  }
6126
+ function describeMember(member) {
6127
+ const parts = [toChecksum(member.address)];
6128
+ if (member.ens) parts.push(`ens=${member.ens}`);
6129
+ if (member.name) parts.push(`name=${member.name}`);
6130
+ return parts.join(" ");
6131
+ }
5621
6132
  var members = Cli4.create("members", {
5622
6133
  description: "Inspect Assembly membership and registry fee state."
5623
6134
  });
5624
6135
  members.command("list", {
5625
6136
  description: "List members from an indexer snapshot (or Registered event fallback) plus on-chain active state.",
5626
6137
  env: env4,
5627
- output: z4.object({
5628
- members: z4.array(
5629
- z4.object({
5630
- address: z4.string(),
5631
- active: z4.boolean(),
5632
- registered: z4.boolean(),
6138
+ output: z5.object({
6139
+ members: z5.array(
6140
+ z5.object({
6141
+ address: z5.string(),
6142
+ active: z5.boolean(),
6143
+ registered: z5.boolean(),
5633
6144
  activeUntil: timestampOutput4,
5634
- activeUntilRelative: z4.string(),
6145
+ activeUntilRelative: z5.string(),
5635
6146
  lastHeartbeatAt: timestampOutput4,
5636
- lastHeartbeatRelative: z4.string()
6147
+ lastHeartbeatRelative: z5.string()
5637
6148
  })
5638
6149
  ),
5639
- count: z4.number()
6150
+ count: z5.number()
5640
6151
  }),
5641
6152
  examples: [
5642
6153
  { description: "List members using default indexer snapshot" },
@@ -5645,10 +6156,12 @@ members.command("list", {
5645
6156
  async run(c) {
5646
6157
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
5647
6158
  const snapshotUrl = c.env.ASSEMBLY_INDEXER_URL ?? DEFAULT_MEMBER_SNAPSHOT_URL;
5648
- let addresses;
6159
+ let memberIdentities;
5649
6160
  let fallbackReason;
5650
6161
  try {
5651
- addresses = await memberSnapshot(snapshotUrl);
6162
+ const loaded = await loadMemberIdentities(client, snapshotUrl);
6163
+ memberIdentities = loaded.members;
6164
+ fallbackReason = loaded.fallbackReason;
5652
6165
  } catch (error) {
5653
6166
  if (error instanceof AssemblyApiValidationError) {
5654
6167
  return c.error({
@@ -5657,27 +6170,19 @@ members.command("list", {
5657
6170
  retryable: false
5658
6171
  });
5659
6172
  }
5660
- if (!(error instanceof AssemblyIndexerUnavailableError)) {
6173
+ if (!(error instanceof Error)) {
5661
6174
  throw error;
5662
6175
  }
5663
- fallbackReason = error.details;
5664
- try {
5665
- addresses = await withTimeout(
5666
- membersFromRegisteredEvents(client),
5667
- REGISTERED_EVENT_SCAN_TIMEOUT_MS,
5668
- `Registered event fallback scan timed out after ${REGISTERED_EVENT_SCAN_TIMEOUT_MS}ms`
5669
- );
5670
- } catch (fallbackError) {
5671
- return c.error({
5672
- code: "MEMBER_LIST_SOURCE_UNAVAILABLE",
5673
- message: `Member indexer unavailable (${indexerIssue(error.details)} at ${error.details.url}) and on-chain Registered event fallback failed: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`,
5674
- retryable: true
5675
- });
5676
- }
6176
+ return c.error({
6177
+ code: "MEMBER_LIST_SOURCE_UNAVAILABLE",
6178
+ message: `Unable to load member list from indexer (${snapshotUrl}) or on-chain fallback: ${error.message}`,
6179
+ retryable: true
6180
+ });
5677
6181
  }
5678
6182
  if (fallbackReason) {
5679
6183
  emitIndexerFallbackWarning(fallbackReason);
5680
6184
  }
6185
+ const addresses = memberIdentities.map((member) => member.address);
5681
6186
  const calls = addresses.flatMap((address) => [
5682
6187
  {
5683
6188
  abi: registryAbi,
@@ -5713,43 +6218,91 @@ members.command("list", {
5713
6218
  }
5714
6219
  });
5715
6220
  members.command("info", {
5716
- description: "Get registry record and active status for a member address.",
5717
- args: z4.object({
5718
- address: z4.string().describe("Member wallet address")
6221
+ description: "Get member registry record and active status by full address, partial address, ENS, or name.",
6222
+ args: z5.object({
6223
+ address: z5.string().describe("Member lookup query (full/partial address, ENS, or name metadata)")
5719
6224
  }),
5720
6225
  env: env4,
5721
- output: z4.object({
5722
- address: z4.string(),
5723
- active: z4.boolean(),
6226
+ output: z5.object({
6227
+ address: z5.string(),
6228
+ active: z5.boolean(),
5724
6229
  activeUntil: timestampOutput4,
5725
6230
  lastHeartbeatAt: timestampOutput4,
5726
- activeUntilRelative: z4.string(),
5727
- lastHeartbeatRelative: z4.string()
6231
+ activeUntilRelative: z5.string(),
6232
+ lastHeartbeatRelative: z5.string()
5728
6233
  }),
5729
6234
  examples: [
5730
6235
  {
5731
6236
  args: { address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" },
5732
6237
  description: "Inspect one member address"
6238
+ },
6239
+ {
6240
+ args: { address: "a96045" },
6241
+ description: "Lookup a member by partial address"
5733
6242
  }
5734
6243
  ],
5735
6244
  async run(c) {
5736
6245
  const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
6246
+ const snapshotUrl = c.env.ASSEMBLY_INDEXER_URL ?? DEFAULT_MEMBER_SNAPSHOT_URL;
6247
+ let lookupAddress = c.args.address;
6248
+ if (!matchableAddressInput(c.args.address)) {
6249
+ let loadedMembers;
6250
+ let fallbackReason;
6251
+ try {
6252
+ const loaded = await loadMemberIdentities(client, snapshotUrl);
6253
+ loadedMembers = loaded.members;
6254
+ fallbackReason = loaded.fallbackReason;
6255
+ } catch (error) {
6256
+ if (error instanceof AssemblyApiValidationError) {
6257
+ return c.error({
6258
+ code: error.details.code,
6259
+ message: `Member snapshot response failed validation. url=${error.details.url}; issues=${JSON.stringify(error.details.issues)}; response=${JSON.stringify(error.details.response)}`,
6260
+ retryable: false
6261
+ });
6262
+ }
6263
+ return c.error({
6264
+ code: "MEMBER_LOOKUP_SOURCE_UNAVAILABLE",
6265
+ message: error instanceof Error ? `Unable to resolve member query from indexer (${snapshotUrl}) or on-chain fallback: ${error.message}` : `Unable to resolve member query from indexer (${snapshotUrl}) or on-chain fallback.`,
6266
+ retryable: true
6267
+ });
6268
+ }
6269
+ if (fallbackReason) {
6270
+ emitIndexerFallbackWarning(fallbackReason);
6271
+ }
6272
+ const matches = searchMemberIdentities(c.args.address, loadedMembers);
6273
+ if (matches.length === 0) {
6274
+ return c.error({
6275
+ code: "MEMBER_NOT_FOUND",
6276
+ message: `No Assembly member matched "${c.args.address}". Try a longer query or run \`assembly members list\` first.`,
6277
+ retryable: false
6278
+ });
6279
+ }
6280
+ if (matches.length > 1) {
6281
+ const suggestions = matches.slice(0, MAX_MEMBER_LOOKUP_SUGGESTIONS).map(describeMember).join("; ");
6282
+ return c.error({
6283
+ code: "AMBIGUOUS_MEMBER_QUERY",
6284
+ message: `Member query "${c.args.address}" matched ${matches.length} members. Be more specific. Matches: ${suggestions}`,
6285
+ retryable: false
6286
+ });
6287
+ }
6288
+ lookupAddress = matches[0].address;
6289
+ }
5737
6290
  const [member, active] = await Promise.all([
5738
6291
  client.readContract({
5739
6292
  abi: registryAbi,
5740
6293
  address: ABSTRACT_MAINNET_ADDRESSES.registry,
5741
6294
  functionName: "members",
5742
- args: [c.args.address]
6295
+ args: [lookupAddress]
5743
6296
  }),
5744
6297
  client.readContract({
5745
6298
  abi: registryAbi,
5746
6299
  address: ABSTRACT_MAINNET_ADDRESSES.registry,
5747
6300
  functionName: "isActive",
5748
- args: [c.args.address]
6301
+ args: [lookupAddress]
5749
6302
  })
5750
6303
  ]);
5751
6304
  return c.ok({
5752
- address: toChecksum(c.args.address),
6305
+ address: toChecksum(lookupAddress),
5753
6306
  active,
5754
6307
  activeUntil: timeValue(member.activeUntil, c.format),
5755
6308
  lastHeartbeatAt: timeValue(member.lastHeartbeatAt, c.format),
@@ -5761,9 +6314,9 @@ members.command("info", {
5761
6314
  members.command("count", {
5762
6315
  description: "Get active and total-known member counts from Registry.",
5763
6316
  env: env4,
5764
- output: z4.object({
5765
- active: z4.number(),
5766
- total: z4.number()
6317
+ output: z5.object({
6318
+ active: z5.number(),
6319
+ total: z5.number()
5767
6320
  }),
5768
6321
  examples: [{ description: "Count active and known members" }],
5769
6322
  async run(c) {
@@ -5786,12 +6339,12 @@ members.command("count", {
5786
6339
  members.command("fees", {
5787
6340
  description: "Get registration and heartbeat fee settings.",
5788
6341
  env: env4,
5789
- output: z4.object({
5790
- registrationFeeWei: z4.string(),
5791
- registrationFee: z4.string(),
5792
- heartbeatFeeWei: z4.string(),
5793
- heartbeatFee: z4.string(),
5794
- heartbeatGracePeriodSeconds: z4.number()
6342
+ output: z5.object({
6343
+ registrationFeeWei: z5.string(),
6344
+ registrationFee: z5.string(),
6345
+ heartbeatFeeWei: z5.string(),
6346
+ heartbeatFee: z5.string(),
6347
+ heartbeatGracePeriodSeconds: z5.number()
5795
6348
  }),
5796
6349
  examples: [{ description: "Inspect current registry fee configuration" }],
5797
6350
  async run(c) {
@@ -5822,23 +6375,196 @@ members.command("fees", {
5822
6375
  });
5823
6376
  }
5824
6377
  });
6378
+ var txOutputSchema = z5.union([
6379
+ z5.object({
6380
+ status: z5.enum(["success", "reverted"]),
6381
+ hash: z5.string(),
6382
+ blockNumber: z5.number(),
6383
+ gasUsed: z5.string(),
6384
+ from: z5.string(),
6385
+ to: z5.string().nullable(),
6386
+ effectiveGasPrice: z5.string().optional(),
6387
+ fee: z5.string(),
6388
+ feeEth: z5.string()
6389
+ }),
6390
+ z5.object({
6391
+ status: z5.literal("dry-run"),
6392
+ estimatedGas: z5.string(),
6393
+ simulationResult: z5.unknown(),
6394
+ fee: z5.string(),
6395
+ feeEth: z5.string()
6396
+ })
6397
+ ]);
6398
+ members.command("register", {
6399
+ description: "Register as a new Assembly member (pays the registration fee).",
6400
+ hint: "Requires PRIVATE_KEY environment variable for signing.",
6401
+ env: writeEnv,
6402
+ options: writeOptions,
6403
+ output: txOutputSchema,
6404
+ examples: [
6405
+ { description: "Register as a member" },
6406
+ { options: { "dry-run": true }, description: "Simulate registration without broadcasting" }
6407
+ ],
6408
+ async run(c) {
6409
+ const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
6410
+ const fee = await client.readContract({
6411
+ abi: registryAbi,
6412
+ address: ABSTRACT_MAINNET_ADDRESSES.registry,
6413
+ functionName: "registrationFee"
6414
+ });
6415
+ process.stderr.write(
6416
+ `${JSON.stringify({ level: "info", message: `Registration fee: ${eth(fee)} (${fee} wei)` })}
6417
+ `
6418
+ );
6419
+ try {
6420
+ const result = await assemblyWriteTx({
6421
+ env: c.env,
6422
+ options: c.options,
6423
+ address: ABSTRACT_MAINNET_ADDRESSES.registry,
6424
+ abi: registryAbi,
6425
+ functionName: "register",
6426
+ value: fee
6427
+ });
6428
+ return c.ok(
6429
+ { ...result, fee: fee.toString(), feeEth: eth(fee) },
6430
+ result.status === "success" ? {
6431
+ cta: {
6432
+ description: "Check your membership:",
6433
+ commands: [{ command: "members info", args: { address: result.from } }]
6434
+ }
6435
+ } : void 0
6436
+ );
6437
+ } catch (error) {
6438
+ if (error instanceof TxError && error.code === "INSUFFICIENT_FUNDS") {
6439
+ return c.error({
6440
+ code: "INSUFFICIENT_FUNDS",
6441
+ message: `Insufficient funds to register. Required fee: ${eth(fee)} (${fee} wei). ${error.message}`,
6442
+ retryable: false
6443
+ });
6444
+ }
6445
+ throw error;
6446
+ }
6447
+ }
6448
+ });
6449
+ members.command("heartbeat", {
6450
+ description: "Send a heartbeat to extend active membership (pays the heartbeat fee).",
6451
+ hint: "Requires PRIVATE_KEY environment variable for signing.",
6452
+ env: writeEnv,
6453
+ options: writeOptions,
6454
+ output: txOutputSchema,
6455
+ examples: [
6456
+ { description: "Send a heartbeat" },
6457
+ { options: { "dry-run": true }, description: "Simulate heartbeat without broadcasting" }
6458
+ ],
6459
+ async run(c) {
6460
+ const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
6461
+ const fee = await client.readContract({
6462
+ abi: registryAbi,
6463
+ address: ABSTRACT_MAINNET_ADDRESSES.registry,
6464
+ functionName: "heartbeatFee"
6465
+ });
6466
+ process.stderr.write(
6467
+ `${JSON.stringify({ level: "info", message: `Heartbeat fee: ${eth(fee)} (${fee} wei)` })}
6468
+ `
6469
+ );
6470
+ try {
6471
+ const result = await assemblyWriteTx({
6472
+ env: c.env,
6473
+ options: c.options,
6474
+ address: ABSTRACT_MAINNET_ADDRESSES.registry,
6475
+ abi: registryAbi,
6476
+ functionName: "heartbeat",
6477
+ value: fee
6478
+ });
6479
+ return c.ok(
6480
+ { ...result, fee: fee.toString(), feeEth: eth(fee) },
6481
+ result.status === "success" ? {
6482
+ cta: {
6483
+ description: "Check your membership:",
6484
+ commands: [{ command: "members info", args: { address: result.from } }]
6485
+ }
6486
+ } : void 0
6487
+ );
6488
+ } catch (error) {
6489
+ if (error instanceof TxError && error.code === "INSUFFICIENT_FUNDS") {
6490
+ return c.error({
6491
+ code: "INSUFFICIENT_FUNDS",
6492
+ message: `Insufficient funds for heartbeat. Required fee: ${eth(fee)} (${fee} wei). ${error.message}`,
6493
+ retryable: false
6494
+ });
6495
+ }
6496
+ throw error;
6497
+ }
6498
+ }
6499
+ });
6500
+ members.command("renew", {
6501
+ description: "Renew an expired membership (pays the registration fee).",
6502
+ hint: "Requires PRIVATE_KEY environment variable for signing. Calls register() to re-activate expired membership.",
6503
+ env: writeEnv,
6504
+ options: writeOptions,
6505
+ output: txOutputSchema,
6506
+ examples: [
6507
+ { description: "Renew expired membership" },
6508
+ { options: { "dry-run": true }, description: "Simulate renewal without broadcasting" }
6509
+ ],
6510
+ async run(c) {
6511
+ const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
6512
+ const fee = await client.readContract({
6513
+ abi: registryAbi,
6514
+ address: ABSTRACT_MAINNET_ADDRESSES.registry,
6515
+ functionName: "registrationFee"
6516
+ });
6517
+ process.stderr.write(
6518
+ `${JSON.stringify({ level: "info", message: `Renewal fee: ${eth(fee)} (${fee} wei)` })}
6519
+ `
6520
+ );
6521
+ try {
6522
+ const result = await assemblyWriteTx({
6523
+ env: c.env,
6524
+ options: c.options,
6525
+ address: ABSTRACT_MAINNET_ADDRESSES.registry,
6526
+ abi: registryAbi,
6527
+ functionName: "register",
6528
+ value: fee
6529
+ });
6530
+ return c.ok(
6531
+ { ...result, fee: fee.toString(), feeEth: eth(fee) },
6532
+ result.status === "success" ? {
6533
+ cta: {
6534
+ description: "Check your membership:",
6535
+ commands: [{ command: "members info", args: { address: result.from } }]
6536
+ }
6537
+ } : void 0
6538
+ );
6539
+ } catch (error) {
6540
+ if (error instanceof TxError && error.code === "INSUFFICIENT_FUNDS") {
6541
+ return c.error({
6542
+ code: "INSUFFICIENT_FUNDS",
6543
+ message: `Insufficient funds to renew. Required fee: ${eth(fee)} (${fee} wei). ${error.message}`,
6544
+ retryable: false
6545
+ });
6546
+ }
6547
+ throw error;
6548
+ }
6549
+ }
6550
+ });
5825
6551
 
5826
6552
  // src/commands/treasury.ts
5827
- import { Cli as Cli5, z as z5 } from "incur";
5828
- var env5 = z5.object({
5829
- ABSTRACT_RPC_URL: z5.string().optional().describe("Abstract RPC URL override")
6553
+ import { Cli as Cli5, z as z6 } from "incur";
6554
+ var env5 = z6.object({
6555
+ ABSTRACT_RPC_URL: z6.string().optional().describe("Abstract RPC URL override")
5830
6556
  });
5831
- var timestampOutput5 = z5.union([z5.number(), z5.string()]);
6557
+ var timestampOutput5 = z6.union([z6.number(), z6.string()]);
5832
6558
  var treasury = Cli5.create("treasury", {
5833
6559
  description: "Inspect treasury balances, execution status, and spend controls."
5834
6560
  });
5835
6561
  treasury.command("balance", {
5836
6562
  description: "Get current native token balance for the treasury contract.",
5837
6563
  env: env5,
5838
- output: z5.object({
5839
- address: z5.string(),
5840
- balanceWei: z5.string(),
5841
- balance: z5.string()
6564
+ output: z6.object({
6565
+ address: z6.string(),
6566
+ balanceWei: z6.string(),
6567
+ balance: z6.string()
5842
6568
  }),
5843
6569
  examples: [{ description: "Check treasury balance" }],
5844
6570
  async run(c) {
@@ -5853,13 +6579,13 @@ treasury.command("balance", {
5853
6579
  });
5854
6580
  treasury.command("whitelist", {
5855
6581
  description: "Check whether an asset address is treasury-whitelisted.",
5856
- args: z5.object({
5857
- asset: z5.string().describe("Token/asset contract address")
6582
+ args: z6.object({
6583
+ asset: z6.string().describe("Token/asset contract address")
5858
6584
  }),
5859
6585
  env: env5,
5860
- output: z5.object({
5861
- asset: z5.string(),
5862
- whitelisted: z5.boolean()
6586
+ output: z6.object({
6587
+ asset: z6.string(),
6588
+ whitelisted: z6.boolean()
5863
6589
  }),
5864
6590
  examples: [
5865
6591
  {
@@ -5881,11 +6607,11 @@ treasury.command("whitelist", {
5881
6607
  treasury.command("major-spend-status", {
5882
6608
  description: "Read major-spend cooldown status for the treasury contract.",
5883
6609
  env: env5,
5884
- output: z5.object({
5885
- majorSpendCooldownSeconds: z5.number(),
6610
+ output: z6.object({
6611
+ majorSpendCooldownSeconds: z6.number(),
5886
6612
  lastMajorSpendAt: timestampOutput5,
5887
- lastMajorSpendRelative: z5.string(),
5888
- isMajorSpendAllowed: z5.boolean()
6613
+ lastMajorSpendRelative: z6.string(),
6614
+ isMajorSpendAllowed: z6.boolean()
5889
6615
  }),
5890
6616
  examples: [{ description: "Inspect treasury major-spend guardrails" }],
5891
6617
  async run(c) {
@@ -5919,13 +6645,13 @@ treasury.command("major-spend-status", {
5919
6645
  });
5920
6646
  treasury.command("executed", {
5921
6647
  description: "Check whether a treasury action for a proposal has executed.",
5922
- args: z5.object({
5923
- proposalId: z5.coerce.number().int().positive().describe("Governance proposal id")
6648
+ args: z6.object({
6649
+ proposalId: z6.coerce.number().int().positive().describe("Governance proposal id")
5924
6650
  }),
5925
6651
  env: env5,
5926
- output: z5.object({
5927
- proposalId: z5.number(),
5928
- executed: z5.boolean()
6652
+ output: z6.object({
6653
+ proposalId: z6.number(),
6654
+ executed: z6.boolean()
5929
6655
  }),
5930
6656
  examples: [{ args: { proposalId: 1 }, description: "Check execution status for proposal #1" }],
5931
6657
  async run(c) {
@@ -6091,20 +6817,20 @@ cli.command(council);
6091
6817
  cli.command(forum);
6092
6818
  cli.command(governance);
6093
6819
  cli.command(treasury);
6094
- var rootEnv = z6.object({
6095
- ABSTRACT_RPC_URL: z6.string().optional().describe("Abstract RPC URL override")
6820
+ var rootEnv = z7.object({
6821
+ ABSTRACT_RPC_URL: z7.string().optional().describe("Abstract RPC URL override")
6096
6822
  });
6097
- var timestampOutput6 = z6.union([z6.number(), z6.string()]);
6823
+ var timestampOutput6 = z7.union([z7.number(), z7.string()]);
6098
6824
  cli.command("status", {
6099
6825
  description: "Get a cross-contract Assembly snapshot (members, council, governance, treasury).",
6100
6826
  env: rootEnv,
6101
- output: z6.object({
6102
- activeMemberCount: z6.number(),
6103
- seatCount: z6.number(),
6104
- proposalCount: z6.number(),
6105
- currentAuctionDay: z6.number(),
6106
- currentAuctionSlot: z6.number(),
6107
- treasuryBalance: z6.string()
6827
+ output: z7.object({
6828
+ activeMemberCount: z7.number(),
6829
+ seatCount: z7.number(),
6830
+ proposalCount: z7.number(),
6831
+ currentAuctionDay: z7.number(),
6832
+ currentAuctionSlot: z7.number(),
6833
+ treasuryBalance: z7.string()
6108
6834
  }),
6109
6835
  examples: [{ description: "Fetch the current Assembly system status" }],
6110
6836
  async run(c) {
@@ -6156,18 +6882,18 @@ cli.command("status", {
6156
6882
  });
6157
6883
  cli.command("health", {
6158
6884
  description: "Check cross-contract health for one address (membership, council, refunds, power).",
6159
- args: z6.object({
6160
- address: z6.string().describe("Member or wallet address to inspect")
6885
+ args: z7.object({
6886
+ address: z7.string().describe("Member or wallet address to inspect")
6161
6887
  }),
6162
6888
  env: rootEnv,
6163
- output: z6.object({
6164
- address: z6.string(),
6165
- isActive: z6.boolean(),
6889
+ output: z7.object({
6890
+ address: z7.string(),
6891
+ isActive: z7.boolean(),
6166
6892
  activeUntil: timestampOutput6,
6167
- activeUntilRelative: z6.string(),
6168
- isCouncilMember: z6.boolean(),
6169
- pendingReturnsWei: z6.string(),
6170
- votingPower: z6.number()
6893
+ activeUntilRelative: z7.string(),
6894
+ isCouncilMember: z7.boolean(),
6895
+ pendingReturnsWei: z7.string(),
6896
+ votingPower: z7.number()
6171
6897
  }),
6172
6898
  examples: [
6173
6899
  {