genlayer 0.31.0 → 0.32.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/CLAUDE.md +55 -0
  3. package/README.md +121 -8
  4. package/dist/index.js +2550 -253
  5. package/docs/delegator-guide.md +203 -0
  6. package/docs/validator-guide.md +260 -0
  7. package/package.json +2 -2
  8. package/src/commands/account/create.ts +23 -0
  9. package/src/commands/account/import.ts +81 -0
  10. package/src/commands/account/index.ts +67 -0
  11. package/src/commands/{keygen → account}/lock.ts +6 -7
  12. package/src/commands/account/send.ts +150 -0
  13. package/src/commands/account/show.ts +60 -0
  14. package/src/commands/{keygen → account}/unlock.ts +12 -12
  15. package/src/commands/network/setNetwork.ts +5 -4
  16. package/src/commands/staking/StakingAction.ts +125 -0
  17. package/src/commands/staking/delegatorClaim.ts +41 -0
  18. package/src/commands/staking/delegatorExit.ts +50 -0
  19. package/src/commands/staking/delegatorJoin.ts +42 -0
  20. package/src/commands/staking/index.ts +224 -0
  21. package/src/commands/staking/setIdentity.ts +61 -0
  22. package/src/commands/staking/setOperator.ts +40 -0
  23. package/src/commands/staking/stakingInfo.ts +292 -0
  24. package/src/commands/staking/validatorClaim.ts +38 -0
  25. package/src/commands/staking/validatorDeposit.ts +35 -0
  26. package/src/commands/staking/validatorExit.ts +44 -0
  27. package/src/commands/staking/validatorJoin.ts +47 -0
  28. package/src/commands/staking/validatorPrime.ts +35 -0
  29. package/src/index.ts +4 -2
  30. package/src/lib/actions/BaseAction.ts +43 -10
  31. package/tests/actions/create.test.ts +18 -18
  32. package/tests/actions/lock.test.ts +7 -7
  33. package/tests/actions/setNetwork.test.ts +18 -57
  34. package/tests/actions/staking.test.ts +323 -0
  35. package/tests/actions/unlock.test.ts +12 -12
  36. package/tests/commands/account.test.ts +121 -0
  37. package/tests/commands/staking.test.ts +211 -0
  38. package/tests/index.test.ts +6 -2
  39. package/tests/libs/baseAction.test.ts +7 -1
  40. package/src/commands/keygen/create.ts +0 -23
  41. package/src/commands/keygen/index.ts +0 -39
  42. package/tests/commands/keygen.test.ts +0 -123
