movehat 0.1.2 → 0.1.4

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 (63) hide show
  1. package/README.md +159 -80
  2. package/bin/movehat.js +10 -0
  3. package/dist/commands/run.d.ts.map +1 -1
  4. package/dist/commands/run.js +40 -3
  5. package/dist/commands/run.js.map +1 -1
  6. package/dist/core/AccountManager.d.ts +186 -0
  7. package/dist/core/AccountManager.d.ts.map +1 -0
  8. package/dist/core/AccountManager.js +363 -0
  9. package/dist/core/AccountManager.js.map +1 -0
  10. package/dist/fork/manager.d.ts +33 -0
  11. package/dist/fork/manager.d.ts.map +1 -1
  12. package/dist/fork/manager.js +61 -0
  13. package/dist/fork/manager.js.map +1 -1
  14. package/dist/fork/storage.d.ts +10 -0
  15. package/dist/fork/storage.d.ts.map +1 -1
  16. package/dist/fork/storage.js +28 -1
  17. package/dist/fork/storage.js.map +1 -1
  18. package/dist/helpers/index.d.ts +8 -1
  19. package/dist/helpers/index.d.ts.map +1 -1
  20. package/dist/helpers/index.js +4 -0
  21. package/dist/helpers/index.js.map +1 -1
  22. package/dist/helpers/setup.d.ts.map +1 -1
  23. package/dist/helpers/setup.js +5 -4
  24. package/dist/helpers/setup.js.map +1 -1
  25. package/dist/helpers/setupLocalTesting.d.ts +60 -0
  26. package/dist/helpers/setupLocalTesting.d.ts.map +1 -0
  27. package/dist/helpers/setupLocalTesting.js +277 -0
  28. package/dist/helpers/setupLocalTesting.js.map +1 -0
  29. package/dist/helpers/testFixtures.d.ts +115 -0
  30. package/dist/helpers/testFixtures.d.ts.map +1 -0
  31. package/dist/helpers/testFixtures.js +163 -0
  32. package/dist/helpers/testFixtures.js.map +1 -0
  33. package/dist/helpers/version-check.d.ts.map +1 -1
  34. package/dist/helpers/version-check.js +4 -0
  35. package/dist/helpers/version-check.js.map +1 -1
  36. package/dist/node/LocalNodeManager.d.ts +68 -0
  37. package/dist/node/LocalNodeManager.d.ts.map +1 -0
  38. package/dist/node/LocalNodeManager.js +237 -0
  39. package/dist/node/LocalNodeManager.js.map +1 -0
  40. package/dist/runtime.d.ts.map +1 -1
  41. package/dist/runtime.js +91 -46
  42. package/dist/runtime.js.map +1 -1
  43. package/dist/templates/README.md +17 -4
  44. package/dist/templates/move/sources/Counter.move +12 -4
  45. package/dist/templates/tests/Counter.test.ts +98 -57
  46. package/dist/types/config.d.ts +24 -0
  47. package/dist/types/config.d.ts.map +1 -1
  48. package/package.json +1 -1
  49. package/src/commands/run.ts +43 -3
  50. package/src/core/AccountManager.ts +439 -0
  51. package/src/fork/manager.ts +74 -0
  52. package/src/fork/storage.ts +33 -1
  53. package/src/helpers/index.ts +18 -1
  54. package/src/helpers/setup.ts +4 -3
  55. package/src/helpers/setupLocalTesting.ts +335 -0
  56. package/src/helpers/testFixtures.ts +222 -0
  57. package/src/helpers/version-check.ts +5 -0
  58. package/src/node/LocalNodeManager.ts +297 -0
  59. package/src/runtime.ts +108 -47
  60. package/src/templates/README.md +17 -4
  61. package/src/templates/move/sources/Counter.move +12 -4
  62. package/src/templates/tests/Counter.test.ts +98 -57
  63. package/src/types/config.ts +32 -0
package/README.md CHANGED
@@ -7,12 +7,14 @@
7
7
 
8
8
  ## Features
9
9
 
