genlayer 0.38.8 → 0.38.10

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 (205) hide show
  1. package/.eslintignore +2 -0
  2. package/.github/workflows/cli-docs.yml +124 -0
  3. package/.github/workflows/publish.yml +55 -0
  4. package/.github/workflows/smoke.yml +27 -0
  5. package/.github/workflows/validate-code.yml +51 -0
  6. package/.prettierignore +19 -0
  7. package/.prettierrc +12 -0
  8. package/.release-it.json +66 -0
  9. package/CHANGELOG.md +545 -0
  10. package/CLAUDE.md +55 -0
  11. package/CONTRIBUTING.md +117 -0
  12. package/dist/index.js +221 -62
  13. package/docs/api-references/_meta.json +9 -0
  14. package/docs/api-references/accounts/_meta.json +3 -0
  15. package/docs/api-references/accounts/account/create.mdx +19 -0
  16. package/docs/api-references/accounts/account/export.mdx +19 -0
  17. package/docs/api-references/accounts/account/import.mdx +22 -0
  18. package/docs/api-references/accounts/account/list.mdx +15 -0
  19. package/docs/api-references/accounts/account/lock.mdx +16 -0
  20. package/docs/api-references/accounts/account/remove.mdx +20 -0
  21. package/docs/api-references/accounts/account/send.mdx +24 -0
  22. package/docs/api-references/accounts/account/show.mdx +17 -0
  23. package/docs/api-references/accounts/account/unlock.mdx +17 -0
  24. package/docs/api-references/accounts/account/use.mdx +19 -0
  25. package/docs/api-references/accounts/account.mdx +32 -0
  26. package/docs/api-references/configuration/_meta.json +4 -0
  27. package/docs/api-references/configuration/config/get.mdx +21 -0
  28. package/docs/api-references/configuration/config/reset.mdx +21 -0
  29. package/docs/api-references/configuration/config/set.mdx +21 -0
  30. package/docs/api-references/configuration/config.mdx +25 -0
  31. package/docs/api-references/configuration/network/info.mdx +15 -0
  32. package/docs/api-references/configuration/network/list.mdx +15 -0
  33. package/docs/api-references/configuration/network/set.mdx +21 -0
  34. package/docs/api-references/configuration/network.mdx +25 -0
  35. package/docs/api-references/contracts/_meta.json +7 -0
  36. package/docs/api-references/contracts/call.mdx +21 -0
  37. package/docs/api-references/contracts/code.mdx +20 -0
  38. package/docs/api-references/contracts/deploy.mdx +17 -0
  39. package/docs/api-references/contracts/schema.mdx +20 -0
  40. package/docs/api-references/contracts/write.mdx +21 -0
  41. package/docs/api-references/environment/_meta.json +7 -0
  42. package/docs/api-references/environment/init.mdx +20 -0
  43. package/docs/api-references/environment/new.mdx +21 -0
  44. package/docs/api-references/environment/stop.mdx +15 -0
  45. package/docs/api-references/environment/up.mdx +20 -0
  46. package/docs/api-references/environment/update/ollama.mdx +16 -0
  47. package/docs/api-references/environment/update.mdx +23 -0
  48. package/docs/api-references/index.mdx +35 -0
  49. package/docs/api-references/localnet/_meta.json +3 -0
  50. package/docs/api-references/localnet/localnet/validators/count.mdx +15 -0
  51. package/docs/api-references/localnet/localnet/validators/create-random.mdx +16 -0
  52. package/docs/api-references/localnet/localnet/validators/create.mdx +19 -0
  53. package/docs/api-references/localnet/localnet/validators/delete.mdx +16 -0
  54. package/docs/api-references/localnet/localnet/validators/get.mdx +16 -0
  55. package/docs/api-references/localnet/localnet/validators/update.mdx +23 -0
  56. package/docs/api-references/localnet/localnet/validators.mdx +28 -0
  57. package/docs/api-references/localnet/localnet.mdx +23 -0
  58. package/docs/api-references/staking/_meta.json +3 -0
  59. package/docs/api-references/staking/staking/active-validators.mdx +18 -0
  60. package/docs/api-references/staking/staking/banned-validators.mdx +18 -0
  61. package/docs/api-references/staking/staking/delegation-info.mdx +25 -0
  62. package/docs/api-references/staking/staking/delegator-claim.mdx +26 -0
  63. package/docs/api-references/staking/staking/delegator-exit.mdx +26 -0
  64. package/docs/api-references/staking/staking/delegator-join.mdx +26 -0
  65. package/docs/api-references/staking/staking/epoch-info.mdx +19 -0
  66. package/docs/api-references/staking/staking/prime-all.mdx +20 -0
  67. package/docs/api-references/staking/staking/quarantined-validators.mdx +18 -0
  68. package/docs/api-references/staking/staking/set-identity.mdx +33 -0
  69. package/docs/api-references/staking/staking/set-operator.mdx +26 -0
  70. package/docs/api-references/staking/staking/validator-claim.mdx +24 -0
  71. package/docs/api-references/staking/staking/validator-deposit.mdx +25 -0
  72. package/docs/api-references/staking/staking/validator-exit.mdx +25 -0
  73. package/docs/api-references/staking/staking/validator-history.mdx +29 -0
  74. package/docs/api-references/staking/staking/validator-info.mdx +25 -0
  75. package/docs/api-references/staking/staking/validator-join.mdx +22 -0
  76. package/docs/api-references/staking/staking/validator-prime.mdx +25 -0
  77. package/docs/api-references/staking/staking/validators.mdx +19 -0
  78. package/docs/api-references/staking/staking/wizard.mdx +20 -0
  79. package/docs/api-references/staking/staking.mdx +42 -0
  80. package/docs/api-references/transactions/_meta.json +6 -0
  81. package/docs/api-references/transactions/appeal-bond.mdx +20 -0
  82. package/docs/api-references/transactions/appeal.mdx +21 -0
  83. package/docs/api-references/transactions/receipt.mdx +25 -0
  84. package/docs/api-references/transactions/trace.mdx +21 -0
  85. package/docs/delegator-guide.md +203 -0
  86. package/docs/validator-guide.md +329 -0
  87. package/esbuild.config.dev.js +17 -0
  88. package/esbuild.config.js +22 -0
  89. package/esbuild.config.prod.js +17 -0
  90. package/eslint.config.js +60 -0
  91. package/package.json +2 -11
  92. package/renovate.json +22 -0
  93. package/scripts/generate-cli-docs.mjs +68 -5
  94. package/src/commands/account/create.ts +30 -0
  95. package/src/commands/account/export.ts +106 -0
  96. package/src/commands/account/import.ts +135 -0
  97. package/src/commands/account/index.ts +129 -0
  98. package/src/commands/account/list.ts +34 -0
  99. package/src/commands/account/lock.ts +39 -0
  100. package/src/commands/account/remove.ts +30 -0
  101. package/src/commands/account/send.ts +162 -0
  102. package/src/commands/account/show.ts +74 -0
  103. package/src/commands/account/unlock.ts +56 -0
  104. package/src/commands/account/use.ts +21 -0
  105. package/src/commands/config/getSetReset.ts +51 -0
  106. package/src/commands/config/index.ts +30 -0
  107. package/src/commands/contracts/call.ts +39 -0
  108. package/src/commands/contracts/code.ts +33 -0
  109. package/src/commands/contracts/deploy.ts +161 -0
  110. package/src/commands/contracts/index.ts +150 -0
  111. package/src/commands/contracts/schema.ts +31 -0
  112. package/src/commands/contracts/write.ts +49 -0
  113. package/src/commands/general/index.ts +45 -0
  114. package/src/commands/general/init.ts +180 -0
  115. package/src/commands/general/start.ts +128 -0
  116. package/src/commands/general/stop.ts +26 -0
  117. package/src/commands/localnet/index.ts +100 -0
  118. package/src/commands/localnet/validators.ts +269 -0
  119. package/src/commands/network/index.ts +29 -0
  120. package/src/commands/network/setNetwork.ts +77 -0
  121. package/src/commands/scaffold/index.ts +16 -0
  122. package/src/commands/scaffold/new.ts +34 -0
  123. package/src/commands/staking/StakingAction.ts +279 -0
  124. package/src/commands/staking/delegatorClaim.ts +41 -0
  125. package/src/commands/staking/delegatorExit.ts +56 -0
  126. package/src/commands/staking/delegatorJoin.ts +44 -0
  127. package/src/commands/staking/index.ts +357 -0
  128. package/src/commands/staking/setIdentity.ts +78 -0
  129. package/src/commands/staking/setOperator.ts +46 -0
  130. package/src/commands/staking/stakingInfo.ts +584 -0
  131. package/src/commands/staking/validatorClaim.ts +43 -0
  132. package/src/commands/staking/validatorDeposit.ts +48 -0
  133. package/src/commands/staking/validatorExit.ts +63 -0
  134. package/src/commands/staking/validatorHistory.ts +300 -0
  135. package/src/commands/staking/validatorJoin.ts +47 -0
  136. package/src/commands/staking/validatorPrime.ts +73 -0
  137. package/src/commands/staking/wizard.ts +809 -0
  138. package/src/commands/transactions/appeal.ts +83 -0
  139. package/src/commands/transactions/index.ts +60 -0
  140. package/src/commands/transactions/receipt.ts +90 -0
  141. package/src/commands/transactions/trace.ts +42 -0
  142. package/src/commands/update/index.ts +25 -0
  143. package/src/commands/update/ollama.ts +103 -0
  144. package/src/lib/actions/BaseAction.ts +301 -0
  145. package/src/lib/clients/jsonRpcClient.ts +41 -0
  146. package/src/lib/clients/system.ts +73 -0
  147. package/src/lib/config/ConfigFileManager.ts +194 -0
  148. package/src/lib/config/KeychainManager.ts +89 -0
  149. package/src/lib/config/simulator.ts +68 -0
  150. package/src/lib/config/text.ts +2 -0
  151. package/src/lib/errors/missingRequirement.ts +9 -0
  152. package/src/lib/errors/versionRequired.ts +9 -0
  153. package/src/lib/interfaces/ISimulatorService.ts +39 -0
  154. package/src/lib/services/simulator.ts +386 -0
  155. package/src/types/node-fetch.d.ts +1 -0
  156. package/tests/actions/appeal.test.ts +141 -0
  157. package/tests/actions/call.test.ts +94 -0
  158. package/tests/actions/code.test.ts +87 -0
  159. package/tests/actions/create.test.ts +65 -0
  160. package/tests/actions/deploy.test.ts +420 -0
  161. package/tests/actions/getSetReset.test.ts +88 -0
  162. package/tests/actions/init.test.ts +483 -0
  163. package/tests/actions/lock.test.ts +86 -0
  164. package/tests/actions/new.test.ts +80 -0
  165. package/tests/actions/ollama.test.ts +193 -0
  166. package/tests/actions/receipt.test.ts +261 -0
  167. package/tests/actions/schema.test.ts +94 -0
  168. package/tests/actions/setNetwork.test.ts +161 -0
  169. package/tests/actions/staking.test.ts +280 -0
  170. package/tests/actions/start.test.ts +257 -0
  171. package/tests/actions/stop.test.ts +77 -0
  172. package/tests/actions/unlock.test.ts +139 -0
  173. package/tests/actions/validators.test.ts +750 -0
  174. package/tests/actions/write.test.ts +102 -0
  175. package/tests/commands/account.test.ts +146 -0
  176. package/tests/commands/appeal.test.ts +97 -0
  177. package/tests/commands/call.test.ts +78 -0
  178. package/tests/commands/code.test.ts +69 -0
  179. package/tests/commands/config.test.ts +54 -0
  180. package/tests/commands/deploy.test.ts +83 -0
  181. package/tests/commands/init.test.ts +101 -0
  182. package/tests/commands/localnet.test.ts +131 -0
  183. package/tests/commands/network.test.ts +60 -0
  184. package/tests/commands/new.test.ts +68 -0
  185. package/tests/commands/parseArg.test.ts +156 -0
  186. package/tests/commands/receipt.test.ts +142 -0
  187. package/tests/commands/schema.test.ts +67 -0
  188. package/tests/commands/staking.test.ts +329 -0
  189. package/tests/commands/stop.test.ts +27 -0
  190. package/tests/commands/up.test.ts +105 -0
  191. package/tests/commands/update.test.ts +45 -0
  192. package/tests/commands/write.test.ts +76 -0
  193. package/tests/index.test.ts +56 -0
  194. package/tests/libs/baseAction.test.ts +535 -0
  195. package/tests/libs/configFileManager.test.ts +118 -0
  196. package/tests/libs/jsonRpcClient.test.ts +59 -0
  197. package/tests/libs/keychainManager.test.ts +156 -0
  198. package/tests/libs/platformCommands.test.ts +78 -0
  199. package/tests/libs/system.test.ts +148 -0
  200. package/tests/services/simulator.test.ts +789 -0
  201. package/tests/smoke.test.ts +134 -0
  202. package/tests/utils.ts +13 -0
  203. package/tsconfig.json +120 -0
  204. package/vitest.config.ts +13 -0
  205. package/vitest.smoke.config.ts +17 -0