@@ -0,0 +1,203 @@
1
+ # Delegator Guide
2
+
3
+ This guide walks you through delegating GEN tokens to a validator on the GenLayer testnet.
4
+
5
+ ## What is Delegation?
6
+
7
+ Delegation allows you to stake your GEN tokens with an existing validator without running validator infrastructure yourself. You earn staking rewards proportional to your stake.
8
+
9
+ ## Prerequisites
10
+
11
+ - Node.js installed
12
+ - GenLayer CLI installed (`npm install -g genlayer`)
13
+ - GEN tokens for staking
14
+
15
+ ## Step 1: Create an Account
16
+
17
+ ```bash
18
+ genlayer account create
19
+ ```
20
+
21
+ You'll be prompted to set a password. This creates an encrypted keystore file.
22
+
23
+ ## Step 2: Set Network to Testnet
24
+
25
+ ```bash
26
+ genlayer network testnet-asimov
27
+ ```
28
+
29
+ ## Step 3: Fund Your Account
30
+
31
+ Transfer GEN tokens to your address. Check your balance:
32
+
33
+ ```bash
34
+ genlayer account
35
+ ```
36
+
37
+ ## Step 4: Check Minimum Delegation
38
+
39
+ ```bash
40
+ genlayer staking epoch-info
41
+ ```
42
+
43
+ Note the `delegatorMinStake` - you need at least this amount.
44
+
45
+ ## Step 5: Find a Validator
46
+
47
+ List all active validators:
48
+
49
+ ```bash
50
+ genlayer staking active-validators
51
+ ```
52
+
53
+ Output:
54
+ ```
55
+ {
56
+ count: 6,
57
+ validators: [
58
+ '0xa8f1BF1e5e709593b4468d7ac5DC315Ea3CAe130',
59
+ '0xe9246A020cbb4fC6C46e60677981879c9219e8B9',
60
+ ...
61
+ ]
62
+ }
63
+ ```
64
+
65
+ Get details about a specific validator:
66
+
67
+ ```bash
68
+ genlayer staking validator-info --validator 0xa8f1BF1e5e709593b4468d7ac5DC315Ea3CAe130
69
+ ```
70
+
71
+ Look for:
72
+ - `live: true` - Validator is active
73
+ - `banned: 'Not banned'` - Validator is in good standing
74
+ - `identity` - Validator's metadata (moniker, website, etc.)
75
+
76
+ ## Step 6: Unlock Your Account (Optional)
77
+
78
+ For convenience:
79
+
80
+ ```bash
81
+ genlayer account unlock
82
+ ```
83
+
84
+ ## Step 7: Delegate to a Validator
85
+
86
+ ```bash
87
+ genlayer staking delegator-join --validator 0xa8f1...130 --amount 100gen
88
+ ```
89
+
90
+ Options:
91
+ - `--validator <address>` - Validator address to delegate to (required)
92
+ - `--amount <amount>` - Amount to stake (e.g., `100gen`)
93
+
94
+ ## Step 8: Verify Your Delegation
95
+
96
+ ```bash
97
+ genlayer staking stake-info --validator 0xa8f1...130
98
+ ```
99
+
100
+ Output:
101
+ ```
102
+ {
103
+ delegator: '0x86D0d159483CBf01E920ECfF8bB7F0Cd7E964E7E',
104
+ validator: '0xa8f1BF1e5e709593b4468d7ac5DC315Ea3CAe130',
105
+ shares: '100000000000000000000',
106
+ stake: '100 GEN',
107
+ projectedReward: '0.2 GEN per epoch',
108
+ pendingDeposits: 'None',
109
+ pendingWithdrawals: 'None'
110
+ }
111
+ ```
112
+
113
+ The `projectedReward` shows your estimated earnings per epoch based on current inflation and your stake weight.
114
+
115
+ ## Managing Your Delegation
116
+
117
+ ### Check Your Stake
118
+
119
+ ```bash
120
+ genlayer staking stake-info --validator 0xa8f1...130
121
+ ```
122
+
123
+ ### Withdraw (Exit) Delegation
124
+
125
+ To withdraw your stake:
126
+
127
+ ```bash
128
+ genlayer staking delegator-exit --validator 0xa8f1...130 --shares 50
129
+ ```
130
+
131
+ Options:
132
+ - `--validator <address>` - Validator you delegated to
133
+ - `--shares <shares>` - Number of shares to withdraw
134
+
135
+ This initiates a withdrawal. Your tokens enter an **unbonding period of 7 epochs** before they can be claimed.
136
+
137
+ Check your pending withdrawals with `stake-info`:
138
+ ```
139
+ pendingWithdrawals: [
140
+ {
141
+ epoch: '5',
142
+ shares: '50',
143
+ stake: '50 GEN',
144
+ claimableAtEpoch: '12',
145
+ status: 'Unbonding (4 epochs remaining)'
146
+ }
147
+ ]
148
+ ```
149
+
150
+ ### Claim Withdrawals
151
+
152
+ After the 7-epoch unbonding period, claim your tokens:
153
+
154
+ ```bash
155
+ genlayer staking delegator-claim --validator 0xa8f1...130
156
+ ```
157
+
158
+ ## Choosing a Validator
159
+
160
+ Consider these factors when choosing a validator:
161
+
162
+ 1. **Uptime** - Validators with high uptime earn more rewards
163
+ 2. **Reputation** - Check their identity metadata and community presence
164
+ 3. **Stake** - Higher stake may indicate trust from the community
165
+ 4. **Not banned/quarantined** - Avoid validators with issues
166
+
167
+ Check quarantined validators:
168
+ ```bash
169
+ genlayer staking quarantined-validators
170
+ ```
171
+
172
+ Check banned validators:
173
+ ```bash
174
+ genlayer staking banned-validators
175
+ ```
176
+
177
+ ## Troubleshooting
178
+
179
+ ### "No account found"
180
+ Run `genlayer account create` first.
181
+
182
+ ### "Insufficient balance"
183
+ Ensure you have enough GEN. Check with `genlayer account`.
184
+
185
+ ### "Below minimum stake"
186
+ Check minimum with `genlayer staking epoch-info` and increase your amount.
187
+
188
+ ### "Validator not found"
189
+ Verify the validator address is correct and they are still active.
190
+
191
+ ### Transaction Stuck
192
+ Check the transaction status:
193
+ ```bash
194
+ genlayer receipt <tx-hash>
195
+ ```
196
+
197
+ ## Lock Your Account
198
+
199
+ When done, lock your account:
200
+
201
+ ```bash
202
+ genlayer account lock
203
+ ```
@@ -0,0 +1,260 @@
1
+ # Validator Guide
2
+
3
+ This guide walks you through becoming a validator on the GenLayer testnet using the CLI.
4
+
5
+ ## Prerequisites
6
+
7
+ - Node.js installed
8
+ - GenLayer CLI installed (`npm install -g genlayer`)
9
+ - GEN tokens for staking (minimum stake required)
10
+
11
+ ## Step 1: Create an Account
12
+
13
+ ```bash
14
+ genlayer account create
15
+ ```
16
+
17
+ You'll be prompted to set a password. This creates an encrypted keystore file.
18
+
19
+ ## Step 2: View Your Account
20
+
21
+ ```bash
22
+ genlayer account
23
+ ```
24
+
25
+ Output:
26
+ ```
27
+ {
28
+ address: '0x86D0d159483CBf01E920ECfF8bB7F0Cd7E964E7E',
29
+ balance: '0 GEN',
30
+ network: 'localnet',
31
+ status: 'locked'
32
+ }
33
+ ```
34
+
35
+ ## Step 3: Set Network to Testnet
36
+
37
+ ```bash
38
+ genlayer network testnet-asimov
39
+ ```
40
+
41
+ Verify with:
42
+ ```bash
43
+ genlayer account
44
+ ```
45
+
46
+ You should see `network: 'Asimov Testnet'`.
47
+
48
+ ## Step 4: Fund Your Account
49
+
50
+ Transfer GEN tokens to your address. You can:
51
+ - Use the faucet (if available)
52
+ - Transfer from another account:
53
+ ```bash
54
+ genlayer account send <your-address> 50000gen
55
+ ```
56
+
57
+ ## Step 5: Check Staking Requirements
58
+
59
+ ```bash
60
+ genlayer staking epoch-info
61
+ ```
62
+
63
+ Output:
64
+ ```
65
+ {
66
+ currentEpoch: '2',
67
+ epochStarted: '2025-01-15T00:00:00.000Z',
68
+ nextEpochEstimate: '2025-01-16T00:00:00.000Z',
69
+ timeUntilNextEpoch: '12h 30m',
70
+ minEpochDuration: '24h 0m',
71
+ validatorMinStake: '42000 GEN',
72
+ delegatorMinStake: '42 GEN',
73
+ activeValidatorsCount: '6',
74
+ epochInflation: '1000 GEN',
75
+ totalWeight: '500000000000000000000000',
76
+ totalClaimed: '500 GEN'
77
+ }
78
+ ```
79
+
80
+ Note the `validatorMinStake` - you need at least this amount.
81
+
82
+ ## Step 6: Unlock Your Account (Optional)
83
+
84
+ For convenience, unlock your account to avoid entering password repeatedly:
85
+
86
+ ```bash
87
+ genlayer account unlock
88
+ ```
89
+
90
+ This caches your private key in the OS keychain.
91
+
92
+ ## Step 7: Join as Validator
93
+
94
+ ```bash
95
+ genlayer staking validator-join --amount 42000gen --operator 0xOperator...
96
+ ```
97
+
98
+ Options:
99
+ - `--amount <amount>` - Stake amount (e.g., `42000gen` or `42000`)
100
+ - `--operator <address>` - Operator address (recommended, see below)
101
+
102
+ ### Why Use an Operator Address?
103
+
104
+ **Recommended:** Use a separate operator address for security.
105
+
106
+ - **Validator wallet** - Holds your staked funds (keep offline/cold)
107
+ - **Operator wallet** - Signs blocks and performs validator duties (hot wallet on server)
108
+
109
+ This way, if your operator server is compromised, your staked funds remain safe.
110
+
111
+ ```bash
112
+ # Create operator account on your validator server
113
+ genlayer account create --output ./operator.json
114
+
115
+ # Get operator address
116
+ cat ./operator.json | jq -r .address
117
+ # 0xOperator123...
118
+
119
+ # Join with separate operator (run from your main wallet)
120
+ genlayer staking validator-join --amount 42000gen --operator 0xOperator123...
121
+ ```
122
+
123
+ You can change the operator later:
124
+
125
+ ```bash
126
+ genlayer staking set-operator --validator 0xYourValidator... --operator 0xNewOperator...
127
+ ```
128
+
129
+ ## Step 8: Verify Your Validator Status
130
+
131
+ ```bash
132
+ genlayer staking validator-info
133
+ ```
134
+
135
+ Output:
136
+ ```
137
+ {
138
+ validator: '0x86D0d159483CBf01E920ECfF8bB7F0Cd7E964E7E',
139
+ vStake: '42000 GEN',
140
+ vShares: '42000000000000000000000',
141
+ live: true,
142
+ banned: 'Not banned',
143
+ ...
144
+ }
145
+ ```
146
+
147
+ ## Step 9: Set Validator Identity (Metadata)
148
+
149
+ Set your validator's public identity so delegators can find you:
150
+
151
+ ```bash
152
+ genlayer staking set-identity \
153
+ --validator 0x86D0...7E \
154
+ --moniker "My Validator" \
155
+ --website "https://myvalidator.com" \
156
+ --description "Reliable validator with 99.9% uptime" \
157
+ --twitter "myvalidator" \
158
+ --github "myvalidator"
159
+ ```
160
+
161
+ **Required:**
162
+ - `--validator <address>` - Your validator address
163
+ - `--moniker <name>` - Display name for your validator
164
+
165
+ **Optional:**
166
+ - `--logo-uri <uri>` - Logo image URL
167
+ - `--website <url>` - Website URL
168
+ - `--description <text>` - Description of your validator
169
+ - `--email <email>` - Contact email
170
+ - `--twitter <handle>` - Twitter handle
171
+ - `--telegram <handle>` - Telegram handle
172
+ - `--github <handle>` - GitHub handle
173
+ - `--extra-cid <cid>` - Additional data as IPFS CID
174
+
175
+ Your identity will show in `validator-info`:
176
+
177
+ ```bash
178
+ genlayer staking validator-info
179
+ ```
180
+
181
+ Output will include:
182
+ ```
183
+ {
184
+ ...
185
+ identity: {
186
+ moniker: 'My Validator',
187
+ website: 'https://myvalidator.com',
188
+ twitter: 'myvalidator',
189
+ github: 'myvalidator'
190
+ }
191
+ }
192
+ ```
193
+
194
+ ## Managing Your Validator
195
+
196
+ ### Add More Stake
197
+
198
+ ```bash
199
+ genlayer staking validator-deposit --amount 1000gen
200
+ ```
201
+
202
+ ### Check Active Validators
203
+
204
+ ```bash
205
+ genlayer staking active-validators
206
+ ```
207
+
208
+ ### Exit as Validator
209
+
210
+ ```bash
211
+ genlayer staking validator-exit --shares 100
212
+ ```
213
+
214
+ This initiates a withdrawal. Your tokens enter an **unbonding period of 7 epochs** before they can be claimed.
215
+
216
+ Check your pending withdrawals with `validator-info`:
217
+ ```
218
+ selfStakePendingWithdrawals: [
219
+ {
220
+ epoch: '5',
221
+ shares: '100',
222
+ stake: '100 GEN',
223
+ claimableAtEpoch: '12',
224
+ status: 'Unbonding (4 epochs remaining)'
225
+ }
226
+ ]
227
+ ```
228
+
229
+ ### Claim Withdrawals
230
+
231
+ After the 7-epoch unbonding period:
232
+
233
+ ```bash
234
+ genlayer staking validator-claim
235
+ ```
236
+
237
+ ## Troubleshooting
238
+
239
+ ### "No account found"
240
+ Run `genlayer account create` first.
241
+
242
+ ### "Insufficient balance"
243
+ Ensure you have enough GEN. Check with `genlayer account`.
244
+
245
+ ### "Below minimum stake"
246
+ Check minimum with `genlayer staking epoch-info` and increase your stake amount.
247
+
248
+ ### Transaction Stuck
249
+ Check the transaction status:
250
+ ```bash
251
+ genlayer receipt <tx-hash>
252
+ ```
253
+
254
+ ## Lock Your Account
255
+
256
+ When done, lock your account to remove the cached private key:
257
+
258
+ ```bash
259
+ genlayer account lock
260
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genlayer",
3
- "version": "0.31.0",
3
+ "version": "0.32.0",
4
4
  "description": "GenLayer Command Line Tool",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -65,7 +65,7 @@
65
65
  "dotenv": "^17.0.0",
66
66
  "ethers": "^6.13.4",
67
67
  "fs-extra": "^11.3.0",
68
- "genlayer-js": "^0.16.0",
68
+ "genlayer-js": "^0.18.5",
69
69
  "inquirer": "^12.0.0",
70
70
  "keytar": "^7.9.0",
71
71
  "node-fetch": "^3.0.0",
@@ -0,0 +1,23 @@
1
+ import {BaseAction} from "../../lib/actions/BaseAction";
2
+
3
+ export interface CreateAccountOptions {
4
+ output: string;
5
+ overwrite: boolean;
6
+ }
7
+
8
+ export class CreateAccountAction extends BaseAction {
9
+ constructor() {
10
+ super();
11
+ }
12
+
13
+ async execute(options: CreateAccountOptions): Promise<void> {
14
+ try {
15
+ this.startSpinner("Creating encrypted keystore...");
16
+ await this.createKeypair(options.output, options.overwrite);
17
+
18
+ this.succeedSpinner(`Account created and saved to: ${options.output}`);
19
+ } catch (error) {
20
+ this.failSpinner("Failed to create account", error);
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,81 @@
1
+ import {BaseAction} from "../../lib/actions/BaseAction";
2
+ import {ethers} from "ethers";
3
+ import {writeFileSync, existsSync} from "fs";
4
+ import {KeystoreData} from "../../lib/interfaces/KeystoreData";
5
+
6
+ export interface ImportAccountOptions {
7
+ privateKey?: string;
8
+ output: string;
9
+ overwrite: boolean;
10
+ }
11
+
12
+ export class ImportAccountAction extends BaseAction {
13
+ private static readonly MIN_PASSWORD_LENGTH = 8;
14
+
15
+ constructor() {
16
+ super();
17
+ }
18
+
19
+ async execute(options: ImportAccountOptions): Promise<void> {
20
+ try {
21
+ const privateKey = options.privateKey || await this.promptPrivateKey();
22
+
23
+ const normalizedKey = this.normalizePrivateKey(privateKey);
24
+ this.validatePrivateKey(normalizedKey);
25
+
26
+ const finalOutputPath = this.getFilePath(options.output);
27
+
28
+ if (existsSync(finalOutputPath) && !options.overwrite) {
29
+ this.failSpinner(`File at ${finalOutputPath} already exists. Use '--overwrite' to replace.`);
30
+ }
31
+
32
+ const wallet = new ethers.Wallet(normalizedKey);
33
+
34
+ const password = await this.promptPassword("Enter a password to encrypt your keystore (minimum 8 characters):");
35
+ const confirmPassword = await this.promptPassword("Confirm password:");
36
+
37
+ if (password !== confirmPassword) {
38
+ this.failSpinner("Passwords do not match");
39
+ }
40
+
41
+ if (password.length < ImportAccountAction.MIN_PASSWORD_LENGTH) {
42
+ this.failSpinner(`Password must be at least ${ImportAccountAction.MIN_PASSWORD_LENGTH} characters long`);
43
+ }
44
+
45
+ this.startSpinner("Encrypting and saving keystore...");
46
+
47
+ const encryptedJson = await wallet.encrypt(password);
48
+
49
+ const keystoreData: KeystoreData = {
50
+ version: 1,
51
+ encrypted: encryptedJson,
52
+ address: wallet.address,
53
+ };
54
+
55
+ writeFileSync(finalOutputPath, JSON.stringify(keystoreData, null, 2));
56
+ this.writeConfig("keyPairPath", finalOutputPath);
57
+
58
+ await this.keychainManager.removePrivateKey();
59
+
60
+ this.succeedSpinner(`Account imported and saved to: ${finalOutputPath}`);
61
+ this.logInfo(`Address: ${wallet.address}`);
62
+ } catch (error) {
63
+ this.failSpinner("Failed to import account", error);
64
+ }
65
+ }
66
+
67
+ private async promptPrivateKey(): Promise<string> {
68
+ return this.promptPassword("Enter private key to import:");
69
+ }
70
+
71
+ private normalizePrivateKey(key: string): string {
72
+ const trimmed = key.trim();
73
+ return trimmed.startsWith("0x") ? trimmed : `0x${trimmed}`;
74
+ }
75
+
76
+ private validatePrivateKey(key: string): void {
77
+ if (!/^0x[0-9a-fA-F]{64}$/.test(key)) {
78
+ this.failSpinner("Invalid private key format. Expected 64 hex characters (with or without 0x prefix).");
79
+ }
80
+ }
81
+ }
@@ -0,0 +1,67 @@
1
+ import {Command} from "commander";
2
+ import {ShowAccountAction} from "./show";
3
+ import {CreateAccountAction, CreateAccountOptions} from "./create";
4
+ import {ImportAccountAction, ImportAccountOptions} from "./import";
5
+ import {UnlockAccountAction} from "./unlock";
6
+ import {LockAccountAction} from "./lock";
7
+ import {SendAction, SendOptions} from "./send";
8
+
9
+ export function initializeAccountCommands(program: Command) {
10
+ const accountCommand = program
11
+ .command("account")
12
+ .description("Manage your account (address, balance, keys)")
13
+ .action(async () => {
14
+ // Default action: show account info
15
+ const showAction = new ShowAccountAction();
16
+ await showAction.execute();
17
+ });
18
+
19
+ accountCommand
20
+ .command("create")
21
+ .description("Create a new account with encrypted keystore")
22
+ .option("--output <path>", "Path to save the keystore", "./keypair.json")
23
+ .option("--overwrite", "Overwrite existing file", false)
24
+ .action(async (options: CreateAccountOptions) => {
25
+ const createAction = new CreateAccountAction();
26
+ await createAction.execute(options);
27
+ });
28
+
29
+ accountCommand
30
+ .command("import")
31
+ .description("Import an account from a private key")
32
+ .option("--private-key <key>", "Private key to import (will prompt if not provided)")
33
+ .option("--output <path>", "Path to save the keystore", "./keypair.json")
34
+ .option("--overwrite", "Overwrite existing file", false)
35
+ .action(async (options: ImportAccountOptions) => {
36
+ const importAction = new ImportAccountAction();
37
+ await importAction.execute(options);
38
+ });
39
+
40
+ accountCommand
41
+ .command("send <to> <amount>")
42
+ .description("Send GEN to an address")
43
+ .option("--rpc <rpcUrl>", "RPC URL for the network")
44
+ .option("--network <network>", "Network to use (localnet, testnet-asimov)")
45
+ .action(async (to: string, amount: string, options: {rpc?: string; network?: string}) => {
46
+ const sendAction = new SendAction();
47
+ await sendAction.execute({to, amount, rpc: options.rpc, network: options.network});
48
+ });
49
+
50
+ accountCommand
51
+ .command("unlock")
52
+ .description("Unlock account by caching private key in OS keychain")
53
+ .action(async () => {
54
+ const unlockAction = new UnlockAccountAction();
55
+ await unlockAction.execute();
56
+ });
57
+
58
+ accountCommand
59
+ .command("lock")
60
+ .description("Lock account by removing private key from OS keychain")
61
+ .action(async () => {
62
+ const lockAction = new LockAccountAction();
63
+ await lockAction.execute();
64
+ });
65
+
66
+ return program;
67
+ }
@@ -1,6 +1,6 @@
1
- import { BaseAction } from "../../lib/actions/BaseAction";
1
+ import {BaseAction} from "../../lib/actions/BaseAction";
2
2
 
3
- export class LockAction extends BaseAction {
3
+ export class LockAccountAction extends BaseAction {
4
4
  async execute(): Promise<void> {
5
5
  this.startSpinner("Checking keychain availability...");
6
6
 
@@ -14,7 +14,7 @@ export class LockAction extends BaseAction {
14
14
 
15
15
  const hasCachedKey = await this.keychainManager.getPrivateKey();
16
16
  if (!hasCachedKey) {
17
- this.succeedSpinner("Wallet is already locked (no cached key found in OS keychain).");
17
+ this.succeedSpinner("Account is already locked.");
18
18
  return;
19
19
  }
20
20
 
@@ -22,10 +22,9 @@ export class LockAction extends BaseAction {
22
22
 
23
23
  try {
24
24
  await this.keychainManager.removePrivateKey();
25
-
26
- this.succeedSpinner("Wallet locked successfully! Your private key has been removed from the OS keychain.");
25
+ this.succeedSpinner("Account locked! Private key removed from OS keychain.");
27
26
  } catch (error) {
28
- this.failSpinner("Failed to lock wallet.", error);
27
+ this.failSpinner("Failed to lock account.", error);
29
28
  }
30
29
  }
31
- }
30
+ }