@spectratools/assembly-cli 0.12.0 → 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.
- package/dist/cli.js +963 -658
- package/dist/index.js +963 -658
- package/package.json +1 -1
package/dist/index.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
|
|
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,9 +5246,9 @@ council.command("withdraw-refund", {
|
|
|
5246
5246
|
}
|
|
5247
5247
|
});
|
|
5248
5248
|
|
|
5249
|
-
// src/commands/
|
|
5250
|
-
import {
|
|
5251
|
-
import {
|
|
5249
|
+
// src/commands/digest.ts
|
|
5250
|
+
import { withCommandSpan } from "@spectratools/cli-shared/telemetry";
|
|
5251
|
+
import { z as z4 } from "incur";
|
|
5252
5252
|
|
|
5253
5253
|
// src/services/forum.ts
|
|
5254
5254
|
function decodeThread(value) {
|
|
@@ -5376,51 +5376,662 @@ async function fetchForumStats(client) {
|
|
|
5376
5376
|
address: ABSTRACT_MAINNET_ADDRESSES.forum,
|
|
5377
5377
|
functionName: "petitionCount"
|
|
5378
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
|
-
};
|
|
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
|
+
});
|
|
5391
6000
|
}
|
|
5392
6001
|
|
|
5393
6002
|
// src/commands/forum.ts
|
|
5394
|
-
|
|
5395
|
-
|
|
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")
|
|
5396
6007
|
});
|
|
5397
6008
|
var commentEnv = env2.extend({
|
|
5398
|
-
PRIVATE_KEY:
|
|
6009
|
+
PRIVATE_KEY: z5.string().optional().describe("Private key (required only when posting a comment via --body)")
|
|
5399
6010
|
});
|
|
5400
|
-
var timestampOutput2 =
|
|
5401
|
-
var txResultOutput2 =
|
|
5402
|
-
|
|
5403
|
-
status:
|
|
5404
|
-
hash:
|
|
5405
|
-
blockNumber:
|
|
5406
|
-
gasUsed:
|
|
5407
|
-
from:
|
|
5408
|
-
to:
|
|
5409
|
-
effectiveGasPrice:
|
|
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()
|
|
5410
6021
|
}),
|
|
5411
|
-
|
|
5412
|
-
status:
|
|
5413
|
-
hash:
|
|
5414
|
-
blockNumber:
|
|
5415
|
-
gasUsed:
|
|
5416
|
-
from:
|
|
5417
|
-
to:
|
|
5418
|
-
effectiveGasPrice:
|
|
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()
|
|
5419
6030
|
}),
|
|
5420
|
-
|
|
5421
|
-
status:
|
|
5422
|
-
estimatedGas:
|
|
5423
|
-
simulationResult:
|
|
6031
|
+
z5.object({
|
|
6032
|
+
status: z5.literal("dry-run"),
|
|
6033
|
+
estimatedGas: z5.string(),
|
|
6034
|
+
simulationResult: z5.unknown()
|
|
5424
6035
|
})
|
|
5425
6036
|
]);
|
|
5426
6037
|
var forum = Cli2.create("forum", {
|
|
@@ -5429,19 +6040,19 @@ var forum = Cli2.create("forum", {
|
|
|
5429
6040
|
forum.command("threads", {
|
|
5430
6041
|
description: "List forum threads with author and creation metadata.",
|
|
5431
6042
|
env: env2,
|
|
5432
|
-
output:
|
|
5433
|
-
threads:
|
|
5434
|
-
|
|
5435
|
-
id:
|
|
5436
|
-
kind:
|
|
5437
|
-
author:
|
|
6043
|
+
output: z5.object({
|
|
6044
|
+
threads: z5.array(
|
|
6045
|
+
z5.object({
|
|
6046
|
+
id: z5.number(),
|
|
6047
|
+
kind: z5.number(),
|
|
6048
|
+
author: z5.string(),
|
|
5438
6049
|
createdAt: timestampOutput2,
|
|
5439
|
-
createdAtRelative:
|
|
5440
|
-
category:
|
|
5441
|
-
title:
|
|
6050
|
+
createdAtRelative: z5.string(),
|
|
6051
|
+
category: z5.string().nullable().optional(),
|
|
6052
|
+
title: z5.string().nullable().optional()
|
|
5442
6053
|
})
|
|
5443
6054
|
),
|
|
5444
|
-
count:
|
|
6055
|
+
count: z5.number()
|
|
5445
6056
|
}),
|
|
5446
6057
|
examples: [{ description: "List all forum threads" }],
|
|
5447
6058
|
async run(c) {
|
|
@@ -5475,13 +6086,13 @@ forum.command("threads", {
|
|
|
5475
6086
|
});
|
|
5476
6087
|
forum.command("thread", {
|
|
5477
6088
|
description: "Get one thread and all comments associated with it.",
|
|
5478
|
-
args:
|
|
5479
|
-
id:
|
|
6089
|
+
args: z5.object({
|
|
6090
|
+
id: z5.coerce.number().int().positive().describe("Thread id (1-indexed)")
|
|
5480
6091
|
}),
|
|
5481
6092
|
env: env2,
|
|
5482
|
-
output:
|
|
5483
|
-
thread:
|
|
5484
|
-
comments:
|
|
6093
|
+
output: z5.object({
|
|
6094
|
+
thread: z5.record(z5.string(), z5.unknown()),
|
|
6095
|
+
comments: z5.array(z5.record(z5.string(), z5.unknown()))
|
|
5485
6096
|
}),
|
|
5486
6097
|
examples: [{ args: { id: 1 }, description: "Fetch thread #1 and its comments" }],
|
|
5487
6098
|
async run(c) {
|
|
@@ -5514,11 +6125,11 @@ forum.command("thread", {
|
|
|
5514
6125
|
});
|
|
5515
6126
|
forum.command("comments", {
|
|
5516
6127
|
description: "List comments for a thread id.",
|
|
5517
|
-
args:
|
|
5518
|
-
threadId:
|
|
6128
|
+
args: z5.object({
|
|
6129
|
+
threadId: z5.coerce.number().int().positive().describe("Thread id to filter comments by")
|
|
5519
6130
|
}),
|
|
5520
6131
|
env: env2,
|
|
5521
|
-
output:
|
|
6132
|
+
output: z5.array(z5.record(z5.string(), z5.unknown())),
|
|
5522
6133
|
examples: [{ args: { threadId: 1 }, description: "List comments for thread #1" }],
|
|
5523
6134
|
async run(c) {
|
|
5524
6135
|
const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
|
|
@@ -5530,15 +6141,15 @@ forum.command("comments", {
|
|
|
5530
6141
|
});
|
|
5531
6142
|
forum.command("comment", {
|
|
5532
6143
|
description: "Get one comment by id, or post to a thread when --body is provided.",
|
|
5533
|
-
args:
|
|
5534
|
-
id:
|
|
6144
|
+
args: z5.object({
|
|
6145
|
+
id: z5.coerce.number().int().positive().describe("Comment id (read) or thread id (write)")
|
|
5535
6146
|
}),
|
|
5536
6147
|
options: writeOptions.extend({
|
|
5537
|
-
body:
|
|
5538
|
-
"parent-id":
|
|
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)")
|
|
5539
6150
|
}),
|
|
5540
6151
|
env: commentEnv,
|
|
5541
|
-
output:
|
|
6152
|
+
output: z5.record(z5.string(), z5.unknown()),
|
|
5542
6153
|
examples: [
|
|
5543
6154
|
{ args: { id: 1 }, description: "Fetch comment #1" },
|
|
5544
6155
|
{
|
|
@@ -5653,16 +6264,16 @@ forum.command("post", {
|
|
|
5653
6264
|
description: "Create a new discussion thread in the forum.",
|
|
5654
6265
|
hint: "Requires PRIVATE_KEY environment variable for signing.",
|
|
5655
6266
|
options: writeOptions.extend({
|
|
5656
|
-
category:
|
|
5657
|
-
title:
|
|
5658
|
-
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")
|
|
5659
6270
|
}),
|
|
5660
6271
|
env: writeEnv,
|
|
5661
|
-
output:
|
|
5662
|
-
author:
|
|
5663
|
-
category:
|
|
5664
|
-
title:
|
|
5665
|
-
expectedThreadId:
|
|
6272
|
+
output: z5.object({
|
|
6273
|
+
author: z5.string(),
|
|
6274
|
+
category: z5.string(),
|
|
6275
|
+
title: z5.string(),
|
|
6276
|
+
expectedThreadId: z5.number(),
|
|
5666
6277
|
tx: txResultOutput2
|
|
5667
6278
|
}),
|
|
5668
6279
|
examples: [
|
|
@@ -5730,19 +6341,19 @@ forum.command("post", {
|
|
|
5730
6341
|
forum.command("post-comment", {
|
|
5731
6342
|
description: "Post a comment to a forum thread.",
|
|
5732
6343
|
hint: "Requires PRIVATE_KEY environment variable for signing.",
|
|
5733
|
-
args:
|
|
5734
|
-
threadId:
|
|
6344
|
+
args: z5.object({
|
|
6345
|
+
threadId: z5.coerce.number().int().positive().describe("Thread id to comment on")
|
|
5735
6346
|
}),
|
|
5736
6347
|
options: writeOptions.extend({
|
|
5737
|
-
body:
|
|
5738
|
-
"parent-id":
|
|
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")
|
|
5739
6350
|
}),
|
|
5740
6351
|
env: writeEnv,
|
|
5741
|
-
output:
|
|
5742
|
-
author:
|
|
5743
|
-
threadId:
|
|
5744
|
-
parentId:
|
|
5745
|
-
expectedCommentId:
|
|
6352
|
+
output: z5.object({
|
|
6353
|
+
author: z5.string(),
|
|
6354
|
+
threadId: z5.number(),
|
|
6355
|
+
parentId: z5.number(),
|
|
6356
|
+
expectedCommentId: z5.number(),
|
|
5746
6357
|
tx: txResultOutput2
|
|
5747
6358
|
}),
|
|
5748
6359
|
examples: [
|
|
@@ -5829,20 +6440,20 @@ forum.command("create-petition", {
|
|
|
5829
6440
|
description: "Create a new petition for community-initiated proposals.",
|
|
5830
6441
|
hint: "Requires PRIVATE_KEY environment variable for signing.",
|
|
5831
6442
|
options: writeOptions.extend({
|
|
5832
|
-
title:
|
|
5833
|
-
description:
|
|
5834
|
-
kind:
|
|
5835
|
-
category:
|
|
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")
|
|
5836
6447
|
}),
|
|
5837
6448
|
env: writeEnv,
|
|
5838
|
-
output:
|
|
5839
|
-
proposer:
|
|
5840
|
-
category:
|
|
5841
|
-
kind:
|
|
5842
|
-
title:
|
|
5843
|
-
description:
|
|
5844
|
-
expectedPetitionId:
|
|
5845
|
-
expectedThreadId:
|
|
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(),
|
|
5846
6457
|
tx: txResultOutput2
|
|
5847
6458
|
}),
|
|
5848
6459
|
examples: [
|
|
@@ -5945,15 +6556,15 @@ forum.command("create-petition", {
|
|
|
5945
6556
|
forum.command("sign-petition", {
|
|
5946
6557
|
description: "Sign an existing petition as an active member.",
|
|
5947
6558
|
hint: "Requires PRIVATE_KEY environment variable for signing.",
|
|
5948
|
-
args:
|
|
5949
|
-
petitionId:
|
|
6559
|
+
args: z5.object({
|
|
6560
|
+
petitionId: z5.coerce.number().int().positive().describe("Petition id (1-indexed)")
|
|
5950
6561
|
}),
|
|
5951
6562
|
options: writeOptions,
|
|
5952
6563
|
env: writeEnv,
|
|
5953
|
-
output:
|
|
5954
|
-
signer:
|
|
5955
|
-
petitionId:
|
|
5956
|
-
expectedSignatures:
|
|
6564
|
+
output: z5.object({
|
|
6565
|
+
signer: z5.string(),
|
|
6566
|
+
petitionId: z5.number(),
|
|
6567
|
+
expectedSignatures: z5.number(),
|
|
5957
6568
|
tx: txResultOutput2
|
|
5958
6569
|
}),
|
|
5959
6570
|
examples: [{ args: { petitionId: 1 }, description: "Sign petition #1" }],
|
|
@@ -6040,7 +6651,7 @@ forum.command("sign-petition", {
|
|
|
6040
6651
|
forum.command("petitions", {
|
|
6041
6652
|
description: "List petitions submitted in the forum contract.",
|
|
6042
6653
|
env: env2,
|
|
6043
|
-
output:
|
|
6654
|
+
output: z5.array(z5.record(z5.string(), z5.unknown())),
|
|
6044
6655
|
examples: [{ description: "List all petitions" }],
|
|
6045
6656
|
async run(c) {
|
|
6046
6657
|
const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
|
|
@@ -6050,11 +6661,11 @@ forum.command("petitions", {
|
|
|
6050
6661
|
});
|
|
6051
6662
|
forum.command("petition", {
|
|
6052
6663
|
description: "Get one petition plus whether proposer already signed it.",
|
|
6053
|
-
args:
|
|
6054
|
-
id:
|
|
6664
|
+
args: z5.object({
|
|
6665
|
+
id: z5.coerce.number().int().positive().describe("Petition id (1-indexed)")
|
|
6055
6666
|
}),
|
|
6056
6667
|
env: env2,
|
|
6057
|
-
output:
|
|
6668
|
+
output: z5.object({ proposerSigned: z5.boolean() }).passthrough(),
|
|
6058
6669
|
examples: [{ args: { id: 1 }, description: "Fetch petition #1" }],
|
|
6059
6670
|
async run(c) {
|
|
6060
6671
|
const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
|
|
@@ -6089,15 +6700,15 @@ forum.command("petition", {
|
|
|
6089
6700
|
});
|
|
6090
6701
|
forum.command("has-signed", {
|
|
6091
6702
|
description: "Check whether an address signed a petition.",
|
|
6092
|
-
args:
|
|
6093
|
-
petitionId:
|
|
6094
|
-
address:
|
|
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")
|
|
6095
6706
|
}),
|
|
6096
6707
|
env: env2,
|
|
6097
|
-
output:
|
|
6098
|
-
petitionId:
|
|
6099
|
-
address:
|
|
6100
|
-
hasSigned:
|
|
6708
|
+
output: z5.object({
|
|
6709
|
+
petitionId: z5.number(),
|
|
6710
|
+
address: z5.string(),
|
|
6711
|
+
hasSigned: z5.boolean()
|
|
6101
6712
|
}),
|
|
6102
6713
|
examples: [
|
|
6103
6714
|
{
|
|
@@ -6122,11 +6733,11 @@ forum.command("has-signed", {
|
|
|
6122
6733
|
forum.command("stats", {
|
|
6123
6734
|
description: "Read top-level forum counters and petition threshold.",
|
|
6124
6735
|
env: env2,
|
|
6125
|
-
output:
|
|
6126
|
-
threadCount:
|
|
6127
|
-
commentCount:
|
|
6128
|
-
petitionCount:
|
|
6129
|
-
petitionThresholdBps:
|
|
6736
|
+
output: z5.object({
|
|
6737
|
+
threadCount: z5.number(),
|
|
6738
|
+
commentCount: z5.number(),
|
|
6739
|
+
petitionCount: z5.number(),
|
|
6740
|
+
petitionThresholdBps: z5.number()
|
|
6130
6741
|
}),
|
|
6131
6742
|
examples: [{ description: "Get forum counts and petition threshold" }],
|
|
6132
6743
|
async run(c) {
|
|
@@ -6137,143 +6748,11 @@ forum.command("stats", {
|
|
|
6137
6748
|
|
|
6138
6749
|
// src/commands/governance.ts
|
|
6139
6750
|
import { TxError as TxError2 } from "@spectratools/tx-shared";
|
|
6140
|
-
import { Cli as Cli3, z as
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
var proposalStatusLabels = {
|
|
6144
|
-
0: "pending",
|
|
6145
|
-
1: "active",
|
|
6146
|
-
2: "passed",
|
|
6147
|
-
3: "executed",
|
|
6148
|
-
4: "defeated",
|
|
6149
|
-
5: "cancelled"
|
|
6150
|
-
};
|
|
6151
|
-
function proposalStatus(status) {
|
|
6152
|
-
const statusCode = asNum(status);
|
|
6153
|
-
return {
|
|
6154
|
-
status: proposalStatusLabels[statusCode] ?? `unknown-${statusCode}`,
|
|
6155
|
-
statusCode
|
|
6156
|
-
};
|
|
6157
|
-
}
|
|
6158
|
-
function decodeProposal(value) {
|
|
6159
|
-
const [
|
|
6160
|
-
kind,
|
|
6161
|
-
configRiskTier,
|
|
6162
|
-
origin,
|
|
6163
|
-
status,
|
|
6164
|
-
proposer,
|
|
6165
|
-
threadId,
|
|
6166
|
-
petitionId,
|
|
6167
|
-
createdAt,
|
|
6168
|
-
deliberationEndsAt,
|
|
6169
|
-
voteStartAt,
|
|
6170
|
-
voteEndAt,
|
|
6171
|
-
timelockEndsAt,
|
|
6172
|
-
activeSeatsSnapshot,
|
|
6173
|
-
forVotes,
|
|
6174
|
-
againstVotes,
|
|
6175
|
-
abstainVotes,
|
|
6176
|
-
amount,
|
|
6177
|
-
snapshotAssetBalance,
|
|
6178
|
-
transferIntent,
|
|
6179
|
-
intentDeadline,
|
|
6180
|
-
intentMaxRiskTier,
|
|
6181
|
-
title,
|
|
6182
|
-
description
|
|
6183
|
-
] = value;
|
|
6184
|
-
return {
|
|
6185
|
-
kind,
|
|
6186
|
-
configRiskTier,
|
|
6187
|
-
origin,
|
|
6188
|
-
status,
|
|
6189
|
-
proposer: toChecksum(proposer),
|
|
6190
|
-
threadId,
|
|
6191
|
-
petitionId,
|
|
6192
|
-
createdAt,
|
|
6193
|
-
deliberationEndsAt,
|
|
6194
|
-
voteStartAt,
|
|
6195
|
-
voteEndAt,
|
|
6196
|
-
timelockEndsAt,
|
|
6197
|
-
activeSeatsSnapshot,
|
|
6198
|
-
forVotes,
|
|
6199
|
-
againstVotes,
|
|
6200
|
-
abstainVotes,
|
|
6201
|
-
amount,
|
|
6202
|
-
snapshotAssetBalance,
|
|
6203
|
-
transferIntent,
|
|
6204
|
-
intentDeadline,
|
|
6205
|
-
intentMaxRiskTier,
|
|
6206
|
-
title,
|
|
6207
|
-
description
|
|
6208
|
-
};
|
|
6209
|
-
}
|
|
6210
|
-
function serializeProposal(proposal) {
|
|
6211
|
-
const status = proposalStatus(proposal.status);
|
|
6212
|
-
return {
|
|
6213
|
-
kind: asNum(proposal.kind),
|
|
6214
|
-
configRiskTier: asNum(proposal.configRiskTier),
|
|
6215
|
-
origin: asNum(proposal.origin),
|
|
6216
|
-
status: status.status,
|
|
6217
|
-
statusCode: status.statusCode,
|
|
6218
|
-
proposer: proposal.proposer,
|
|
6219
|
-
threadId: asNum(proposal.threadId),
|
|
6220
|
-
petitionId: asNum(proposal.petitionId),
|
|
6221
|
-
createdAt: asNum(proposal.createdAt),
|
|
6222
|
-
deliberationEndsAt: asNum(proposal.deliberationEndsAt),
|
|
6223
|
-
voteStartAt: asNum(proposal.voteStartAt),
|
|
6224
|
-
voteEndAt: asNum(proposal.voteEndAt),
|
|
6225
|
-
timelockEndsAt: asNum(proposal.timelockEndsAt),
|
|
6226
|
-
activeSeatsSnapshot: asNum(proposal.activeSeatsSnapshot),
|
|
6227
|
-
forVotes: proposal.forVotes.toString(),
|
|
6228
|
-
againstVotes: proposal.againstVotes.toString(),
|
|
6229
|
-
abstainVotes: proposal.abstainVotes.toString(),
|
|
6230
|
-
amount: proposal.amount.toString(),
|
|
6231
|
-
snapshotAssetBalance: proposal.snapshotAssetBalance.toString(),
|
|
6232
|
-
transferIntent: proposal.transferIntent,
|
|
6233
|
-
intentDeadline: asNum(proposal.intentDeadline),
|
|
6234
|
-
intentMaxRiskTier: asNum(proposal.intentMaxRiskTier),
|
|
6235
|
-
title: proposal.title,
|
|
6236
|
-
description: proposal.description
|
|
6237
|
-
};
|
|
6238
|
-
}
|
|
6239
|
-
async function fetchProposalCount(client) {
|
|
6240
|
-
return await client.readContract({
|
|
6241
|
-
abi: governanceAbi,
|
|
6242
|
-
address: ABSTRACT_MAINNET_ADDRESSES.governance,
|
|
6243
|
-
functionName: "proposalCount"
|
|
6244
|
-
});
|
|
6245
|
-
}
|
|
6246
|
-
async function fetchProposalById(client, id) {
|
|
6247
|
-
return decodeProposal(
|
|
6248
|
-
await client.readContract({
|
|
6249
|
-
abi: governanceAbi,
|
|
6250
|
-
address: ABSTRACT_MAINNET_ADDRESSES.governance,
|
|
6251
|
-
functionName: "proposals",
|
|
6252
|
-
args: [BigInt(id)]
|
|
6253
|
-
})
|
|
6254
|
-
);
|
|
6255
|
-
}
|
|
6256
|
-
async function fetchAllProposals(client) {
|
|
6257
|
-
const count = await fetchProposalCount(client);
|
|
6258
|
-
const ids = Array.from({ length: Number(count) }, (_, i) => BigInt(i + 1));
|
|
6259
|
-
if (ids.length === 0) return [];
|
|
6260
|
-
const proposalTuples = await client.multicall({
|
|
6261
|
-
allowFailure: false,
|
|
6262
|
-
contracts: ids.map((id) => ({
|
|
6263
|
-
abi: governanceAbi,
|
|
6264
|
-
address: ABSTRACT_MAINNET_ADDRESSES.governance,
|
|
6265
|
-
functionName: "proposals",
|
|
6266
|
-
args: [id]
|
|
6267
|
-
}))
|
|
6268
|
-
});
|
|
6269
|
-
return proposalTuples.map(decodeProposal);
|
|
6270
|
-
}
|
|
6271
|
-
|
|
6272
|
-
// src/commands/governance.ts
|
|
6273
|
-
var env3 = z4.object({
|
|
6274
|
-
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")
|
|
6275
6754
|
});
|
|
6276
|
-
var timestampOutput3 =
|
|
6755
|
+
var timestampOutput3 = z6.union([z6.number(), z6.string()]);
|
|
6277
6756
|
var PROPOSAL_STATUS_PENDING = 0;
|
|
6278
6757
|
var PROPOSAL_STATUS_ACTIVE = 1;
|
|
6279
6758
|
var PROPOSAL_STATUS_PASSED = 2;
|
|
@@ -6282,31 +6761,31 @@ var supportChoiceToValue = {
|
|
|
6282
6761
|
for: 1,
|
|
6283
6762
|
abstain: 2
|
|
6284
6763
|
};
|
|
6285
|
-
var proposalOutputSchema =
|
|
6286
|
-
kind:
|
|
6287
|
-
configRiskTier:
|
|
6288
|
-
origin:
|
|
6289
|
-
status:
|
|
6290
|
-
statusCode:
|
|
6291
|
-
proposer:
|
|
6292
|
-
threadId:
|
|
6293
|
-
petitionId:
|
|
6294
|
-
createdAt:
|
|
6295
|
-
deliberationEndsAt:
|
|
6296
|
-
voteStartAt:
|
|
6297
|
-
voteEndAt:
|
|
6298
|
-
timelockEndsAt:
|
|
6299
|
-
activeSeatsSnapshot:
|
|
6300
|
-
forVotes:
|
|
6301
|
-
againstVotes:
|
|
6302
|
-
abstainVotes:
|
|
6303
|
-
amount:
|
|
6304
|
-
snapshotAssetBalance:
|
|
6305
|
-
transferIntent:
|
|
6306
|
-
intentDeadline:
|
|
6307
|
-
intentMaxRiskTier:
|
|
6308
|
-
title:
|
|
6309
|
-
description:
|
|
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()
|
|
6310
6789
|
});
|
|
6311
6790
|
var governance = Cli3.create("governance", {
|
|
6312
6791
|
description: "Inspect Assembly governance proposals, votes, and parameters."
|
|
@@ -6314,19 +6793,19 @@ var governance = Cli3.create("governance", {
|
|
|
6314
6793
|
governance.command("proposals", {
|
|
6315
6794
|
description: "List governance proposals with status and vote end time.",
|
|
6316
6795
|
env: env3,
|
|
6317
|
-
output:
|
|
6318
|
-
proposals:
|
|
6319
|
-
|
|
6320
|
-
id:
|
|
6321
|
-
kind:
|
|
6322
|
-
status:
|
|
6323
|
-
statusCode:
|
|
6324
|
-
title:
|
|
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(),
|
|
6325
6804
|
voteEndAt: timestampOutput3,
|
|
6326
|
-
voteEndRelative:
|
|
6805
|
+
voteEndRelative: z6.string()
|
|
6327
6806
|
})
|
|
6328
6807
|
),
|
|
6329
|
-
count:
|
|
6808
|
+
count: z6.number()
|
|
6330
6809
|
}),
|
|
6331
6810
|
examples: [{ description: "List all proposals" }],
|
|
6332
6811
|
async run(c) {
|
|
@@ -6362,8 +6841,8 @@ governance.command("proposals", {
|
|
|
6362
6841
|
});
|
|
6363
6842
|
governance.command("proposal", {
|
|
6364
6843
|
description: "Get full raw proposal details by proposal id.",
|
|
6365
|
-
args:
|
|
6366
|
-
id:
|
|
6844
|
+
args: z6.object({
|
|
6845
|
+
id: z6.coerce.number().int().positive().describe("Proposal id (1-indexed)")
|
|
6367
6846
|
}),
|
|
6368
6847
|
env: env3,
|
|
6369
6848
|
output: proposalOutputSchema,
|
|
@@ -6384,15 +6863,15 @@ governance.command("proposal", {
|
|
|
6384
6863
|
});
|
|
6385
6864
|
governance.command("has-voted", {
|
|
6386
6865
|
description: "Check if an address has voted on a proposal.",
|
|
6387
|
-
args:
|
|
6388
|
-
proposalId:
|
|
6389
|
-
address:
|
|
6866
|
+
args: z6.object({
|
|
6867
|
+
proposalId: z6.coerce.number().int().positive().describe("Proposal id (1-indexed)"),
|
|
6868
|
+
address: z6.string().describe("Voter address")
|
|
6390
6869
|
}),
|
|
6391
6870
|
env: env3,
|
|
6392
|
-
output:
|
|
6393
|
-
proposalId:
|
|
6394
|
-
address:
|
|
6395
|
-
hasVoted:
|
|
6871
|
+
output: z6.object({
|
|
6872
|
+
proposalId: z6.number(),
|
|
6873
|
+
address: z6.string(),
|
|
6874
|
+
hasVoted: z6.boolean()
|
|
6396
6875
|
}),
|
|
6397
6876
|
examples: [
|
|
6398
6877
|
{
|
|
@@ -6421,19 +6900,19 @@ governance.command("has-voted", {
|
|
|
6421
6900
|
governance.command("params", {
|
|
6422
6901
|
description: "Read governance threshold and timing parameters.",
|
|
6423
6902
|
env: env3,
|
|
6424
|
-
output:
|
|
6425
|
-
deliberationPeriod:
|
|
6426
|
-
votePeriod:
|
|
6427
|
-
quorumBps:
|
|
6428
|
-
constitutionalDeliberationPeriod:
|
|
6429
|
-
constitutionalVotePeriod:
|
|
6430
|
-
constitutionalPassBps:
|
|
6431
|
-
majorPassBps:
|
|
6432
|
-
parameterPassBps:
|
|
6433
|
-
significantPassBps:
|
|
6434
|
-
significantThresholdBps:
|
|
6435
|
-
routineThresholdBps:
|
|
6436
|
-
timelockPeriod:
|
|
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()
|
|
6437
6916
|
}),
|
|
6438
6917
|
examples: [{ description: "Inspect governance timing and pass thresholds" }],
|
|
6439
6918
|
async run(c) {
|
|
@@ -6476,36 +6955,36 @@ governance.command("params", {
|
|
|
6476
6955
|
});
|
|
6477
6956
|
}
|
|
6478
6957
|
});
|
|
6479
|
-
var txResultOutput3 =
|
|
6480
|
-
|
|
6481
|
-
status:
|
|
6482
|
-
hash:
|
|
6483
|
-
blockNumber:
|
|
6484
|
-
gasUsed:
|
|
6485
|
-
from:
|
|
6486
|
-
to:
|
|
6487
|
-
effectiveGasPrice:
|
|
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()
|
|
6488
6967
|
}),
|
|
6489
|
-
|
|
6490
|
-
status:
|
|
6491
|
-
estimatedGas:
|
|
6492
|
-
simulationResult:
|
|
6968
|
+
z6.object({
|
|
6969
|
+
status: z6.literal("dry-run"),
|
|
6970
|
+
estimatedGas: z6.string(),
|
|
6971
|
+
simulationResult: z6.unknown()
|
|
6493
6972
|
})
|
|
6494
6973
|
]);
|
|
6495
6974
|
governance.command("vote", {
|
|
6496
6975
|
description: "Cast a governance vote on a proposal.",
|
|
6497
6976
|
hint: "Requires PRIVATE_KEY environment variable for signing.",
|
|
6498
|
-
args:
|
|
6499
|
-
proposalId:
|
|
6500
|
-
support:
|
|
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")
|
|
6501
6980
|
}),
|
|
6502
6981
|
options: writeOptions,
|
|
6503
6982
|
env: writeEnv,
|
|
6504
|
-
output:
|
|
6505
|
-
proposalId:
|
|
6506
|
-
proposalTitle:
|
|
6507
|
-
support:
|
|
6508
|
-
supportValue:
|
|
6983
|
+
output: z6.object({
|
|
6984
|
+
proposalId: z6.number(),
|
|
6985
|
+
proposalTitle: z6.string(),
|
|
6986
|
+
support: z6.enum(["for", "against", "abstain"]),
|
|
6987
|
+
supportValue: z6.number(),
|
|
6509
6988
|
tx: txResultOutput3
|
|
6510
6989
|
}),
|
|
6511
6990
|
examples: [
|
|
@@ -6585,22 +7064,22 @@ governance.command("propose", {
|
|
|
6585
7064
|
description: "Create a new council-originated governance proposal.",
|
|
6586
7065
|
hint: "Requires PRIVATE_KEY environment variable for signing.",
|
|
6587
7066
|
options: writeOptions.extend({
|
|
6588
|
-
title:
|
|
6589
|
-
description:
|
|
6590
|
-
kind:
|
|
6591
|
-
category:
|
|
6592
|
-
"risk-tier":
|
|
6593
|
-
amount:
|
|
6594
|
-
recipient:
|
|
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)")
|
|
6595
7074
|
}),
|
|
6596
7075
|
env: writeEnv,
|
|
6597
|
-
output:
|
|
6598
|
-
proposer:
|
|
6599
|
-
category:
|
|
6600
|
-
kind:
|
|
6601
|
-
title:
|
|
6602
|
-
description:
|
|
6603
|
-
expectedProposalId:
|
|
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(),
|
|
6604
7083
|
tx: txResultOutput3
|
|
6605
7084
|
}),
|
|
6606
7085
|
examples: [
|
|
@@ -6689,15 +7168,15 @@ governance.command("propose", {
|
|
|
6689
7168
|
governance.command("queue", {
|
|
6690
7169
|
description: "Finalize voting and queue an eligible proposal into timelock.",
|
|
6691
7170
|
hint: "Requires PRIVATE_KEY environment variable for signing.",
|
|
6692
|
-
args:
|
|
6693
|
-
proposalId:
|
|
7171
|
+
args: z6.object({
|
|
7172
|
+
proposalId: z6.coerce.number().int().positive().describe("Proposal id (1-indexed)")
|
|
6694
7173
|
}),
|
|
6695
7174
|
options: writeOptions,
|
|
6696
7175
|
env: writeEnv,
|
|
6697
|
-
output:
|
|
6698
|
-
proposalId:
|
|
6699
|
-
proposalTitle:
|
|
6700
|
-
statusBefore:
|
|
7176
|
+
output: z6.object({
|
|
7177
|
+
proposalId: z6.number(),
|
|
7178
|
+
proposalTitle: z6.string(),
|
|
7179
|
+
statusBefore: z6.string(),
|
|
6701
7180
|
tx: txResultOutput3
|
|
6702
7181
|
}),
|
|
6703
7182
|
examples: [
|
|
@@ -6777,14 +7256,14 @@ governance.command("queue", {
|
|
|
6777
7256
|
governance.command("execute", {
|
|
6778
7257
|
description: "Execute a queued governance proposal after timelock expiry.",
|
|
6779
7258
|
hint: "Requires PRIVATE_KEY environment variable for signing.",
|
|
6780
|
-
args:
|
|
6781
|
-
proposalId:
|
|
7259
|
+
args: z6.object({
|
|
7260
|
+
proposalId: z6.coerce.number().int().positive().describe("Proposal id (1-indexed)")
|
|
6782
7261
|
}),
|
|
6783
7262
|
options: writeOptions,
|
|
6784
7263
|
env: writeEnv,
|
|
6785
|
-
output:
|
|
6786
|
-
proposalId:
|
|
6787
|
-
proposalTitle:
|
|
7264
|
+
output: z6.object({
|
|
7265
|
+
proposalId: z6.number(),
|
|
7266
|
+
proposalTitle: z6.string(),
|
|
6788
7267
|
timelockEndsAt: timestampOutput3,
|
|
6789
7268
|
tx: txResultOutput3
|
|
6790
7269
|
}),
|
|
@@ -6851,189 +7330,14 @@ governance.command("execute", {
|
|
|
6851
7330
|
|
|
6852
7331
|
// src/commands/members.ts
|
|
6853
7332
|
import { TxError as TxError3 } from "@spectratools/tx-shared";
|
|
6854
|
-
import { Cli as Cli4, z as
|
|
6855
|
-
|
|
6856
|
-
// src/services/members.ts
|
|
6857
|
-
import { z as z5 } from "incur";
|
|
6858
|
-
var DEFAULT_MEMBER_SNAPSHOT_URL = "https://www.theaiassembly.org/api/indexer/members";
|
|
6859
|
-
var REGISTERED_EVENT_SCAN_STEP = 100000n;
|
|
6860
|
-
var REGISTERED_EVENT_SCAN_TIMEOUT_MS = 2e4;
|
|
6861
|
-
var memberSnapshotEntrySchema = z5.union([
|
|
6862
|
-
z5.string(),
|
|
6863
|
-
z5.object({
|
|
6864
|
-
address: z5.string(),
|
|
6865
|
-
ens: z5.string().optional(),
|
|
6866
|
-
name: z5.string().optional()
|
|
6867
|
-
})
|
|
6868
|
-
]);
|
|
6869
|
-
var memberSnapshotSchema = z5.array(memberSnapshotEntrySchema);
|
|
6870
|
-
var AssemblyApiValidationError = class extends Error {
|
|
6871
|
-
constructor(details) {
|
|
6872
|
-
super("Assembly API response validation failed");
|
|
6873
|
-
this.details = details;
|
|
6874
|
-
this.name = "AssemblyApiValidationError";
|
|
6875
|
-
}
|
|
6876
|
-
};
|
|
6877
|
-
var AssemblyIndexerUnavailableError = class extends Error {
|
|
6878
|
-
constructor(details) {
|
|
6879
|
-
super("Assembly indexer unavailable");
|
|
6880
|
-
this.details = details;
|
|
6881
|
-
this.name = "AssemblyIndexerUnavailableError";
|
|
6882
|
-
}
|
|
6883
|
-
};
|
|
6884
|
-
function memberSnapshotEntryToIdentity(entry) {
|
|
6885
|
-
if (typeof entry === "string") return { address: entry };
|
|
6886
|
-
const identity = { address: entry.address };
|
|
6887
|
-
if (entry.ens !== void 0) identity.ens = entry.ens;
|
|
6888
|
-
if (entry.name !== void 0) identity.name = entry.name;
|
|
6889
|
-
return identity;
|
|
6890
|
-
}
|
|
6891
|
-
function mergeMemberIdentities(entries) {
|
|
6892
|
-
const byAddress = /* @__PURE__ */ new Map();
|
|
6893
|
-
for (const entry of entries) {
|
|
6894
|
-
const key = entry.address.toLowerCase();
|
|
6895
|
-
const existing = byAddress.get(key);
|
|
6896
|
-
if (!existing) {
|
|
6897
|
-
byAddress.set(key, entry);
|
|
6898
|
-
continue;
|
|
6899
|
-
}
|
|
6900
|
-
const merged = { address: existing.address };
|
|
6901
|
-
const ens = existing.ens ?? entry.ens;
|
|
6902
|
-
const name = existing.name ?? entry.name;
|
|
6903
|
-
if (ens !== void 0) merged.ens = ens;
|
|
6904
|
-
if (name !== void 0) merged.name = name;
|
|
6905
|
-
byAddress.set(key, merged);
|
|
6906
|
-
}
|
|
6907
|
-
return [...byAddress.values()];
|
|
6908
|
-
}
|
|
6909
|
-
async function memberSnapshot(url) {
|
|
6910
|
-
let res;
|
|
6911
|
-
try {
|
|
6912
|
-
res = await fetch(url);
|
|
6913
|
-
} catch (error) {
|
|
6914
|
-
throw new AssemblyIndexerUnavailableError({
|
|
6915
|
-
code: "ASSEMBLY_INDEXER_UNAVAILABLE",
|
|
6916
|
-
url,
|
|
6917
|
-
reason: error instanceof Error ? error.message : String(error)
|
|
6918
|
-
});
|
|
6919
|
-
}
|
|
6920
|
-
if (!res.ok) {
|
|
6921
|
-
throw new AssemblyIndexerUnavailableError({
|
|
6922
|
-
code: "ASSEMBLY_INDEXER_UNAVAILABLE",
|
|
6923
|
-
url,
|
|
6924
|
-
status: res.status,
|
|
6925
|
-
statusText: res.statusText
|
|
6926
|
-
});
|
|
6927
|
-
}
|
|
6928
|
-
const json = await res.json();
|
|
6929
|
-
const parsed = memberSnapshotSchema.safeParse(json);
|
|
6930
|
-
if (parsed.success) {
|
|
6931
|
-
return mergeMemberIdentities(parsed.data.map(memberSnapshotEntryToIdentity));
|
|
6932
|
-
}
|
|
6933
|
-
throw new AssemblyApiValidationError({
|
|
6934
|
-
code: "INVALID_ASSEMBLY_API_RESPONSE",
|
|
6935
|
-
url,
|
|
6936
|
-
issues: parsed.error.issues,
|
|
6937
|
-
response: json
|
|
6938
|
-
});
|
|
6939
|
-
}
|
|
6940
|
-
async function withTimeout(promise, timeoutMs, timeoutMessage) {
|
|
6941
|
-
let timer;
|
|
6942
|
-
try {
|
|
6943
|
-
return await Promise.race([
|
|
6944
|
-
promise,
|
|
6945
|
-
new Promise((_, reject) => {
|
|
6946
|
-
timer = setTimeout(() => {
|
|
6947
|
-
reject(new Error(timeoutMessage));
|
|
6948
|
-
}, timeoutMs);
|
|
6949
|
-
})
|
|
6950
|
-
]);
|
|
6951
|
-
} finally {
|
|
6952
|
-
if (timer) clearTimeout(timer);
|
|
6953
|
-
}
|
|
6954
|
-
}
|
|
6955
|
-
async function membersFromRegisteredEvents(client) {
|
|
6956
|
-
const latestBlock = await client.getBlockNumber();
|
|
6957
|
-
const addresses = /* @__PURE__ */ new Set();
|
|
6958
|
-
for (let fromBlock = ABSTRACT_MAINNET_DEPLOYMENT_BLOCKS.registry; fromBlock <= latestBlock; fromBlock += REGISTERED_EVENT_SCAN_STEP) {
|
|
6959
|
-
const toBlock = fromBlock + REGISTERED_EVENT_SCAN_STEP - 1n > latestBlock ? latestBlock : fromBlock + REGISTERED_EVENT_SCAN_STEP - 1n;
|
|
6960
|
-
const events = await client.getContractEvents({
|
|
6961
|
-
abi: registryAbi,
|
|
6962
|
-
address: ABSTRACT_MAINNET_ADDRESSES.registry,
|
|
6963
|
-
eventName: "Registered",
|
|
6964
|
-
fromBlock,
|
|
6965
|
-
toBlock,
|
|
6966
|
-
strict: true
|
|
6967
|
-
});
|
|
6968
|
-
for (const event of events) {
|
|
6969
|
-
const member = event.args.member;
|
|
6970
|
-
if (typeof member === "string") {
|
|
6971
|
-
addresses.add(member);
|
|
6972
|
-
}
|
|
6973
|
-
}
|
|
6974
|
-
}
|
|
6975
|
-
return [...addresses].map((address) => ({ address }));
|
|
6976
|
-
}
|
|
6977
|
-
async function fetchMemberList(client, snapshotUrl) {
|
|
6978
|
-
const url = snapshotUrl ?? DEFAULT_MEMBER_SNAPSHOT_URL;
|
|
6979
|
-
try {
|
|
6980
|
-
return { members: await memberSnapshot(url) };
|
|
6981
|
-
} catch (error) {
|
|
6982
|
-
if (error instanceof AssemblyApiValidationError) {
|
|
6983
|
-
throw error;
|
|
6984
|
-
}
|
|
6985
|
-
if (!(error instanceof AssemblyIndexerUnavailableError)) {
|
|
6986
|
-
throw error;
|
|
6987
|
-
}
|
|
6988
|
-
const fallbackMembers = await withTimeout(
|
|
6989
|
-
membersFromRegisteredEvents(client),
|
|
6990
|
-
REGISTERED_EVENT_SCAN_TIMEOUT_MS,
|
|
6991
|
-
`Registered event fallback scan timed out after ${REGISTERED_EVENT_SCAN_TIMEOUT_MS}ms`
|
|
6992
|
-
);
|
|
6993
|
-
return {
|
|
6994
|
-
members: mergeMemberIdentities(fallbackMembers),
|
|
6995
|
-
fallbackReason: error.details
|
|
6996
|
-
};
|
|
6997
|
-
}
|
|
6998
|
-
}
|
|
6999
|
-
async function fetchMemberOnchainState(client, addresses) {
|
|
7000
|
-
if (addresses.length === 0) return [];
|
|
7001
|
-
const calls = addresses.flatMap((address) => [
|
|
7002
|
-
{
|
|
7003
|
-
abi: registryAbi,
|
|
7004
|
-
address: ABSTRACT_MAINNET_ADDRESSES.registry,
|
|
7005
|
-
functionName: "isActive",
|
|
7006
|
-
args: [address]
|
|
7007
|
-
},
|
|
7008
|
-
{
|
|
7009
|
-
abi: registryAbi,
|
|
7010
|
-
address: ABSTRACT_MAINNET_ADDRESSES.registry,
|
|
7011
|
-
functionName: "members",
|
|
7012
|
-
args: [address]
|
|
7013
|
-
}
|
|
7014
|
-
]);
|
|
7015
|
-
const values = await client.multicall({ allowFailure: false, contracts: calls });
|
|
7016
|
-
return addresses.map((address, i) => {
|
|
7017
|
-
const active = values[i * 2];
|
|
7018
|
-
const info = values[i * 2 + 1];
|
|
7019
|
-
return {
|
|
7020
|
-
address: toChecksum(address),
|
|
7021
|
-
active,
|
|
7022
|
-
registered: info.registered,
|
|
7023
|
-
activeUntil: info.activeUntil,
|
|
7024
|
-
lastHeartbeatAt: info.lastHeartbeatAt
|
|
7025
|
-
};
|
|
7026
|
-
});
|
|
7027
|
-
}
|
|
7028
|
-
|
|
7029
|
-
// src/commands/members.ts
|
|
7333
|
+
import { Cli as Cli4, z as z7 } from "incur";
|
|
7030
7334
|
var DEFAULT_MEMBER_SNAPSHOT_URL2 = "https://www.theaiassembly.org/api/indexer/members";
|
|
7031
7335
|
var MAX_MEMBER_LOOKUP_SUGGESTIONS = 5;
|
|
7032
|
-
var env4 =
|
|
7033
|
-
ABSTRACT_RPC_URL:
|
|
7034
|
-
ASSEMBLY_INDEXER_URL:
|
|
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)")
|
|
7035
7339
|
});
|
|
7036
|
-
var timestampOutput4 =
|
|
7340
|
+
var timestampOutput4 = z7.union([z7.number(), z7.string()]);
|
|
7037
7341
|
function matchableAddressInput(query) {
|
|
7038
7342
|
return query.startsWith("0x") && query.length === 42;
|
|
7039
7343
|
}
|
|
@@ -7079,19 +7383,19 @@ var members = Cli4.create("members", {
|
|
|
7079
7383
|
members.command("list", {
|
|
7080
7384
|
description: "List members from an indexer snapshot (or Registered event fallback) plus on-chain active state.",
|
|
7081
7385
|
env: env4,
|
|
7082
|
-
output:
|
|
7083
|
-
members:
|
|
7084
|
-
|
|
7085
|
-
address:
|
|
7086
|
-
active:
|
|
7087
|
-
registered:
|
|
7386
|
+
output: z7.object({
|
|
7387
|
+
members: z7.array(
|
|
7388
|
+
z7.object({
|
|
7389
|
+
address: z7.string(),
|
|
7390
|
+
active: z7.boolean(),
|
|
7391
|
+
registered: z7.boolean(),
|
|
7088
7392
|
activeUntil: timestampOutput4,
|
|
7089
|
-
activeUntilRelative:
|
|
7393
|
+
activeUntilRelative: z7.string(),
|
|
7090
7394
|
lastHeartbeatAt: timestampOutput4,
|
|
7091
|
-
lastHeartbeatRelative:
|
|
7395
|
+
lastHeartbeatRelative: z7.string()
|
|
7092
7396
|
})
|
|
7093
7397
|
),
|
|
7094
|
-
count:
|
|
7398
|
+
count: z7.number()
|
|
7095
7399
|
}),
|
|
7096
7400
|
examples: [
|
|
7097
7401
|
{ description: "List members using default indexer snapshot" },
|
|
@@ -7145,17 +7449,17 @@ members.command("list", {
|
|
|
7145
7449
|
});
|
|
7146
7450
|
members.command("info", {
|
|
7147
7451
|
description: "Get member registry record and active status by full address, partial address, ENS, or name.",
|
|
7148
|
-
args:
|
|
7149
|
-
address:
|
|
7452
|
+
args: z7.object({
|
|
7453
|
+
address: z7.string().describe("Member lookup query (full/partial address, ENS, or name metadata)")
|
|
7150
7454
|
}),
|
|
7151
7455
|
env: env4,
|
|
7152
|
-
output:
|
|
7153
|
-
address:
|
|
7154
|
-
active:
|
|
7456
|
+
output: z7.object({
|
|
7457
|
+
address: z7.string(),
|
|
7458
|
+
active: z7.boolean(),
|
|
7155
7459
|
activeUntil: timestampOutput4,
|
|
7156
7460
|
lastHeartbeatAt: timestampOutput4,
|
|
7157
|
-
activeUntilRelative:
|
|
7158
|
-
lastHeartbeatRelative:
|
|
7461
|
+
activeUntilRelative: z7.string(),
|
|
7462
|
+
lastHeartbeatRelative: z7.string()
|
|
7159
7463
|
}),
|
|
7160
7464
|
examples: [
|
|
7161
7465
|
{
|
|
@@ -7240,9 +7544,9 @@ members.command("info", {
|
|
|
7240
7544
|
members.command("count", {
|
|
7241
7545
|
description: "Get active and total-known member counts from Registry.",
|
|
7242
7546
|
env: env4,
|
|
7243
|
-
output:
|
|
7244
|
-
active:
|
|
7245
|
-
total:
|
|
7547
|
+
output: z7.object({
|
|
7548
|
+
active: z7.number(),
|
|
7549
|
+
total: z7.number()
|
|
7246
7550
|
}),
|
|
7247
7551
|
examples: [{ description: "Count active and known members" }],
|
|
7248
7552
|
async run(c) {
|
|
@@ -7265,12 +7569,12 @@ members.command("count", {
|
|
|
7265
7569
|
members.command("fees", {
|
|
7266
7570
|
description: "Get registration and heartbeat fee settings.",
|
|
7267
7571
|
env: env4,
|
|
7268
|
-
output:
|
|
7269
|
-
registrationFeeWei:
|
|
7270
|
-
registrationFee:
|
|
7271
|
-
heartbeatFeeWei:
|
|
7272
|
-
heartbeatFee:
|
|
7273
|
-
heartbeatGracePeriodSeconds:
|
|
7572
|
+
output: z7.object({
|
|
7573
|
+
registrationFeeWei: z7.string(),
|
|
7574
|
+
registrationFee: z7.string(),
|
|
7575
|
+
heartbeatFeeWei: z7.string(),
|
|
7576
|
+
heartbeatFee: z7.string(),
|
|
7577
|
+
heartbeatGracePeriodSeconds: z7.number()
|
|
7274
7578
|
}),
|
|
7275
7579
|
examples: [{ description: "Inspect current registry fee configuration" }],
|
|
7276
7580
|
async run(c) {
|
|
@@ -7301,24 +7605,24 @@ members.command("fees", {
|
|
|
7301
7605
|
});
|
|
7302
7606
|
}
|
|
7303
7607
|
});
|
|
7304
|
-
var txOutputSchema =
|
|
7305
|
-
|
|
7306
|
-
status:
|
|
7307
|
-
hash:
|
|
7308
|
-
blockNumber:
|
|
7309
|
-
gasUsed:
|
|
7310
|
-
from:
|
|
7311
|
-
to:
|
|
7312
|
-
effectiveGasPrice:
|
|
7313
|
-
fee:
|
|
7314
|
-
feeEth:
|
|
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()
|
|
7315
7619
|
}),
|
|
7316
|
-
|
|
7317
|
-
status:
|
|
7318
|
-
estimatedGas:
|
|
7319
|
-
simulationResult:
|
|
7320
|
-
fee:
|
|
7321
|
-
feeEth:
|
|
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()
|
|
7322
7626
|
})
|
|
7323
7627
|
]);
|
|
7324
7628
|
members.command("register", {
|
|
@@ -7477,35 +7781,35 @@ members.command("renew", {
|
|
|
7477
7781
|
|
|
7478
7782
|
// src/commands/treasury.ts
|
|
7479
7783
|
import { TxError as TxError4 } from "@spectratools/tx-shared";
|
|
7480
|
-
import { Cli as Cli5, z as
|
|
7784
|
+
import { Cli as Cli5, z as z8 } from "incur";
|
|
7481
7785
|
import { encodeAbiParameters, parseUnits, zeroAddress } from "viem";
|
|
7482
|
-
var env5 =
|
|
7483
|
-
ABSTRACT_RPC_URL:
|
|
7786
|
+
var env5 = z8.object({
|
|
7787
|
+
ABSTRACT_RPC_URL: z8.string().optional().describe("Abstract RPC URL override")
|
|
7484
7788
|
});
|
|
7485
|
-
var timestampOutput5 =
|
|
7486
|
-
var txResultOutput4 =
|
|
7487
|
-
|
|
7488
|
-
status:
|
|
7489
|
-
hash:
|
|
7490
|
-
blockNumber:
|
|
7491
|
-
gasUsed:
|
|
7492
|
-
from:
|
|
7493
|
-
to:
|
|
7494
|
-
effectiveGasPrice:
|
|
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()
|
|
7495
7799
|
}),
|
|
7496
|
-
|
|
7497
|
-
status:
|
|
7498
|
-
hash:
|
|
7499
|
-
blockNumber:
|
|
7500
|
-
gasUsed:
|
|
7501
|
-
from:
|
|
7502
|
-
to:
|
|
7503
|
-
effectiveGasPrice:
|
|
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()
|
|
7504
7808
|
}),
|
|
7505
|
-
|
|
7506
|
-
status:
|
|
7507
|
-
estimatedGas:
|
|
7508
|
-
simulationResult:
|
|
7809
|
+
z8.object({
|
|
7810
|
+
status: z8.literal("dry-run"),
|
|
7811
|
+
estimatedGas: z8.string(),
|
|
7812
|
+
simulationResult: z8.unknown()
|
|
7509
7813
|
})
|
|
7510
7814
|
]);
|
|
7511
7815
|
var treasury = Cli5.create("treasury", {
|
|
@@ -7514,10 +7818,10 @@ var treasury = Cli5.create("treasury", {
|
|
|
7514
7818
|
treasury.command("balance", {
|
|
7515
7819
|
description: "Get current native token balance for the treasury contract.",
|
|
7516
7820
|
env: env5,
|
|
7517
|
-
output:
|
|
7518
|
-
address:
|
|
7519
|
-
balanceWei:
|
|
7520
|
-
balance:
|
|
7821
|
+
output: z8.object({
|
|
7822
|
+
address: z8.string(),
|
|
7823
|
+
balanceWei: z8.string(),
|
|
7824
|
+
balance: z8.string()
|
|
7521
7825
|
}),
|
|
7522
7826
|
examples: [{ description: "Check treasury balance" }],
|
|
7523
7827
|
async run(c) {
|
|
@@ -7532,13 +7836,13 @@ treasury.command("balance", {
|
|
|
7532
7836
|
});
|
|
7533
7837
|
treasury.command("whitelist", {
|
|
7534
7838
|
description: "Check whether an asset address is treasury-whitelisted.",
|
|
7535
|
-
args:
|
|
7536
|
-
asset:
|
|
7839
|
+
args: z8.object({
|
|
7840
|
+
asset: z8.string().describe("Token/asset contract address")
|
|
7537
7841
|
}),
|
|
7538
7842
|
env: env5,
|
|
7539
|
-
output:
|
|
7540
|
-
asset:
|
|
7541
|
-
whitelisted:
|
|
7843
|
+
output: z8.object({
|
|
7844
|
+
asset: z8.string(),
|
|
7845
|
+
whitelisted: z8.boolean()
|
|
7542
7846
|
}),
|
|
7543
7847
|
examples: [
|
|
7544
7848
|
{
|
|
@@ -7560,11 +7864,11 @@ treasury.command("whitelist", {
|
|
|
7560
7864
|
treasury.command("major-spend-status", {
|
|
7561
7865
|
description: "Read major-spend cooldown status for the treasury contract.",
|
|
7562
7866
|
env: env5,
|
|
7563
|
-
output:
|
|
7564
|
-
majorSpendCooldownSeconds:
|
|
7867
|
+
output: z8.object({
|
|
7868
|
+
majorSpendCooldownSeconds: z8.number(),
|
|
7565
7869
|
lastMajorSpendAt: timestampOutput5,
|
|
7566
|
-
lastMajorSpendRelative:
|
|
7567
|
-
isMajorSpendAllowed:
|
|
7870
|
+
lastMajorSpendRelative: z8.string(),
|
|
7871
|
+
isMajorSpendAllowed: z8.boolean()
|
|
7568
7872
|
}),
|
|
7569
7873
|
examples: [{ description: "Inspect treasury major-spend guardrails" }],
|
|
7570
7874
|
async run(c) {
|
|
@@ -7598,13 +7902,13 @@ treasury.command("major-spend-status", {
|
|
|
7598
7902
|
});
|
|
7599
7903
|
treasury.command("executed", {
|
|
7600
7904
|
description: "Check whether a treasury action for a proposal has executed.",
|
|
7601
|
-
args:
|
|
7602
|
-
proposalId:
|
|
7905
|
+
args: z8.object({
|
|
7906
|
+
proposalId: z8.coerce.number().int().positive().describe("Governance proposal id")
|
|
7603
7907
|
}),
|
|
7604
7908
|
env: env5,
|
|
7605
|
-
output:
|
|
7606
|
-
proposalId:
|
|
7607
|
-
executed:
|
|
7909
|
+
output: z8.object({
|
|
7910
|
+
proposalId: z8.number(),
|
|
7911
|
+
executed: z8.boolean()
|
|
7608
7912
|
}),
|
|
7609
7913
|
examples: [{ args: { proposalId: 1 }, description: "Check execution status for proposal #1" }],
|
|
7610
7914
|
async run(c) {
|
|
@@ -7634,25 +7938,25 @@ treasury.command("propose-spend", {
|
|
|
7634
7938
|
description: "Create a council proposal that spends treasury funds via TreasuryTransferIntentModule.",
|
|
7635
7939
|
hint: "Requires PRIVATE_KEY environment variable for signing.",
|
|
7636
7940
|
options: writeOptions.extend({
|
|
7637
|
-
token:
|
|
7638
|
-
recipient:
|
|
7639
|
-
amount:
|
|
7640
|
-
decimals:
|
|
7641
|
-
title:
|
|
7642
|
-
description:
|
|
7643
|
-
category:
|
|
7644
|
-
"risk-tier":
|
|
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)")
|
|
7645
7949
|
}),
|
|
7646
7950
|
env: writeEnv,
|
|
7647
|
-
output:
|
|
7648
|
-
proposer:
|
|
7649
|
-
category:
|
|
7650
|
-
token:
|
|
7651
|
-
recipient:
|
|
7652
|
-
amount:
|
|
7653
|
-
amountWei:
|
|
7654
|
-
expectedProposalId:
|
|
7655
|
-
expectedThreadId:
|
|
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(),
|
|
7656
7960
|
tx: txResultOutput4
|
|
7657
7961
|
}),
|
|
7658
7962
|
examples: [
|
|
@@ -7956,24 +8260,25 @@ cli.command(council);
|
|
|
7956
8260
|
cli.command(forum);
|
|
7957
8261
|
cli.command(governance);
|
|
7958
8262
|
cli.command(treasury);
|
|
7959
|
-
|
|
7960
|
-
|
|
8263
|
+
registerDigestCommand(cli);
|
|
8264
|
+
var rootEnv = z9.object({
|
|
8265
|
+
ABSTRACT_RPC_URL: z9.string().optional().describe("Abstract RPC URL override")
|
|
7961
8266
|
});
|
|
7962
|
-
var timestampOutput6 =
|
|
8267
|
+
var timestampOutput6 = z9.union([z9.number(), z9.string()]);
|
|
7963
8268
|
cli.command("status", {
|
|
7964
8269
|
description: "Get a cross-contract Assembly snapshot (members, council, governance, treasury).",
|
|
7965
8270
|
env: rootEnv,
|
|
7966
|
-
output:
|
|
7967
|
-
activeMemberCount:
|
|
7968
|
-
seatCount:
|
|
7969
|
-
proposalCount:
|
|
7970
|
-
currentAuctionDay:
|
|
7971
|
-
currentAuctionSlot:
|
|
7972
|
-
treasuryBalance:
|
|
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()
|
|
7973
8278
|
}),
|
|
7974
8279
|
examples: [{ description: "Fetch the current Assembly system status" }],
|
|
7975
8280
|
async run(c) {
|
|
7976
|
-
return
|
|
8281
|
+
return withCommandSpan2("assembly status", {}, async () => {
|
|
7977
8282
|
const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
|
|
7978
8283
|
const [
|
|
7979
8284
|
activeMemberCount,
|
|
@@ -8023,18 +8328,18 @@ cli.command("status", {
|
|
|
8023
8328
|
});
|
|
8024
8329
|
cli.command("health", {
|
|
8025
8330
|
description: "Check cross-contract health for one address (membership, council, refunds, power).",
|
|
8026
|
-
args:
|
|
8027
|
-
address:
|
|
8331
|
+
args: z9.object({
|
|
8332
|
+
address: z9.string().describe("Member or wallet address to inspect")
|
|
8028
8333
|
}),
|
|
8029
8334
|
env: rootEnv,
|
|
8030
|
-
output:
|
|
8031
|
-
address:
|
|
8032
|
-
isActive:
|
|
8335
|
+
output: z9.object({
|
|
8336
|
+
address: z9.string(),
|
|
8337
|
+
isActive: z9.boolean(),
|
|
8033
8338
|
activeUntil: timestampOutput6,
|
|
8034
|
-
activeUntilRelative:
|
|
8035
|
-
isCouncilMember:
|
|
8036
|
-
pendingReturnsWei:
|
|
8037
|
-
votingPower:
|
|
8339
|
+
activeUntilRelative: z9.string(),
|
|
8340
|
+
isCouncilMember: z9.boolean(),
|
|
8341
|
+
pendingReturnsWei: z9.string(),
|
|
8342
|
+
votingPower: z9.number()
|
|
8038
8343
|
}),
|
|
8039
8344
|
examples: [
|
|
8040
8345
|
{
|
|
@@ -8043,7 +8348,7 @@ cli.command("health", {
|
|
|
8043
8348
|
}
|
|
8044
8349
|
],
|
|
8045
8350
|
async run(c) {
|
|
8046
|
-
return
|
|
8351
|
+
return withCommandSpan2("assembly health", { address: c.args.address }, async () => {
|
|
8047
8352
|
const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
|
|
8048
8353
|
const [isActive, member, isCouncilMember, pendingReturns, votingPower] = await Promise.all([
|
|
8049
8354
|
client.readContract({
|