genlayer 0.32.5 → 0.32.8

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.
@@ -88,19 +88,28 @@ genlayer staking epoch-info
88
88
 
89
89
  Output:
90
90
  ```
91
- {
92
- currentEpoch: '2',
93
- epochStarted: '2025-01-15T00:00:00.000Z',
94
- nextEpochEstimate: '2025-01-16T00:00:00.000Z',
95
- timeUntilNextEpoch: '12h 30m',
96
- minEpochDuration: '24h 0m',
97
- validatorMinStake: '42000 GEN',
98
- delegatorMinStake: '42 GEN',
99
- activeValidatorsCount: '6',
100
- epochInflation: '1000 GEN',
101
- totalWeight: '500000000000000000000000',
102
- totalClaimed: '500 GEN'
103
- }
91
+ ✔ Epoch info
92
+
93
+ Current Epoch: 5 (started 9h 30m ago)
94
+ Next Epoch: in 14h 30m
95
+ Validators: 33
96
+ Weight: 6061746783417938774454
97
+ Slashed: 0 GEN
98
+
99
+ Previous Epoch: 4 (finalized)
100
+ Inflation: 1732904.66 GEN
101
+ Claimed: 0 GEN
102
+ Unclaimed: 1732904.66 GEN
103
+ Slashed: 0 GEN
104
+
105
+ Min Epoch Duration: 24h 0m
106
+ Validator Min Stake: 42000 GEN
107
+ Delegator Min Stake: 42 GEN
108
+ ```
109
+
110
+ You can also query a specific epoch:
111
+ ```bash
112
+ genlayer staking epoch-info --epoch 4
104
113
  ```
105
114
 
106
115
  Note the `validatorMinStake` - you need at least this amount.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genlayer",
3
- "version": "0.32.5",
3
+ "version": "0.32.8",
4
4
  "description": "GenLayer Command Line Tool",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -60,12 +60,13 @@
60
60
  },
