genlayer 0.33.1 → 0.34.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/CHANGELOG.md +6 -0
- package/dist/index.js +56 -29
- package/package.json +1 -1
- package/src/commands/account/create.ts +2 -1
- package/src/commands/account/index.ts +5 -2
- package/src/commands/account/send.ts +9 -3
- package/src/commands/account/unlock.ts +8 -3
- package/src/commands/staking/StakingAction.ts +15 -3
- package/src/commands/staking/index.ts +11 -0
- package/src/lib/actions/BaseAction.ts +10 -6
- package/tests/actions/create.test.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.34.0 (2026-02-08)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* add --password flag for non-interactive CLI usage ([#275](https://github.com/yeagerai/genlayer-cli/issues/275)) ([c5fffa6](https://github.com/yeagerai/genlayer-cli/commit/c5fffa6faaf0133ad83dd47279e3383d0a0cbacb))
|
|
8
|
+
|
|
3
9
|
## 0.33.1 (2026-02-07)
|
|
4
10
|
|
|
5
11
|
### Bug Fixes
|
package/dist/index.js
CHANGED
|
@@ -20078,7 +20078,7 @@ var require_cli_table3 = __commonJS({
|
|
|
20078
20078
|
import { program } from "commander";
|
|
20079
20079
|
|
|
20080
20080
|
// package.json
|
|
20081
|
-
var version = "0.
|
|
20081
|
+
var version = "0.34.0";
|
|
20082
20082
|
var package_default = {
|
|
20083
20083
|
name: "genlayer",
|
|
20084
20084
|
version,
|
|
@@ -48674,17 +48674,22 @@ var _BaseAction = class _BaseAction extends ConfigFileManager {
|
|
|
48674
48674
|
getAddress(keystoreData) {
|
|
48675
48675
|
return keystoreData.address;
|
|
48676
48676
|
}
|
|
48677
|
-
async createKeypairByName(accountName, overwrite) {
|
|
48677
|
+
async createKeypairByName(accountName, overwrite, passwordInput) {
|
|
48678
48678
|
const keystorePath = this.getKeystorePath(accountName);
|
|
48679
48679
|
this.stopSpinner();
|
|
48680
48680
|
if (existsSync(keystorePath) && !overwrite) {
|
|
48681
48681
|
this.failSpinner(`Account '${accountName}' already exists. Use '--overwrite' to replace it.`);
|
|
48682
48682
|
}
|
|
48683
48683
|
const wallet = ethers.Wallet.createRandom();
|
|
48684
|
-
|
|
48685
|
-
|
|
48686
|
-
|
|
48687
|
-
|
|
48684
|
+
let password;
|
|
48685
|
+
if (passwordInput) {
|
|
48686
|
+
password = passwordInput;
|
|
48687
|
+
} else {
|
|
48688
|
+
password = await this.promptPassword("Enter a password to encrypt your keystore (minimum 8 characters):");
|
|
48689
|
+
const confirmPassword = await this.promptPassword("Confirm password:");
|
|
48690
|
+
if (password !== confirmPassword) {
|
|
48691
|
+
this.failSpinner("Passwords do not match");
|
|
48692
|
+
}
|
|
48688
48693
|
}
|
|
48689
48694
|
if (password.length < _BaseAction.MIN_PASSWORD_LENGTH) {
|
|
48690
48695
|
this.failSpinner(`Password must be at least ${_BaseAction.MIN_PASSWORD_LENGTH} characters long`);
|
|
@@ -50011,7 +50016,7 @@ var CreateAccountAction = class extends BaseAction {
|
|
|
50011
50016
|
async execute(options) {
|
|
50012
50017
|
try {
|
|
50013
50018
|
this.startSpinner(`Creating account '${options.name}'...`);
|
|
50014
|
-
await this.createKeypairByName(options.name, options.overwrite);
|
|
50019
|
+
await this.createKeypairByName(options.name, options.overwrite, options.password);
|
|
50015
50020
|
if (options.setActive !== false) {
|
|
50016
50021
|
this.setActiveAccount(options.name);
|
|
50017
50022
|
}
|
|
@@ -50216,9 +50221,14 @@ var UnlockAccountAction = class extends BaseAction {
|
|
|
50216
50221
|
this.failSpinner("Invalid keystore format.");
|
|
50217
50222
|
return;
|
|
50218
50223
|
}
|
|
50219
|
-
this.stopSpinner();
|
|
50220
50224
|
try {
|
|
50221
|
-
|
|
50225
|
+
let password;
|
|
50226
|
+
if (options?.password) {
|
|
50227
|
+
password = options.password;
|
|
50228
|
+
} else {
|
|
50229
|
+
this.stopSpinner();
|
|
50230
|
+
password = await this.promptPassword(`Enter password to unlock '${accountName}':`);
|
|
50231
|
+
}
|
|
50222
50232
|
const wallet = await ethers4.Wallet.fromEncryptedJson(keystoreJson, password);
|
|
50223
50233
|
await this.keychainManager.storePrivateKey(accountName, wallet.privateKey);
|
|
50224
50234
|
this.succeedSpinner(`Account '${accountName}' unlocked! Private key cached in OS keychain.`);
|
|
@@ -50308,9 +50318,14 @@ var SendAction = class extends BaseAction {
|
|
|
50308
50318
|
if (cachedKey) {
|
|
50309
50319
|
privateKey = cachedKey;
|
|
50310
50320
|
} else {
|
|
50311
|
-
|
|
50312
|
-
|
|
50313
|
-
|
|
50321
|
+
let password;
|
|
50322
|
+
if (options.password) {
|
|
50323
|
+
password = options.password;
|
|
50324
|
+
} else {
|
|
50325
|
+
this.stopSpinner();
|
|
50326
|
+
password = await this.promptPassword(`Enter password to unlock account '${accountName}':`);
|
|
50327
|
+
this.startSpinner("Preparing transfer...");
|
|
50328
|
+
}
|
|
50314
50329
|
const wallet = await ethers5.Wallet.fromEncryptedJson(keystoreJson, password);
|
|
50315
50330
|
privateKey = wallet.privateKey;
|
|
50316
50331
|
}
|
|
@@ -50458,7 +50473,7 @@ function initializeAccountCommands(program2) {
|
|
|
50458
50473
|
const showAction = new ShowAccountAction();
|
|
50459
50474
|
await showAction.execute(options);
|
|
50460
50475
|
});
|
|
50461
|
-
accountCommand.command("create").description("Create a new account with encrypted keystore").requiredOption("--name <name>", "Name for the account").option("--overwrite", "Overwrite existing account", false).option("--no-set-active", "Do not set as active account").action(async (options) => {
|
|
50476
|
+
accountCommand.command("create").description("Create a new account with encrypted keystore").requiredOption("--name <name>", "Name for the account").option("--password <password>", "Password for the keystore (skips interactive prompt)").option("--overwrite", "Overwrite existing account", false).option("--no-set-active", "Do not set as active account").action(async (options) => {
|
|
50462
50477
|
const createAction = new CreateAccountAction();
|
|
50463
50478
|
await createAction.execute(options);
|
|
50464
50479
|
});
|
|
@@ -50478,11 +50493,11 @@ function initializeAccountCommands(program2) {
|
|
|
50478
50493
|
const removeAction = new RemoveAccountAction();
|
|
50479
50494
|
await removeAction.execute(name, options);
|
|
50480
50495
|
});
|
|
50481
|
-
accountCommand.command("send <to> <amount>").description("Send GEN to an address").option("--rpc <rpcUrl>", "RPC URL for the network").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--account <name>", "Account to send from").action(async (to, amount, options) => {
|
|
50496
|
+
accountCommand.command("send <to> <amount>").description("Send GEN to an address").option("--rpc <rpcUrl>", "RPC URL for the network").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--account <name>", "Account to send from").option("--password <password>", "Password to unlock account (skips interactive prompt)").action(async (to, amount, options) => {
|
|
50482
50497
|
const sendAction = new SendAction();
|
|
50483
|
-
await sendAction.execute({ to, amount, rpc: options.rpc, network: options.network, account: options.account });
|
|
50498
|
+
await sendAction.execute({ to, amount, rpc: options.rpc, network: options.network, account: options.account, password: options.password });
|
|
50484
50499
|
});
|
|
50485
|
-
accountCommand.command("unlock").description("Unlock account by caching private key in OS keychain").option("--account <name>", "Account to unlock").action(async (options) => {
|
|
50500
|
+
accountCommand.command("unlock").description("Unlock account by caching private key in OS keychain").option("--account <name>", "Account to unlock").option("--password <password>", "Password to unlock account (skips interactive prompt)").action(async (options) => {
|
|
50486
50501
|
const unlockAction = new UnlockAccountAction();
|
|
50487
50502
|
await unlockAction.execute(options);
|
|
50488
50503
|
});
|
|
@@ -51321,6 +51336,7 @@ var StakingAction = class extends BaseAction {
|
|
|
51321
51336
|
constructor() {
|
|
51322
51337
|
super();
|
|
51323
51338
|
__publicField(this, "_stakingClient", null);
|
|
51339
|
+
__publicField(this, "_passwordOverride");
|
|
51324
51340
|
}
|
|
51325
51341
|
getNetwork(config) {
|
|
51326
51342
|
if (config.network) {
|
|
@@ -51337,6 +51353,9 @@ var StakingAction = class extends BaseAction {
|
|
|
51337
51353
|
if (config.account) {
|
|
51338
51354
|
this.accountOverride = config.account;
|
|
51339
51355
|
}
|
|
51356
|
+
if (config.password) {
|
|
51357
|
+
this._passwordOverride = config.password;
|
|
51358
|
+
}
|
|
51340
51359
|
const network = this.getNetwork(config);
|
|
51341
51360
|
if (config.stakingAddress) {
|
|
51342
51361
|
network.stakingContract = {
|
|
@@ -51401,8 +51420,13 @@ var StakingAction = class extends BaseAction {
|
|
|
51401
51420
|
return cachedKey;
|
|
51402
51421
|
}
|
|
51403
51422
|
}
|
|
51404
|
-
|
|
51405
|
-
|
|
51423
|
+
let password;
|
|
51424
|
+
if (this._passwordOverride) {
|
|
51425
|
+
password = this._passwordOverride;
|
|
51426
|
+
} else {
|
|
51427
|
+
this.stopSpinner();
|
|
51428
|
+
password = await this.promptPassword(`Enter password to unlock account '${accountName}':`);
|
|
51429
|
+
}
|
|
51406
51430
|
this.startSpinner("Unlocking account...");
|
|
51407
51431
|
const wallet = await ethers6.Wallet.fromEncryptedJson(keystoreJson, password);
|
|
51408
51432
|
return wallet.privateKey;
|
|
@@ -51431,6 +51455,9 @@ var StakingAction = class extends BaseAction {
|
|
|
51431
51455
|
if (config.account) {
|
|
51432
51456
|
this.accountOverride = config.account;
|
|
51433
51457
|
}
|
|
51458
|
+
if (config.password) {
|
|
51459
|
+
this._passwordOverride = config.password;
|
|
51460
|
+
}
|
|
51434
51461
|
const network = this.getNetwork(config);
|
|
51435
51462
|
const rpcUrl = config.rpc || network.rpcUrls.default.http[0];
|
|
51436
51463
|
const privateKey = await this.getPrivateKeyForStaking();
|
|
@@ -53162,11 +53189,11 @@ function initializeStakingCommands(program2) {
|
|
|
53162
53189
|
const wizard = new ValidatorWizardAction();
|
|
53163
53190
|
await wizard.execute(options);
|
|
53164
53191
|
});
|
|
53165
|
-
staking.command("validator-join").description("Join as a validator by staking tokens").requiredOption("--amount <amount>", "Amount to stake (in wei or with 'eth'/'gen' suffix, e.g., '42000gen')").option("--operator <address>", "Operator address (defaults to signer)").option("--account <name>", "Account to use").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").option("--staking-address <address>", "Staking contract address (overrides chain config)").action(async (options) => {
|
|
53192
|
+
staking.command("validator-join").description("Join as a validator by staking tokens").requiredOption("--amount <amount>", "Amount to stake (in wei or with 'eth'/'gen' suffix, e.g., '42000gen')").option("--operator <address>", "Operator address (defaults to signer)").option("--account <name>", "Account to use").option("--password <password>", "Password to unlock account (skips interactive prompt)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").option("--staking-address <address>", "Staking contract address (overrides chain config)").action(async (options) => {
|
|
53166
53193
|
const action = new ValidatorJoinAction();
|
|
53167
53194
|
await action.execute(options);
|
|
53168
53195
|
});
|
|
53169
|
-
staking.command("validator-deposit [validator]").description("Make an additional deposit to a validator wallet").option("--validator <address>", "Validator wallet contract address (deprecated, use positional arg)").requiredOption("--amount <amount>", "Amount to deposit (in wei or with 'eth'/'gen' suffix)").option("--account <name>", "Account to use (must be validator owner)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").action(async (validatorArg, options) => {
|
|
53196
|
+
staking.command("validator-deposit [validator]").description("Make an additional deposit to a validator wallet").option("--validator <address>", "Validator wallet contract address (deprecated, use positional arg)").requiredOption("--amount <amount>", "Amount to deposit (in wei or with 'eth'/'gen' suffix)").option("--account <name>", "Account to use (must be validator owner)").option("--password <password>", "Password to unlock account (skips interactive prompt)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").action(async (validatorArg, options) => {
|
|
53170
53197
|
const validator = validatorArg || options.validator;
|
|
53171
53198
|
if (!validator) {
|
|
53172
53199
|
console.error("Error: validator address is required");
|
|
@@ -53175,7 +53202,7 @@ function initializeStakingCommands(program2) {
|
|
|
53175
53202
|
const action = new ValidatorDepositAction();
|
|
53176
53203
|
await action.execute({ ...options, validator });
|
|
53177
53204
|
});
|
|
53178
|
-
staking.command("validator-exit [validator]").description("Exit as a validator by withdrawing shares").option("--validator <address>", "Validator wallet contract address (deprecated, use positional arg)").requiredOption("--shares <shares>", "Number of shares to withdraw").option("--account <name>", "Account to use (must be validator owner)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").action(async (validatorArg, options) => {
|
|
53205
|
+
staking.command("validator-exit [validator]").description("Exit as a validator by withdrawing shares").option("--validator <address>", "Validator wallet contract address (deprecated, use positional arg)").requiredOption("--shares <shares>", "Number of shares to withdraw").option("--account <name>", "Account to use (must be validator owner)").option("--password <password>", "Password to unlock account (skips interactive prompt)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").action(async (validatorArg, options) => {
|
|
53179
53206
|
const validator = validatorArg || options.validator;
|
|
53180
53207
|
if (!validator) {
|
|
53181
53208
|
console.error("Error: validator address is required");
|
|
@@ -53184,7 +53211,7 @@ function initializeStakingCommands(program2) {
|
|
|
53184
53211
|
const action = new ValidatorExitAction();
|
|
53185
53212
|
await action.execute({ ...options, validator });
|
|
53186
53213
|
});
|
|
53187
|
-
staking.command("validator-claim [validator]").description("Claim validator withdrawals after unbonding period").option("--validator <address>", "Validator wallet contract address (deprecated, use positional arg)").option("--account <name>", "Account to use").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").action(async (validatorArg, options) => {
|
|
53214
|
+
staking.command("validator-claim [validator]").description("Claim validator withdrawals after unbonding period").option("--validator <address>", "Validator wallet contract address (deprecated, use positional arg)").option("--account <name>", "Account to use").option("--password <password>", "Password to unlock account (skips interactive prompt)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").action(async (validatorArg, options) => {
|
|
53188
53215
|
const validator = validatorArg || options.validator;
|
|
53189
53216
|
if (!validator) {
|
|
53190
53217
|
console.error("Error: validator address is required");
|
|
@@ -53193,7 +53220,7 @@ function initializeStakingCommands(program2) {
|
|
|
53193
53220
|
const action = new ValidatorClaimAction();
|
|
53194
53221
|
await action.execute({ ...options, validator });
|
|
53195
53222
|
});
|
|
53196
|
-
staking.command("validator-prime [validator]").description("Prime a validator to prepare their stake record for the next epoch").option("--validator <address>", "Validator address to prime (deprecated, use positional arg)").option("--account <name>", "Account to use").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").option("--staking-address <address>", "Staking contract address (overrides chain config)").action(async (validatorArg, options) => {
|
|
53223
|
+
staking.command("validator-prime [validator]").description("Prime a validator to prepare their stake record for the next epoch").option("--validator <address>", "Validator address to prime (deprecated, use positional arg)").option("--account <name>", "Account to use").option("--password <password>", "Password to unlock account (skips interactive prompt)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").option("--staking-address <address>", "Staking contract address (overrides chain config)").action(async (validatorArg, options) => {
|
|
53197
53224
|
const validator = validatorArg || options.validator;
|
|
53198
53225
|
if (!validator) {
|
|
53199
53226
|
console.error("Error: validator address is required");
|
|
@@ -53202,11 +53229,11 @@ function initializeStakingCommands(program2) {
|
|
|
53202
53229
|
const action = new ValidatorPrimeAction();
|
|
53203
53230
|
await action.execute({ ...options, validator });
|
|
53204
53231
|
});
|
|
53205
|
-
staking.command("prime-all").description("Prime all validators that need priming").option("--account <name>", "Account to use (pays gas)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").option("--staking-address <address>", "Staking contract address (overrides chain config)").action(async (options) => {
|
|
53232
|
+
staking.command("prime-all").description("Prime all validators that need priming").option("--account <name>", "Account to use (pays gas)").option("--password <password>", "Password to unlock account (skips interactive prompt)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").option("--staking-address <address>", "Staking contract address (overrides chain config)").action(async (options) => {
|
|
53206
53233
|
const action = new ValidatorPrimeAction();
|
|
53207
53234
|
await action.primeAll(options);
|
|
53208
53235
|
});
|
|
53209
|
-
staking.command("set-operator [validator] [operator]").description("Change the operator address for a validator wallet").option("--validator <address>", "Validator wallet address (deprecated, use positional arg)").option("--operator <address>", "New operator address (deprecated, use positional arg)").option("--account <name>", "Account to use (must be validator owner)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").action(async (validatorArg, operatorArg, options) => {
|
|
53236
|
+
staking.command("set-operator [validator] [operator]").description("Change the operator address for a validator wallet").option("--validator <address>", "Validator wallet address (deprecated, use positional arg)").option("--operator <address>", "New operator address (deprecated, use positional arg)").option("--account <name>", "Account to use (must be validator owner)").option("--password <password>", "Password to unlock account (skips interactive prompt)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").action(async (validatorArg, operatorArg, options) => {
|
|
53210
53237
|
const validator = validatorArg || options.validator;
|
|
53211
53238
|
const operator = operatorArg || options.operator;
|
|
53212
53239
|
if (!validator || !operator) {
|
|
@@ -53216,7 +53243,7 @@ function initializeStakingCommands(program2) {
|
|
|
53216
53243
|
const action = new SetOperatorAction();
|
|
53217
53244
|
await action.execute({ ...options, validator, operator });
|
|
53218
53245
|
});
|
|
53219
|
-
staking.command("set-identity [validator]").description("Set validator identity metadata (moniker, website, socials, etc.)").option("--validator <address>", "Validator wallet address (deprecated, use positional arg)").requiredOption("--moniker <name>", "Validator display name").option("--logo-uri <uri>", "Logo URI").option("--website <url>", "Website URL").option("--description <text>", "Description").option("--email <email>", "Contact email").option("--twitter <handle>", "Twitter handle").option("--telegram <handle>", "Telegram handle").option("--github <handle>", "GitHub handle").option("--extra-cid <cid>", "Extra data as IPFS CID or hex bytes (0x...)").option("--account <name>", "Account to use (must be validator operator)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").action(async (validatorArg, options) => {
|
|
53246
|
+
staking.command("set-identity [validator]").description("Set validator identity metadata (moniker, website, socials, etc.)").option("--validator <address>", "Validator wallet address (deprecated, use positional arg)").requiredOption("--moniker <name>", "Validator display name").option("--logo-uri <uri>", "Logo URI").option("--website <url>", "Website URL").option("--description <text>", "Description").option("--email <email>", "Contact email").option("--twitter <handle>", "Twitter handle").option("--telegram <handle>", "Telegram handle").option("--github <handle>", "GitHub handle").option("--extra-cid <cid>", "Extra data as IPFS CID or hex bytes (0x...)").option("--account <name>", "Account to use (must be validator operator)").option("--password <password>", "Password to unlock account (skips interactive prompt)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").action(async (validatorArg, options) => {
|
|
53220
53247
|
const validator = validatorArg || options.validator;
|
|
53221
53248
|
if (!validator) {
|
|
53222
53249
|
console.error("Error: validator address is required");
|
|
@@ -53225,7 +53252,7 @@ function initializeStakingCommands(program2) {
|
|
|
53225
53252
|
const action = new SetIdentityAction();
|
|
53226
53253
|
await action.execute({ ...options, validator });
|
|
53227
53254
|
});
|
|
53228
|
-
staking.command("delegator-join [validator]").description("Join as a delegator by staking with a validator").option("--validator <address>", "Validator address to delegate to (deprecated, use positional arg)").requiredOption("--amount <amount>", "Amount to stake (in wei or with 'eth'/'gen' suffix)").option("--account <name>", "Account to use").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").option("--staking-address <address>", "Staking contract address (overrides chain config)").action(async (validatorArg, options) => {
|
|
53255
|
+
staking.command("delegator-join [validator]").description("Join as a delegator by staking with a validator").option("--validator <address>", "Validator address to delegate to (deprecated, use positional arg)").requiredOption("--amount <amount>", "Amount to stake (in wei or with 'eth'/'gen' suffix)").option("--account <name>", "Account to use").option("--password <password>", "Password to unlock account (skips interactive prompt)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").option("--staking-address <address>", "Staking contract address (overrides chain config)").action(async (validatorArg, options) => {
|
|
53229
53256
|
const validator = validatorArg || options.validator;
|
|
53230
53257
|
if (!validator) {
|
|
53231
53258
|
console.error("Error: validator address is required");
|
|
@@ -53234,7 +53261,7 @@ function initializeStakingCommands(program2) {
|
|
|
53234
53261
|
const action = new DelegatorJoinAction();
|
|
53235
53262
|
await action.execute({ ...options, validator });
|
|
53236
53263
|
});
|
|
53237
|
-
staking.command("delegator-exit [validator]").description("Exit as a delegator by withdrawing shares from a validator").option("--validator <address>", "Validator address to exit from (deprecated, use positional arg)").requiredOption("--shares <shares>", "Number of shares to withdraw").option("--account <name>", "Account to use").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").option("--staking-address <address>", "Staking contract address (overrides chain config)").action(async (validatorArg, options) => {
|
|
53264
|
+
staking.command("delegator-exit [validator]").description("Exit as a delegator by withdrawing shares from a validator").option("--validator <address>", "Validator address to exit from (deprecated, use positional arg)").requiredOption("--shares <shares>", "Number of shares to withdraw").option("--account <name>", "Account to use").option("--password <password>", "Password to unlock account (skips interactive prompt)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").option("--staking-address <address>", "Staking contract address (overrides chain config)").action(async (validatorArg, options) => {
|
|
53238
53265
|
const validator = validatorArg || options.validator;
|
|
53239
53266
|
if (!validator) {
|
|
53240
53267
|
console.error("Error: validator address is required");
|
|
@@ -53243,7 +53270,7 @@ function initializeStakingCommands(program2) {
|
|
|
53243
53270
|
const action = new DelegatorExitAction();
|
|
53244
53271
|
await action.execute({ ...options, validator });
|
|
53245
53272
|
});
|
|
53246
|
-
staking.command("delegator-claim [validator]").description("Claim delegator withdrawals after unbonding period").option("--validator <address>", "Validator address (deprecated, use positional arg)").option("--delegator <address>", "Delegator address (defaults to signer)").option("--account <name>", "Account to use").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").option("--staking-address <address>", "Staking contract address (overrides chain config)").action(async (validatorArg, options) => {
|
|
53273
|
+
staking.command("delegator-claim [validator]").description("Claim delegator withdrawals after unbonding period").option("--validator <address>", "Validator address (deprecated, use positional arg)").option("--delegator <address>", "Delegator address (defaults to signer)").option("--account <name>", "Account to use").option("--password <password>", "Password to unlock account (skips interactive prompt)").option("--network <network>", "Network to use (localnet, testnet-asimov)").option("--rpc <rpcUrl>", "RPC URL for the network").option("--staking-address <address>", "Staking contract address (overrides chain config)").action(async (validatorArg, options) => {
|
|
53247
53274
|
const validator = validatorArg || options.validator;
|
|
53248
53275
|
if (!validator) {
|
|
53249
53276
|
console.error("Error: validator address is required");
|
package/package.json
CHANGED
|
@@ -4,6 +4,7 @@ export interface CreateAccountOptions {
|
|
|
4
4
|
name: string;
|
|
5
5
|
overwrite: boolean;
|
|
6
6
|
setActive?: boolean;
|
|
7
|
+
password?: string;
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
export class CreateAccountAction extends BaseAction {
|
|
@@ -14,7 +15,7 @@ export class CreateAccountAction extends BaseAction {
|
|
|
14
15
|
async execute(options: CreateAccountOptions): Promise<void> {
|
|
15
16
|
try {
|
|
16
17
|
this.startSpinner(`Creating account '${options.name}'...`);
|
|
17
|
-
await this.createKeypairByName(options.name, options.overwrite);
|
|
18
|
+
await this.createKeypairByName(options.name, options.overwrite, options.password);
|
|
18
19
|
|
|
19
20
|
if (options.setActive !== false) {
|
|
20
21
|
this.setActiveAccount(options.name);
|
|
@@ -42,6 +42,7 @@ export function initializeAccountCommands(program: Command) {
|
|
|
42
42
|
.command("create")
|
|
43
43
|
.description("Create a new account with encrypted keystore")
|
|
44
44
|
.requiredOption("--name <name>", "Name for the account")
|
|
45
|
+
.option("--password <password>", "Password for the keystore (skips interactive prompt)")
|
|
45
46
|
.option("--overwrite", "Overwrite existing account", false)
|
|
46
47
|
.option("--no-set-active", "Do not set as active account")
|
|
47
48
|
.action(async (options: CreateAccountOptions) => {
|
|
@@ -99,15 +100,17 @@ export function initializeAccountCommands(program: Command) {
|
|
|
99
100
|
.option("--rpc <rpcUrl>", "RPC URL for the network")
|
|
100
101
|
.option("--network <network>", "Network to use (localnet, testnet-asimov)")
|
|
101
102
|
.option("--account <name>", "Account to send from")
|
|
102
|
-
.
|
|
103
|
+
.option("--password <password>", "Password to unlock account (skips interactive prompt)")
|
|
104
|
+
.action(async (to: string, amount: string, options: {rpc?: string; network?: string; account?: string; password?: string}) => {
|
|
103
105
|
const sendAction = new SendAction();
|
|
104
|
-
await sendAction.execute({to, amount, rpc: options.rpc, network: options.network, account: options.account});
|
|
106
|
+
await sendAction.execute({to, amount, rpc: options.rpc, network: options.network, account: options.account, password: options.password});
|
|
105
107
|
});
|
|
106
108
|
|
|
107
109
|
accountCommand
|
|
108
110
|
.command("unlock")
|
|
109
111
|
.description("Unlock account by caching private key in OS keychain")
|
|
110
112
|
.option("--account <name>", "Account to unlock")
|
|
113
|
+
.option("--password <password>", "Password to unlock account (skips interactive prompt)")
|
|
111
114
|
.action(async (options: UnlockAccountOptions) => {
|
|
112
115
|
const unlockAction = new UnlockAccountAction();
|
|
113
116
|
await unlockAction.execute(options);
|
|
@@ -11,6 +11,7 @@ export interface SendOptions {
|
|
|
11
11
|
rpc?: string;
|
|
12
12
|
network?: string;
|
|
13
13
|
account?: string;
|
|
14
|
+
password?: string;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
export class SendAction extends BaseAction {
|
|
@@ -75,9 +76,14 @@ export class SendAction extends BaseAction {
|
|
|
75
76
|
if (cachedKey) {
|
|
76
77
|
privateKey = cachedKey;
|
|
77
78
|
} else {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
let password: string;
|
|
80
|
+
if (options.password) {
|
|
81
|
+
password = options.password;
|
|
82
|
+
} else {
|
|
83
|
+
this.stopSpinner();
|
|
84
|
+
password = await this.promptPassword(`Enter password to unlock account '${accountName}':`);
|
|
85
|
+
this.startSpinner("Preparing transfer...");
|
|
86
|
+
}
|
|
81
87
|
const wallet = await ethers.Wallet.fromEncryptedJson(keystoreJson, password);
|
|
82
88
|
privateKey = wallet.privateKey;
|
|
83
89
|
}
|
|
@@ -4,6 +4,7 @@ import {ethers} from "ethers";
|
|
|
4
4
|
|
|
5
5
|
export interface UnlockAccountOptions {
|
|
6
6
|
account?: string;
|
|
7
|
+
password?: string;
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
export class UnlockAccountAction extends BaseAction {
|
|
@@ -36,10 +37,14 @@ export class UnlockAccountAction extends BaseAction {
|
|
|
36
37
|
return;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
this.stopSpinner();
|
|
40
|
-
|
|
41
40
|
try {
|
|
42
|
-
|
|
41
|
+
let password: string;
|
|
42
|
+
if (options?.password) {
|
|
43
|
+
password = options.password;
|
|
44
|
+
} else {
|
|
45
|
+
this.stopSpinner();
|
|
46
|
+
password = await this.promptPassword(`Enter password to unlock '${accountName}':`);
|
|
47
|
+
}
|
|
43
48
|
const wallet = await ethers.Wallet.fromEncryptedJson(keystoreJson, password);
|
|
44
49
|
|
|
45
50
|
await this.keychainManager.storePrivateKey(accountName, wallet.privateKey);
|
|
@@ -25,10 +25,12 @@ export interface StakingConfig {
|
|
|
25
25
|
stakingAddress?: string;
|
|
26
26
|
network?: string;
|
|
27
27
|
account?: string;
|
|
28
|
+
password?: string;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export class StakingAction extends BaseAction {
|
|
31
32
|
private _stakingClient: GenLayerClient<GenLayerChain> | null = null;
|
|
33
|
+
private _passwordOverride: string | undefined;
|
|
32
34
|
|
|
33
35
|
constructor() {
|
|
34
36
|
super();
|
|
@@ -53,6 +55,9 @@ export class StakingAction extends BaseAction {
|
|
|
53
55
|
if (config.account) {
|
|
54
56
|
this.accountOverride = config.account;
|
|
55
57
|
}
|
|
58
|
+
if (config.password) {
|
|
59
|
+
this._passwordOverride = config.password;
|
|
60
|
+
}
|
|
56
61
|
|
|
57
62
|
const network = this.getNetwork(config);
|
|
58
63
|
|
|
@@ -140,9 +145,13 @@ export class StakingAction extends BaseAction {
|
|
|
140
145
|
}
|
|
141
146
|
}
|
|
142
147
|
|
|
143
|
-
|
|
144
|
-
this.
|
|
145
|
-
|
|
148
|
+
let password: string;
|
|
149
|
+
if (this._passwordOverride) {
|
|
150
|
+
password = this._passwordOverride;
|
|
151
|
+
} else {
|
|
152
|
+
this.stopSpinner();
|
|
153
|
+
password = await this.promptPassword(`Enter password to unlock account '${accountName}':`);
|
|
154
|
+
}
|
|
146
155
|
this.startSpinner("Unlocking account...");
|
|
147
156
|
|
|
148
157
|
const wallet = await ethers.Wallet.fromEncryptedJson(keystoreJson, password);
|
|
@@ -180,6 +189,9 @@ export class StakingAction extends BaseAction {
|
|
|
180
189
|
if (config.account) {
|
|
181
190
|
this.accountOverride = config.account;
|
|
182
191
|
}
|
|
192
|
+
if (config.password) {
|
|
193
|
+
this._passwordOverride = config.password;
|
|
194
|
+
}
|
|
183
195
|
|
|
184
196
|
const network = this.getNetwork(config);
|
|
185
197
|
const rpcUrl = config.rpc || network.rpcUrls.default.http[0];
|
|
@@ -37,6 +37,7 @@ export function initializeStakingCommands(program: Command) {
|
|
|
37
37
|
.requiredOption("--amount <amount>", "Amount to stake (in wei or with 'eth'/'gen' suffix, e.g., '42000gen')")
|
|
38
38
|
.option("--operator <address>", "Operator address (defaults to signer)")
|
|
39
39
|
.option("--account <name>", "Account to use")
|
|
40
|
+
.option("--password <password>", "Password to unlock account (skips interactive prompt)")
|
|
40
41
|
.option("--network <network>", "Network to use (localnet, testnet-asimov)")
|
|
41
42
|
.option("--rpc <rpcUrl>", "RPC URL for the network")
|
|
42
43
|
.option("--staking-address <address>", "Staking contract address (overrides chain config)")
|
|
@@ -51,6 +52,7 @@ export function initializeStakingCommands(program: Command) {
|
|
|
51
52
|
.option("--validator <address>", "Validator wallet contract address (deprecated, use positional arg)")
|
|
52
53
|
.requiredOption("--amount <amount>", "Amount to deposit (in wei or with 'eth'/'gen' suffix)")
|
|
53
54
|
.option("--account <name>", "Account to use (must be validator owner)")
|
|
55
|
+
.option("--password <password>", "Password to unlock account (skips interactive prompt)")
|
|
54
56
|
.option("--network <network>", "Network to use (localnet, testnet-asimov)")
|
|
55
57
|
.option("--rpc <rpcUrl>", "RPC URL for the network")
|
|
56
58
|
.action(async (validatorArg: string | undefined, options: ValidatorDepositOptions) => {
|
|
@@ -69,6 +71,7 @@ export function initializeStakingCommands(program: Command) {
|
|
|
69
71
|
.option("--validator <address>", "Validator wallet contract address (deprecated, use positional arg)")
|
|
70
72
|
.requiredOption("--shares <shares>", "Number of shares to withdraw")
|
|
71
73
|
.option("--account <name>", "Account to use (must be validator owner)")
|
|
74
|
+
.option("--password <password>", "Password to unlock account (skips interactive prompt)")
|
|
72
75
|
.option("--network <network>", "Network to use (localnet, testnet-asimov)")
|
|
73
76
|
.option("--rpc <rpcUrl>", "RPC URL for the network")
|
|
74
77
|
.action(async (validatorArg: string | undefined, options: ValidatorExitOptions) => {
|
|
@@ -86,6 +89,7 @@ export function initializeStakingCommands(program: Command) {
|
|
|
86
89
|
.description("Claim validator withdrawals after unbonding period")
|
|
87
90
|
.option("--validator <address>", "Validator wallet contract address (deprecated, use positional arg)")
|
|
88
91
|
.option("--account <name>", "Account to use")
|
|
92
|
+
.option("--password <password>", "Password to unlock account (skips interactive prompt)")
|
|
89
93
|
.option("--network <network>", "Network to use (localnet, testnet-asimov)")
|
|
90
94
|
.option("--rpc <rpcUrl>", "RPC URL for the network")
|
|
91
95
|
.action(async (validatorArg: string | undefined, options: ValidatorClaimOptions) => {
|
|
@@ -103,6 +107,7 @@ export function initializeStakingCommands(program: Command) {
|
|
|
103
107
|
.description("Prime a validator to prepare their stake record for the next epoch")
|
|
104
108
|
.option("--validator <address>", "Validator address to prime (deprecated, use positional arg)")
|
|
105
109
|
.option("--account <name>", "Account to use")
|
|
110
|
+
.option("--password <password>", "Password to unlock account (skips interactive prompt)")
|
|
106
111
|
.option("--network <network>", "Network to use (localnet, testnet-asimov)")
|
|
107
112
|
.option("--rpc <rpcUrl>", "RPC URL for the network")
|
|
108
113
|
.option("--staking-address <address>", "Staking contract address (overrides chain config)")
|
|
@@ -120,6 +125,7 @@ export function initializeStakingCommands(program: Command) {
|
|
|
120
125
|
.command("prime-all")
|
|
121
126
|
.description("Prime all validators that need priming")
|
|
122
127
|
.option("--account <name>", "Account to use (pays gas)")
|
|
128
|
+
.option("--password <password>", "Password to unlock account (skips interactive prompt)")
|
|
123
129
|
.option("--network <network>", "Network to use (localnet, testnet-asimov)")
|
|
124
130
|
.option("--rpc <rpcUrl>", "RPC URL for the network")
|
|
125
131
|
.option("--staking-address <address>", "Staking contract address (overrides chain config)")
|
|
@@ -134,6 +140,7 @@ export function initializeStakingCommands(program: Command) {
|
|
|
134
140
|
.option("--validator <address>", "Validator wallet address (deprecated, use positional arg)")
|
|
135
141
|
.option("--operator <address>", "New operator address (deprecated, use positional arg)")
|
|
136
142
|
.option("--account <name>", "Account to use (must be validator owner)")
|
|
143
|
+
.option("--password <password>", "Password to unlock account (skips interactive prompt)")
|
|
137
144
|
.option("--network <network>", "Network to use (localnet, testnet-asimov)")
|
|
138
145
|
.option("--rpc <rpcUrl>", "RPC URL for the network")
|
|
139
146
|
.action(async (validatorArg: string | undefined, operatorArg: string | undefined, options: SetOperatorOptions) => {
|
|
@@ -161,6 +168,7 @@ export function initializeStakingCommands(program: Command) {
|
|
|
161
168
|
.option("--github <handle>", "GitHub handle")
|
|
162
169
|
.option("--extra-cid <cid>", "Extra data as IPFS CID or hex bytes (0x...)")
|
|
163
170
|
.option("--account <name>", "Account to use (must be validator operator)")
|
|
171
|
+
.option("--password <password>", "Password to unlock account (skips interactive prompt)")
|
|
164
172
|
.option("--network <network>", "Network to use (localnet, testnet-asimov)")
|
|
165
173
|
.option("--rpc <rpcUrl>", "RPC URL for the network")
|
|
166
174
|
.action(async (validatorArg: string | undefined, options: SetIdentityOptions) => {
|
|
@@ -180,6 +188,7 @@ export function initializeStakingCommands(program: Command) {
|
|
|
180
188
|
.option("--validator <address>", "Validator address to delegate to (deprecated, use positional arg)")
|
|
181
189
|
.requiredOption("--amount <amount>", "Amount to stake (in wei or with 'eth'/'gen' suffix)")
|
|
182
190
|
.option("--account <name>", "Account to use")
|
|
191
|
+
.option("--password <password>", "Password to unlock account (skips interactive prompt)")
|
|
183
192
|
.option("--network <network>", "Network to use (localnet, testnet-asimov)")
|
|
184
193
|
.option("--rpc <rpcUrl>", "RPC URL for the network")
|
|
185
194
|
.option("--staking-address <address>", "Staking contract address (overrides chain config)")
|
|
@@ -199,6 +208,7 @@ export function initializeStakingCommands(program: Command) {
|
|
|
199
208
|
.option("--validator <address>", "Validator address to exit from (deprecated, use positional arg)")
|
|
200
209
|
.requiredOption("--shares <shares>", "Number of shares to withdraw")
|
|
201
210
|
.option("--account <name>", "Account to use")
|
|
211
|
+
.option("--password <password>", "Password to unlock account (skips interactive prompt)")
|
|
202
212
|
.option("--network <network>", "Network to use (localnet, testnet-asimov)")
|
|
203
213
|
.option("--rpc <rpcUrl>", "RPC URL for the network")
|
|
204
214
|
.option("--staking-address <address>", "Staking contract address (overrides chain config)")
|
|
@@ -218,6 +228,7 @@ export function initializeStakingCommands(program: Command) {
|
|
|
218
228
|
.option("--validator <address>", "Validator address (deprecated, use positional arg)")
|
|
219
229
|
.option("--delegator <address>", "Delegator address (defaults to signer)")
|
|
220
230
|
.option("--account <name>", "Account to use")
|
|
231
|
+
.option("--password <password>", "Password to unlock account (skips interactive prompt)")
|
|
221
232
|
.option("--network <network>", "Network to use (localnet, testnet-asimov)")
|
|
222
233
|
.option("--rpc <rpcUrl>", "RPC URL for the network")
|
|
223
234
|
.option("--staking-address <address>", "Staking contract address (overrides chain config)")
|
|
@@ -171,7 +171,7 @@ export class BaseAction extends ConfigFileManager {
|
|
|
171
171
|
return keystoreData.address as Address;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
protected async createKeypairByName(accountName: string, overwrite: boolean): Promise<string> {
|
|
174
|
+
protected async createKeypairByName(accountName: string, overwrite: boolean, passwordInput?: string): Promise<string> {
|
|
175
175
|
const keystorePath = this.getKeystorePath(accountName);
|
|
176
176
|
this.stopSpinner();
|
|
177
177
|
|
|
@@ -181,11 +181,15 @@ export class BaseAction extends ConfigFileManager {
|
|
|
181
181
|
|
|
182
182
|
const wallet = ethers.Wallet.createRandom();
|
|
183
183
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
this.
|
|
184
|
+
let password: string;
|
|
185
|
+
if (passwordInput) {
|
|
186
|
+
password = passwordInput;
|
|
187
|
+
} else {
|
|
188
|
+
password = await this.promptPassword("Enter a password to encrypt your keystore (minimum 8 characters):");
|
|
189
|
+
const confirmPassword = await this.promptPassword("Confirm password:");
|
|
190
|
+
if (password !== confirmPassword) {
|
|
191
|
+
this.failSpinner("Passwords do not match");
|
|
192
|
+
}
|
|
189
193
|
}
|
|
190
194
|
|
|
191
195
|
if (password.length < BaseAction.MIN_PASSWORD_LENGTH) {
|
|
@@ -38,7 +38,7 @@ describe("CreateAccountAction", () => {
|
|
|
38
38
|
await createAction.execute(options);
|
|
39
39
|
|
|
40
40
|
expect(createAction["startSpinner"]).toHaveBeenCalledWith("Creating account 'main'...");
|
|
41
|
-
expect(createAction["createKeypairByName"]).toHaveBeenCalledWith("main", false);
|
|
41
|
+
expect(createAction["createKeypairByName"]).toHaveBeenCalledWith("main", false, undefined);
|
|
42
42
|
expect(createAction["setActiveAccount"]).toHaveBeenCalledWith("main");
|
|
43
43
|
expect(createAction["succeedSpinner"]).toHaveBeenCalledWith(
|
|
44
44
|
`Account 'main' created at: ${mockKeystorePath}`,
|