10
- - **Auto-detection of Named Addresses** - Automatically detects and configures addresses from Move code (like Hardhat)
10
+ - **Local Node Testing** - Run a real Movement blockchain locally for testing (just like Hardhat!)
11
+ - **Dual Testing Modes** - Choose between `local-node` (full blockchain) or `fork` (read-only snapshot)
12
+ - **Auto-Deploy in Tests** - Contracts deploy automatically when tests run - zero manual setup
13
+ - **setupTestFixture Helper** - High-level API for test setup with type-safe contracts
14
+ - **Auto-detection of Named Addresses** - Automatically detects and configures addresses from Move code
11
15
  - **Quick Start** - Scaffold new Move projects in seconds
12
16
  - **TypeScript Testing** - Write integration tests with familiar tools (Mocha, Chai)
13
- - **Built-in Helpers** - Interact with contracts easily
14
17
  - **Movement CLI Integration** - Seamless compilation and deployment
15
- - **Hot Reload** - Test changes instantly with watch mode
16
18
 
17
19
  ## Prerequisites
18
20
 
@@ -102,140 +104,217 @@ MH_NETWORK=testnet
102
104
 
103
105
  ## Writing Tests
104
106
 
105
- Movehat uses **Transaction Simulation** for testing - no real blockchain or gas costs required:
107
+ Movehat runs tests on a **real local Movement blockchain** (just like Hardhat!):
106
108
 
107
109
  ```typescript
108
- import { describe, it, before } from "mocha";
110
+ import { describe, it, before, after } from "mocha";
109
111
  import { expect } from "chai";
110
- import { getMovehat, type MovehatRuntime } from "movehat";
112
+ import { setupTestFixture, teardownTestFixture, type TestFixture } from "movehat/helpers";
111
113
 
112
114
  describe("Counter Contract", () => {
113
- let mh: MovehatRuntime;
114
- let contractAddress: string;
115
+ let fixture: TestFixture<'counter'>;
115
116
 
116
117
  before(async function () {
117
- this.timeout(30000);
118
+ this.timeout(60000); // Allow time for local node startup + deployment
119
+
120
+ // Setup local testing environment with auto-deployment
121
+ // This will:
122
+ // 1. Start a local Movement blockchain node
123
+ // 2. Generate and fund test accounts from local faucet
124
+ // 3. Auto-deploy the counter module
125
+ // 4. Return everything ready to use
126
+ fixture = await setupTestFixture(['counter'] as const, ['alice', 'bob']);
127
+
128
+ console.log(`\n✅ Testing on local blockchain`);
129
+ console.log(` Deployer: ${fixture.accounts.deployer.accountAddress.toString()}`);
130
+ });
131
+
132
+ it("should initialize with value 0", async () => {
133
+ const counter = fixture.contracts.counter; // Type-safe, no `!` needed
134
+ const deployer = fixture.accounts.deployer;
135
+
136
+ // Read counter value (returns string from view function)
137
+ const value = await counter.view<string>("get", [
138
+ deployer.accountAddress.toString()
139
+ ]);
140
+
141
+ expect(parseInt(value)).to.equal(0);
142
+ });
118
143
 
119
- // Initialize Movehat Runtime Environment
120
- // Uses Movement testnet by default with auto-generated test accounts
121
- mh = await getMovehat();
122
- contractAddress = mh.account.accountAddress.toString();
144
+ it("should increment counter", async () => {
145
+ const counter = fixture.contracts.counter;
146
+ const deployer = fixture.accounts.deployer;
147
+
148
+ // Increment the counter (real transaction on local blockchain!)
149
+ const tx = await counter.call(deployer, "increment", []);
150
+ console.log(` Transaction: ${tx.hash}`);
151
+
152
+ // Read new value
153
+ const value = await counter.view<string>("get", [
154
+ deployer.accountAddress.toString()
155
+ ]);
156
+
157
+ expect(parseInt(value)).to.equal(1);
123
158
  });
124
159
 
125
- it("should initialize counter using simulation", async function () {
126
- this.timeout(30000);
127
-
128
- // Build transaction
129
- const transaction = await mh.aptos.transaction.build.simple({
130
- sender: mh.account.accountAddress,
131
- data: {
132
- function: `${contractAddress}::counter::init`,
133
- functionArguments: []
134
- }
135
- });
136
-
137
- // Simulate transaction (no gas cost, instant)
138
- const [simulation] = await mh.aptos.transaction.simulate.simple({
139
- signerPublicKey: mh.account.publicKey,
140
- transaction
141
- });
142
-
143
- // Verify simulation succeeded
144
- expect(simulation.success).to.be.true;
145
- console.log(`Gas used: ${simulation.gas_used}`);
160
+ after(async () => {
161
+ // Cleanup: Stop local node and clear account pool
162
+ await teardownTestFixture();
146
163
  });
147
164
  });
148
165
  ```
