@spectratools/assembly-cli 0.8.2 → 0.9.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 +406 -5
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -5622,6 +5622,7 @@ forum.command("stats", {
|
|
|
5622
5622
|
});
|
|
5623
5623
|
|
|
5624
5624
|
// src/commands/governance.ts
|
|
5625
|
+
import { TxError } from "@spectratools/tx-shared";
|
|
5625
5626
|
import { Cli as Cli3, z as z4 } from "incur";
|
|
5626
5627
|
var env3 = z4.object({
|
|
5627
5628
|
ABSTRACT_RPC_URL: z4.string().optional().describe("Abstract RPC URL override")
|
|
@@ -5635,6 +5636,14 @@ var proposalStatusLabels = {
|
|
|
5635
5636
|
4: "defeated",
|
|
5636
5637
|
5: "cancelled"
|
|
5637
5638
|
};
|
|
5639
|
+
var PROPOSAL_STATUS_PENDING = 0;
|
|
5640
|
+
var PROPOSAL_STATUS_ACTIVE = 1;
|
|
5641
|
+
var PROPOSAL_STATUS_PASSED = 2;
|
|
5642
|
+
var supportChoiceToValue = {
|
|
5643
|
+
against: 0,
|
|
5644
|
+
for: 1,
|
|
5645
|
+
abstain: 2
|
|
5646
|
+
};
|
|
5638
5647
|
function proposalStatus(status) {
|
|
5639
5648
|
const statusCode = asNum(status);
|
|
5640
5649
|
return {
|
|
@@ -5749,6 +5758,23 @@ function serializeProposal(proposal) {
|
|
|
5749
5758
|
description: proposal.description
|
|
5750
5759
|
};
|
|
5751
5760
|
}
|
|
5761
|
+
async function readProposalCount(client) {
|
|
5762
|
+
return await client.readContract({
|
|
5763
|
+
abi: governanceAbi,
|
|
5764
|
+
address: ABSTRACT_MAINNET_ADDRESSES.governance,
|
|
5765
|
+
functionName: "proposalCount"
|
|
5766
|
+
});
|
|
5767
|
+
}
|
|
5768
|
+
async function readProposalById(client, proposalId) {
|
|
5769
|
+
return decodeProposal(
|
|
5770
|
+
await client.readContract({
|
|
5771
|
+
abi: governanceAbi,
|
|
5772
|
+
address: ABSTRACT_MAINNET_ADDRESSES.governance,
|
|
5773
|
+
functionName: "proposals",
|
|
5774
|
+
args: [BigInt(proposalId)]
|
|
5775
|
+
})
|
|
5776
|
+
);
|
|
5777
|
+
}
|
|
5752
5778
|
var governance = Cli3.create("governance", {
|
|
5753
5779
|
description: "Inspect Assembly governance proposals, votes, and parameters."
|
|
5754
5780
|
});
|
|
@@ -5806,7 +5832,10 @@ governance.command("proposals", {
|
|
|
5806
5832
|
description: "Inspect or vote:",
|
|
5807
5833
|
commands: [
|
|
5808
5834
|
{ command: "governance proposal", args: { id: "<id>" } },
|
|
5809
|
-
{
|
|
5835
|
+
{
|
|
5836
|
+
command: "governance vote",
|
|
5837
|
+
args: { proposalId: "<id>", support: "<for|against|abstain>" }
|
|
5838
|
+
}
|
|
5810
5839
|
]
|
|
5811
5840
|
}
|
|
5812
5841
|
}
|
|
@@ -5940,9 +5969,381 @@ governance.command("params", {
|
|
|
5940
5969
|
});
|
|
5941
5970
|
}
|
|
5942
5971
|
});
|
|
5972
|
+
var txResultOutput2 = z4.union([
|
|
5973
|
+
z4.object({
|
|
5974
|
+
status: z4.enum(["success", "reverted"]),
|
|
5975
|
+
hash: z4.string(),
|
|
5976
|
+
blockNumber: z4.number(),
|
|
5977
|
+
gasUsed: z4.string(),
|
|
5978
|
+
from: z4.string(),
|
|
5979
|
+
to: z4.string().nullable(),
|
|
5980
|
+
effectiveGasPrice: z4.string().optional()
|
|
5981
|
+
}),
|
|
5982
|
+
z4.object({
|
|
5983
|
+
status: z4.literal("dry-run"),
|
|
5984
|
+
estimatedGas: z4.string(),
|
|
5985
|
+
simulationResult: z4.unknown()
|
|
5986
|
+
})
|
|
5987
|
+
]);
|
|
5988
|
+
governance.command("vote", {
|
|
5989
|
+
description: "Cast a governance vote on a proposal.",
|
|
5990
|
+
hint: "Requires PRIVATE_KEY environment variable for signing.",
|
|
5991
|
+
args: z4.object({
|
|
5992
|
+
proposalId: z4.coerce.number().int().positive().describe("Proposal id (1-indexed)"),
|
|
5993
|
+
support: z4.enum(["for", "against", "abstain"]).describe("Vote support: for, against, or abstain")
|
|
5994
|
+
}),
|
|
5995
|
+
options: writeOptions,
|
|
5996
|
+
env: writeEnv,
|
|
5997
|
+
output: z4.object({
|
|
5998
|
+
proposalId: z4.number(),
|
|
5999
|
+
proposalTitle: z4.string(),
|
|
6000
|
+
support: z4.enum(["for", "against", "abstain"]),
|
|
6001
|
+
supportValue: z4.number(),
|
|
6002
|
+
tx: txResultOutput2
|
|
6003
|
+
}),
|
|
6004
|
+
examples: [
|
|
6005
|
+
{
|
|
6006
|
+
args: { proposalId: 1, support: "for" },
|
|
6007
|
+
description: "Vote in favor of proposal #1"
|
|
6008
|
+
},
|
|
6009
|
+
{
|
|
6010
|
+
args: { proposalId: 1, support: "abstain" },
|
|
6011
|
+
options: { "dry-run": true },
|
|
6012
|
+
description: "Simulate casting an abstain vote"
|
|
6013
|
+
}
|
|
6014
|
+
],
|
|
6015
|
+
async run(c) {
|
|
6016
|
+
const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
|
|
6017
|
+
const account = resolveAccount(c.env);
|
|
6018
|
+
const proposalCount = await readProposalCount(client);
|
|
6019
|
+
if (c.args.proposalId > Number(proposalCount)) {
|
|
6020
|
+
return c.error({
|
|
6021
|
+
code: "OUT_OF_RANGE",
|
|
6022
|
+
message: `Proposal id ${c.args.proposalId} does not exist (proposalCount: ${proposalCount})`,
|
|
6023
|
+
retryable: false
|
|
6024
|
+
});
|
|
6025
|
+
}
|
|
6026
|
+
const proposal = await readProposalById(client, c.args.proposalId);
|
|
6027
|
+
const status = proposalStatus(proposal.status);
|
|
6028
|
+
if (status.statusCode !== PROPOSAL_STATUS_ACTIVE) {
|
|
6029
|
+
return c.error({
|
|
6030
|
+
code: "PROPOSAL_NOT_VOTING",
|
|
6031
|
+
message: `Proposal ${c.args.proposalId} is ${status.status} and cannot be voted right now.`,
|
|
6032
|
+
retryable: false
|
|
6033
|
+
});
|
|
6034
|
+
}
|
|
6035
|
+
const hasVoted = await client.readContract({
|
|
6036
|
+
abi: governanceAbi,
|
|
6037
|
+
address: ABSTRACT_MAINNET_ADDRESSES.governance,
|
|
6038
|
+
functionName: "hasVoted",
|
|
6039
|
+
args: [BigInt(c.args.proposalId), account.address]
|
|
6040
|
+
});
|
|
6041
|
+
if (hasVoted) {
|
|
6042
|
+
return c.error({
|
|
6043
|
+
code: "ALREADY_VOTED",
|
|
6044
|
+
message: `Address ${toChecksum(account.address)} has already voted on proposal ${c.args.proposalId}.`,
|
|
6045
|
+
retryable: false
|
|
6046
|
+
});
|
|
6047
|
+
}
|
|
6048
|
+
const supportValue = supportChoiceToValue[c.args.support];
|
|
6049
|
+
try {
|
|
6050
|
+
const txResult = await assemblyWriteTx({
|
|
6051
|
+
env: c.env,
|
|
6052
|
+
options: c.options,
|
|
6053
|
+
address: ABSTRACT_MAINNET_ADDRESSES.governance,
|
|
6054
|
+
abi: governanceAbi,
|
|
6055
|
+
functionName: "castVote",
|
|
6056
|
+
args: [BigInt(c.args.proposalId), supportValue]
|
|
6057
|
+
});
|
|
6058
|
+
return c.ok({
|
|
6059
|
+
proposalId: c.args.proposalId,
|
|
6060
|
+
proposalTitle: proposal.title,
|
|
6061
|
+
support: c.args.support,
|
|
6062
|
+
supportValue,
|
|
6063
|
+
tx: txResult
|
|
6064
|
+
});
|
|
6065
|
+
} catch (error) {
|
|
6066
|
+
if (error instanceof TxError) {
|
|
6067
|
+
return c.error({
|
|
6068
|
+
code: error.code,
|
|
6069
|
+
message: error.message,
|
|
6070
|
+
retryable: error.code === "NONCE_CONFLICT"
|
|
6071
|
+
});
|
|
6072
|
+
}
|
|
6073
|
+
throw error;
|
|
6074
|
+
}
|
|
6075
|
+
}
|
|
6076
|
+
});
|
|
6077
|
+
governance.command("propose", {
|
|
6078
|
+
description: "Create a new council-originated governance proposal.",
|
|
6079
|
+
hint: "Requires PRIVATE_KEY environment variable for signing.",
|
|
6080
|
+
options: writeOptions.extend({
|
|
6081
|
+
title: z4.string().min(1).describe("Proposal title"),
|
|
6082
|
+
description: z4.string().min(1).describe("Proposal description"),
|
|
6083
|
+
kind: z4.coerce.number().int().nonnegative().max(255).describe("Proposal kind enum value"),
|
|
6084
|
+
category: z4.string().default("governance").describe("Forum category label for the proposal"),
|
|
6085
|
+
"risk-tier": z4.coerce.number().int().nonnegative().max(255).optional().describe("Optional max allowed intent risk tier (default: 0)"),
|
|
6086
|
+
amount: z4.string().optional().describe("Optional treasury amount hint (currently unsupported for intent encoding)"),
|
|
6087
|
+
recipient: z4.string().optional().describe("Optional treasury recipient hint (currently unsupported for intent encoding)")
|
|
6088
|
+
}),
|
|
6089
|
+
env: writeEnv,
|
|
6090
|
+
output: z4.object({
|
|
6091
|
+
proposer: z4.string(),
|
|
6092
|
+
category: z4.string(),
|
|
6093
|
+
kind: z4.number(),
|
|
6094
|
+
title: z4.string(),
|
|
6095
|
+
description: z4.string(),
|
|
6096
|
+
expectedProposalId: z4.number(),
|
|
6097
|
+
tx: txResultOutput2
|
|
6098
|
+
}),
|
|
6099
|
+
examples: [
|
|
6100
|
+
{
|
|
6101
|
+
options: {
|
|
6102
|
+
title: "Increase quorum requirement",
|
|
6103
|
+
description: "Raise quorum from 10% to 12% for governance votes.",
|
|
6104
|
+
kind: 3
|
|
6105
|
+
},
|
|
6106
|
+
description: "Create a governance proposal from a council member account"
|
|
6107
|
+
}
|
|
6108
|
+
],
|
|
6109
|
+
async run(c) {
|
|
6110
|
+
const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
|
|
6111
|
+
const account = resolveAccount(c.env);
|
|
6112
|
+
if (c.options.amount && !c.options.recipient || !c.options.amount && c.options.recipient) {
|
|
6113
|
+
return c.error({
|
|
6114
|
+
code: "INVALID_PROPOSAL_OPTIONS",
|
|
6115
|
+
message: "Both --amount and --recipient must be provided together when setting transfer hints.",
|
|
6116
|
+
retryable: false
|
|
6117
|
+
});
|
|
6118
|
+
}
|
|
6119
|
+
if (c.options.amount || c.options.recipient) {
|
|
6120
|
+
return c.error({
|
|
6121
|
+
code: "UNSUPPORTED_TRANSFER_INTENT",
|
|
6122
|
+
message: "Transfer intents are not yet supported by `governance propose`. Omit --amount/--recipient and use intent-specific tooling.",
|
|
6123
|
+
retryable: false
|
|
6124
|
+
});
|
|
6125
|
+
}
|
|
6126
|
+
const isCouncilMember = await client.readContract({
|
|
6127
|
+
abi: councilSeatsAbi,
|
|
6128
|
+
address: ABSTRACT_MAINNET_ADDRESSES.councilSeats,
|
|
6129
|
+
functionName: "isCouncilMember",
|
|
6130
|
+
args: [account.address]
|
|
6131
|
+
});
|
|
6132
|
+
if (!isCouncilMember) {
|
|
6133
|
+
return c.error({
|
|
6134
|
+
code: "NOT_COUNCIL_MEMBER",
|
|
6135
|
+
message: `Address ${toChecksum(account.address)} is not an active council member and cannot create a council proposal.`,
|
|
6136
|
+
retryable: false
|
|
6137
|
+
});
|
|
6138
|
+
}
|
|
6139
|
+
const proposalCountBefore = await readProposalCount(client);
|
|
6140
|
+
const expectedProposalId = Number(proposalCountBefore) + 1;
|
|
6141
|
+
const proposalInput = {
|
|
6142
|
+
kind: c.options.kind,
|
|
6143
|
+
title: c.options.title,
|
|
6144
|
+
description: c.options.description,
|
|
6145
|
+
intentSteps: [],
|
|
6146
|
+
intentConstraints: {
|
|
6147
|
+
deadline: 0,
|
|
6148
|
+
maxAllowedRiskTier: c.options["risk-tier"] ?? 0
|
|
6149
|
+
},
|
|
6150
|
+
configUpdates: []
|
|
6151
|
+
};
|
|
6152
|
+
try {
|
|
6153
|
+
const txResult = await assemblyWriteTx({
|
|
6154
|
+
env: c.env,
|
|
6155
|
+
options: c.options,
|
|
6156
|
+
address: ABSTRACT_MAINNET_ADDRESSES.forum,
|
|
6157
|
+
abi: forumAbi,
|
|
6158
|
+
functionName: "createCouncilProposal",
|
|
6159
|
+
args: [c.options.category, proposalInput]
|
|
6160
|
+
});
|
|
6161
|
+
return c.ok({
|
|
6162
|
+
proposer: toChecksum(account.address),
|
|
6163
|
+
category: c.options.category,
|
|
6164
|
+
kind: c.options.kind,
|
|
6165
|
+
title: c.options.title,
|
|
6166
|
+
description: c.options.description,
|
|
6167
|
+
expectedProposalId,
|
|
6168
|
+
tx: txResult
|
|
6169
|
+
});
|
|
6170
|
+
} catch (error) {
|
|
6171
|
+
if (error instanceof TxError) {
|
|
6172
|
+
return c.error({
|
|
6173
|
+
code: error.code,
|
|
6174
|
+
message: error.message,
|
|
6175
|
+
retryable: error.code === "NONCE_CONFLICT"
|
|
6176
|
+
});
|
|
6177
|
+
}
|
|
6178
|
+
throw error;
|
|
6179
|
+
}
|
|
6180
|
+
}
|
|
6181
|
+
});
|
|
6182
|
+
governance.command("queue", {
|
|
6183
|
+
description: "Finalize voting and queue an eligible proposal into timelock.",
|
|
6184
|
+
hint: "Requires PRIVATE_KEY environment variable for signing.",
|
|
6185
|
+
args: z4.object({
|
|
6186
|
+
proposalId: z4.coerce.number().int().positive().describe("Proposal id (1-indexed)")
|
|
6187
|
+
}),
|
|
6188
|
+
options: writeOptions,
|
|
6189
|
+
env: writeEnv,
|
|
6190
|
+
output: z4.object({
|
|
6191
|
+
proposalId: z4.number(),
|
|
6192
|
+
proposalTitle: z4.string(),
|
|
6193
|
+
statusBefore: z4.string(),
|
|
6194
|
+
tx: txResultOutput2
|
|
6195
|
+
}),
|
|
6196
|
+
examples: [
|
|
6197
|
+
{
|
|
6198
|
+
args: { proposalId: 1 },
|
|
6199
|
+
description: "Finalize voting for proposal #1 and queue if passed"
|
|
6200
|
+
}
|
|
6201
|
+
],
|
|
6202
|
+
async run(c) {
|
|
6203
|
+
const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
|
|
6204
|
+
const proposalCount = await readProposalCount(client);
|
|
6205
|
+
if (c.args.proposalId > Number(proposalCount)) {
|
|
6206
|
+
return c.error({
|
|
6207
|
+
code: "OUT_OF_RANGE",
|
|
6208
|
+
message: `Proposal id ${c.args.proposalId} does not exist (proposalCount: ${proposalCount})`,
|
|
6209
|
+
retryable: false
|
|
6210
|
+
});
|
|
6211
|
+
}
|
|
6212
|
+
const proposal = await readProposalById(client, c.args.proposalId);
|
|
6213
|
+
const status = proposalStatus(proposal.status);
|
|
6214
|
+
if (status.statusCode === PROPOSAL_STATUS_PASSED) {
|
|
6215
|
+
return c.error({
|
|
6216
|
+
code: "ALREADY_QUEUED",
|
|
6217
|
+
message: `Proposal ${c.args.proposalId} is already queued in timelock.`,
|
|
6218
|
+
retryable: false
|
|
6219
|
+
});
|
|
6220
|
+
}
|
|
6221
|
+
if (status.statusCode === PROPOSAL_STATUS_PENDING) {
|
|
6222
|
+
return c.error({
|
|
6223
|
+
code: "PROPOSAL_NOT_QUEUEABLE",
|
|
6224
|
+
message: `Proposal ${c.args.proposalId} is still in deliberation and cannot be queued yet.`,
|
|
6225
|
+
retryable: false
|
|
6226
|
+
});
|
|
6227
|
+
}
|
|
6228
|
+
if (status.statusCode !== PROPOSAL_STATUS_ACTIVE) {
|
|
6229
|
+
return c.error({
|
|
6230
|
+
code: "PROPOSAL_NOT_QUEUEABLE",
|
|
6231
|
+
message: `Proposal ${c.args.proposalId} is ${status.status} and cannot be queued.`,
|
|
6232
|
+
retryable: false
|
|
6233
|
+
});
|
|
6234
|
+
}
|
|
6235
|
+
const latestBlock = await client.getBlock({ blockTag: "latest" });
|
|
6236
|
+
if (latestBlock.timestamp < proposal.voteEndAt) {
|
|
6237
|
+
return c.error({
|
|
6238
|
+
code: "VOTING_STILL_ACTIVE",
|
|
6239
|
+
message: `Proposal ${c.args.proposalId} voting window is still open (ends ${relTime(proposal.voteEndAt)}).`,
|
|
6240
|
+
retryable: false
|
|
6241
|
+
});
|
|
6242
|
+
}
|
|
6243
|
+
try {
|
|
6244
|
+
const txResult = await assemblyWriteTx({
|
|
6245
|
+
env: c.env,
|
|
6246
|
+
options: c.options,
|
|
6247
|
+
address: ABSTRACT_MAINNET_ADDRESSES.governance,
|
|
6248
|
+
abi: governanceAbi,
|
|
6249
|
+
functionName: "finalizeVote",
|
|
6250
|
+
args: [BigInt(c.args.proposalId)]
|
|
6251
|
+
});
|
|
6252
|
+
return c.ok({
|
|
6253
|
+
proposalId: c.args.proposalId,
|
|
6254
|
+
proposalTitle: proposal.title,
|
|
6255
|
+
statusBefore: status.status,
|
|
6256
|
+
tx: txResult
|
|
6257
|
+
});
|
|
6258
|
+
} catch (error) {
|
|
6259
|
+
if (error instanceof TxError) {
|
|
6260
|
+
return c.error({
|
|
6261
|
+
code: error.code,
|
|
6262
|
+
message: error.message,
|
|
6263
|
+
retryable: error.code === "NONCE_CONFLICT"
|
|
6264
|
+
});
|
|
6265
|
+
}
|
|
6266
|
+
throw error;
|
|
6267
|
+
}
|
|
6268
|
+
}
|
|
6269
|
+
});
|
|
6270
|
+
governance.command("execute", {
|
|
6271
|
+
description: "Execute a queued governance proposal after timelock expiry.",
|
|
6272
|
+
hint: "Requires PRIVATE_KEY environment variable for signing.",
|
|
6273
|
+
args: z4.object({
|
|
6274
|
+
proposalId: z4.coerce.number().int().positive().describe("Proposal id (1-indexed)")
|
|
6275
|
+
}),
|
|
6276
|
+
options: writeOptions,
|
|
6277
|
+
env: writeEnv,
|
|
6278
|
+
output: z4.object({
|
|
6279
|
+
proposalId: z4.number(),
|
|
6280
|
+
proposalTitle: z4.string(),
|
|
6281
|
+
timelockEndsAt: timestampOutput3,
|
|
6282
|
+
tx: txResultOutput2
|
|
6283
|
+
}),
|
|
6284
|
+
examples: [
|
|
6285
|
+
{
|
|
6286
|
+
args: { proposalId: 1 },
|
|
6287
|
+
description: "Execute proposal #1 after timelock has expired"
|
|
6288
|
+
}
|
|
6289
|
+
],
|
|
6290
|
+
async run(c) {
|
|
6291
|
+
const client = createAssemblyPublicClient(c.env.ABSTRACT_RPC_URL);
|
|
6292
|
+
const proposalCount = await readProposalCount(client);
|
|
6293
|
+
if (c.args.proposalId > Number(proposalCount)) {
|
|
6294
|
+
return c.error({
|
|
6295
|
+
code: "OUT_OF_RANGE",
|
|
6296
|
+
message: `Proposal id ${c.args.proposalId} does not exist (proposalCount: ${proposalCount})`,
|
|
6297
|
+
retryable: false
|
|
6298
|
+
});
|
|
6299
|
+
}
|
|
6300
|
+
const proposal = await readProposalById(client, c.args.proposalId);
|
|
6301
|
+
const status = proposalStatus(proposal.status);
|
|
6302
|
+
if (status.statusCode !== PROPOSAL_STATUS_PASSED) {
|
|
6303
|
+
return c.error({
|
|
6304
|
+
code: "PROPOSAL_NOT_EXECUTABLE",
|
|
6305
|
+
message: `Proposal ${c.args.proposalId} is ${status.status} and cannot be executed.`,
|
|
6306
|
+
retryable: false
|
|
6307
|
+
});
|
|
6308
|
+
}
|
|
6309
|
+
const latestBlock = await client.getBlock({ blockTag: "latest" });
|
|
6310
|
+
if (latestBlock.timestamp < proposal.timelockEndsAt) {
|
|
6311
|
+
return c.error({
|
|
6312
|
+
code: "TIMELOCK_ACTIVE",
|
|
6313
|
+
message: `Proposal ${c.args.proposalId} timelock has not expired yet (ends ${relTime(proposal.timelockEndsAt)}).`,
|
|
6314
|
+
retryable: false
|
|
6315
|
+
});
|
|
6316
|
+
}
|
|
6317
|
+
try {
|
|
6318
|
+
const txResult = await assemblyWriteTx({
|
|
6319
|
+
env: c.env,
|
|
6320
|
+
options: c.options,
|
|
6321
|
+
address: ABSTRACT_MAINNET_ADDRESSES.governance,
|
|
6322
|
+
abi: governanceAbi,
|
|
6323
|
+
functionName: "executeProposal",
|
|
6324
|
+
args: [BigInt(c.args.proposalId)]
|
|
6325
|
+
});
|
|
6326
|
+
return c.ok({
|
|
6327
|
+
proposalId: c.args.proposalId,
|
|
6328
|
+
proposalTitle: proposal.title,
|
|
6329
|
+
timelockEndsAt: timeValue(proposal.timelockEndsAt, c.format),
|
|
6330
|
+
tx: txResult
|
|
6331
|
+
});
|
|
6332
|
+
} catch (error) {
|
|
6333
|
+
if (error instanceof TxError) {
|
|
6334
|
+
return c.error({
|
|
6335
|
+
code: error.code,
|
|
6336
|
+
message: error.message,
|
|
6337
|
+
retryable: error.code === "NONCE_CONFLICT"
|
|
6338
|
+
});
|
|
6339
|
+
}
|
|
6340
|
+
throw error;
|
|
6341
|
+
}
|
|
6342
|
+
}
|
|
6343
|
+
});
|
|
5943
6344
|
|
|
5944
6345
|
// src/commands/members.ts
|
|
5945
|
-
import { TxError } from "@spectratools/tx-shared";
|
|
6346
|
+
import { TxError as TxError2 } from "@spectratools/tx-shared";
|
|
5946
6347
|
import { Cli as Cli4, z as z5 } from "incur";
|
|
5947
6348
|
var DEFAULT_MEMBER_SNAPSHOT_URL = "https://www.theaiassembly.org/api/indexer/members";
|
|
5948
6349
|
var REGISTERED_EVENT_SCAN_STEP = 100000n;
|
|
@@ -6435,7 +6836,7 @@ members.command("register", {
|
|
|
6435
6836
|
} : void 0
|
|
6436
6837
|
);
|
|
6437
6838
|
} catch (error) {
|
|
6438
|
-
if (error instanceof
|
|
6839
|
+
if (error instanceof TxError2 && error.code === "INSUFFICIENT_FUNDS") {
|
|
6439
6840
|
return c.error({
|
|
6440
6841
|
code: "INSUFFICIENT_FUNDS",
|
|
6441
6842
|
message: `Insufficient funds to register. Required fee: ${eth(fee)} (${fee} wei). ${error.message}`,
|
|
@@ -6486,7 +6887,7 @@ members.command("heartbeat", {
|
|
|
6486
6887
|
} : void 0
|
|
6487
6888
|
);
|
|
6488
6889
|
} catch (error) {
|
|
6489
|
-
if (error instanceof
|
|
6890
|
+
if (error instanceof TxError2 && error.code === "INSUFFICIENT_FUNDS") {
|
|
6490
6891
|
return c.error({
|
|
6491
6892
|
code: "INSUFFICIENT_FUNDS",
|
|
6492
6893
|
message: `Insufficient funds for heartbeat. Required fee: ${eth(fee)} (${fee} wei). ${error.message}`,
|
|
@@ -6537,7 +6938,7 @@ members.command("renew", {
|
|
|
6537
6938
|
} : void 0
|
|
6538
6939
|
);
|
|
6539
6940
|
} catch (error) {
|
|
6540
|
-
if (error instanceof
|
|
6941
|
+
if (error instanceof TxError2 && error.code === "INSUFFICIENT_FUNDS") {
|
|
6541
6942
|
return c.error({
|
|
6542
6943
|
code: "INSUFFICIENT_FUNDS",
|
|
6543
6944
|
message: `Insufficient funds to renew. Required fee: ${eth(fee)} (${fee} wei). ${error.message}`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spectratools/assembly-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "CLI for Assembly governance on Abstract (members, council, forum, proposals, and treasury).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"ox": "^0.14.0",
|
|
34
34
|
"viem": "^2.47.0",
|
|
35
35
|
"@spectratools/cli-shared": "0.1.1",
|
|
36
|
-
"@spectratools/tx-shared": "0.4.
|
|
36
|
+
"@spectratools/tx-shared": "0.4.3"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"typescript": "5.7.3",
|