61
61
  "dependencies": {
62
62
  "chalk": "^5.4.1",
63
+ "cli-table3": "^0.6.5",
63
64
  "commander": "^14.0.0",
64
65
  "dockerode": "^4.0.2",
65
66
  "dotenv": "^17.0.0",
66
67
  "ethers": "^6.13.4",
67
68
  "fs-extra": "^11.3.0",
68
- "genlayer-js": "^0.18.8",
69
+ "genlayer-js": "^0.18.9",
69
70
  "inquirer": "^12.0.0",
70
71
  "keytar": "^7.9.0",
71
72
  "node-fetch": "^3.0.0",
@@ -10,6 +10,7 @@ import {DelegatorJoinAction, DelegatorJoinOptions} from "./delegatorJoin";
10
10
  import {DelegatorExitAction, DelegatorExitOptions} from "./delegatorExit";
11
11
  import {DelegatorClaimAction, DelegatorClaimOptions} from "./delegatorClaim";
12
12
  import {StakingInfoAction, StakingInfoOptions} from "./stakingInfo";
13
+ import {ValidatorHistoryAction, ValidatorHistoryOptions} from "./validatorHistory";
13
14
  import {ValidatorWizardAction, WizardOptions} from "./wizard";
14
15
 
15
16
  export function initializeStakingCommands(program: Command) {
@@ -45,73 +46,99 @@ export function initializeStakingCommands(program: Command) {
45
46
  });
46
47
 
47
48
  staking
48
- .command("validator-deposit")
49
+ .command("validator-deposit [validator]")
49
50
  .description("Make an additional deposit to a validator wallet")
50
- .requiredOption("--validator <address>", "Validator wallet contract address to deposit to")
51
+ .option("--validator <address>", "Validator wallet contract address (deprecated, use positional arg)")
51
52
  .requiredOption("--amount <amount>", "Amount to deposit (in wei or with 'eth'/'gen' suffix)")
52
53
  .option("--account <name>", "Account to use (must be validator owner)")
53
54
  .option("--network <network>", "Network to use (localnet, testnet-asimov)")
54
55
  .option("--rpc <rpcUrl>", "RPC URL for the network")
55
- .action(async (options: ValidatorDepositOptions) => {
56
+ .action(async (validatorArg: string | undefined, options: ValidatorDepositOptions) => {
57
+ const validator = validatorArg || options.validator;
58
+ if (!validator) {
59
+ console.error("Error: validator address is required");
60
+ process.exit(1);
61
+ }
56
62
  const action = new ValidatorDepositAction();
57
- await action.execute(options);
63
+ await action.execute({...options, validator});
58
64
  });
59
65
 
60
66
  staking
61
- .command("validator-exit")
67
+ .command("validator-exit [validator]")
62
68
  .description("Exit as a validator by withdrawing shares")
63
- .requiredOption("--validator <address>", "Validator wallet contract address")
69
+ .option("--validator <address>", "Validator wallet contract address (deprecated, use positional arg)")
64
70
  .requiredOption("--shares <shares>", "Number of shares to withdraw")
65
71
  .option("--account <name>", "Account to use (must be validator owner)")
66
72
  .option("--network <network>", "Network to use (localnet, testnet-asimov)")
67
73
  .option("--rpc <rpcUrl>", "RPC URL for the network")
68
- .action(async (options: ValidatorExitOptions) => {
74
+ .action(async (validatorArg: string | undefined, options: ValidatorExitOptions) => {
75
+ const validator = validatorArg || options.validator;
76
+ if (!validator) {
77
+ console.error("Error: validator address is required");
78
+ process.exit(1);
79
+ }
69
80
  const action = new ValidatorExitAction();
70
- await action.execute(options);
81
+ await action.execute({...options, validator});
71
82
  });
72
83
 
73
84
  staking
74
- .command("validator-claim")
85
+ .command("validator-claim [validator]")
75
86
  .description("Claim validator withdrawals after unbonding period")
76
- .requiredOption("--validator <address>", "Validator wallet contract address")
87
+ .option("--validator <address>", "Validator wallet contract address (deprecated, use positional arg)")
77
88
  .option("--account <name>", "Account to use")
78
89
  .option("--network <network>", "Network to use (localnet, testnet-asimov)")
79
90
  .option("--rpc <rpcUrl>", "RPC URL for the network")
80
- .action(async (options: ValidatorClaimOptions) => {
91
+ .action(async (validatorArg: string | undefined, options: ValidatorClaimOptions) => {
92
+ const validator = validatorArg || options.validator;
93
+ if (!validator) {
94
+ console.error("Error: validator address is required");
95
+ process.exit(1);
96
+ }
81
97
  const action = new ValidatorClaimAction();
82
- await action.execute(options);
98
+ await action.execute({...options, validator});
83
99
  });
84
100
 
85
101
  staking
86
- .command("validator-prime")
102
+ .command("validator-prime [validator]")
87
103
  .description("Prime a validator to prepare their stake record for the next epoch")
88
- .requiredOption("--validator <address>", "Validator address to prime")
104
+ .option("--validator <address>", "Validator address to prime (deprecated, use positional arg)")
89
105
  .option("--account <name>", "Account to use")
90
106
  .option("--network <network>", "Network to use (localnet, testnet-asimov)")
91
107
  .option("--rpc <rpcUrl>", "RPC URL for the network")
92
108
  .option("--staking-address <address>", "Staking contract address (overrides chain config)")
93
- .action(async (options: ValidatorPrimeOptions) => {
109
+ .action(async (validatorArg: string | undefined, options: ValidatorPrimeOptions) => {
110
+ const validator = validatorArg || options.validator;
111
+ if (!validator) {
112
+ console.error("Error: validator address is required");
113
+ process.exit(1);
114
+ }
94
115
  const action = new ValidatorPrimeAction();
95
- await action.execute(options);
116
+ await action.execute({...options, validator});
96
117
  });
97
118
 
98
119
  staking
99
- .command("set-operator")
120
+ .command("set-operator [validator] [operator]")
100
121
  .description("Change the operator address for a validator wallet")
101
- .requiredOption("--validator <address>", "Validator wallet address")
102
- .requiredOption("--operator <address>", "New operator address")
122
+ .option("--validator <address>", "Validator wallet address (deprecated, use positional arg)")
123
+ .option("--operator <address>", "New operator address (deprecated, use positional arg)")
103
124
  .option("--account <name>", "Account to use (must be validator owner)")
104
125
  .option("--network <network>", "Network to use (localnet, testnet-asimov)")
105
126
  .option("--rpc <rpcUrl>", "RPC URL for the network")
106
- .action(async (options: SetOperatorOptions) => {
127
+ .action(async (validatorArg: string | undefined, operatorArg: string | undefined, options: SetOperatorOptions) => {
128
+ const validator = validatorArg || options.validator;
129
+ const operator = operatorArg || options.operator;
130
+ if (!validator || !operator) {
131
+ console.error("Error: validator and operator addresses are required");
132
+ process.exit(1);
133
+ }
107
134
  const action = new SetOperatorAction();
108
- await action.execute(options);
135
+ await action.execute({...options, validator, operator});
109
136
  });
110
137
 
111
138
  staking
112
- .command("set-identity")
139
+ .command("set-identity [validator]")
113
140
  .description("Set validator identity metadata (moniker, website, socials, etc.)")
114
- .requiredOption("--validator <address>", "Validator wallet address")
141
+ .option("--validator <address>", "Validator wallet address (deprecated, use positional arg)")
115
142
  .requiredOption("--moniker <name>", "Validator display name")
116
143
  .option("--logo-uri <uri>", "Logo URI")
117
144
  .option("--website <url>", "Website URL")
@@ -124,89 +151,116 @@ export function initializeStakingCommands(program: Command) {
124
151
  .option("--account <name>", "Account to use (must be validator operator)")
125
152
  .option("--network <network>", "Network to use (localnet, testnet-asimov)")
126
153
  .option("--rpc <rpcUrl>", "RPC URL for the network")
127
- .action(async (options: SetIdentityOptions) => {
154
+ .action(async (validatorArg: string | undefined, options: SetIdentityOptions) => {
155
+ const validator = validatorArg || options.validator;
156
+ if (!validator) {
157
+ console.error("Error: validator address is required");
158
+ process.exit(1);
159
+ }
128
160
  const action = new SetIdentityAction();
129
- await action.execute(options);
161
+ await action.execute({...options, validator});
130
162
  });
131
163
 
132
164
  // Delegator commands
133
165
  staking
134
- .command("delegator-join")
166
+ .command("delegator-join [validator]")
135
167
  .description("Join as a delegator by staking with a validator")
136
- .requiredOption("--validator <address>", "Validator address to delegate to")
168
+ .option("--validator <address>", "Validator address to delegate to (deprecated, use positional arg)")
137
169
  .requiredOption("--amount <amount>", "Amount to stake (in wei or with 'eth'/'gen' suffix)")
138
170
  .option("--account <name>", "Account to use")
139
171
  .option("--network <network>", "Network to use (localnet, testnet-asimov)")
140
172
  .option("--rpc <rpcUrl>", "RPC URL for the network")
141
173
  .option("--staking-address <address>", "Staking contract address (overrides chain config)")
142
- .action(async (options: DelegatorJoinOptions) => {
174
+ .action(async (validatorArg: string | undefined, options: DelegatorJoinOptions) => {
175
+ const validator = validatorArg || options.validator;
176
+ if (!validator) {
177
+ console.error("Error: validator address is required");
178
+ process.exit(1);
179
+ }
143
180
  const action = new DelegatorJoinAction();
144
- await action.execute(options);
181
+ await action.execute({...options, validator});
145
182
  });
146
183
 
147
184
  staking
148
- .command("delegator-exit")
185
+ .command("delegator-exit [validator]")
149
186
  .description("Exit as a delegator by withdrawing shares from a validator")
150
- .requiredOption("--validator <address>", "Validator address to exit from")
187
+ .option("--validator <address>", "Validator address to exit from (deprecated, use positional arg)")
151
188
  .requiredOption("--shares <shares>", "Number of shares to withdraw")
152
189
  .option("--account <name>", "Account to use")
153
190
  .option("--network <network>", "Network to use (localnet, testnet-asimov)")
154
191
  .option("--rpc <rpcUrl>", "RPC URL for the network")
155
192
  .option("--staking-address <address>", "Staking contract address (overrides chain config)")
156
- .action(async (options: DelegatorExitOptions) => {
193
+ .action(async (validatorArg: string | undefined, options: DelegatorExitOptions) => {
194
+ const validator = validatorArg || options.validator;
195
+ if (!validator) {
196
+ console.error("Error: validator address is required");
197
+ process.exit(1);
198
+ }
157
199
  const action = new DelegatorExitAction();
158
- await action.execute(options);
200
+ await action.execute({...options, validator});
159
201
  });
160
202
 
161
203
  staking
162
- .command("delegator-claim")
204
+ .command("delegator-claim [validator]")
163
205
  .description("Claim delegator withdrawals after unbonding period")
164
- .requiredOption("--validator <address>", "Validator address")
206
+ .option("--validator <address>", "Validator address (deprecated, use positional arg)")
165
207
  .option("--delegator <address>", "Delegator address (defaults to signer)")
166
208
  .option("--account <name>", "Account to use")
167
209
  .option("--network <network>", "Network to use (localnet, testnet-asimov)")
168
210
  .option("--rpc <rpcUrl>", "RPC URL for the network")
169
211
  .option("--staking-address <address>", "Staking contract address (overrides chain config)")
170
- .action(async (options: DelegatorClaimOptions) => {
212
+ .action(async (validatorArg: string | undefined, options: DelegatorClaimOptions) => {
213
+ const validator = validatorArg || options.validator;
214
+ if (!validator) {
215
+ console.error("Error: validator address is required");
216
+ process.exit(1);
217
+ }
171
218
  const action = new DelegatorClaimAction();
172
- await action.execute(options);
219
+ await action.execute({...options, validator});
173
220
  });
174
221
 
175
222
  // Info commands
176
223
  staking
177
- .command("validator-info")
224
+ .command("validator-info [validator]")
178
225
  .description("Get information about a validator")
179
- .option("--validator <address>", "Validator address (defaults to signer)")
226
+ .option("--validator <address>", "Validator address (deprecated, use positional arg)")
180
227
  .option("--account <name>", "Account to use (for default validator address)")
181
228
  .option("--network <network>", "Network to use (localnet, testnet-asimov)")
182
229
  .option("--rpc <rpcUrl>", "RPC URL for the network")
183
230
  .option("--staking-address <address>", "Staking contract address (overrides chain config)")
184
- .action(async (options: StakingInfoOptions) => {
231
+ .action(async (validatorArg: string | undefined, options: StakingInfoOptions) => {
232
+ const validator = validatorArg || options.validator;
185
233
  const action = new StakingInfoAction();
186
- await action.getValidatorInfo(options);
234
+ await action.getValidatorInfo({...options, validator});
187
235
  });
188
236
 
189
237
  staking
190
- .command("delegation-info")
238
+ .command("delegation-info [validator]")
191
239
  .description("Get delegation info for a delegator with a validator")
192
- .requiredOption("--validator <address>", "Validator address")
240
+ .option("--validator <address>", "Validator address (deprecated, use positional arg)")
193
241
  .option("--delegator <address>", "Delegator address (defaults to signer)")
194
242
  .option("--account <name>", "Account to use (for default delegator address)")
195
243
  .option("--network <network>", "Network to use (localnet, testnet-asimov)")
196
244
  .option("--rpc <rpcUrl>", "RPC URL for the network")
197
245
  .option("--staking-address <address>", "Staking contract address (overrides chain config)")
198
- .action(async (options: StakingInfoOptions & {delegator?: string}) => {
246
+ .action(async (validatorArg: string | undefined, options: StakingInfoOptions & {delegator?: string}) => {
247
+ const validator = validatorArg || options.validator;
248
+ if (!validator) {
249
+ console.error("Error: validator address is required");
250
+ process.exit(1);
251
+ }
199
252
  const action = new StakingInfoAction();
200
- await action.getStakeInfo(options);
253
+ await action.getStakeInfo({...options, validator});
201
254
  });
202
255
 
203
256
  staking
204
257
  .command("epoch-info")
205
258
  .description("Get current epoch and staking parameters")
259
+ .option("--epoch <number>", "Show data for specific epoch (current or previous only)")
206
260
  .option("--network <network>", "Network to use (localnet, testnet-asimov)")
207
261
  .option("--rpc <rpcUrl>", "RPC URL for the network")
208
262
  .option("--staking-address <address>", "Staking contract address (overrides chain config)")
209
- .action(async (options: StakingInfoOptions) => {
263
+ .action(async (options: StakingInfoOptions & {epoch?: string}) => {
210
264
  const action = new StakingInfoAction();
211
265
  await action.getEpochInfo(options);
212
266
  });
@@ -244,5 +298,36 @@ export function initializeStakingCommands(program: Command) {
244
298
  await action.listBannedValidators(options);
245
299
  });
246
300
 
301
+ staking
302
+ .command("validators")
303
+ .description("Show validator set with stake, status, and voting power")
304
+ .option("--all", "Include banned validators")
305
+ .option("--network <network>", "Network to use (localnet, testnet-asimov)")
306
+ .option("--rpc <rpcUrl>", "RPC URL for the network")
307
+ .option("--staking-address <address>", "Staking contract address (overrides chain config)")
308
+ .action(async (options: StakingInfoOptions & {all?: boolean}) => {
309
+ const action = new StakingInfoAction();
310
+ await action.listValidators(options);
311
+ });
312
+
313
+ staking
314
+ .command("validator-history [validator]")
315
+ .description("Show slash and reward history for a validator (default: last 10 epochs)")
316
+ .option("--validator <address>", "Validator address (deprecated, use positional arg)")
317
+ .option("--epochs <count>", "Number of recent epochs to fetch (default: 10)")
318
+ .option("--from-epoch <epoch>", "Start from this epoch number")
319
+ .option("--from-block <block>", "Start from this block number (advanced)")
320
+ .option("--all", "Fetch complete history from genesis (slow)")
321
+ .option("--limit <count>", "Maximum number of events to show (default: 50)")
322
+ .option("--account <name>", "Account to use (for default validator address)")
323
+ .option("--network <network>", "Network to use (localnet, testnet-asimov)")
324
+ .option("--rpc <rpcUrl>", "RPC URL for the network")
325
+ .option("--staking-address <address>", "Staking contract address (overrides chain config)")
326
+ .action(async (validatorArg: string | undefined, options: ValidatorHistoryOptions) => {
327
+ const validator = validatorArg || options.validator;
328
+ const action = new ValidatorHistoryAction();
329
+ await action.execute({...options, validator});
330
+ });
331
+
247
332
  return program;
248
333
  }