149
166
 
150
- **Benefits of Transaction Simulation:**
151
- - No blockchain or fork server required
152
- - Instant test execution
153
- - No gas costs
154
- - Perfect for TDD and CI/CD
155
- - Uses Movement testnet with auto-generated accounts by default
167
+ **Benefits of Local Node Testing:**
168
+ - Real blockchain with actual state changes
169
+ - Test real transactions (not just simulations)
170
+ - Auto-deploy contracts for each test run
171
+ - Type-safe contract access (no `!` operator needed)
172
+ - Automatic cleanup after tests
173
+ - Just like Hardhat - zero manual setup
156
174
 
157
175
  ## Writing Deployment Scripts
158
176
 
159
177
  ```typescript
160
- import { setupTestEnvironment, getContract } from "movehat/helpers";
178
+ import { getMovehat } from "movehat";
161
179
 
162
180
  async function main() {
163
- console.log("Deploying Counter contract...\n");
164
-
165
- const env = await setupTestEnvironment();
166
-
167
- const counter = getContract(
168
- env.aptos,
169
- env.account.accountAddress.toString(),
170
- "counter"
171
- );
172
-
173
- console.log(`Contract address: ${env.account.accountAddress.toString()}::counter`);
174
-
181
+ const mh = await getMovehat();
182
+
183
+ console.log("Deploying from:", mh.account.accountAddress.toString());
184
+ console.log("Network:", mh.config.network);
185
+
186
+ // Deploy (publish) the module
187
+ // Movehat automatically checks if already deployed
188
+ const deployment = await mh.deployContract("counter");
189
+
190
+ console.log("Module deployed at:", deployment.address);
191
+ console.log("Transaction:", deployment.txHash);
192
+
193
+ // Get contract instance
194
+ const contract = mh.getContract(deployment.address, "counter");
195
+
175
196
  // Initialize the counter
176
- console.log("\nInitializing counter...");
177
- const txResult = await counter.call(env.account, "init", []);
178
-
179
- console.log(`Transaction hash: ${txResult.hash}`);
180
- console.log(`Counter initialized successfully!`);
181
-
197
+ await contract.call(mh.account, "init", []);
198
+
199
+ console.log("Counter initialized!");
200
+
182
201
  // Verify
183
- const value = await counter.view<number>("get", [
184
- env.account.accountAddress.toString()
202
+ const value = await contract.view<string>("get", [
203
+ mh.account.accountAddress.toString()
185
204
  ]);
186
-
205
+
187
206
  console.log(`Initial counter value: ${value}`);
188
207
  }
189
208
 
190
209
  main().catch((error) => {
191
- console.error("Deployment failed:", error);
210
+ console.error(error);
192
211
  process.exit(1);
193
212
  });
194
213
  ```
195
214
 
196
215
  ## API Reference
197
216
 
198
- ### Helpers
217
+ ### Testing Helpers
199
218
 
200
- #### `setupTestEnvironment()`
219
+ #### `setupTestFixture(modules, accountLabels, options?)`
201
220
 
202
- Sets up the test environment with Aptos client and account.
221
+ High-level API for setting up local testing with auto-deployment. Returns type-safe fixture with contracts and accounts.
203
222
 
204
223
  ```typescript
205
- const env = await setupTestEnvironment();
206
- // Returns: { aptos: Aptos, account: Account, config: MovehatConfig }
224
+ // Setup with type inference
225
+ const fixture = await setupTestFixture(
226
+ ['counter'] as const, // Modules to deploy
227
+ ['alice', 'bob'] // Additional account labels
228
+ );
229
+
230
+ // Access type-safe contracts (no `!` needed)
231
+ const counter = fixture.contracts.counter;
232
+
233
+ // Access accounts
234
+ const deployer = fixture.accounts.deployer;
235
+ const alice = fixture.accounts.alice;
236
+
237
+ // Options (all optional)
238
+ const fixture = await setupTestFixture(['counter'] as const, ['alice'], {
239
+ mode: 'fork', // 'local-node' (default) or 'fork'
240
+ defaultBalance: 100_000_000, // Balance per account in octas
241
+ nodeForceRestart: true, // Restart node on each run
242
+ // ... see LocalTestOptions for more
243
+ });
207
244
  ```
