genlayer 0.34.0 → 0.34.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/dist/index.js +13 -3
  2. package/package.json +11 -2
  3. package/.eslintignore +0 -2
  4. package/.github/workflows/cli-docs.yml +0 -121
  5. package/.github/workflows/publish-beta.yml +0 -41
  6. package/.github/workflows/publish.yml +0 -43
  7. package/.github/workflows/validate-code.yml +0 -47
  8. package/.prettierignore +0 -19
  9. package/.prettierrc +0 -12
  10. package/.release-it.json +0 -64
  11. package/CHANGELOG.md +0 -425
  12. package/CLAUDE.md +0 -55
  13. package/CONTRIBUTING.md +0 -117
  14. package/docker-compose.yml +0 -154
  15. package/docs/delegator-guide.md +0 -203
  16. package/docs/validator-guide.md +0 -329
  17. package/esbuild.config.dev.js +0 -17
  18. package/esbuild.config.js +0 -22
  19. package/esbuild.config.prod.js +0 -17
  20. package/eslint.config.js +0 -60
  21. package/renovate.json +0 -22
  22. package/src/commands/account/create.ts +0 -30
  23. package/src/commands/account/export.ts +0 -106
  24. package/src/commands/account/import.ts +0 -135
  25. package/src/commands/account/index.ts +0 -129
  26. package/src/commands/account/list.ts +0 -34
  27. package/src/commands/account/lock.ts +0 -39
  28. package/src/commands/account/remove.ts +0 -30
  29. package/src/commands/account/send.ts +0 -162
  30. package/src/commands/account/show.ts +0 -74
  31. package/src/commands/account/unlock.ts +0 -56
  32. package/src/commands/account/use.ts +0 -21
  33. package/src/commands/config/getSetReset.ts +0 -51
  34. package/src/commands/config/index.ts +0 -30
  35. package/src/commands/contracts/call.ts +0 -39
  36. package/src/commands/contracts/code.ts +0 -33
  37. package/src/commands/contracts/deploy.ts +0 -157
  38. package/src/commands/contracts/index.ts +0 -86
  39. package/src/commands/contracts/schema.ts +0 -31
  40. package/src/commands/contracts/write.ts +0 -49
  41. package/src/commands/general/index.ts +0 -45
  42. package/src/commands/general/init.ts +0 -179
  43. package/src/commands/general/start.ts +0 -116
  44. package/src/commands/general/stop.ts +0 -26
  45. package/src/commands/localnet/index.ts +0 -100
  46. package/src/commands/localnet/validators.ts +0 -269
  47. package/src/commands/network/index.ts +0 -29
  48. package/src/commands/network/setNetwork.ts +0 -77
  49. package/src/commands/scaffold/index.ts +0 -16
  50. package/src/commands/scaffold/new.ts +0 -34
  51. package/src/commands/staking/StakingAction.ts +0 -279
  52. package/src/commands/staking/delegatorClaim.ts +0 -41
  53. package/src/commands/staking/delegatorExit.ts +0 -56
  54. package/src/commands/staking/delegatorJoin.ts +0 -44
  55. package/src/commands/staking/index.ts +0 -357
  56. package/src/commands/staking/setIdentity.ts +0 -78
  57. package/src/commands/staking/setOperator.ts +0 -46
  58. package/src/commands/staking/stakingInfo.ts +0 -584
  59. package/src/commands/staking/validatorClaim.ts +0 -43
  60. package/src/commands/staking/validatorDeposit.ts +0 -48
  61. package/src/commands/staking/validatorExit.ts +0 -63
  62. package/src/commands/staking/validatorHistory.ts +0 -298
  63. package/src/commands/staking/validatorJoin.ts +0 -47
  64. package/src/commands/staking/validatorPrime.ts +0 -73
  65. package/src/commands/staking/wizard.ts +0 -809
  66. package/src/commands/transactions/appeal.ts +0 -39
  67. package/src/commands/transactions/index.ts +0 -39
  68. package/src/commands/transactions/receipt.ts +0 -90
  69. package/src/commands/update/index.ts +0 -25
  70. package/src/commands/update/ollama.ts +0 -103
  71. package/src/lib/actions/BaseAction.ts +0 -299
  72. package/src/lib/clients/jsonRpcClient.ts +0 -41
  73. package/src/lib/clients/system.ts +0 -73
  74. package/src/lib/config/ConfigFileManager.ts +0 -194
  75. package/src/lib/config/KeychainManager.ts +0 -89
  76. package/src/lib/config/simulator.ts +0 -68
  77. package/src/lib/config/text.ts +0 -2
  78. package/src/lib/errors/missingRequirement.ts +0 -9
  79. package/src/lib/errors/versionRequired.ts +0 -9
  80. package/src/lib/interfaces/ISimulatorService.ts +0 -37
  81. package/src/lib/services/simulator.ts +0 -351
  82. package/src/types/node-fetch.d.ts +0 -1
  83. package/tests/actions/appeal.test.ts +0 -99
  84. package/tests/actions/call.test.ts +0 -94
  85. package/tests/actions/code.test.ts +0 -87
  86. package/tests/actions/create.test.ts +0 -65
  87. package/tests/actions/deploy.test.ts +0 -420
  88. package/tests/actions/getSetReset.test.ts +0 -88
  89. package/tests/actions/init.test.ts +0 -467
  90. package/tests/actions/lock.test.ts +0 -86
  91. package/tests/actions/new.test.ts +0 -80
  92. package/tests/actions/ollama.test.ts +0 -193
  93. package/tests/actions/receipt.test.ts +0 -261
  94. package/tests/actions/schema.test.ts +0 -94
  95. package/tests/actions/setNetwork.test.ts +0 -160
  96. package/tests/actions/staking.test.ts +0 -279
  97. package/tests/actions/start.test.ts +0 -235
  98. package/tests/actions/stop.test.ts +0 -77
  99. package/tests/actions/unlock.test.ts +0 -139
  100. package/tests/actions/validators.test.ts +0 -750
  101. package/tests/actions/write.test.ts +0 -102
  102. package/tests/commands/account.test.ts +0 -146
  103. package/tests/commands/appeal.test.ts +0 -58
  104. package/tests/commands/call.test.ts +0 -78
  105. package/tests/commands/code.test.ts +0 -69
  106. package/tests/commands/config.test.ts +0 -54
  107. package/tests/commands/deploy.test.ts +0 -83
  108. package/tests/commands/init.test.ts +0 -101
  109. package/tests/commands/localnet.test.ts +0 -131
  110. package/tests/commands/network.test.ts +0 -60
  111. package/tests/commands/new.test.ts +0 -68
  112. package/tests/commands/receipt.test.ts +0 -142
  113. package/tests/commands/schema.test.ts +0 -67
  114. package/tests/commands/staking.test.ts +0 -329
  115. package/tests/commands/stop.test.ts +0 -27
  116. package/tests/commands/up.test.ts +0 -105
  117. package/tests/commands/update.test.ts +0 -45
  118. package/tests/commands/write.test.ts +0 -76
  119. package/tests/index.test.ts +0 -56
  120. package/tests/libs/baseAction.test.ts +0 -516
  121. package/tests/libs/configFileManager.test.ts +0 -117
  122. package/tests/libs/jsonRpcClient.test.ts +0 -59
  123. package/tests/libs/keychainManager.test.ts +0 -156
  124. package/tests/libs/system.test.ts +0 -148
  125. package/tests/services/simulator.test.ts +0 -705
  126. package/tests/utils.ts +0 -13
  127. package/tsconfig.json +0 -120
  128. package/vitest.config.ts +0 -12
