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,80 @@
1
+ import { describe, test, vi, beforeEach, afterEach, expect } from "vitest";
2
+ import fs from "fs-extra";
3
+ import path from "path";
4
+ import { NewAction } from "../../src/commands/scaffold/new";
5
+
6
+ vi.mock("fs-extra");
7
+
8
+ describe("NewAction", () => {
9
+ let newAction: NewAction;
10
+ let mockExistsSync: any;
11
+ let mockCopySync: any;
12
+
13
+ beforeEach(() => {
14
+ vi.clearAllMocks();
15
+ newAction = new NewAction();
16
+
17
+ mockExistsSync = vi.mocked(fs.existsSync);
18
+ mockCopySync = vi.mocked(fs.copySync);
19
+
20
+ vi.spyOn(newAction as any, "startSpinner").mockImplementation(() => {});
21
+ vi.spyOn(newAction as any, "succeedSpinner").mockImplementation(() => {});
22
+ vi.spyOn(newAction as any, "failSpinner").mockImplementation(() => {});
23
+ });
24
+
25
+ afterEach(() => {
26
+ vi.restoreAllMocks();
27
+ });
28
+
29
+ test("should successfully create a new project", async () => {
30
+ mockExistsSync.mockReturnValue(false);
31
+ mockCopySync.mockImplementation(() => {});
32
+
33
+ await newAction.createProject("myProject", { path: ".", overwrite: false });
34
+
35
+ expect(newAction["startSpinner"]).toHaveBeenCalledWith("Creating new GenLayer project: myProject");
36
+ expect(mockCopySync).toHaveBeenCalledWith(expect.any(String), path.resolve(".", "myProject"));
37
+ expect(newAction["succeedSpinner"]).toHaveBeenCalledWith(
38
+ `Project "myProject" created successfully at ${path.resolve(".", "myProject")}`
39
+ );
40
+ });
41
+
42
+ test("should fail if project directory exists and overwrite is not set", async () => {
43
+ mockExistsSync.mockReturnValue(true);
44
+
45
+ await newAction.createProject("existingProject", { path: ".", overwrite: false });
46
+
47
+ expect(newAction["failSpinner"]).toHaveBeenCalledWith(
48
+ `Project directory "${path.resolve(".", "existingProject")}" already exists. Use --overwrite to replace it.`
49
+ );
50
+ expect(mockCopySync).not.toHaveBeenCalled();
51
+ });
52
+
53
+ test("should overwrite existing project if overwrite is set", async () => {
54
+ mockExistsSync.mockReturnValue(true);
55
+ mockCopySync.mockImplementation(() => {});
56
+
57
+ await newAction.createProject("overwriteProject", { path: ".", overwrite: true });
58
+
59
+ expect(newAction["startSpinner"]).toHaveBeenCalledWith("Creating new GenLayer project: overwriteProject");
60
+ expect(mockCopySync).toHaveBeenCalledWith(expect.any(String), path.resolve(".", "overwriteProject"));
61
+ expect(newAction["succeedSpinner"]).toHaveBeenCalledWith(
62
+ `Project "overwriteProject" created successfully at ${path.resolve(".", "overwriteProject")}`
63
+ );
64
+ });
65
+
66
+ test("should fail if an error occurs while copying files", async () => {
67
+ mockExistsSync.mockReturnValue(false);
68
+ const error = new Error("Mocked file system error");
69
+ mockCopySync.mockImplementation(() => {
70
+ throw error;
71
+ });
72
+
73
+ await newAction.createProject("errorProject", { path: ".", overwrite: false });
74
+
75
+ expect(newAction["failSpinner"]).toHaveBeenCalledWith(
76
+ "Error creating project \"errorProject\"",
77
+ error
78
+ );
79
+ });
80
+ });
@@ -0,0 +1,193 @@
1
+ import { describe, test, vi, beforeEach, afterEach, expect, Mock } from "vitest";
2
+ import { OllamaAction } from "../../src/commands/update/ollama";
3
+ import { rpcClient } from "../../src/lib/clients/jsonRpcClient";
4
+ import Docker from "dockerode";
5
+
6
+ vi.mock("dockerode");
7
+ vi.mock("../../src/lib/clients/jsonRpcClient");
8
+
9
+ describe("OllamaAction", () => {
10
+ let ollamaAction: OllamaAction;
11
+ let mockGetContainer: Mock;
12
+ let mockExec: Mock;
13
+ let mockStart: Mock;
14
+ let mockStream: any;
15
+
16
+ beforeEach(() => {
17
+ vi.clearAllMocks();
18
+ ollamaAction = new OllamaAction();
19
+
20
+ mockGetContainer = vi.mocked(Docker.prototype.getContainer);
21
+ mockExec = vi.fn();
22
+ mockStart = vi.fn();
23
+
24
+ mockStream = {
25
+ on: vi.fn(),
26
+ };
27
+
28
+ mockExec.mockResolvedValue({
29
+ start: mockStart,
30
+ });
31
+
32
+ mockStart.mockResolvedValue(mockStream);
33
+
34
+ mockGetContainer.mockReturnValue({
35
+ exec: mockExec,
36
+ } as unknown as Docker.Container);
37
+
38
+ Docker.prototype.getContainer = mockGetContainer;
39
+
40
+ vi.spyOn(ollamaAction as any, "startSpinner").mockImplementation(() => {});
41
+ vi.spyOn(ollamaAction as any, "setSpinnerText").mockImplementation(() => {});
42
+ vi.spyOn(ollamaAction as any, "succeedSpinner").mockImplementation(() => {});
43
+ vi.spyOn(ollamaAction as any, "failSpinner").mockImplementation(() => {});
44
+ });
45
+
46
+ afterEach(() => {
47
+ vi.restoreAllMocks();
48
+ });
49
+
50
+ test("should update the model using 'pull'", async () => {
51
+ const mockProvider = {
52
+ plugin: "ollama",
53
+ config: { key: "value" },
54
+ plugin_config: { pluginKey: "pluginValue" },
55
+ };
56
+
57
+ vi.mocked(rpcClient.request).mockResolvedValueOnce({
58
+ result: [mockProvider],
59
+ });
60
+
61
+ mockStream.on.mockImplementation((event: any, callback: any) => {
62
+ if (event === "data") {
63
+ callback(Buffer.from("Mocked output success"));
64
+ }
65
+ if (event === "end") {
66
+ callback();
67
+ }
68
+ });
69
+
70
+ await ollamaAction.updateModel("mocked_model");
71
+
72
+ expect(ollamaAction["startSpinner"]).toHaveBeenCalledWith(`Updating model "mocked_model"...`);
73
+ expect(mockGetContainer).toHaveBeenCalledWith("genlayer-ollama");
74
+ expect(mockExec).toHaveBeenCalledWith({
75
+ Cmd: ["ollama", "pull", "mocked_model"],
76
+ AttachStdout: true,
77
+ AttachStderr: true,
78
+ });
79
+ expect(mockStart).toHaveBeenCalledWith({ Detach: false, Tty: false });
80
+ expect(ollamaAction["setSpinnerText"]).toHaveBeenCalledWith("Mocked output success");
81
+ expect(ollamaAction["succeedSpinner"]).toHaveBeenCalledWith(`Model "mocked_model" updated successfully`);
82
+ });
83
+
84
+ test("should remove the model using 'rm'", async () => {
85
+ mockStream.on.mockImplementation((event: any, callback: any) => {
86
+ if (event === "data") {
87
+ callback(Buffer.from("Mocked output success"));
88
+ }
89
+ if (event === "end") {
90
+ callback();
91
+ }
92
+ });
93
+
94
+ await ollamaAction.removeModel("mocked_model");
95
+
96
+ expect(ollamaAction["startSpinner"]).toHaveBeenCalledWith(`Executing 'rm' command on model "mocked_model"...`);
97
+ expect(mockGetContainer).toHaveBeenCalledWith("genlayer-ollama");
98
+ expect(mockExec).toHaveBeenCalledWith({
99
+ Cmd: ["ollama", "rm", "mocked_model"],
100
+ AttachStdout: true,
101
+ AttachStderr: true,
102
+ });
103
+ expect(mockStart).toHaveBeenCalledWith({ Detach: false, Tty: false });
104
+ expect(ollamaAction["setSpinnerText"]).toHaveBeenCalledWith("Mocked output success");
105
+ expect(ollamaAction["succeedSpinner"]).toHaveBeenCalledWith(`Model "mocked_model" removed successfully`);
106
+ });
107
+
108
+ test("should log an error if an exception occurs during 'pull'", async () => {
109
+ const mockProvider = {
110
+ plugin: "ollama",
111
+ config: { key: "value" },
112
+ plugin_config: { pluginKey: "pluginValue" },
113
+ };
114
+
115
+ vi.mocked(rpcClient.request).mockResolvedValueOnce({
116
+ result: [mockProvider],
117
+ });
118
+
119
+ const error = new Error("Mocked error");
120
+ mockExec.mockRejectedValue(error);
121
+
122
+ await ollamaAction.updateModel("mocked_model");
123
+
124
+ expect(ollamaAction["failSpinner"]).toHaveBeenCalledWith(`Error executing command "pull" on model "mocked_model"`, error);
125
+ });
126
+
127
+ test("should log an error if an exception occurs during 'rm'", async () => {
128
+ const error = new Error("Mocked error");
129
+ mockExec.mockRejectedValue(error);
130
+
131
+ await ollamaAction.removeModel("mocked_model");
132
+
133
+ expect(ollamaAction["failSpinner"]).toHaveBeenCalledWith(`Error executing command "rm" on model "mocked_model"`, error);
134
+ });
135
+
136
+ test("should throw an error if no 'ollama' provider exists during updateModel", async () => {
137
+ vi.mocked(rpcClient.request).mockResolvedValueOnce({
138
+ result: [],
139
+ });
140
+
141
+ await ollamaAction.updateModel("mocked_model");
142
+
143
+ expect(ollamaAction["failSpinner"]).toHaveBeenCalledWith(
144
+ "No existing 'ollama' provider found. Unable to add/update a model."
145
+ );
146
+ });
147
+
148
+ test("should reject with an error if success is not set to true", async () => {
149
+ const mockProvider = {
150
+ plugin: "ollama",
151
+ config: { key: "value" },
152
+ plugin_config: { pluginKey: "pluginValue" },
153
+ };
154
+
155
+ vi.mocked(rpcClient.request).mockResolvedValueOnce({
156
+ result: [mockProvider],
157
+ });
158
+
159
+ mockStream.on.mockImplementation((event: any, callback: any) => {
160
+ if (event === "data") {
161
+ callback(Buffer.from("Mocked output failure"));
162
+ }
163
+ if (event === "end") {
164
+ callback();
165
+ }
166
+ });
167
+
168
+ await ollamaAction.updateModel("mocked_model");
169
+
170
+ expect(ollamaAction["failSpinner"]).toHaveBeenCalledWith(
171
+ `Failed to execute 'pull' on model "mocked_model".`
172
+ );
173
+ });
174
+
175
+ test("should log an error if an exception occurs inside updateModel", async () => {
176
+ const mockError = new Error("Mocked error");
177
+
178
+ vi.mocked(rpcClient.request).mockRejectedValue(mockError);
179
+
180
+ await ollamaAction.updateModel("mocked_model");
181
+
182
+ expect(ollamaAction["failSpinner"]).toHaveBeenCalledWith(`Error updating model "mocked_model"`, mockError);
183
+ });
184
+
185
+ test("should call get config if modelName is empty", async () => {
186
+ const defaultModel = "default_model";
187
+ vi.spyOn(ollamaAction as any, "getConfig").mockReturnValue({ defaultOllamaModel: defaultModel });
188
+
189
+ await ollamaAction.updateModel("");
190
+ expect(ollamaAction.getConfig).toHaveBeenCalledTimes(1);
191
+ });
192
+
193
+ });
@@ -0,0 +1,261 @@
1
+ import {describe, test, vi, beforeEach, afterEach, expect} from "vitest";
2
+ import {createClient, createAccount} from "genlayer-js";
3
+ import type {TransactionHash} from "genlayer-js/types";
4
+ import {TransactionStatus} from "genlayer-js/types";
5
+ import {ReceiptAction, type ReceiptParams} from "../../src/commands/transactions/receipt";
6
+
7
+ vi.mock("genlayer-js");
8
+
9
+ describe("ReceiptAction", () => {
10
+ let receiptAction: ReceiptAction;
11
+ const mockClient = {
12
+ waitForTransactionReceipt: vi.fn(),
13
+ initializeConsensusSmartContract: vi.fn(),
14
+ };
15
+
16
+ const mockPrivateKey = "mocked_private_key";
17
+ const mockTxId = "0x1234567890123456789012345678901234567890123456789012345678901234" as TransactionHash;
18
+ const defaultRetries = 100;
19
+ const defaultInterval = 5000;
20
+
21
+ beforeEach(() => {
22
+ vi.clearAllMocks();
23
+ vi.mocked(createClient).mockReturnValue(mockClient as any);
24
+ vi.mocked(createAccount).mockReturnValue({privateKey: mockPrivateKey} as any);
25
+ receiptAction = new ReceiptAction();
26
+ vi.spyOn(receiptAction as any, "getAccount").mockResolvedValue({privateKey: mockPrivateKey});
27
+
28
+ vi.spyOn(receiptAction as any, "startSpinner").mockImplementation(() => {});
29
+ vi.spyOn(receiptAction as any, "succeedSpinner").mockImplementation(() => {});
30
+ vi.spyOn(receiptAction as any, "failSpinner").mockImplementation(() => {});
31
+ });
32
+
33
+ afterEach(() => {
34
+ vi.restoreAllMocks();
35
+ });
36
+
37
+ test("retrieves transaction receipt successfully with default options", async () => {
38
+ const mockReceipt = {status: "FINALIZED", data: {hash: mockTxId}};
39
+
40
+ vi.mocked(mockClient.waitForTransactionReceipt).mockResolvedValue(mockReceipt);
41
+
42
+ await receiptAction.receipt({
43
+ txId: mockTxId,
44
+ retries: defaultRetries,
45
+ interval: defaultInterval,
46
+ });
47
+
48
+ expect(mockClient.waitForTransactionReceipt).toHaveBeenCalledWith({
49
+ hash: mockTxId,
50
+ status: TransactionStatus.FINALIZED,
51
+ retries: defaultRetries,
52
+ interval: defaultInterval,
53
+ });
54
+ expect(receiptAction["succeedSpinner"]).toHaveBeenCalledWith(
55
+ "Transaction receipt retrieved successfully",
56
+ mockReceipt,
57
+ );
58
+ });
59
+
60
+ test("retrieves transaction receipt with custom options", async () => {
61
+ const mockReceipt = {status: "ACCEPTED", data: {hash: mockTxId}};
62
+
63
+ vi.mocked(mockClient.waitForTransactionReceipt).mockResolvedValue(mockReceipt);
64
+
65
+ await receiptAction.receipt({
66
+ txId: mockTxId,
67
+ status: "ACCEPTED",
68
+ retries: 50,
69
+ interval: 3000,
70
+ });
71
+
72
+ expect(mockClient.waitForTransactionReceipt).toHaveBeenCalledWith({
73
+ hash: mockTxId,
74
+ status: TransactionStatus.ACCEPTED,
75
+ retries: 50,
76
+ interval: 3000,
77
+ });
78
+ expect(receiptAction["succeedSpinner"]).toHaveBeenCalledWith(
79
+ "Transaction receipt retrieved successfully",
80
+ mockReceipt,
81
+ );
82
+ });
83
+
84
+ test("handles waitForTransactionReceipt errors", async () => {
85
+ vi.mocked(mockClient.waitForTransactionReceipt).mockRejectedValue(new Error("Mocked receipt error"));
86
+
87
+ await receiptAction.receipt({
88
+ txId: mockTxId,
89
+ retries: defaultRetries,
90
+ interval: defaultInterval,
91
+ });
92
+
93
+ expect(receiptAction["failSpinner"]).toHaveBeenCalledWith(
94
+ "Error retrieving transaction receipt",
95
+ expect.any(Error),
96
+ );
97
+ });
98
+
99
+ test("uses custom RPC URL for receipt operations", async () => {
100
+ const rpcUrl = "https://custom-rpc-url.com";
101
+ const mockReceipt = {status: "FINALIZED", data: {hash: mockTxId}};
102
+
103
+ vi.mocked(mockClient.waitForTransactionReceipt).mockResolvedValue(mockReceipt);
104
+
105
+ await receiptAction.receipt({
106
+ txId: mockTxId,
107
+ retries: defaultRetries,
108
+ interval: defaultInterval,
109
+ rpc: rpcUrl,
110
+ });
111
+
112
+ expect(createClient).toHaveBeenCalledWith(
113
+ expect.objectContaining({
114
+ endpoint: rpcUrl,
115
+ }),
116
+ );
117
+ expect(mockClient.waitForTransactionReceipt).toHaveBeenCalledWith({
118
+ hash: mockTxId,
119
+ status: TransactionStatus.FINALIZED,
120
+ retries: defaultRetries,
121
+ interval: defaultInterval,
122
+ });
123
+ expect(receiptAction["succeedSpinner"]).toHaveBeenCalledWith(
124
+ "Transaction receipt retrieved successfully",
125
+ mockReceipt,
126
+ );
127
+ });
128
+
129
+ test("validates transaction status and shows error for invalid status", async () => {
130
+ await receiptAction.receipt({
131
+ txId: mockTxId,
132
+ status: "INVALID_STATUS",
133
+ retries: defaultRetries,
134
+ interval: defaultInterval,
135
+ });
136
+
137
+ expect(receiptAction["failSpinner"]).toHaveBeenCalledWith(
138
+ "Invalid transaction status",
139
+ expect.stringContaining("Invalid status: INVALID_STATUS")
140
+ );
141
+
142
+ expect(mockClient.waitForTransactionReceipt).not.toHaveBeenCalled();
143
+ });
144
+
145
+ test("accepts valid transaction statuses", async () => {
146
+ const mockReceipt = {status: "PENDING", data: {hash: mockTxId}};
147
+ vi.mocked(mockClient.waitForTransactionReceipt).mockResolvedValue(mockReceipt);
148
+
149
+ const testStatuses = [
150
+ {input: "accepted", expected: TransactionStatus.ACCEPTED},
151
+ {input: "FINALIZED", expected: TransactionStatus.FINALIZED},
152
+ {input: "pending", expected: TransactionStatus.PENDING},
153
+ {input: "COMMITTING", expected: TransactionStatus.COMMITTING},
154
+ ];
155
+
156
+ for (const {input, expected} of testStatuses) {
157
+ await receiptAction.receipt({
158
+ txId: mockTxId,
159
+ status: input,
160
+ retries: defaultRetries,
161
+ interval: defaultInterval,
162
+ });
163
+
164
+ expect(mockClient.waitForTransactionReceipt).toHaveBeenCalledWith({
165
+ hash: mockTxId,
166
+ status: expected,
167
+ retries: defaultRetries,
168
+ interval: defaultInterval,
169
+ });
170
+ }
171
+ });
172
+
173
+ test("prints only stdout when --stdout is provided", async () => {
174
+ const mockReceipt = {
175
+ consensus_data: {
176
+ leader_receipt: [
177
+ {
178
+ genvm_result: {
179
+ stdout: "program stdout",
180
+ stderr: "program stderr",
181
+ },
182
+ },
183
+ ],
184
+ },
185
+ };
186
+
187
+ vi.mocked(mockClient.waitForTransactionReceipt).mockResolvedValue(mockReceipt as any);
188
+
189
+ await receiptAction.receipt({
190
+ txId: mockTxId,
191
+ retries: defaultRetries,
192
+ interval: defaultInterval,
193
+ stdout: true,
194
+ } as ReceiptParams);
195
+
196
+ expect(receiptAction["succeedSpinner"]).toHaveBeenCalledWith(
197
+ "Transaction stdout retrieved successfully",
198
+ "program stdout",
199
+ );
200
+ });
201
+
202
+ test("prints only stderr when --stderr is provided", async () => {
203
+ const mockReceipt = {
204
+ consensus_data: {
205
+ leader_receipt: [
206
+ {
207
+ genvm_result: {
208
+ stdout: "program stdout",
209
+ stderr: "program stderr",
210
+ },
211
+ },
212
+ ],
213
+ },
214
+ };
215
+
216
+ vi.mocked(mockClient.waitForTransactionReceipt).mockResolvedValue(mockReceipt as any);
217
+
218
+ await receiptAction.receipt({
219
+ txId: mockTxId,
220
+ retries: defaultRetries,
221
+ interval: defaultInterval,
222
+ stderr: true,
223
+ } as ReceiptParams);
224
+
225
+ expect(receiptAction["succeedSpinner"]).toHaveBeenCalledWith(
226
+ "Transaction stderr retrieved successfully",
227
+ "program stderr",
228
+ );
229
+ });
230
+
231
+ test("prints both stdout and stderr when both flags are provided", async () => {
232
+ const mockReceipt = {
233
+ consensus_data: {
234
+ leader_receipt: [
235
+ {
236
+ genvm_result: {
237
+ stdout: "program stdout",
238
+ stderr: "program stderr",
239
+ },
240
+ },
241
+ ],
242
+ },
243
+ };
244
+
245
+ vi.mocked(mockClient.waitForTransactionReceipt).mockResolvedValue(mockReceipt as any);
246
+
247
+ await receiptAction.receipt({
248
+ txId: mockTxId,
249
+ retries: defaultRetries,
250
+ interval: defaultInterval,
251
+ stdout: true,
252
+ stderr: true,
253
+ } as ReceiptParams);
254
+
255
+ expect(receiptAction["succeedSpinner"]).toHaveBeenCalledWith(
256
+ "Transaction stdout and stderr",
257
+ { stdout: "program stdout", stderr: "program stderr" },
258
+ );
259
+ });
260
+
261
+ });
@@ -0,0 +1,94 @@
1
+ import {describe, test, vi, beforeEach, afterEach, expect} from "vitest";
2
+ import {createClient, createAccount} from "genlayer-js";
3
+ import {SchemaAction} from "../../src/commands/contracts/schema";
4
+
5
+ vi.mock("genlayer-js");
6
+
7
+ describe("SchemaAction", () => {
8
+ let schemaAction: SchemaAction;
9
+ const mockClient = {
10
+ getContractSchema: vi.fn(),
11
+ initializeConsensusSmartContract: vi.fn(),
12
+ };
13
+
14
+ const mockPrivateKey = "mocked_private_key";
15
+
16
+ beforeEach(() => {
17
+ vi.clearAllMocks();
18
+ vi.mocked(createClient).mockReturnValue(mockClient as any);
19
+ vi.mocked(createAccount).mockReturnValue({privateKey: mockPrivateKey} as any);
20
+ schemaAction = new SchemaAction();
21
+ vi.spyOn(schemaAction as any, "getAccount").mockResolvedValue({privateKey: mockPrivateKey});
22
+
23
+ vi.spyOn(schemaAction as any, "startSpinner").mockImplementation(() => {});
24
+ vi.spyOn(schemaAction as any, "succeedSpinner").mockImplementation(() => {});
25
+ vi.spyOn(schemaAction as any, "failSpinner").mockImplementation(() => {});
26
+ vi.spyOn(schemaAction as any, "log").mockImplementation(() => {});
27
+ });
28
+
29
+ afterEach(() => {
30
+ vi.restoreAllMocks();
31
+ });
32
+
33
+ test("gets contract schema successfully", async () => {
34
+ const mockResult = {
35
+ methods: {
36
+ getData: {
37
+ params: [["value", "int"]],
38
+ ret: "int",
39
+ readonly: true,
40
+ },
41
+ },
42
+ };
43
+
44
+ vi.mocked(mockClient.getContractSchema).mockResolvedValue(mockResult);
45
+
46
+ await schemaAction.schema({
47
+ contractAddress: "0xMockedContract",
48
+ });
49
+
50
+ expect(mockClient.getContractSchema).toHaveBeenCalledWith("0xMockedContract");
51
+ expect(schemaAction["succeedSpinner"]).toHaveBeenCalledWith(
52
+ "Contract schema retrieved successfully",
53
+ mockResult,
54
+ );
55
+ });
56
+
57
+ test("handles getContractSchema errors", async () => {
58
+ vi.mocked(mockClient.getContractSchema).mockRejectedValue(new Error("Mocked schema error"));
59
+
60
+ await schemaAction.schema({contractAddress: "0xMockedContract"});
61
+
62
+ expect(schemaAction["failSpinner"]).toHaveBeenCalledWith("Error retrieving contract schema", expect.any(Error));
63
+ });
64
+
65
+ test("uses custom RPC URL when provided", async () => {
66
+ const mockResult = {methods: {}};
67
+ vi.mocked(mockClient.getContractSchema).mockResolvedValue(mockResult);
68
+
69
+ await schemaAction.schema({
70
+ contractAddress: "0xMockedContract",
71
+ rpc: "https://custom-rpc-url.com",
72
+ });
73
+
74
+ expect(createClient).toHaveBeenCalledWith(
75
+ expect.objectContaining({
76
+ endpoint: "https://custom-rpc-url.com",
77
+ }),
78
+ );
79
+ expect(mockClient.getContractSchema).toHaveBeenCalledWith("0xMockedContract");
80
+ expect(schemaAction["succeedSpinner"]).toHaveBeenCalledWith(
81
+ "Contract schema retrieved successfully",
82
+ mockResult,
83
+ );
84
+ });
85
+
86
+ test("initializes consensus smart contract", async () => {
87
+ const mockResult = {methods: {}};
88
+ vi.mocked(mockClient.getContractSchema).mockResolvedValue(mockResult);
89
+
90
+ await schemaAction.schema({contractAddress: "0xMockedContract"});
91
+
92
+ expect(mockClient.initializeConsensusSmartContract).toHaveBeenCalled();
93
+ });
94
+ });