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.
- package/CHANGELOG.md +2 -0
- package/README.md +41 -15
- package/dist/index.js +2450 -92
- package/docs/validator-guide.md +22 -13
- package/package.json +3 -2
- package/src/commands/staking/index.ts +131 -46
- package/src/commands/staking/stakingInfo.ts +285 -19
- package/src/commands/staking/validatorHistory.ts +298 -0
- package/tests/actions/staking.test.ts +12 -1
package/docs/validator-guide.md
CHANGED
|
@@ -88,19 +88,28 @@ genlayer staking epoch-info
|
|
|
88
88
|
|
|
89
89
|
Output:
|
|
90
90
|
```
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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.
|
|
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.
|
|
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
|
-
.
|
|
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
|
-
.
|
|
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
|
-
.
|
|
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
|
-
.
|
|
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
|
-
.
|
|
102
|
-
.
|
|
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
|
-
.
|
|
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
|
-
.
|
|
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
|
-
.
|
|
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
|
-
.
|
|
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 (
|
|
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
|
-
.
|
|
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
|
}
|