genlayer 0.30.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 (46) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/CLAUDE.md +55 -0
  3. package/README.md +121 -8
  4. package/dist/index.js +8424 -2489
  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/contracts/code.ts +33 -0
  16. package/src/commands/contracts/index.ts +10 -0
  17. package/src/commands/network/setNetwork.ts +5 -4
  18. package/src/commands/staking/StakingAction.ts +125 -0
  19. package/src/commands/staking/delegatorClaim.ts +41 -0
  20. package/src/commands/staking/delegatorExit.ts +50 -0
  21. package/src/commands/staking/delegatorJoin.ts +42 -0
  22. package/src/commands/staking/index.ts +224 -0
  23. package/src/commands/staking/setIdentity.ts +61 -0
  24. package/src/commands/staking/setOperator.ts +40 -0
  25. package/src/commands/staking/stakingInfo.ts +292 -0
  26. package/src/commands/staking/validatorClaim.ts +38 -0
  27. package/src/commands/staking/validatorDeposit.ts +35 -0
  28. package/src/commands/staking/validatorExit.ts +44 -0
  29. package/src/commands/staking/validatorJoin.ts +47 -0
  30. package/src/commands/staking/validatorPrime.ts +35 -0
  31. package/src/index.ts +4 -2
  32. package/src/lib/actions/BaseAction.ts +43 -10
  33. package/tests/actions/code.test.ts +87 -0
  34. package/tests/actions/create.test.ts +18 -18
  35. package/tests/actions/lock.test.ts +7 -7
  36. package/tests/actions/setNetwork.test.ts +18 -57
  37. package/tests/actions/staking.test.ts +323 -0
  38. package/tests/actions/unlock.test.ts +12 -12
  39. package/tests/commands/account.test.ts +121 -0
  40. package/tests/commands/code.test.ts +69 -0
  41. package/tests/commands/staking.test.ts +211 -0
  42. package/tests/index.test.ts +6 -2
  43. package/tests/libs/baseAction.test.ts +7 -1
  44. package/src/commands/keygen/create.ts +0 -23
  45. package/src/commands/keygen/index.ts +0 -39
  46. package/tests/commands/keygen.test.ts +0 -123