208
245
 
209
- #### `getContract(aptos, moduleAddress, moduleName)`
246
+ #### `setupLocalTesting(options?)`
210
247
 
211
- Creates a contract wrapper for easy interaction.
248
+ Lower-level API for setting up local testing environment. Returns MovehatRuntime.
249
+
250
+ ```typescript
251
+ import { setupLocalTesting } from "movehat/helpers";
252
+
253
+ // Local node mode (default) - Full blockchain
254
+ const mh = await setupLocalTesting({
255
+ mode: 'local-node',
256
+ accountLabels: ['deployer', 'alice', 'bob'],
257
+ autoDeploy: ['counter'], // Auto-deploy modules
258
+ autoFund: true,
259
+ defaultBalance: 100_000_000
260
+ });
261
+
262
+ // Fork mode - Read-only snapshot
263
+ const mh = await setupLocalTesting({
264
+ mode: 'fork',
265
+ forkNetwork: 'testnet',
266
+ forkName: 'my-fork',
267
+ accountLabels: ['alice', 'bob'],
268
+ // Note: autoDeploy doesn't work in fork mode
269
+ });
270
+ ```
271
+
272
+ #### `teardownTestFixture()`
273
+
274
+ Cleanup function to stop local node and clear accounts.
212
275
 
213
276
  ```typescript
214
- const counter = getContract(aptos, accountAddress, "counter");
277
+ after(async () => {
278
+ await teardownTestFixture();
279
+ });
215
280
  ```
216
281
 
217
- #### `contract.call(signer, functionName, args, typeArgs)`
282
+ #### `stopLocalTesting()`
218
283
 
219
- Executes an entry function (transaction).
284
+ Stops the local testing environment (for lower-level API).
220
285
 
221
286
  ```typescript
222
- const tx = await counter.call(account, "increment", []);
287
+ await stopLocalTesting();
223
288
  ```
224
289
 
225
- #### `contract.view(functionName, args, typeArgs)`
290
+ ### Contract Interaction
226
291
 
227
- Reads data from a view function (no transaction).
292
+ #### `mh.getContract(moduleAddress, moduleName)`
293
+
294
+ Creates a contract wrapper for easy interaction.
295
+
296
+ ```typescript
297
+ const mh = await getMovehat();
298
+ const counter = mh.getContract(deployment.address, "counter");
299
+ ```
300
+
301
+ #### `contract.call(signer, functionName, args, typeArgs?)`
302
+
303
+ Executes an entry function (transaction).
228
304
 
229
305
  ```typescript
230
- const value = await counter.view<number>("get", [address]);
306
+ const tx = await counter.call(account, "increment", []);
307
+ console.log(`Transaction: ${tx.hash}`);
231
308
  ```
232
309
 
233
- #### `assertTransactionSuccess(result)`
310
+ #### `contract.view<T>(functionName, args, typeArgs?)`
234
311
 
235
- Asserts that a transaction was successful.
312
+ Reads data from a view function (no transaction).
236
313
 
237
314
  ```typescript
238
- assertTransactionSuccess(txResult);
315
+ // Note: View functions return strings
316
+ const value = await counter.view<string>("get", [address]);
317
+ console.log(`Value: ${parseInt(value)}`);
239
318
  ```
240
319
 
241
320
  ## Available Commands
package/bin/movehat.js CHANGED
@@ -1,5 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ // Suppress experimental JSON module warning
4
+ process.removeAllListeners('warning');
5
+ process.on('warning', (warning) => {
6
+ if (warning.name === 'ExperimentalWarning' &&
7
+ warning.message.includes('Importing JSON modules')) {
8
+ return;
9
+ }
10
+ console.warn(warning);
11
+ });
12
+
3
13
  import { fileURLToPath } from 'url';
4
14
  import { dirname, join } from 'path';