@@ -1,63 +0,0 @@
1
- import {StakingAction, StakingConfig} from "./StakingAction";
2
- import type {Address} from "genlayer-js/types";
3
- import {abi} from "genlayer-js";
4
-
5
- export interface ValidatorExitOptions extends StakingConfig {
6
- validator: string;
7
- shares: string;
8
- }
9
-
10
- export class ValidatorExitAction extends StakingAction {
11
- constructor() {
12
- super();
13
- }
14
-
15
- async execute(options: ValidatorExitOptions): Promise<void> {
16
- this.startSpinner("Initiating validator exit...");
17
-
18
- try {
19
- let shares: bigint;
20
- try {
21
- shares = BigInt(options.shares);
22
- if (shares <= 0n) throw new Error("must be positive");
23
- } catch {
24
- this.failSpinner(`Invalid shares value: "${options.shares}". Must be a positive whole number.`);
25
- return;
26
- }
27
-
28
- const validatorWallet = options.validator as Address;
29
- const {walletClient, publicClient} = await this.getViemClients(options);
30
-
31
- this.setSpinnerText(`Exiting validator ${validatorWallet} with ${shares} shares...`);
32
-
33
- const hash = await walletClient.writeContract({
34
- address: validatorWallet,
35
- abi: abi.VALIDATOR_WALLET_ABI,
36
- functionName: "validatorExit",
37
- args: [shares],
38
- });
39
-
40
- const receipt = await publicClient.waitForTransactionReceipt({hash});
41
-
42
- // Check epoch to determine note
43
- const readClient = await this.getReadOnlyStakingClient(options);
44
- const epochInfo = await readClient.getEpochInfo();
45
- const isEpochZero = epochInfo.currentEpoch === 0n;
46
-
47
- const output = {
48
- transactionHash: receipt.transactionHash,
49
- validator: validatorWallet,
50
- sharesWithdrawn: shares.toString(),
51
- blockNumber: receipt.blockNumber.toString(),
52
- gasUsed: receipt.gasUsed.toString(),
53
- note: isEpochZero
54
- ? "Epoch 0: Withdrawal claimable immediately"
55
- : "Withdrawal will be claimable after the unbonding period",
56
- };
57
-
58
- this.succeedSpinner("Exit initiated successfully!", output);
59
- } catch (error: any) {
60
- this.failSpinner("Failed to exit", error.message || error);
61
- }
62
- }
63
- }
@@ -1,298 +0,0 @@
1
- import {StakingAction, StakingConfig, BUILT_IN_NETWORKS} from "./StakingAction";
2
- import type {Address, GenLayerChain} from "genlayer-js/types";
3
- import {createPublicClient, http} from "viem";
4
- import Table from "cli-table3";
5
- import chalk from "chalk";
6
-
7
- // Event ABIs for log fetching
8
- const SLASH_EVENT_ABI = {
9
- type: "event",
10
- name: "SlashedFromIdleness",
11
- inputs: [
12
- {name: "validator", type: "address", indexed: true},
13
- {name: "txId", type: "bytes32", indexed: false},
14
- {name: "epoch", type: "uint256", indexed: false},
15
- {name: "percentage", type: "uint256", indexed: false},
16
- ],
17
- } as const;
18
-
19
- const REWARD_EVENT_ABI = {
20
- type: "event",
21
- name: "ValidatorPrime",
22
- inputs: [
23
- {name: "validator", type: "address", indexed: false},
24
- {name: "epoch", type: "uint256", indexed: false},
25
- {name: "validatorRewards", type: "uint256", indexed: false},
26
- {name: "delegatorRewards", type: "uint256", indexed: false},
27
- ],
28
- } as const;
29
-
30
- export interface ValidatorHistoryOptions extends StakingConfig {
31
- validator?: string;
32
- fromBlock?: string;
33
- fromEpoch?: string;
34
- epochs?: string;
35
- limit?: string;
36
- all?: boolean;
37
- }
38
-
39
- interface SlashEvent {
40
- type: "slash";
41
- epoch: bigint;
42
- txId: string;
43
- percentage: bigint;
44
- blockNumber: bigint;
45
- timestamp: Date;
46
- }
47
-
48
- interface RewardEvent {
49
- type: "reward";
50
- epoch: bigint;
51
- validatorRewards: bigint;
52
- delegatorRewards: bigint;
53
- blockNumber: bigint;
54
- timestamp: Date;
55
- }
56
-
57
- type HistoryEvent = SlashEvent | RewardEvent;
58
-
59
- export class ValidatorHistoryAction extends StakingAction {
60
- constructor() {
61
- super();
62
- }
63
-
64
- private getNetworkForHistory(config: StakingConfig): GenLayerChain {
65
- if (config.network) {
66
- const network = BUILT_IN_NETWORKS[config.network];
67
- if (!network) {
68
- throw new Error(`Unknown network: ${config.network}`);
69
- }
70
- return network;
71
- }
72
- // Check global config
73
- const globalNetwork = this.getConfig().network;
74
- if (globalNetwork && BUILT_IN_NETWORKS[globalNetwork]) {
75
- return BUILT_IN_NETWORKS[globalNetwork];
76
- }
77
- return BUILT_IN_NETWORKS["localnet"];
78
- }
79
-
80
- async execute(options: ValidatorHistoryOptions): Promise<void> {
81
- this.startSpinner("Fetching validator history...");
82
-
83
- try {
84
- // Check network - localnet doesn't support eth_getLogs
85
- const chain = this.getNetworkForHistory(options);
86
- if (chain.id === 808080) {
87
- this.failSpinner("validator-history requires testnet-asimov (localnet doesn't support event logs)");
88
- return;
89
- }
90
-
91
- const client = await this.getReadOnlyStakingClient(options);
92
- const validatorAddress = options.validator || (await this.getSignerAddress());
93
-
94
- // Verify it's a validator
95
- const isValidator = await client.isValidator(validatorAddress as Address);
96
- if (!isValidator) {
97
- this.failSpinner(`Address ${validatorAddress} is not a validator`);
98
- return;
99
- }
100
-
101
- this.setSpinnerText("Fetching contract addresses...");
102
-
103
- // Get addresses
104
- const stakingAddress = client.getStakingContract().address;
105
- const slashingAddress = await client.getSlashingAddress();
106
-
107
- // Create public client for log fetching
108
- const publicClient = createPublicClient({
109
- chain,
110
- transport: http(chain.rpcUrls.default.http[0]),
111
- });
112
-
113
- // Determine epoch range for filtering
114
- const epochInfo = await client.getEpochInfo();
115
- const currentEpoch = epochInfo.currentEpoch;
116
- const defaultEpochs = 10n;
117
-
118
- let minEpoch: bigint | null = null;
119
- let fromBlock: bigint | "earliest" = "earliest";
120
-
121
- if (options.fromBlock) {
122
- // Explicit block takes precedence
123
- fromBlock = BigInt(options.fromBlock);
124
- } else if (options.fromEpoch) {
125
- // Filter by starting epoch
126
- minEpoch = BigInt(options.fromEpoch);
127
- } else if (options.all) {
128
- // Fetch all history (warn user)
129
- console.log(chalk.yellow("Warning: Fetching all history from genesis. This may be slow for long-lived validators."));
130
- console.log(chalk.yellow("Consider using --epochs <n> or --from-epoch <n> for faster queries.\n"));
131
- } else {
132
- // Default: last N epochs
133
- const numEpochs = options.epochs ? BigInt(options.epochs) : defaultEpochs;
134
- minEpoch = currentEpoch > numEpochs ? currentEpoch - numEpochs : 0n;
135
- }
136
-
137
- const limit = options.limit ? parseInt(options.limit) : 50;
138
-
139
- this.setSpinnerText("Fetching slash events...");
140
-
141
- // Fetch slash events (indexed by validator)
142
- const slashLogs = await publicClient.getLogs({
143
- address: slashingAddress as `0x${string}`,
144
- event: SLASH_EVENT_ABI,
145
- args: {validator: validatorAddress as `0x${string}`},
146
- fromBlock,
147
- toBlock: "latest",
148
- });
149
-
150
- this.setSpinnerText("Fetching reward events...");
151
-
152
- // Fetch reward events (not indexed, need to filter client-side)
153
- const rewardLogs = await publicClient.getLogs({
154
- address: stakingAddress,
155
- event: REWARD_EVENT_ABI,
156
- fromBlock,
157
- toBlock: "latest",
158
- });
159
-
160
- // Filter rewards to this validator
161
- const filteredRewardLogs = rewardLogs.filter(
162
- log => (log.args as any).validator?.toLowerCase() === validatorAddress.toLowerCase()
163
- );
164
-
165
- // Get unique block numbers to fetch timestamps
166
- const allLogs = [...slashLogs, ...filteredRewardLogs];
167
- const uniqueBlocks = [...new Set(allLogs.map(l => l.blockNumber))];
168
-
169
- this.setSpinnerText("Fetching block timestamps...");
170
-
171
- // Fetch block timestamps in batches
172
- const blockTimestamps = new Map<bigint, Date>();
173
- const BATCH_SIZE = 10;
174
- for (let i = 0; i < uniqueBlocks.length; i += BATCH_SIZE) {
175
- const batch = uniqueBlocks.slice(i, i + BATCH_SIZE);
176
- const blocks = await Promise.all(
177
- batch.map(blockNumber => publicClient.getBlock({blockNumber}))
178
- );
179
- blocks.forEach(block => {
180
- blockTimestamps.set(block.number, new Date(Number(block.timestamp) * 1000));
181
- });
182
- }
183
-
184
- // Transform to typed events
185
- let slashEvents: SlashEvent[] = slashLogs.map(log => ({
186
- type: "slash" as const,
187
- epoch: (log.args as any).epoch as bigint,
188
- txId: (log.args as any).txId as string,
189
- percentage: (log.args as any).percentage as bigint,
190
- blockNumber: log.blockNumber,
191
- timestamp: blockTimestamps.get(log.blockNumber) || new Date(0),
192
- }));
193
-
194
- let rewardEvents: RewardEvent[] = filteredRewardLogs.map(log => ({
195
- type: "reward" as const,
196
- epoch: (log.args as any).epoch as bigint,
197
- validatorRewards: (log.args as any).validatorRewards as bigint,
198
- delegatorRewards: (log.args as any).delegatorRewards as bigint,
199
- blockNumber: log.blockNumber,
200
- timestamp: blockTimestamps.get(log.blockNumber) || new Date(0),
201
- }));
202
-
203
- // Filter by epoch if specified
204
- if (minEpoch !== null) {
205
- slashEvents = slashEvents.filter(e => e.epoch >= minEpoch!);
206
- rewardEvents = rewardEvents.filter(e => e.epoch >= minEpoch!);
207
- }
208
-
209
- // Combine and sort by block number descending
210
- const allEvents: HistoryEvent[] = [...slashEvents, ...rewardEvents];
211
- allEvents.sort((a, b) => Number(b.blockNumber - a.blockNumber));
212
-
213
- // Apply limit
214
- const limitedEvents = allEvents.slice(0, limit);
215
-
216
- // Calculate totals
217
- const totalValidatorRewards = rewardEvents.reduce((sum, e) => sum + e.validatorRewards, 0n);
218
- const totalDelegatorRewards = rewardEvents.reduce((sum, e) => sum + e.delegatorRewards, 0n);
219
-
220
- this.stopSpinner();
221
-
222
- // Display results
223
- if (limitedEvents.length === 0) {
224
- console.log(chalk.yellow("\nNo history events found for this validator.\n"));
225
- return;
226
- }
227
-
228
- // Format timestamp as datetime
229
- const formatTime = (date: Date): string => {
230
- const month = String(date.getMonth() + 1).padStart(2, "0");
231
- const day = String(date.getDate()).padStart(2, "0");
232
- const hours = String(date.getHours()).padStart(2, "0");
233
- const minutes = String(date.getMinutes()).padStart(2, "0");
234
- return `${month}-${day} ${hours}:${minutes}`;
235
- };
236
-
237
- // Create table
238
- const table = new Table({
239
- head: [
240
- chalk.cyan("Time"),
241
- chalk.cyan("Epoch"),
242
- chalk.cyan("Type"),
243
- chalk.cyan("Details"),
244
- chalk.cyan("GL TxId / Block"),
245
- ],
246
- style: {head: [], border: []},
247
- });
248
-
249
- for (const event of limitedEvents) {
250
- if (event.type === "slash") {
251
- const pct = Number(event.percentage) / 100; // basis points to %
252
- table.push([
253
- formatTime(event.timestamp),
254
- event.epoch.toString(),
255
- chalk.red("SLASH"),
256
- `${pct.toFixed(2)}%`,
257
- event.txId,
258
- ]);
259
- } else {
260
- const valReward = client.formatStakingAmount(event.validatorRewards);
261
- const delReward = client.formatStakingAmount(event.delegatorRewards);
262
- table.push([
263
- formatTime(event.timestamp),
264
- event.epoch.toString(),
265
- chalk.green("REWARD"),
266
- `Val: ${valReward}, Del: ${delReward}`,
267
- `block ${event.blockNumber}`,
268
- ]);
269
- }
270
- }
271
-
272
- console.log("");
273
- console.log(chalk.bold(`History for ${validatorAddress}`));
274
- console.log(table.toString());
275
- console.log("");
276
-
277
- // Summary
278
- const epochRangeInfo = minEpoch !== null
279
- ? `epochs ${minEpoch}-${currentEpoch}`
280
- : options.fromBlock
281
- ? `from block ${options.fromBlock}`
282
- : "all epochs";
283
- console.log(chalk.gray("Summary:"));
284
- console.log(chalk.gray(` Range: ${epochRangeInfo}`));
285
- console.log(chalk.gray(` Slash events: ${slashEvents.length}`));
286
- console.log(chalk.gray(` Reward events: ${rewardEvents.length}`));
287
- console.log(chalk.gray(` Total validator rewards: ${client.formatStakingAmount(totalValidatorRewards)}`));
288
- console.log(chalk.gray(` Total delegator rewards: ${client.formatStakingAmount(totalDelegatorRewards)}`));
289
- if (allEvents.length > limit) {
290
- console.log(chalk.gray(` (showing ${limit} of ${allEvents.length} events)`));
291
- }
292
- console.log(chalk.gray(` Use --all to fetch complete history, --epochs <n> for last N epochs`));
293
- console.log("");
294
- } catch (error: any) {
295
- this.failSpinner("Failed to get validator history", error.message || error);
296
- }
297
- }
298
- }
@@ -1,47 +0,0 @@
1
- import {StakingAction, StakingConfig} from "./StakingAction";
2
- import type {Address} from "genlayer-js/types";
3
-
4
- export interface ValidatorJoinOptions extends StakingConfig {
5
- amount: string;
6
- operator?: string;
7
- }
8
-
9
- export class ValidatorJoinAction extends StakingAction {
10
- constructor() {
11
- super();
12
- }
13
-
14
- async execute(options: ValidatorJoinOptions): Promise<void> {
15
- this.startSpinner("Creating a new validator...");
16
-
17
- try {
18
- const client = await this.getStakingClient(options);
19
- const amount = this.parseAmount(options.amount);
20
- const signerAddress = await this.getSignerAddress();
21
-
22
- this.setSpinnerText(`Creating validator with ${this.formatAmount(amount)} stake...`);
23
- this.log(` From: ${signerAddress}`);
24
- if (options.operator) {
25
- this.log(` Operator: ${options.operator}`);
26
- }
27
-
28
- const result = await client.validatorJoin({
29
- amount,
30
- operator: options.operator as Address | undefined,
31
- });
32
-
33
- const output = {
34
- transactionHash: result.transactionHash,
35
- validatorWallet: result.validatorWallet,
36
- amount: result.amount,
37
- operator: result.operator,
38
- blockNumber: result.blockNumber.toString(),
39
- gasUsed: result.gasUsed.toString(),
40
- };
41
-
42
- this.succeedSpinner("Validator created successfully!", output);
43
- } catch (error: any) {
44
- this.failSpinner("Failed to create validator", error.message || error);
45
- }
46
- }
47
- }
@@ -1,73 +0,0 @@
1
- import {StakingAction, StakingConfig} from "./StakingAction";
2
- import type {Address} from "genlayer-js/types";
3
- import chalk from "chalk";
4
-
5
- export interface ValidatorPrimeOptions extends StakingConfig {
6
- validator: string;
7
- }
8
-
9
- export class ValidatorPrimeAction extends StakingAction {
10
- constructor() {
11
- super();
12
- }
13
-
14
- async execute(options: ValidatorPrimeOptions): Promise<void> {
15
- this.startSpinner("Priming validator...");
16
-
17
- try {
18
- const client = await this.getStakingClient(options);
19
-
20
- this.setSpinnerText(`Priming validator ${options.validator}...`);
21
-
22
- const result = await client.validatorPrime({validator: options.validator as Address});
23
-
24
- const output = {
25
- transactionHash: result.transactionHash,
26
- validator: options.validator,
27
- blockNumber: result.blockNumber.toString(),
28
- gasUsed: result.gasUsed.toString(),
29
- };
30
-
31
- this.succeedSpinner("Validator primed for next epoch!", output);
32
- } catch (error: any) {
33
- this.failSpinner("Failed to prime validator", error.message || error);
34
- }
35
- }
36
-
37
- async primeAll(options: StakingConfig): Promise<void> {
38
- this.startSpinner("Fetching validators...");
39
-
40
- try {
41
- const client = await this.getStakingClient(options);
42
-
43
- // Get all validators from tree
44
- this.setSpinnerText("Fetching validators...");
45
- const allValidators = await this.getAllValidatorsFromTree(options);
46
-
47
- this.stopSpinner();
48
- console.log(`\nPriming ${allValidators.length} validators:\n`);
49
-
50
- let succeeded = 0;
51
- let skipped = 0;
52
-
53
- for (const addr of allValidators) {
54
- process.stdout.write(` ${addr} ... `);
55
-
56
- try {
57
- const result = await client.validatorPrime({validator: addr});
58
- console.log(chalk.green(`primed ${result.transactionHash}`));
59
- succeeded++;
60
- } catch (error: any) {
61
- const msg = error.message || String(error);
62
- const shortErr = msg.length > 60 ? msg.slice(0, 57) + "..." : msg;
63
- console.log(chalk.gray(`skipped: ${shortErr}`));
64
- skipped++;
65
- }
66
- }
67
-
68
- console.log(`\n${chalk.green(`${succeeded} primed`)}, ${chalk.gray(`${skipped} skipped`)}\n`);
69
- } catch (error: any) {
70
- this.failSpinner("Failed to prime validators", error.message || error);
71
- }
72
- }
73
- }