@@ -0,0 +1,211 @@
1
+ import {Command} from "commander";
2
+ import {vi, describe, beforeEach, afterEach, test, expect} from "vitest";
3
+ import {initializeStakingCommands} from "../../src/commands/staking";
4
+ import {ValidatorJoinAction} from "../../src/commands/staking/validatorJoin";
5
+ import {ValidatorDepositAction} from "../../src/commands/staking/validatorDeposit";
6
+ import {ValidatorExitAction} from "../../src/commands/staking/validatorExit";
7
+ import {ValidatorClaimAction} from "../../src/commands/staking/validatorClaim";
8
+ import {DelegatorJoinAction} from "../../src/commands/staking/delegatorJoin";
9
+ import {DelegatorExitAction} from "../../src/commands/staking/delegatorExit";
10
+ import {DelegatorClaimAction} from "../../src/commands/staking/delegatorClaim";
11
+ import {StakingInfoAction} from "../../src/commands/staking/stakingInfo";
12
+
13
+ vi.mock("../../src/commands/staking/validatorJoin");
14
+ vi.mock("../../src/commands/staking/validatorDeposit");
15
+ vi.mock("../../src/commands/staking/validatorExit");
16
+ vi.mock("../../src/commands/staking/validatorClaim");
17
+ vi.mock("../../src/commands/staking/delegatorJoin");
18
+ vi.mock("../../src/commands/staking/delegatorExit");
19
+ vi.mock("../../src/commands/staking/delegatorClaim");
20
+ vi.mock("../../src/commands/staking/stakingInfo");
21
+
22
+ describe("staking commands", () => {
23
+ let program: Command;
24
+
25
+ beforeEach(() => {
26
+ program = new Command();
27
+ initializeStakingCommands(program);
28
+ vi.clearAllMocks();
29
+ });
30
+
31
+ afterEach(() => {
32
+ vi.restoreAllMocks();
33
+ });
34
+
35
+ describe("validator-join", () => {
36
+ test("calls ValidatorJoinAction.execute with amount", async () => {
37
+ program.parse(["node", "test", "staking", "validator-join", "--amount", "42000gen"]);
38
+
39
+ expect(ValidatorJoinAction).toHaveBeenCalledTimes(1);
40
+ expect(ValidatorJoinAction.prototype.execute).toHaveBeenCalledWith({
41
+ amount: "42000gen",
42
+ });
43
+ });
44
+
45
+ test("calls ValidatorJoinAction.execute with operator", async () => {
46
+ program.parse([
47
+ "node",
48
+ "test",
49
+ "staking",
50
+ "validator-join",
51
+ "--amount",
52
+ "42000gen",
53
+ "--operator",
54
+ "0xOperator",
55
+ ]);
56
+
57
+ expect(ValidatorJoinAction.prototype.execute).toHaveBeenCalledWith({
58
+ amount: "42000gen",
59
+ operator: "0xOperator",
60
+ });
61
+ });
62
+
63
+ test("accepts staking-address option", async () => {
64
+ program.parse([
65
+ "node",
66
+ "test",
67
+ "staking",
68
+ "validator-join",
69
+ "--amount",
70
+ "42000",
71
+ "--staking-address",
72
+ "0xStaking",
73
+ ]);
74
+
75
+ expect(ValidatorJoinAction.prototype.execute).toHaveBeenCalledWith(
76
+ expect.objectContaining({stakingAddress: "0xStaking"}),
77
+ );
78
+ });
79
+ });
80
+
81
+ describe("validator-deposit", () => {
82
+ test("calls ValidatorDepositAction.execute", async () => {
83
+ program.parse(["node", "test", "staking", "validator-deposit", "--amount", "1000gen"]);
84
+
85
+ expect(ValidatorDepositAction).toHaveBeenCalledTimes(1);
86
+ expect(ValidatorDepositAction.prototype.execute).toHaveBeenCalledWith({
87
+ amount: "1000gen",
88
+ });
89
+ });
90
+ });
91
+
92
+ describe("validator-exit", () => {
93
+ test("calls ValidatorExitAction.execute", async () => {
94
+ program.parse(["node", "test", "staking", "validator-exit", "--shares", "100"]);
95
+
96
+ expect(ValidatorExitAction).toHaveBeenCalledTimes(1);
97
+ expect(ValidatorExitAction.prototype.execute).toHaveBeenCalledWith({
98
+ shares: "100",
99
+ });
100
+ });
101
+ });
102
+
103
+ describe("validator-claim", () => {
104
+ test("calls ValidatorClaimAction.execute", async () => {
105
+ program.parse(["node", "test", "staking", "validator-claim", "--validator", "0xValidator"]);
106
+
107
+ expect(ValidatorClaimAction).toHaveBeenCalledTimes(1);
108
+ expect(ValidatorClaimAction.prototype.execute).toHaveBeenCalledWith({
109
+ validator: "0xValidator",
110
+ });
111
+ });
112
+
113
+ test("works without validator option", async () => {
114
+ program.parse(["node", "test", "staking", "validator-claim"]);
115
+
116
+ expect(ValidatorClaimAction.prototype.execute).toHaveBeenCalledWith({});
117
+ });
118
+ });
119
+
120
+ describe("delegator-join", () => {
121
+ test("calls DelegatorJoinAction.execute", async () => {
122
+ program.parse([
123
+ "node",
124
+ "test",
125
+ "staking",
126
+ "delegator-join",
127
+ "--validator",
128
+ "0xValidator",
129
+ "--amount",
130
+ "42gen",
131
+ ]);
132
+
133
+ expect(DelegatorJoinAction).toHaveBeenCalledTimes(1);
134
+ expect(DelegatorJoinAction.prototype.execute).toHaveBeenCalledWith({
135
+ validator: "0xValidator",
136
+ amount: "42gen",
137
+ });
138
+ });
139
+ });
140
+
141
+ describe("delegator-exit", () => {
142
+ test("calls DelegatorExitAction.execute", async () => {
143
+ program.parse([
144
+ "node",
145
+ "test",
146
+ "staking",
147
+ "delegator-exit",
148
+ "--validator",
149
+ "0xValidator",
150
+ "--shares",
151
+ "50",
152
+ ]);
153
+
154
+ expect(DelegatorExitAction).toHaveBeenCalledTimes(1);
155
+ expect(DelegatorExitAction.prototype.execute).toHaveBeenCalledWith({
156
+ validator: "0xValidator",
157
+ shares: "50",
158
+ });
159
+ });
160
+ });
161
+
162
+ describe("delegator-claim", () => {
163
+ test("calls DelegatorClaimAction.execute", async () => {
164
+ program.parse([
165
+ "node",
166
+ "test",
167
+ "staking",
168
+ "delegator-claim",
169
+ "--validator",
170
+ "0xValidator",
171
+ "--delegator",
172
+ "0xDelegator",
173
+ ]);
174
+
175
+ expect(DelegatorClaimAction).toHaveBeenCalledTimes(1);
176
+ expect(DelegatorClaimAction.prototype.execute).toHaveBeenCalledWith({
177
+ validator: "0xValidator",
178
+ delegator: "0xDelegator",
179
+ });
180
+ });
181
+ });
182
+
183
+ describe("validator-info", () => {
184
+ test("calls StakingInfoAction.getValidatorInfo", async () => {
185
+ program.parse(["node", "test", "staking", "validator-info", "--validator", "0xValidator"]);
186
+
187
+ expect(StakingInfoAction).toHaveBeenCalledTimes(1);
188
+ expect(StakingInfoAction.prototype.getValidatorInfo).toHaveBeenCalledWith({
189
+ validator: "0xValidator",
190
+ });
191
+ });
192
+ });
193
+
194
+ describe("epoch-info", () => {
195
+ test("calls StakingInfoAction.getEpochInfo", async () => {
196
+ program.parse(["node", "test", "staking", "epoch-info"]);
197
+
198
+ expect(StakingInfoAction).toHaveBeenCalledTimes(1);
199
+ expect(StakingInfoAction.prototype.getEpochInfo).toHaveBeenCalledWith({});
200
+ });
201
+ });
202
+
203
+ describe("active-validators", () => {
204
+ test("calls StakingInfoAction.listActiveValidators", async () => {
205
+ program.parse(["node", "test", "staking", "active-validators"]);
206
+
207
+ expect(StakingInfoAction).toHaveBeenCalledTimes(1);
208
+ expect(StakingInfoAction.prototype.listActiveValidators).toHaveBeenCalledWith({});
209
+ });
210
+ });
211
+ });
@@ -13,8 +13,8 @@ vi.mock("../src/commands/general", () => ({
13
13
  initializeGeneralCommands: vi.fn(),
14
14
  }));
