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