5
15
 
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAKA,wBAA8B,UAAU,CAAC,UAAU,EAAE,MAAM,iBAqD1D"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAMA,wBAA8B,UAAU,CAAC,UAAU,EAAE,MAAM,iBA4F1D"}
@@ -2,6 +2,7 @@ import { spawn } from "child_process";
2
2
  import { resolve, extname, dirname, join } from "path";
3
3
  import { existsSync } from "fs";
4
4
  import { fileURLToPath } from "url";
5
+ import { createRequire } from "module";
5
6
  export default async function runCommand(scriptPath) {
6
7
  if (!scriptPath) {
7
8
  console.error("❌ Error: No script path provided");
@@ -28,12 +29,48 @@ export default async function runCommand(scriptPath) {
28
29
  console.log(` Network: ${network}`);
29
30
  }
30
31
  console.log();
31
- // Find tsx from movehat's node_modules
32
+ // Find tsx binary - try multiple locations for compatibility
33
+ // Uses require.resolve for cross-platform compatibility (works on Windows, macOS, Linux)
32
34
  const __filename = fileURLToPath(import.meta.url);
33
35
  const __dirname = dirname(__filename);
34
- const tsxPath = join(__dirname, "..", "..", "node_modules", ".bin", "tsx");
36
+ // Create require function for ESM (needed to use require.resolve in ESM modules)
37
+ const require = createRequire(import.meta.url);
38
+ let tsxPath;
39
+ try {
40
+ // Try to resolve tsx package from user's project first
41
+ const tsxPackagePath = require.resolve("tsx", { paths: [process.cwd()] });
42
+ // require.resolve("tsx") returns .../tsx/dist/loader.mjs
43
+ // We need to go up to the tsx package root, then into dist/cli.mjs
44
+ const tsxPackageRoot = dirname(dirname(tsxPackagePath));
45
+ tsxPath = join(tsxPackageRoot, "dist", "cli.mjs");
46
+ // Verify the file exists
47
+ if (!existsSync(tsxPath)) {
48
+ throw new Error("cli.mjs not found");
49
+ }
50
+ }
51
+ catch {
52
+ try {
53
+ // Fallback to movehat's own tsx
54
+ const tsxPackagePath = require.resolve("tsx", { paths: [__dirname] });
55
+ const tsxPackageRoot = dirname(dirname(tsxPackagePath));
56
+ tsxPath = join(tsxPackageRoot, "dist", "cli.mjs");
57
+ if (!existsSync(tsxPath)) {
58
+ throw new Error("cli.mjs not found");
59
+ }
60
+ }
61
+ catch {
62
+ tsxPath = "";
63
+ }
64
+ }
65
+ if (!tsxPath) {
66
+ console.error("❌ Error: tsx binary not found");
67
+ console.error(" Make sure 'tsx' is installed in your project:");
68
+ console.error(" npm install --save-dev tsx");
69
+ process.exit(1);
70
+ }
35
71
  // Execute script with tsx (handles both .ts and .js files)
36
- const child = spawn(tsxPath, [fullPath], {
72
+ // Using 'node' to execute tsx for cross-platform compatibility
73
+ const child = spawn("node", [tsxPath, fullPath], {
37
74
  stdio: "inherit",
38
75
  env: {
39
76
  ...process.env,
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,UAAU,CAAC,UAAkB;IACzD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAClD,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACrE,OAAO,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;QAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;IAEpD,uBAAuB;IACvB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,uBAAuB,UAAU,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,gDAAgD;IAChD,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9B,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,OAAO,CAAC,KAAK,CAAC,4BAA4B,GAAG,EAAE,CAAC,CAAC;QACjD,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC;IAChD,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,eAAe,OAAO,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,uCAAuC;IACvC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IAE3E,2DAA2D;IAC3D,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE;QACvC,KAAK,EAAE,SAAS;QAChB,GAAG,EAAE;YACH,GAAG,OAAO,CAAC,GAAG;YACd,gDAAgD;SACjD;KACF,CAAC,CAAC;IAEH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACxB,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QAC1B,OAAO,CAAC,KAAK,CAAC,+BAA+B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,186 @@
1
+ import { Account } from "@aptos-labs/ts-sdk";
2
+ import { MovehatConfig } from "../types/config.js";
3
+ /**
4
+ * Represents a stored account in the pool
5
+ */
6
+ export interface StoredAccount {
7
+ label?: string;
8
+ privateKey: string;
9
+ address: string;
10
+ createdAt: number;
11
+ }
12
+ /**
13
+ * Centralized Account Manager for movehat
14
+ *
15
+ * Manages all account creation, loading, and lifecycle operations.
16
+ * Provides a pool of reusable test accounts with labels for better test readability.
17
+ */
18
+ export declare class AccountManager {
19
+ private static pool;
20
+ private static privateKeys;
21
+ private static labelMap;
22
+ private static poolLoaded;
23
+ private static defaultPoolPath;
24
+ /**
25
+ * Get a test account from the pool. If label is provided and exists, returns that account.
26
+ * Otherwise creates a new account with the optional label.
27
+ *
28
+ * @param label Optional label for the account (e.g., "alice", "bob", "deployer")
29
+ * @returns An Account instance
30
+ *
31
+ * @example
32
+ * const alice = AccountManager.getTestAccount("alice");
33
+ * const randomAccount = AccountManager.getTestAccount();
34
+ */
35
+ static getTestAccount(label?: string): Account;
36
+ /**
37
+ * Create a new account and optionally add it to the pool with a label
38
+ *
39
+ * @param label Optional label for the account
40
+ * @param fund Whether to fund the account (handled externally)
41
+ * @returns A new Account instance
42
+ *
43
+ * @example
44
+ * const deployer = AccountManager.createAccount("deployer");
45
+ * const bob = AccountManager.createAccount("bob", true);
46
+ */
47
+ static createAccount(label?: string, fund?: boolean): Account;
48
+ /**
49
+ * Get an account by its label
50
+ *
51
+ * @param label The label to look up
52
+ * @returns The Account if found, undefined otherwise
53
+ *
54
+ * @example
55
+ * const alice = AccountManager.getAccountByLabel("alice");
56
+ * if (alice) {
57
+ * console.log(`Alice's address: ${alice.accountAddress.toString()}`);
58
+ * }
59
+ */
60
+ static getAccountByLabel(label: string): Account | undefined;
61
+ /**
62
+ * Load account from environment variable
63
+ *
64
+ * @param envVar The environment variable name (defaults to "PRIVATE_KEY")
65
+ * @returns Account instance
66
+ * @throws Error if environment variable is not set
67
+ *
68
+ * @example
69
+ * const account = AccountManager.loadAccountFromEnv("MH_PRIVATE_KEY");
70
+ */
71
+ static loadAccountFromEnv(envVar?: string): Account;
72
+ /**
73
+ * Load account from a private key hex string
74
+ *
75
+ * @param privateKeyHex The private key as a hex string (with or without 0x prefix)
76
+ * @returns Account instance
77
+ *
78
+ * @example
79
+ * const account = AccountManager.loadAccountFromPrivateKey("0xabc123...");
80
+ */
81
+ static loadAccountFromPrivateKey(privateKeyHex: string): Account;
82
+ /**
83
+ * Load all accounts from movehat config
84
+ *
85
+ * @param config The resolved MovehatConfig
86
+ * @returns Array of Account instances
87
+ *
88
+ * @example
89
+ * const config = await resolveNetworkConfig(userConfig);
90
+ * const accounts = AccountManager.loadAccountsFromConfig(config);
91
+ */
92
+ static loadAccountsFromConfig(config: MovehatConfig): Account[];
93
+ /**
94
+ * Get all labeled accounts in the pool
95
+ *
96
+ * @returns Record of label to Account mappings
97
+ *
98
+ * @example
99
+ * const labeled = AccountManager.getLabeledAccounts();
100
+ * console.log(`Deployer: ${labeled.deployer?.accountAddress.toString()}`);
101
+ */
102
+ static getLabeledAccounts(): Record<string, Account>;
103
+ /**
104
+ * Save the current account pool to disk for persistence
105
+ *
106
+ * @param poolPath Optional custom path (defaults to .movehat/accounts)
107
+ *
108
+ * @example
109
+ * AccountManager.saveAccountPool();
110
+ */
111
+ static saveAccountPool(poolPath?: string): void;
112
+ /**
113
+ * Load account pool from disk
114
+ *
115
+ * @param poolPath Optional custom path (defaults to .movehat/accounts)
116
+ * @returns true if pool was loaded, false if file doesn't exist
117
+ *
118
+ * @example
119
+ * if (AccountManager.loadAccountPool()) {
120
+ * console.log("Pool loaded successfully");
121
+ * }
122
+ */
123
+ static loadAccountPool(poolPath?: string): boolean;
124
+ /**
125
+ * Clear the entire account pool
126
+ * Useful for test isolation
127
+ *
128
+ * @example
129
+ * after(() => {
130
+ * AccountManager.clearPool();
131
+ * });
132
+ */
133
+ static clearPool(): void;
134
+ /**
135
+ * Get the current size of the account pool
136
+ *
137
+ * @returns Number of accounts in the pool
138
+ */
139
+ static getPoolSize(): number;
140
+ /**
141
+ * Get all accounts in the pool
142
+ *
143
+ * @returns Array of all Account instances
144
+ */
145
+ static getAllAccounts(): Account[];
146
+ /**
147
+ * Check if a label is already in use
148
+ *
149
+ * @param label The label to check
150
+ * @returns true if label exists, false otherwise
151
+ */
152
+ static hasLabel(label: string): boolean;
153
+ /**
154
+ * Get or create an account with a specific label
155
+ * If the label exists, returns the existing account
156
+ * Otherwise creates a new account with that label
157
+ *
158
+ * @param label The label for the account
159
+ * @returns Account instance
160
+ *
161
+ * @example
162
+ * const alice = AccountManager.getOrCreateLabeled("alice");
163
+ * const aliceAgain = AccountManager.getOrCreateLabeled("alice"); // Same account
164
+ */
165
+ static getOrCreateLabeled(label: string): Account;
166
+ /**
167
+ * Batch create multiple labeled accounts
168
+ *
169
+ * @param labels Array of labels to create
170
+ * @returns Record of label to Account mappings
171
+ *
172
+ * @example
173
+ * const accounts = AccountManager.createBatch(["alice", "bob", "charlie"]);
174
+ * console.log(accounts.alice.accountAddress.toString());
175
+ */
176
+ static createBatch(labels: readonly string[]): Record<string, Account>;
177
+ /**
178
+ * Export account private keys for backup/sharing
179
+ * WARNING: Only use this for test accounts, never production keys
180
+ *
181
+ * @param labels Optional array of labels to export (exports all if not provided)
182
+ * @returns Record of label/address to private key hex string
183
+ */
184
+ static exportPrivateKeys(labels?: string[]): Record<string, string>;
185
+ }
186
+ //# sourceMappingURL=AccountManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AccountManager.d.ts","sourceRoot":"","sources":["../../src/core/AccountManager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAER,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAUD;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAmC;IACtD,OAAO,CAAC,MAAM,CAAC,WAAW,CAAkC;IAC5D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkC;IACzD,OAAO,CAAC,MAAM,CAAC,UAAU,CAAS;IAClC,OAAO,CAAC,MAAM,CAAC,eAAe,CAA+C;IAE7E;;;;;;;;;;OAUG;IACH,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO;IAa9C;;;;;;;;;;OAUG;IACH,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,OAAe,GAAG,OAAO;IAkBpE;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAQ5D;;;;;;;;;OASG;IACH,MAAM,CAAC,kBAAkB,CAAC,MAAM,GAAE,MAAsB,GAAG,OAAO;IAalE;;;;;;;;OAQG;IACH,MAAM,CAAC,yBAAyB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO;IAchE;;;;;;;;;OASG;IACH,MAAM,CAAC,sBAAsB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,EAAE;IAiB/D;;;;;;;;OAQG;IACH,MAAM,CAAC,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAapD;;;;;;;OAOG;IACH,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IA+C/C;;;;;;;;;;OAUG;IACH,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO;IAgDlD;;;;;;;;OAQG;IACH,MAAM,CAAC,SAAS,IAAI,IAAI;IAOxB;;;;OAIG;IACH,MAAM,CAAC,WAAW,IAAI,MAAM;IAI5B;;;;OAIG;IACH,MAAM,CAAC,cAAc,IAAI,OAAO,EAAE;IAIlC;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIvC;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAQjD;;;;;;;;;OASG;IACH,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAUtE;;;;;;OAMG;IACH,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CA0BpE"}