@@ -0,0 +1,101 @@
1
+ import { Command } from "commander";
2
+ import { vi, describe, beforeEach, afterEach, test, expect } from "vitest";
3
+ import { initializeGeneralCommands } from "../../src/commands/general";
4
+ import { getCommand, getCommandOption } from "../utils";
5
+ import simulatorService from '../../src/lib/services/simulator'
6
+ import {localnetCompatibleVersion} from "../../src/lib/config/simulator";
7
+ import { InitAction } from "../../src/commands/general/init";
8
+
9
+
10
+ vi.mock("../../src/commands/general/init");
11
+
12
+
13
+ const openFrontendSpy = vi.spyOn(simulatorService, "openFrontend");
14
+ const defaultOptions = {
15
+ numValidators: "5",
16
+ headless: false,
17
+ resetDb: false,
18
+ localnetVersion: localnetCompatibleVersion,
19
+ ollama: false,
20
+ }
21
+
22
+ vi.mock("inquirer", () => ({
23
+ prompt: vi.fn(() => {}),
24
+ }));
25
+
26
+ describe("init command", () => {
27
+ let initCommand: Command;
28
+ let program: Command;
29
+
30
+ beforeEach(() => {
31
+ program = new Command();
32
+ initializeGeneralCommands(program);
33
+
34
+ initCommand = getCommand(program, "init");
35
+ vi.clearAllMocks();
36
+ });
37
+
38
+ afterEach(() => {
39
+ vi.restoreAllMocks();
40
+ });
41
+
42
+ test("doesn't have required arguments nor options", async () => {
43
+ expect(() => program.parse(["node", "test", "init"])).not.toThrow();
44
+ });
45
+
46
+ test("option --numValidators is accepted", async () => {
47
+ expect(() => program.parse(["node", "test", "init", "--numValidators", "10"])).not.toThrow();
48
+ });
49
+
50
+ test("option --numValidators default value is 5", async () => {
51
+ const numValidatorsOption = getCommandOption(initCommand, "--numValidators");
52
+ expect(numValidatorsOption?.defaultValue).toBe("5");
53
+ });
54
+
55
+
56
+ test("random option is not accepted", async () => {
57
+ initCommand?.exitOverride();
58
+ expect(() => program.parse(["node", "test", "init", "-random"])).toThrowError(
59
+ "error: unknown option '-random'"
60
+ );
61
+ expect(() => program.parse(["node", "test", "init", "--randomOption"])).toThrowError(
62
+ "error: unknown option '--randomOption'"
63
+ );
64
+ });
65
+
66
+ test("action is called", async () => {
67
+ program.parse(["node", "test", "init"]);
68
+ expect(InitAction).toHaveBeenCalledTimes(1);
69
+ expect(InitAction.prototype.execute).toHaveBeenCalledWith(defaultOptions);
70
+ });
71
+
72
+ test("option --headless is accepted", async () => {
73
+ program.parse(["node", "test", "init", "--headless"]);
74
+ expect(InitAction).toHaveBeenCalledTimes(1);
75
+ expect(InitAction.prototype.execute).toHaveBeenCalledWith({...defaultOptions, headless: true});
76
+ expect(openFrontendSpy).not.toHaveBeenCalled();
77
+ });
78
+
79
+ test("option --localnet-version is accepted", async () => {
80
+ program.parse(["node", "test", "init", "--localnet-version", "v1.0.0"]);
81
+ expect(InitAction).toHaveBeenCalledTimes(1);
82
+ expect(InitAction.prototype.execute).toHaveBeenCalledWith({...defaultOptions, localnetVersion: "v1.0.0"});
83
+ expect(openFrontendSpy).not.toHaveBeenCalled();
84
+ });
85
+
86
+ test("option --localnet-version description includes minimum version", async () => {
87
+ const localnetVersionOption = getCommandOption(initCommand, "--localnet-version");
88
+ expect(localnetVersionOption?.description).toBe(`Select a specific localnet version (minimum: ${localnetCompatibleVersion})`);
89
+ });
90
+
91
+ test("option --localnet-version default value is compatible version", async () => {
92
+ const localnetVersionOption = getCommandOption(initCommand, "--localnet-version");
93
+ expect(localnetVersionOption?.defaultValue).toBe(localnetCompatibleVersion);
94
+ });
95
+
96
+ test("option --ollama is accepted", async () => {
97
+ program.parse(["node", "test", "init", "--ollama"]);
98
+ expect(InitAction).toHaveBeenCalledTimes(1);
99
+ expect(InitAction.prototype.execute).toHaveBeenCalledWith({...defaultOptions, ollama: true});
100
+ });
101
+ });
@@ -0,0 +1,131 @@
1
+ import { Command } from "commander";
2
+ import { vi, describe, beforeEach, afterEach, test, expect } from "vitest";
3
+ import { initializeValidatorCommands } from "../../src/commands/localnet";
4
+ import { ValidatorsAction } from "../../src/commands/localnet/validators";
5
+
6
+ vi.mock("../../src/commands/localnet/validators");
7
+
8
+ describe("localnet validator command", () => {
9
+ let program: Command;
10
+
11
+ beforeEach(() => {
12
+ program = new Command();
13
+ initializeValidatorCommands(program);
14
+ });
15
+
16
+ afterEach(() => {
17
+ vi.restoreAllMocks();
18
+ });
19
+
20
+ test("ValidatorsAction.getValidator is called with address option", async () => {
21
+ program.parse(["node", "test", "localnet", "validators", "get", "--address", "mocked_address"]);
22
+ expect(ValidatorsAction).toHaveBeenCalledTimes(1);
23
+ expect(ValidatorsAction.prototype.getValidator).toHaveBeenCalledWith({
24
+ address: "mocked_address",
25
+ });
26
+ });
27
+
28
+ test("ValidatorsAction.getValidator is called without address option", async () => {
29
+ program.parse(["node", "test", "localnet", "validators", "get"]);
30
+ expect(ValidatorsAction).toHaveBeenCalledTimes(1);
31
+ expect(ValidatorsAction.prototype.getValidator).toHaveBeenCalledWith({});
32
+ });
33
+
34
+ test("ValidatorsAction.deleteValidator is called with address option", async () => {
35
+ program.parse(["node", "test", "localnet", "validators", "delete", "--address", "mocked_address"]);
36
+ expect(ValidatorsAction).toHaveBeenCalledTimes(1);
37
+ expect(ValidatorsAction.prototype.deleteValidator).toHaveBeenCalledWith({
38
+ address: "mocked_address",
39
+ });
40
+ });
41
+
42
+ test("ValidatorsAction.deleteValidator is called without address option", async () => {
43
+ program.parse(["node", "test", "localnet", "validators", "delete"]);
44
+ expect(ValidatorsAction).toHaveBeenCalledTimes(1);
45
+ expect(ValidatorsAction.prototype.deleteValidator).toHaveBeenCalledWith({});
46
+ });
47
+
48
+ test("ValidatorsAction.countValidators is called", async () => {
49
+ program.parse(["node", "test", "localnet", "validators", "count"]);
50
+ expect(ValidatorsAction).toHaveBeenCalledTimes(1);
51
+ expect(ValidatorsAction.prototype.countValidators).toHaveBeenCalled();
52
+ });
53
+
54
+ test("ValidatorsAction.updateValidator is called with all options", async () => {
55
+ program.parse([
56
+ "node",
57
+ "test",
58
+ "localnet",
59
+ "validators",
60
+ "update",
61
+ "mocked_address",
62
+ "--stake",
63
+ "10",
64
+ "--provider",
65
+ "mocked_provider",
66
+ "--model",
67
+ "mocked_model",
68
+ '--config',
69
+ '{"max_tokens":500}',
70
+ ]);
71
+ expect(ValidatorsAction).toHaveBeenCalledTimes(1);
72
+ expect(ValidatorsAction.prototype.updateValidator).toHaveBeenCalledWith({
73
+ address: "mocked_address",
74
+ stake: "10",
75
+ provider: "mocked_provider",
76
+ model: "mocked_model",
77
+ config: '{"max_tokens":500}',
78
+ });
79
+ });
80
+
81
+ test("ValidatorsAction.createRandomValidators is called with count and providers", async () => {
82
+ program.parse([
83
+ "node",
84
+ "test",
85
+ "localnet",
86
+ "validators",
87
+ "create-random",
88
+ "--count",
89
+ "3",
90
+ "--providers",
91
+ "provider1",
92
+ "provider2",
93
+ ]);
94
+ expect(ValidatorsAction).toHaveBeenCalledTimes(1);
95
+ expect(ValidatorsAction.prototype.createRandomValidators).toHaveBeenCalledWith({
96
+ count: "3",
97
+ providers: ["provider1", "provider2"],
98
+ models: []
99
+ });
100
+ });
101
+
102
+ test("ValidatorsAction.createValidator is called with default stake", async () => {
103
+ program.parse(["node", "test", "localnet", "validators", "create"]);
104
+ expect(ValidatorsAction).toHaveBeenCalledTimes(1);
105
+ expect(ValidatorsAction.prototype.createValidator).toHaveBeenCalledWith({
106
+ stake: "1",
107
+ config: undefined,
108
+ });
109
+ });
110
+
111
+ test("ValidatorsAction.createValidator is called with stake and config", async () => {
112
+ program.parse([
113
+ "node",
114
+ "test",
115
+ "localnet",
116
+ "validators",
117
+ "create",
118
+ "--stake",
119
+ "5",
120
+ '--config',
121
+ '{"temperature":0.8}',
122
+ ]);
123
+ expect(ValidatorsAction).toHaveBeenCalledTimes(1);
124
+ expect(ValidatorsAction.prototype.createValidator).toHaveBeenCalledWith({
125
+ stake: "5",
126
+ config: '{"temperature":0.8}',
127
+ });
128
+ });
129
+ });
130
+
131
+
@@ -0,0 +1,60 @@
1
+ import {Command} from "commander";
2
+ import {vi, describe, beforeEach, afterEach, test, expect} from "vitest";
3
+ import {initializeNetworkCommands} from "../../src/commands/network";
4
+ import {NetworkActions} from "../../src/commands/network/setNetwork";
5
+
6
+ vi.mock("../../src/commands/network/setNetwork");
7
+
8
+ describe("network commands", () => {
9
+ let program: Command;
10
+
11
+ beforeEach(() => {
12
+ program = new Command();
13
+ initializeNetworkCommands(program);
14
+ });
15
+
16
+ afterEach(() => {
17
+ vi.restoreAllMocks();
18
+ });
19
+
20
+ test("NetworkActions.setNetwork is called with the correct network name", async () => {
21
+ program.parse(["node", "test", "network", "set", "localnet"]);
22
+ expect(NetworkActions).toHaveBeenCalledTimes(1);
23
+ expect(NetworkActions.prototype.setNetwork).toHaveBeenCalledWith("localnet");
24
+ });
25
+
26
+ test("NetworkActions.setNetwork is called with testnet-asimov", async () => {
27
+ program.parse(["node", "test", "network", "set", "testnet-asimov"]);
28
+ expect(NetworkActions).toHaveBeenCalledTimes(1);
29
+ expect(NetworkActions.prototype.setNetwork).toHaveBeenCalledWith("testnet-asimov");
30
+ });
31
+
32
+ test("NetworkActions.setNetwork is called with studionet", async () => {
33
+ program.parse(["node", "test", "network", "set", "studionet"]);
34
+ expect(NetworkActions).toHaveBeenCalledTimes(1);
35
+ expect(NetworkActions.prototype.setNetwork).toHaveBeenCalledWith("studionet");
36
+ });
37
+
38
+ test("NetworkActions.setNetwork is called without a network name", async () => {
39
+ program.parse(["node", "test", "network", "set"]);
40
+ expect(NetworkActions).toHaveBeenCalledTimes(1);
41
+ expect(NetworkActions.prototype.setNetwork).toHaveBeenCalledWith(undefined);
42
+ });
43
+
44
+ test("NetworkActions is instantiated when the command is executed", async () => {
45
+ program.parse(["node", "test", "network", "set", "localnet"]);
46
+ expect(NetworkActions).toHaveBeenCalledTimes(1);
47
+ });
48
+
49
+ test("NetworkActions.setNetwork is called without throwing errors for valid network", async () => {
50
+ program.parse(["node", "test", "network", "set", "localnet"]);
51
+ vi.mocked(NetworkActions.prototype.setNetwork).mockResolvedValue();
52
+ expect(() => program.parse(["node", "test", "network", "set", "localnet"])).not.toThrow();
53
+ });
54
+
55
+ test("NetworkActions.showInfo is called for network info", async () => {
56
+ program.parse(["node", "test", "network", "info"]);
57
+ expect(NetworkActions).toHaveBeenCalledTimes(1);
58
+ expect(NetworkActions.prototype.showInfo).toHaveBeenCalled();
59
+ });
60
+ });
@@ -0,0 +1,68 @@
1
+ import { Command } from "commander";
2
+ import { vi, describe, beforeEach, afterEach, test, expect } from "vitest";
3
+ import { initializeScaffoldCommands } from "../../src/commands/scaffold";
4
+ import { NewAction } from "../../src/commands/scaffold/new";
5
+
6
+ vi.mock("../../src/commands/scaffold/new");
7
+
8
+ describe("new command", () => {
9
+ let program: Command;
10
+
11
+ beforeEach(() => {
12
+ program = new Command();
13
+ initializeScaffoldCommands(program);
14
+ vi.clearAllMocks();
15
+ });
16
+
17
+ afterEach(() => {
18
+ vi.restoreAllMocks();
19
+ });
20
+
21
+ test("NewAction.createProject is called with default options", async () => {
22
+ program.parse(["node", "test", "new", "myProject"]);
23
+ expect(NewAction).toHaveBeenCalledTimes(1);
24
+ expect(NewAction.prototype.createProject).toHaveBeenCalledWith("myProject", {
25
+ path: ".",
26
+ overwrite: false,
27
+ });
28
+ });
29
+
30
+ test("NewAction.createProject is called with custom path", async () => {
31
+ program.parse(["node", "test", "new", "myProject", "--path", "./customDir"]);
32
+ expect(NewAction).toHaveBeenCalledTimes(1);
33
+ expect(NewAction.prototype.createProject).toHaveBeenCalledWith("myProject", {
34
+ path: "./customDir",
35
+ overwrite: false,
36
+ });
37
+ });
38
+
39
+ test("NewAction.createProject is called with overwrite flag", async () => {
40
+ program.parse(["node", "test", "new", "myProject", "--overwrite"]);
41
+ expect(NewAction).toHaveBeenCalledTimes(1);
42
+ expect(NewAction.prototype.createProject).toHaveBeenCalledWith("myProject", {
43
+ path: ".",
44
+ overwrite: true,
45
+ });
46
+ });
47
+
48
+ test("NewAction is instantiated when the new command is executed", async () => {
49
+ program.parse(["node", "test", "new", "myProject"]);
50
+ expect(NewAction).toHaveBeenCalledTimes(1);
51
+ });
52
+
53
+ test("throws error for unrecognized options", async () => {
54
+ const newCommand = program.commands.find((cmd) => cmd.name() === "new");
55
+ newCommand?.exitOverride();
56
+ expect(() => program.parse(["node", "test", "new", "myProject", "--unknown"])).toThrowError(
57
+ "error: unknown option '--unknown'"
58
+ );
59
+ });
60
+
61
+ test("NewAction.createProject is called without throwing errors for valid options", async () => {
62
+ program.parse(["node", "test", "new", "myProject"]);
63
+ vi.mocked(NewAction.prototype.createProject).mockResolvedValueOnce(undefined);
64
+ expect(() =>
65
+ program.parse(["node", "test", "new", "myProject"])
66
+ ).not.toThrow();
67
+ });
68
+ });
@@ -0,0 +1,156 @@
1
+ import {vi, describe, test, expect} from "vitest";
2
+ import {CalldataAddress} from "genlayer-js/types";
3
+ import {parseArg, parseScalar, coerceValue} from "../../src/commands/contracts";
4
+
5
+ vi.mock("esbuild", () => ({
6
+ buildSync: vi.fn(),
7
+ }));
8
+
9
+ describe("parseScalar", () => {
10
+ test("parses booleans", () => {
11
+ expect(parseScalar("true")).toBe(true);
12
+ expect(parseScalar("false")).toBe(false);
13
+ });
14
+
15
+ test("parses null", () => {
16
+ expect(parseScalar("null")).toBeNull();
17
+ });
18
+
19
+ test("parses small integers as Number", () => {
20
+ expect(parseScalar("42")).toBe(42);
21
+ expect(parseScalar("0")).toBe(0);
22
+ expect(parseScalar("-1")).toBe(-1);
23
+ });
24
+
25
+ test("parses 0x address as CalldataAddress", () => {
26
+ const result = parseScalar("0x6857Ed54CbafaA74Fc0357145eC0ee1536ca45A0");
27
+ expect(result).toBeInstanceOf(CalldataAddress);
28
+ const addr = result as CalldataAddress;
29
+ expect(addr.bytes).toHaveLength(20);
30
+ expect(addr.bytes[0]).toBe(0x68);
31
+ expect(addr.bytes[19]).toBe(0xa0);
32
+ });
33
+
34
+ test("parses addr# prefix as CalldataAddress", () => {
35
+ const result = parseScalar("addr#6857Ed54CbafaA74Fc0357145eC0ee1536ca45A0");
36
+ expect(result).toBeInstanceOf(CalldataAddress);
37
+ const addr = result as CalldataAddress;
38
+ expect(addr.bytes).toHaveLength(20);
39
+ expect(addr.bytes[0]).toBe(0x68);
40
+ });
41
+
42
+ test("parses b# prefix as Uint8Array", () => {
43
+ const result = parseScalar("b#deadbeef");
44
+ expect(result).toBeInstanceOf(Uint8Array);
45
+ const bytes = result as Uint8Array;
46
+ expect(bytes).toEqual(new Uint8Array([0xde, 0xad, 0xbe, 0xef]));
47
+ });
48
+
49
+ test("parses empty b# as empty Uint8Array", () => {
50
+ const result = parseScalar("b#");
51
+ expect(result).toBeInstanceOf(Uint8Array);
52
+ expect(result).toEqual(new Uint8Array([]));
53
+ });
54
+
55
+ test("parses non-address hex as BigInt", () => {
56
+ expect(parseScalar("0x1234")).toBe(BigInt("0x1234"));
57
+ });
58
+
59
+ test("parses large decimal as BigInt", () => {
60
+ const big = "99999999999999999999";
61
+ expect(parseScalar(big)).toBe(BigInt(big));
62
+ });
63
+
64
+ test("parses plain strings", () => {
65
+ expect(parseScalar("hello")).toBe("hello");
66
+ expect(parseScalar("someString")).toBe("someString");
67
+ });
68
+
69
+ test("does not treat invalid hex as address", () => {
70
+ const invalid = "0xZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
71
+ expect(parseScalar(invalid)).toBe(invalid);
72
+ });
73
+ });
74
+
75
+ describe("coerceValue", () => {
76
+ test("coerces null", () => {
77
+ expect(coerceValue(null)).toBeNull();
78
+ });
79
+
80
+ test("coerces booleans", () => {
81
+ expect(coerceValue(true)).toBe(true);
82
+ expect(coerceValue(false)).toBe(false);
83
+ });
84
+
85
+ test("coerces safe integers", () => {
86
+ expect(coerceValue(42)).toBe(42);
87
+ });
88
+
89
+ test("coerces arrays recursively", () => {
90
+ expect(coerceValue([1, "hello", null])).toEqual([1, "hello", null]);
91
+ });
92
+
93
+ test("coerces objects recursively", () => {
94
+ expect(coerceValue({key: "value", n: 42})).toEqual({key: "value", n: 42});
95
+ });
96
+
97
+ test("coerces address strings inside objects", () => {
98
+ const result = coerceValue({recipient: "0x6857Ed54CbafaA74Fc0357145eC0ee1536ca45A0"}) as any;
99
+ expect(result.recipient).toBeInstanceOf(CalldataAddress);
100
+ });
101
+
102
+ test("coerces address strings inside arrays", () => {
103
+ const result = coerceValue(["0x6857Ed54CbafaA74Fc0357145eC0ee1536ca45A0"]) as any[];
104
+ expect(result[0]).toBeInstanceOf(CalldataAddress);
105
+ });
106
+ });
107
+
108
+ describe("parseArg", () => {
109
+ test("parses scalars", () => {
110
+ expect(parseArg("42")).toEqual([42]);
111
+ expect(parseArg("true")).toEqual([true]);
112
+ expect(parseArg("hello")).toEqual(["hello"]);
113
+ });
114
+
115
+ test("parses null", () => {
116
+ expect(parseArg("null")).toEqual([null]);
117
+ });
118
+
119
+ test("parses JSON array", () => {
120
+ const result = parseArg('[1, 2, "three"]');
121
+ expect(result).toEqual([[1, 2, "three"]]);
122
+ });
123
+
124
+ test("parses JSON object", () => {
125
+ const result = parseArg('{"key": "value", "n": 42}');
126
+ expect(result).toEqual([{key: "value", n: 42}]);
127
+ });
128
+
129
+ test("parses nested JSON with address strings", () => {
130
+ const result = parseArg('{"to": "0x6857Ed54CbafaA74Fc0357145eC0ee1536ca45A0", "amount": 100}');
131
+ expect(result).toHaveLength(1);
132
+ const obj = result[0] as any;
133
+ expect(obj.to).toBeInstanceOf(CalldataAddress);
134
+ expect(obj.amount).toBe(100);
135
+ });
136
+
137
+ test("parses 0x address as CalldataAddress", () => {
138
+ const result = parseArg("0x6857Ed54CbafaA74Fc0357145eC0ee1536ca45A0");
139
+ expect(result).toHaveLength(1);
140
+ expect(result[0]).toBeInstanceOf(CalldataAddress);
141
+ });
142
+
143
+ test("accumulates with previous args", () => {
144
+ const result = parseArg("42", ["existing"]);
145
+ expect(result).toEqual(["existing", 42]);
146
+ });
147
+
148
+ test("treats invalid JSON as plain string", () => {
149
+ expect(parseArg("{not json}")).toEqual(["{not json}"]);
150
+ });
151
+
152
+ test("quoted string stays as string with quotes", () => {
153
+ // '"hello"' has literal quote chars — treated as a plain string, not JSON-unwrapped
154
+ expect(parseArg('"hello"')).toEqual(['"hello"']);
155
+ });
156
+ });
@@ -0,0 +1,142 @@
1
+ import {Command} from "commander";
2
+ import {ReceiptAction} from "../../src/commands/transactions/receipt";
3
+ import {vi, describe, beforeEach, afterEach, test, expect} from "vitest";
4
+ import {initializeTransactionsCommands} from "../../src/commands/transactions";
5
+
6
+ vi.mock("../../src/commands/transactions/receipt");
7
+
8
+ describe("receipt command", () => {
9
+ let program: Command;
10
+ const mockTxId = "0x1234567890123456789012345678901234567890123456789012345678901234";
11
+
12
+ beforeEach(() => {
13
+ program = new Command();
14
+ initializeTransactionsCommands(program);
15
+ vi.clearAllMocks();
16
+ });
17
+
18
+ afterEach(() => {
19
+ vi.restoreAllMocks();
20
+ });
21
+
22
+ test("ReceiptAction.receipt is called with default options", async () => {
23
+ program.parse(["node", "test", "receipt", mockTxId]);
24
+ expect(ReceiptAction).toHaveBeenCalledTimes(1);
25
+ expect(ReceiptAction.prototype.receipt).toHaveBeenCalledWith({
26
+ txId: mockTxId,
27
+ status: "FINALIZED",
28
+ retries: 100,
29
+ interval: 5000,
30
+ });
31
+ });
32
+
33
+ test("ReceiptAction.receipt is called with custom options", async () => {
34
+ program.parse([
35
+ "node",
36
+ "test",
37
+ "receipt",
38
+ mockTxId,
39
+ "--status",
40
+ "ACCEPTED",
41
+ "--retries",
42
+ "50",
43
+ "--interval",
44
+ "3000",
45
+ "--rpc",
46
+ "https://custom-rpc-url-for-receipt.com",
47
+ ]);
48
+ expect(ReceiptAction).toHaveBeenCalledTimes(1);
49
+ expect(ReceiptAction.prototype.receipt).toHaveBeenCalledWith({
50
+ txId: mockTxId,
51
+ status: "ACCEPTED",
52
+ retries: 50,
53
+ interval: 3000,
54
+ rpc: "https://custom-rpc-url-for-receipt.com",
55
+ });
56
+ });
57
+
58
+ test("ReceiptAction is instantiated when the receipt command is executed", async () => {
59
+ program.parse(["node", "test", "receipt", mockTxId]);
60
+ expect(ReceiptAction).toHaveBeenCalledTimes(1);
61
+ });
62
+
63
+ test("throws error for unrecognized options", async () => {
64
+ const receiptCommand = program.commands.find(cmd => cmd.name() === "receipt");
65
+ receiptCommand?.exitOverride();
66
+ expect(() =>
67
+ program.parse(["node", "test", "receipt", mockTxId, "--invalid-option"]),
68
+ ).toThrowError("error: unknown option '--invalid-option'");
69
+ });
70
+
71
+ test("parses numeric options correctly", async () => {
72
+ program.parse([
73
+ "node",
74
+ "test",
75
+ "receipt",
76
+ mockTxId,
77
+ "--retries",
78
+ "25",
79
+ "--interval",
80
+ "1000",
81
+ ]);
82
+ expect(ReceiptAction.prototype.receipt).toHaveBeenCalledWith({
83
+ txId: mockTxId,
84
+ status: "FINALIZED",
85
+ retries: 25,
86
+ interval: 1000,
87
+ });
88
+ });
89
+
90
+ test("uses fallback value for invalid numeric options", async () => {
91
+ program.parse([
92
+ "node",
93
+ "test",
94
+ "receipt",
95
+ mockTxId,
96
+ "--retries",
97
+ "invalid",
98
+ "--interval",
99
+ "notanumber",
100
+ ]);
101
+ expect(ReceiptAction.prototype.receipt).toHaveBeenCalledWith({
102
+ txId: mockTxId,
103
+ status: "FINALIZED",
104
+ retries: 100,
105
+ interval: 5000,
106
+ });
107
+ });
108
+
109
+ test("parses --stdout flag", async () => {
110
+ program.parse(["node", "test", "receipt", mockTxId, "--stdout"]);
111
+ expect(ReceiptAction.prototype.receipt).toHaveBeenCalledWith({
112
+ txId: mockTxId,
113
+ status: "FINALIZED",
114
+ retries: 100,
115
+ interval: 5000,
116
+ stdout: true,
117
+ });
118
+ });
119
+
120
+ test("parses --stderr flag", async () => {
121
+ program.parse(["node", "test", "receipt", mockTxId, "--stderr"]);
122
+ expect(ReceiptAction.prototype.receipt).toHaveBeenCalledWith({
123
+ txId: mockTxId,
124
+ status: "FINALIZED",
125
+ retries: 100,
126
+ interval: 5000,
127
+ stderr: true,
128
+ });
129
+ });
130
+
131
+ test("parses both --stdout and --stderr flags", async () => {
132
+ program.parse(["node", "test", "receipt", mockTxId, "--stdout", "--stderr"]);
133
+ expect(ReceiptAction.prototype.receipt).toHaveBeenCalledWith({
134
+ txId: mockTxId,
135
+ status: "FINALIZED",
136
+ retries: 100,
137
+ interval: 5000,
138
+ stdout: true,
139
+ stderr: true,
140
+ });
141
+ });
142
+ });