15
15
 
16
- vi.mock("../src/commands/keygen", () => ({
17
- initializeKeygenCommands: vi.fn(),
16
+ vi.mock("../src/commands/account", () => ({
17
+ initializeAccountCommands: vi.fn(),
18
18
  }));
19
19
 
20
20
  vi.mock("../src/commands/contracts", () => ({
@@ -45,6 +45,10 @@ vi.mock("../src/commands/transactions", () => ({
45
45
  initializeTransactionsCommands: vi.fn(),
46
46
  }));
47
47
 
48
+ vi.mock("../src/commands/staking", () => ({
49
+ initializeStakingCommands: vi.fn(),
50
+ }));
51
+
48
52
  describe("CLI", () => {
49
53
  it("should initialize CLI", () => {
50
54
  expect(initializeCLI).not.toThrow();
@@ -109,7 +109,7 @@ describe("BaseAction", () => {
109
109
 
110
110
  test("should fail the spinner with an error message", () => {
111
111
  const error = new Error("Something went wrong");
112
- baseAction["failSpinner"]("Failure", error);
112
+ baseAction["failSpinner"]("Failure", error, false); // Don't exit for test
113
113
 
114
114
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error:"));
115
115
  expect(consoleSpy).toHaveBeenCalledWith(inspect(error, {depth: null, colors: false}));
@@ -117,6 +117,12 @@ describe("BaseAction", () => {
117
117
  expect(mockSpinner.fail).toHaveBeenCalledWith(expect.stringContaining("Failure"));
118
118
  });
119
119
 
120
+ test("should fail the spinner and exit by default", () => {
121
+ const error = new Error("Fatal error");
122
+ expect(() => baseAction["failSpinner"]("Fatal", error)).toThrow("process exited");
123
+ expect(processExitSpy).toHaveBeenCalledWith(1);
124
+ });
125
+
120
126
  test("should stop the spinner", () => {
121
127
  baseAction["stopSpinner"]();
122
128
  expect(mockSpinner.stop).toHaveBeenCalled();
@@ -1,23 +0,0 @@
1
- import {BaseAction} from "../../lib/actions/BaseAction";
2
-
3
- export interface CreateKeypairOptions {
4
- output: string;
5
- overwrite: boolean;
6
- }
7
-
8
- export class KeypairCreator extends BaseAction {
9
- constructor() {
10
- super();
11
- }
12
-
13
- async createKeypairAction(options: CreateKeypairOptions) {
14
- try {
15
- this.startSpinner(`Creating encrypted keystore...`);
16
- await this.createKeypair(options.output, options.overwrite);
17
-
18
- this.succeedSpinner(`Encrypted keystore successfully created and saved to: ${options.output}`);
19
- } catch (error) {
20
- this.failSpinner("Failed to generate keystore", error);
21
- }
22
- }
23
- }
@@ -1,39 +0,0 @@
1
- import { Command } from "commander";
2
- import { CreateKeypairOptions, KeypairCreator } from "./create";
3
- import { UnlockAction } from "./unlock";
4
- import { LockAction } from "./lock";
5
-
6
- export function initializeKeygenCommands(program: Command) {
7
-
8
- const keygenCommand = program
9
- .command("keygen")
10
- .description("Manage keypair generation");
11
-
12
- keygenCommand
13
- .command("create")
14
- .description("Generates a new encrypted keystore and saves it to a file")
15
- .option("--output <path>", "Path to save the keystore", "./keypair.json")
16
- .option("--overwrite", "Overwrite the existing file if it already exists", false)
17
- .action(async (options: CreateKeypairOptions) => {
18
- const keypairCreator = new KeypairCreator();
19
- await keypairCreator.createKeypairAction(options);
20
- });
21
-
22
- keygenCommand
23
- .command("unlock")
24
- .description("Unlock your wallet by storing the decrypted private key in OS keychain")
25
- .action(async () => {
26
- const unlockAction = new UnlockAction();
27
- await unlockAction.execute();
28
- });
29
-
30
- keygenCommand
31
- .command("lock")
32
- .description("Lock your wallet by removing the decrypted private key from OS keychain")
33
- .action(async () => {
34
- const lockAction = new LockAction();
35
- await lockAction.execute();
36
- });
37
-
38
- return program;
39
- }
@@ -1,123 +0,0 @@
1
- import { Command } from "commander";
2
- import { vi, describe, beforeEach, afterEach, test, expect } from "vitest";
3
- import { initializeKeygenCommands } from "../../src/commands/keygen";
4
- import { KeypairCreator } from "../../src/commands/keygen/create";
5
- import { UnlockAction } from "../../src/commands/keygen/unlock";
6
- import { LockAction } from "../../src/commands/keygen/lock";
7
-
8
- vi.mock("../../src/commands/keygen/create");
9
- vi.mock("../../src/commands/keygen/unlock");
10
- vi.mock("../../src/commands/keygen/lock");
11
-
12
- describe("keygen create command", () => {
13
- let program: Command;
14
-
15
- beforeEach(() => {
16
- program = new Command();
17
- initializeKeygenCommands(program);
18
- vi.clearAllMocks();
19
- });
20
-
21
- afterEach(() => {
22
- vi.restoreAllMocks();
23
- });
24
-
25
- test("keypairCreator.createKeypairAction is called with default options", async () => {
26
- program.parse(["node", "test", "keygen", "create"]);
27
- expect(KeypairCreator).toHaveBeenCalledTimes(1);
28
- expect(KeypairCreator.prototype.createKeypairAction).toHaveBeenCalledWith({
29
- output: "./keypair.json",
30
- overwrite: false,
31
- });
32
- });
33
-
34
- test("keypairCreator.createKeypairAction is called with custom output option", async () => {
35
- program.parse(["node", "test", "keygen", "create", "--output", "./custom.json"]);
36
- expect(KeypairCreator).toHaveBeenCalledTimes(1);
37
- expect(KeypairCreator.prototype.createKeypairAction).toHaveBeenCalledWith({
38
- output: "./custom.json",
39
- overwrite: false,
40
- });
41
- });
42
-
43
- test("keypairCreator.createKeypairAction is called with overwrite enabled", async () => {
44
- program.parse(["node", "test", "keygen", "create", "--overwrite"]);
45
- expect(KeypairCreator).toHaveBeenCalledTimes(1);
46
- expect(KeypairCreator.prototype.createKeypairAction).toHaveBeenCalledWith({
47
- output: "./keypair.json",
48
- overwrite: true,
49
- });
50
- });
51
-
52
- test("keypairCreator.createKeypairAction is called with custom output and overwrite enabled", async () => {
53
- program.parse(["node", "test", "keygen", "create", "--output", "./custom.json", "--overwrite"]);
54
- expect(KeypairCreator).toHaveBeenCalledTimes(1);
55
- expect(KeypairCreator.prototype.createKeypairAction).toHaveBeenCalledWith({
56
- output: "./custom.json",
57
- overwrite: true,
58
- });
59
- });
60
-
61
- test("KeypairCreator is instantiated when the command is executed", async () => {
62
- program.parse(["node", "test", "keygen", "create"]);
63
- expect(KeypairCreator).toHaveBeenCalledTimes(1);
64
- });
65
-
66
-
67
-
68
- test("keypairCreator.createKeypairAction is called without throwing errors for default options", async () => {
69
- program.parse(["node", "test", "keygen", "create"]);
70
- vi.mocked(KeypairCreator.prototype.createKeypairAction).mockReturnValue();
71
- expect(() => program.parse(["node", "test", "keygen", "create"])).not.toThrow();
72
- });
73
- });
74
-
75
- describe("keygen unlock command", () => {
76
- let program: Command;
77
-
78
- beforeEach(() => {
79
- program = new Command();
80
- initializeKeygenCommands(program);
81
- vi.clearAllMocks();
82
- });
83
-
84
- afterEach(() => {
85
- vi.restoreAllMocks();
86
- });
87
-
88
- test("UnlockAction is instantiated and execute is called", async () => {
89
- program.parse(["node", "test", "keygen", "unlock"]);
90
- expect(UnlockAction).toHaveBeenCalledTimes(1);
91
- expect(UnlockAction.prototype.execute).toHaveBeenCalled();
92
- });
93
-
94
- test("UnlockAction.execute is called without throwing errors", async () => {
95
- vi.mocked(UnlockAction.prototype.execute).mockResolvedValue();
96
- expect(() => program.parse(["node", "test", "keygen", "unlock"])).not.toThrow();
97
- });
98
- });
99
-
100
- describe("keygen lock command", () => {
101
- let program: Command;
102
-
103
- beforeEach(() => {
104
- program = new Command();
105
- initializeKeygenCommands(program);
106
- vi.clearAllMocks();
107
- });
108
-
109
- afterEach(() => {
110
- vi.restoreAllMocks();
111
- });
112
-
113
- test("LockAction is instantiated and execute is called", async () => {
114
- program.parse(["node", "test", "keygen", "lock"]);
115
- expect(LockAction).toHaveBeenCalledTimes(1);
116
- expect(LockAction.prototype.execute).toHaveBeenCalled();
117
- });
118
-
119
- test("LockAction.execute is called without throwing errors", async () => {
120
- vi.mocked(LockAction.prototype.execute).mockResolvedValue();
121
- expect(() => program.parse(["node", "test", "keygen", "lock"])).not.toThrow();
122
- });
123
- });