movehat 0.1.3 → 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 (58) hide show
  1. package/README.md +159 -80
  2. package/dist/commands/run.d.ts.map +1 -1
  3. package/dist/commands/run.js +40 -3
  4. package/dist/commands/run.js.map +1 -1
  5. package/dist/core/AccountManager.d.ts +186 -0
  6. package/dist/core/AccountManager.d.ts.map +1 -0
  7. package/dist/core/AccountManager.js +363 -0
  8. package/dist/core/AccountManager.js.map +1 -0
  9. package/dist/fork/manager.d.ts +33 -0
  10. package/dist/fork/manager.d.ts.map +1 -1
  11. package/dist/fork/manager.js +61 -0
  12. package/dist/fork/manager.js.map +1 -1
  13. package/dist/fork/storage.d.ts +10 -0
  14. package/dist/fork/storage.d.ts.map +1 -1
  15. package/dist/fork/storage.js +28 -1
  16. package/dist/fork/storage.js.map +1 -1
  17. package/dist/helpers/index.d.ts +8 -1
  18. package/dist/helpers/index.d.ts.map +1 -1
  19. package/dist/helpers/index.js +4 -0
  20. package/dist/helpers/index.js.map +1 -1
  21. package/dist/helpers/setup.d.ts.map +1 -1
  22. package/dist/helpers/setup.js +5 -4
  23. package/dist/helpers/setup.js.map +1 -1
  24. package/dist/helpers/setupLocalTesting.d.ts +60 -0
  25. package/dist/helpers/setupLocalTesting.d.ts.map +1 -0
  26. package/dist/helpers/setupLocalTesting.js +277 -0
  27. package/dist/helpers/setupLocalTesting.js.map +1 -0
  28. package/dist/helpers/testFixtures.d.ts +115 -0
  29. package/dist/helpers/testFixtures.d.ts.map +1 -0
  30. package/dist/helpers/testFixtures.js +163 -0
  31. package/dist/helpers/testFixtures.js.map +1 -0
  32. package/dist/node/LocalNodeManager.d.ts +68 -0
  33. package/dist/node/LocalNodeManager.d.ts.map +1 -0
  34. package/dist/node/LocalNodeManager.js +237 -0
  35. package/dist/node/LocalNodeManager.js.map +1 -0
  36. package/dist/runtime.d.ts.map +1 -1
  37. package/dist/runtime.js +91 -46
  38. package/dist/runtime.js.map +1 -1
  39. package/dist/templates/README.md +17 -4
  40. package/dist/templates/move/sources/Counter.move +12 -4
  41. package/dist/templates/tests/Counter.test.ts +98 -57
  42. package/dist/types/config.d.ts +24 -0
  43. package/dist/types/config.d.ts.map +1 -1
  44. package/package.json +1 -1
  45. package/src/commands/run.ts +43 -3
  46. package/src/core/AccountManager.ts +439 -0
  47. package/src/fork/manager.ts +74 -0
  48. package/src/fork/storage.ts +33 -1
  49. package/src/helpers/index.ts +18 -1
  50. package/src/helpers/setup.ts +4 -3
  51. package/src/helpers/setupLocalTesting.ts +335 -0
  52. package/src/helpers/testFixtures.ts +222 -0
  53. package/src/node/LocalNodeManager.ts +297 -0
  54. package/src/runtime.ts +108 -47
  55. package/src/templates/README.md +17 -4
  56. package/src/templates/move/sources/Counter.move +12 -4
  57. package/src/templates/tests/Counter.test.ts +98 -57
  58. package/src/types/config.ts +32 -0
package/dist/runtime.js CHANGED
@@ -1,8 +1,9 @@
1
- import { Account, Aptos, AptosConfig, Ed25519PrivateKey, } from "@aptos-labs/ts-sdk";
1
+ import { Aptos, AptosConfig, } from "@aptos-labs/ts-sdk";
2
2
  import { loadUserConfig, resolveNetworkConfig } from "./core/config.js";
3
3
  import { getContract } from "./core/contract.js";
4
4
  import { saveDeployment, loadDeployment, getAllDeployments, getDeployedAddress, validateSafeName, } from "./core/deployments.js";
5
5
  import { ModuleAlreadyDeployedError } from "./errors.js";
6
+ import { AccountManager } from "./core/AccountManager.js";
6
7
  let cachedRuntime = null;
7
8
  /**
8
9
  * Initialize the Movehat Runtime Environment
@@ -23,12 +24,9 @@ export async function initRuntime(options = {}) {
23
24
  fullnode: config.rpc,
24
25
  });
25
26
  const aptos = new Aptos(aptosConfig);
26
- // Setup accounts
27
+ // Setup accounts using AccountManager
27
28
  const accountIndex = options.accountIndex || 0;
28
- const accounts = config.allAccounts.map((pk) => {
29
- const privateKey = new Ed25519PrivateKey(pk);
30
- return Account.fromPrivateKey({ privateKey });
31
- });
29
+ const accounts = AccountManager.loadAccountsFromConfig(config);
32
30
  // Primary account (accounts[0] or selected index)
33
31
  const account = accounts[accountIndex];
34
32
  if (!account) {
@@ -93,50 +91,98 @@ export async function initRuntime(options = {}) {
93
91
  const safeProfile = validateAndEscapeProfile(profile);
94
92
  console.log(`📦 Publishing module "${moduleName}" from ${dir}...`);
95
93
  try {
96
- // Ensure Movement CLI config exists
97
- const aptosConfigDir = join(homedir(), ".aptos");
98
- const aptosConfigPath = join(aptosConfigDir, "config.yaml");
99
- if (!existsSync(aptosConfigPath)) {
100
- console.log("⚙️ Creating Movement CLI configuration...");
101
- if (!existsSync(aptosConfigDir)) {
102
- mkdirSync(aptosConfigDir, { recursive: true });
103
- }
104
- // Create minimal config.yaml using js-yaml to prevent YAML injection
105
- const configData = {
106
- profiles: {
107
- [profile]: {
108
- private_key: config.privateKey,
109
- public_key: account.publicKey.toString(),
110
- account: account.accountAddress.toString(),
111
- rest_url: config.rpc,
112
- },
113
- },
114
- };
115
- const configContent = yaml.dump(configData);
116
- writeFileSync(aptosConfigPath, configContent, "utf-8");
117
- // Restrict file permissions to owner only (600) for security
118
- // This prevents other users from reading the private key
119
- try {
120
- chmodSync(aptosConfigPath, 0o600);
121
- }
122
- catch (error) {
123
- // chmod may fail on Windows, but that's okay
124
- // Windows has different permission model (ACLs)
125
- console.warn("⚠️ Could not set file permissions (this is normal on Windows)");
126
- }
127
- }
128
94
  // Build first
129
95
  console.log("🔨 Building package...");
130
96
  const buildCmd = `movement move build --package-dir ${safeDir}`;
131
97
  const { stdout: buildOut } = await execAsync(buildCmd);
132
98
  if (buildOut)
133
99
  console.log(buildOut.trim());
134
- // Publish
100
+ // Publish using direct parameters (avoid config file issues)
135
101
  console.log("📤 Publishing to blockchain...");
136
- const publishCmd = `movement move publish --profile ${safeProfile} --package-dir ${safeDir} --assume-yes`;
137
- const { stdout: publishOut } = await execAsync(publishCmd);
138
- if (publishOut)
139
- console.log(publishOut.trim());
102
+ // Use parameters directly instead of relying on config file
103
+ // Strip any ed25519-priv- prefix if present
104
+ let cleanPrivateKey = config.privateKey;
105
+ if (cleanPrivateKey.startsWith('ed25519-priv-')) {
106
+ cleanPrivateKey = cleanPrivateKey.replace('ed25519-priv-', '');
107
+ }
108
+ // Get the deployer address
109
+ const deployerAddress = account.accountAddress.toString();
110
+ // Read Move.toml to update named addresses with deployer address
111
+ const moveTomlPath = join(dir, 'Move.toml');
112
+ let originalMoveToml = '';
113
+ if (existsSync(moveTomlPath)) {
114
+ const { readFile, writeFile } = await import('fs').then(fs => fs.promises);
115
+ originalMoveToml = await readFile(moveTomlPath, 'utf-8');
116
+ // Replace addresses in [addresses] section with deployer address
117
+ const updatedMoveToml = originalMoveToml.replace(/\[addresses\]([\s\S]*?)(?=\n\[|$)/, (match, addressesSection) => {
118
+ const updatedSection = addressesSection.replace(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*"0x[a-fA-F0-9]+"/gm, `$1 = "${deployerAddress}"`);
119
+ return `[addresses]${updatedSection}`;
120
+ });
121
+ // Write updated Move.toml temporarily
122
+ await writeFile(moveTomlPath, updatedMoveToml, 'utf-8');
123
+ }
124
+ let publishOut = '';
125
+ let publishErr = '';
126
+ // Setup Movement CLI config with private key securely
127
+ const movementConfigDir = join(homedir(), '.movement');
128
+ const movementConfigPath = join(movementConfigDir, 'config.yaml');
129
+ let originalMovementConfig = '';
130
+ try {
131
+ // Ensure .movement directory exists
132
+ if (!existsSync(movementConfigDir)) {
133
+ mkdirSync(movementConfigDir, { recursive: true, mode: 0o700 });
134
+ }
135
+ // Backup original config if it exists
136
+ if (existsSync(movementConfigPath)) {
137
+ const { readFile } = await import('fs').then(fs => fs.promises);
138
+ originalMovementConfig = await readFile(movementConfigPath, 'utf-8');
139
+ }
140
+ // Create Movement config with private key
141
+ // Movement CLI reads from ~/.movement/config.yaml
142
+ const movementConfig = originalMovementConfig ? yaml.load(originalMovementConfig) : {};
143
+ // Set profile with private key
144
+ if (!movementConfig.profiles) {
145
+ movementConfig.profiles = {};
146
+ }
147
+ if (!movementConfig.profiles[safeProfile]) {
148
+ movementConfig.profiles[safeProfile] = {};
149
+ }
150
+ movementConfig.profiles[safeProfile].private_key = cleanPrivateKey;
151
+ movementConfig.profiles[safeProfile].public_key = account.publicKey.toString();
152
+ movementConfig.profiles[safeProfile].account = deployerAddress;
153
+ movementConfig.profiles[safeProfile].rest_url = config.rpc;
154
+ // Write config file with restrictive permissions
155
+ const configYaml = yaml.dump(movementConfig);
156
+ writeFileSync(movementConfigPath, configYaml, { mode: 0o600 });
157
+ // Execute publish command without exposing private key in CLI
158
+ const publishCmd = `movement move publish --package-dir ${safeDir} --url ${config.rpc} --assume-yes`;
159
+ const result = await execAsync(publishCmd);
160
+ publishOut = result.stdout || '';
161
+ publishErr = result.stderr || '';
162
+ if (publishOut)
163
+ console.log(publishOut.trim());
164
+ if (publishErr)
165
+ console.error(publishErr.trim());
166
+ }
167
+ finally {
168
+ // Restore original Movement config
169
+ if (existsSync(movementConfigPath)) {
170
+ if (originalMovementConfig) {
171
+ // Restore original config
172
+ writeFileSync(movementConfigPath, originalMovementConfig, { mode: 0o600 });
173
+ }
174
+ else {
175
+ // Remove config file if it didn't exist before
176
+ const { unlink } = await import('fs').then(fs => fs.promises);
177
+ await unlink(movementConfigPath).catch(() => { });
178
+ }
179
+ }
180
+ // Restore original Move.toml
181
+ if (originalMoveToml && existsSync(moveTomlPath)) {
182
+ const { writeFile } = await import('fs').then(fs => fs.promises);
183
+ await writeFile(moveTomlPath, originalMoveToml, 'utf-8');
184
+ }
185
+ }
140
186
  // Extract transaction hash from output
141
187
  // Look for patterns like "Transaction hash: 0x..." or "Txn: 0x..." or just a 64-char hex
142
188
  // The regex tries to match with context first, then falls back to any 64-char hex
@@ -181,11 +227,10 @@ export async function initRuntime(options = {}) {
181
227
  return getDeployedAddress(config.network, moduleName);
182
228
  };
183
229
  const createAccount = () => {
184
- return Account.generate();
230
+ return AccountManager.createAccount();
185
231
  };
186
232
  const getAccountHelper = (privateKeyHex) => {
187
- const pk = new Ed25519PrivateKey(privateKeyHex);
188
- return Account.fromPrivateKey({ privateKey: pk });
233
+ return AccountManager.loadAccountFromPrivateKey(privateKeyHex);
189
234
  };
190
235
  const getAccountByIndex = (index) => {
191
236
  if (index < 0 || index >= accounts.length) {
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,EACL,WAAW,GAGZ,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAgB,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EACL,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAElB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,IAAI,aAAa,GAA0B,IAAI,CAAC;AAQhD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,UAA8B,EAAE;IAEhC,0CAA0C;IAC1C,MAAM,UAAU,GAAG,MAAM,cAAc,EAAE,CAAC;IAE1C,oCAAoC;IACpC,MAAM,gBAAgB,GAAsB,OAAO,CAAC,cAAc;QAChE,CAAC,CAAC,EAAE,GAAG,UAAU,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE;QAC9C,CAAC,CAAC,UAAU,CAAC;IAEf,6CAA6C;IAC7C,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,gBAAgB,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAE7E,qBAAqB;IACrB,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC;QAClC,OAAO,EAAE,MAAM,CAAC,OAAkB;QAClC,QAAQ,EAAE,MAAM,CAAC,GAAG;KACrB,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;IAErC,sCAAsC;IACtC,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAc,cAAc,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAE1E,kDAAkD;IAClD,MAAM,OAAO,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IACvC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,iBAAiB,YAAY,oBAAoB,QAAQ,CAAC,MAAM,uBAAuB,CAAC,CAAC;IAC3G,CAAC;IAED,6CAA6C;IAC7C,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;IAEnD,eAAe;IACf,MAAM,OAAO,GAAgB;QAC3B,IAAI,EAAE,MAAM,CAAC,OAAO;QACpB,GAAG,EAAE,MAAM,CAAC,GAAG;KAChB,CAAC;IAEF,mBAAmB;IACnB,MAAM,iBAAiB,GAAG,CAAC,OAAe,EAAE,UAAkB,EAAgB,EAAE;QAC9E,OAAO,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IACjD,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,KAAK,EAC1B,UAAkB,EAClB,OAEC,EACwB,EAAE;QAC3B,4BAA4B;QAC5B,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAEvC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;QAC/C,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QAC/E,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAC5F,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAElC,8CAA8C;QAC9C,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM,CAAC;QAE7D,4BAA4B;QAC5B,MAAM,kBAAkB,GAAG,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACtE,IAAI,kBAAkB,IAAI,CAAC,aAAa,EAAE,CAAC;YACzC,wDAAwD;YACxD,MAAM,YAAY,GAAG;gBACnB,WAAW,UAAU,4BAA4B,MAAM,CAAC,OAAO,EAAE;gBACjE,YAAY,kBAAkB,CAAC,OAAO,EAAE;gBACxC,gBAAgB,IAAI,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,EAAE;gBACzE,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,kBAAkB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI;gBAC9E,8CAA8C;gBAC9C,kCAAkC,MAAM,CAAC,OAAO,aAAa;aAC9D,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE7B,uCAAuC;YACvC,MAAM,gBAAgB,GAAG;gBACvB,eAAe,UAAU,4BAA4B,MAAM,CAAC,OAAO,EAAE;gBACrE,eAAe,kBAAkB,CAAC,OAAO,EAAE;gBAC3C,mBAAmB,IAAI,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,EAAE;gBAC5E,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,mBAAmB,kBAAkB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI;gBACjF,iDAAiD;gBACjD,qCAAqC,MAAM,CAAC,OAAO,eAAe;aACnE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE7B,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAEhC,qEAAqE;YACrE,MAAM,IAAI,0BAA0B,CAClC,YAAY,EACZ,UAAU,EACV,MAAM,CAAC,OAAO,EACd,kBAAkB,CAAC,OAAO,EAC1B,kBAAkB,CAAC,SAAS,EAC5B,kBAAkB,CAAC,MAAM,CAC1B,CAAC;QACJ,CAAC;QAED,IAAI,aAAa,IAAI,kBAAkB,EAAE,CAAC;YACxC,OAAO,CAAC,GAAG,CAAC,0BAA0B,UAAU,QAAQ,MAAM,CAAC,OAAO,KAAK,CAAC,CAAC;QAC/E,CAAC;QAED,MAAM,GAAG,GAAG,OAAO,EAAE,UAAU,IAAI,MAAM,CAAC,OAAO,CAAC;QAClD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,SAAS,CAAC;QAE5C,mDAAmD;QACnD,MAAM,OAAO,GAAG,qBAAqB,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;QAChE,MAAM,WAAW,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAEtD,OAAO,CAAC,GAAG,CAAC,yBAAyB,UAAU,UAAU,GAAG,KAAK,CAAC,CAAC;QAEnE,IAAI,CAAC;YACH,cAAc;YACd,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;YACtC,MAAM,QAAQ,GAAG,qCAAqC,OAAO,EAAE,CAAC;YAChE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;YACvD,IAAI,QAAQ;gBAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YAE3C,6DAA6D;YAC7D,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;YAE9C,4DAA4D;YAC5D,4CAA4C;YAC5C,IAAI,eAAe,GAAG,MAAM,CAAC,UAAU,CAAC;YACxC,IAAI,eAAe,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;gBAChD,eAAe,GAAG,eAAe,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;YACjE,CAAC;YAED,2BAA2B;YAC3B,MAAM,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;YAE1D,iEAAiE;YACjE,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;YAC5C,IAAI,gBAAgB,GAAG,EAAE,CAAC;YAE1B,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC7B,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;gBAC3E,gBAAgB,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;gBAEzD,iEAAiE;gBACjE,MAAM,eAAe,GAAG,gBAAgB,CAAC,OAAO,CAC9C,mCAAmC,EACnC,CAAC,KAAK,EAAE,gBAAgB,EAAE,EAAE;oBAC1B,MAAM,cAAc,GAAG,gBAAgB,CAAC,OAAO,CAC7C,oDAAoD,EACpD,SAAS,eAAe,GAAG,CAC5B,CAAC;oBACF,OAAO,cAAc,cAAc,EAAE,CAAC;gBACxC,CAAC,CACF,CAAC;gBAEF,sCAAsC;gBACtC,MAAM,SAAS,CAAC,YAAY,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;YAC1D,CAAC;YAED,IAAI,UAAU,GAAG,EAAE,CAAC;YACpB,IAAI,UAAU,GAAG,EAAE,CAAC;YAEpB,sDAAsD;YACtD,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;YACvD,MAAM,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;YAClE,IAAI,sBAAsB,GAAG,EAAE,CAAC;YAEhC,IAAI,CAAC;gBACH,oCAAoC;gBACpC,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;oBACnC,SAAS,CAAC,iBAAiB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;gBACjE,CAAC;gBAED,sCAAsC;gBACtC,IAAI,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;oBACnC,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;oBAChE,sBAAsB,GAAG,MAAM,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;gBACvE,CAAC;gBAED,0CAA0C;gBAC1C,kDAAkD;gBAClD,MAAM,cAAc,GAAQ,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAE5F,+BAA+B;gBAC/B,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;oBAC7B,cAAc,CAAC,QAAQ,GAAG,EAAE,CAAC;gBAC/B,CAAC;gBACD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;oBAC1C,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;gBAC5C,CAAC;gBAED,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,WAAW,GAAG,eAAe,CAAC;gBACnE,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;gBAC/E,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,OAAO,GAAG,eAAe,CAAC;gBAC/D,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC;gBAE3D,iDAAiD;gBACjD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBAC7C,aAAa,CAAC,kBAAkB,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;gBAE/D,8DAA8D;gBAC9D,MAAM,UAAU,GAAG,uCAAuC,OAAO,UAAU,MAAM,CAAC,GAAG,eAAe,CAAC;gBACrG,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,UAAU,CAAC,CAAC;gBAC3C,UAAU,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;gBACjC,UAAU,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;gBACjC,IAAI,UAAU;oBAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC/C,IAAI,UAAU;oBAAE,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;YACnD,CAAC;oBAAS,CAAC;gBACT,mCAAmC;gBACnC,IAAI,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;oBACnC,IAAI,sBAAsB,EAAE,CAAC;wBAC3B,0BAA0B;wBAC1B,aAAa,CAAC,kBAAkB,EAAE,sBAAsB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;oBAC7E,CAAC;yBAAM,CAAC;wBACN,+CAA+C;wBAC/C,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;wBAC9D,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;oBACnD,CAAC;gBACH,CAAC;gBAED,6BAA6B;gBAC7B,IAAI,gBAAgB,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;oBACjD,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;oBACjE,MAAM,SAAS,CAAC,YAAY,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;gBAC3D,CAAC;YACH,CAAC;YAED,uCAAuC;YACvC,yFAAyF;YACzF,kFAAkF;YAClF,IAAI,MAA0B,CAAC;YAC/B,MAAM,sBAAsB,GAAG,UAAU,CAAC,KAAK,CAAC,4EAA4E,CAAC,CAAC;YAC9H,IAAI,sBAAsB,EAAE,CAAC;gBAC3B,MAAM,GAAG,sBAAsB,CAAC,CAAC,CAAC,CAAC;YACrC,CAAC;iBAAM,CAAC;gBACN,mEAAmE;gBACnE,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;gBAChE,IAAI,WAAW,EAAE,CAAC;oBAChB,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;YAEhD,yBAAyB;YACzB,MAAM,UAAU,GAAmB;gBACjC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE;gBAC1C,UAAU;gBACV,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,QAAQ,EAAE,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE;gBAC3C,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;gBACrB,MAAM;aACP,CAAC;YAEF,kBAAkB;YAClB,cAAc,CAAC,UAAU,CAAC,CAAC;YAE3B,OAAO,UAAU,CAAC;QACpB,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO,CAAC,KAAK,CAAC,+BAA+B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9D,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,UAAkB,EAAyB,EAAE;QAClE,OAAO,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACpD,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,GAAmC,EAAE;QAC1D,OAAO,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC,CAAC;IAEF,MAAM,oBAAoB,GAAG,CAAC,UAAkB,EAAiB,EAAE;QACjE,OAAO,kBAAkB,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACxD,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,GAAY,EAAE;QAClC,OAAO,cAAc,CAAC,aAAa,EAAE,CAAC;IACxC,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,CAAC,aAAqB,EAAW,EAAE;QAC1D,OAAO,cAAc,CAAC,yBAAyB,CAAC,aAAa,CAAC,CAAC;IACjE,CAAC,CAAC;IAEF,MAAM,iBAAiB,GAAG,CAAC,KAAa,EAAW,EAAE;QACnD,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,wCAAwC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC;QACvG,CAAC;QACD,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,KAAK,EAAE,WAAmB,EAAiB,EAAE;QACjE,gDAAgD;QAChD,aAAa,GAAG,IAAI,CAAC;QACrB,MAAM,WAAW,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC;IAEF,uBAAuB;IACvB,MAAM,OAAO,GAAmB;QAC9B,MAAM;QACN,OAAO;QACP,KAAK;QACL,OAAO;QACP,QAAQ;QACR,WAAW,EAAE,iBAAiB;QAC9B,cAAc;QACd,aAAa;QACb,cAAc;QACd,oBAAoB;QACpB,aAAa;QACb,UAAU,EAAE,gBAAgB;QAC5B,iBAAiB;QACjB,aAAa;KACd,CAAC;IAEF,aAAa,GAAG,OAAO,CAAC;IACxB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CACb,gFAAgF,CACjF,CAAC;IACJ,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,OAAO,WAAW,EAAE,CAAC;AACvB,CAAC;AAED,mDAAmD;AACnD,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,IAAI,OAAO;QACT,OAAO,UAAU,EAAE,CAAC;IACtB,CAAC;CACF,CAAC"}
@@ -54,18 +54,31 @@ npm test
54
54
 
55
55
  **Two types of tests available:**
56
56
 
57
- 1. **Move Unit Tests** (`tests/Counter.move` lines 50-63)
57
+ 1. **Move Unit Tests** (`move/sources/Counter.move` in `#[test]` blocks)
58
58
  - Written in Move with `#[test]` annotations
59
59
  - Test internal logic and business rules
60
60
  - Ultra-fast execution (milliseconds)
61
61
  - Run with: `npm run test:move`
62
62
 
63
63
  2. **TypeScript Integration Tests** (`tests/Counter.test.ts`)
64
- - Written in TypeScript using Transaction Simulation
65
- - Test end-to-end flows and SDK integration
66
- - No blockchain or gas costs required
64
+ - Written in TypeScript on a **local Movement blockchain**
65
+ - Automatically starts a local node, funds accounts, and deploys contracts
66
+ - Runs real transactions (not simulation!)
67
+ - Just like Hardhat - zero manual setup
67
68
  - Run with: `npm run test:ts`
68
69
 
70
+ **How it works:**
71
+ Tests run on a real local blockchain (similar to Hardhat):
72
+ - 🚀 Automatically starts a Movement node locally
73
+ - 💰 Funds test accounts from local faucet
74
+ - 📦 Auto-deploys your contracts
75
+ - ✅ Runs real transactions
76
+ - 🧹 Cleans up when done
77
+
78
+ **Two modes available:**
79
+ - `local-node` (default): Full blockchain with real transactions
80
+ - `fork`: Read-only snapshot of testnet (faster but limited)
81
+
69
82
  **Commands:**
70
83
  - `npm test` - Runs both Move + TypeScript tests
71
84
  - `npm run test:move` - Only Move unit tests (fast)
@@ -3,6 +3,13 @@ module counter::counter {
3
3
  use aptos_framework::event;
4
4
  use aptos_framework::account;
5
5
 
6
+ /// Error code for counter overflow
7
+ const E_OVERFLOW: u64 = 1;
8
+ /// Error code for counter not initialized
9
+ const E_NOT_INITIALIZED: u64 = 2;
10
+ /// Maximum value for u64
11
+ const U64_MAX: u64 = 18446744073709551615;
12
+
6
13
  struct Counter has key {
7
14
  value: u64,
8
15
  increment_events: event::EventHandle<IncrementEvent>,
@@ -26,12 +33,13 @@ module counter::counter {
26
33
 
27
34
  public entry fun increment(account: &signer) acquires Counter {
28
35
  let account_addr = signer::address_of(account);
29
- assert!(exists<Counter>(account_addr), 1);
30
-
36
+ assert!(exists<Counter>(account_addr), E_NOT_INITIALIZED);
37
+
31
38
  let counter = borrow_global_mut<Counter>(account_addr);
32
39
  let old_value = counter.value;
40
+ assert!(old_value < U64_MAX, E_OVERFLOW);
33
41
  counter.value = old_value + 1;
34
-
42
+
35
43
  event::emit_event(&mut counter.increment_events, IncrementEvent {
36
44
  old_value,
37
45
  new_value: counter.value,
@@ -40,7 +48,7 @@ module counter::counter {
40
48
 
41
49
  #[view]
42
50
  public fun get(addr: address): u64 acquires Counter {
43
- assert!(exists<Counter>(addr), 1);
51
+ assert!(exists<Counter>(addr), E_NOT_INITIALIZED);
44
52
  borrow_global<Counter>(addr).value
45
53
  }
46
54
 
@@ -1,72 +1,113 @@
1
1
  // @ts-nocheck - This is a template file, dependencies are installed in user projects
2
- import { describe, it, before } from "mocha";
2
+ import { describe, it, before, after } from "mocha";
3
3
  import { expect } from "chai";
4
- import { getMovehat, type MovehatRuntime } from "movehat";
4
+ import { setupTestFixture, teardownTestFixture, type TestFixture } from "movehat/helpers";
5
5
 
6
6
  describe("Counter Contract", () => {
7
- let mh: MovehatRuntime;
8
- let contractAddress: string;
7
+ let fixture: TestFixture<'counter'>;
9
8
 
10
9
  before(async function () {
11
- this.timeout(30000);
10
+ this.timeout(60000); // Allow time for local node startup + deployment
12
11
 
13
- // Initialize Movehat Runtime Environment
14
- // Uses testnet by default - no local setup required
15
- mh = await getMovehat();
12
+ // Setup local testing environment with auto-deployment
13
+ // This will:
14
+ // 1. Start a local Movement blockchain node
15
+ // 2. Generate and fund test accounts from local faucet
16
+ // 3. Auto-deploy the counter module
17
+ // 4. Return everything ready to use
18
+ //
19
+ // By default uses 'local-node' mode (full blockchain)
20
+ // For faster tests on existing state, pass { mode: 'fork' }
21
+ //
22
+ // Note: Use 'as const' for type inference
23
+ fixture = await setupTestFixture(['counter'] as const, ['alice', 'bob']);
16
24
 
17
- contractAddress = mh.account.accountAddress.toString();
18
-
19
- console.log(`\nTesting on ${mh.network.name}`);
20
- console.log(`Account: ${contractAddress}\n`);
25
+ console.log(`\n✅ Testing on local blockchain`);
26
+ console.log(` Deployer: ${fixture.accounts.deployer.accountAddress.toString()}`);
27
+ console.log(` Alice: ${fixture.accounts.alice.accountAddress.toString()}`);
28
+ console.log(` Bob: ${fixture.accounts.bob.accountAddress.toString()}\n`);
21
29
  });
22
30
 
23
31
  describe("Counter functionality", () => {
24
- it("should initialize counter using simulation", async function () {
25
- this.timeout(30000);
26
-
27
- // Build transaction
28
- const transaction = await mh.aptos.transaction.build.simple({
29
- sender: mh.account.accountAddress,
30
- data: {
31
- function: `${contractAddress}::counter::init`,
32
- functionArguments: []
33
- }
34
- });
35
-
36
- // Simulate transaction (no gas cost, instant)
37
- const [simulation] = await mh.aptos.transaction.simulate.simple({
38
- signerPublicKey: mh.account.publicKey,
39
- transaction
40
- });
41
-
42
- // Verify simulation succeeded
43
- expect(simulation.success).to.be.true;
44
- console.log(`Counter init simulated successfully`);
45
- console.log(`Gas used: ${simulation.gas_used}`);
32
+ it("should initialize with value 0", async () => {
33
+ const counter = fixture.contracts.counter; // Type-safe, no `!` needed
34
+ const deployer = fixture.accounts.deployer;
35
+
36
+ // Read counter value (returns string from view function)
37
+ const value = await counter.view<string>("get", [
38
+ deployer.accountAddress.toString()
39
+ ]);
40
+
41
+ console.log(` Counter value: ${value}`);
42
+
43
+ // Assert the counter is 0 (note: values from view are strings)
44
+ expect(parseInt(value)).to.equal(0);
45
+ });
46
+
47
+ it("should increment counter", async () => {
48
+ const counter = fixture.contracts.counter;
49
+ const deployer = fixture.accounts.deployer;
50
+
51
+ // Increment the counter
52
+ const tx = await counter.call(deployer, "increment", []);
53
+ console.log(` Transaction: ${tx.hash}`);
54
+
55
+ // Read new value
56
+ const value = await counter.view<string>("get", [
57
+ deployer.accountAddress.toString()
58
+ ]);
59
+
60
+ console.log(` New counter value: ${value}`);
61
+
62
+ // Should be 1 now
63
+ expect(parseInt(value)).to.equal(1);
64
+ });
65
+
66
+ it("alice can also increment counter", async () => {
67
+ const counter = fixture.contracts.counter;
68
+ const alice = fixture.accounts.alice;
69
+
70
+ // Alice increments her own counter
71
+ const tx = await counter.call(alice, "increment", []);
72
+ console.log(` Alice's transaction: ${tx.hash}`);
73
+
74
+ // Read counter value for Alice (each user has their own counter)
75
+ const aliceValue = await counter.view<string>("get", [
76
+ alice.accountAddress.toString()
77
+ ]);
78
+
79
+ console.log(` Alice's counter value: ${aliceValue}`);
80
+ expect(parseInt(aliceValue)).to.equal(1);
81
+
82
+ // Deployer's counter should still be 1 (unchanged)
83
+ const deployerValue = await counter.view<string>("get", [
84
+ fixture.accounts.deployer.accountAddress.toString()
85
+ ]);
86
+
87
+ console.log(` Deployer's counter value: ${deployerValue}`);
88
+ expect(parseInt(deployerValue)).to.equal(1);
46
89
  });
47
90
 
48
- it("should increment counter using simulation", async function () {
49
- this.timeout(30000);
50
-
51
- // Build increment transaction
52
- const transaction = await mh.aptos.transaction.build.simple({
53
- sender: mh.account.accountAddress,
54
- data: {
55
- function: `${contractAddress}::counter::increment`,
56
- functionArguments: []
57
- }
58
- });
59
-
60
- // Simulate transaction
61
- const [simulation] = await mh.aptos.transaction.simulate.simple({
62
- signerPublicKey: mh.account.publicKey,
63
- transaction
64
- });
65
-
66
- // Verify simulation succeeded
67
- expect(simulation.success).to.be.true;
68
- console.log(`Counter increment simulated successfully`);
69
- console.log(`Gas used: ${simulation.gas_used}`);
91
+ it("bob can also increment the counter", async () => {
92
+ const counter = fixture.contracts.counter;
93
+ const bob = fixture.accounts.bob;
94
+
95
+ // Bob increments his own counter
96
+ const tx = await counter.call(bob, "increment", []);
97
+ console.log(` Bob's transaction: ${tx.hash}`);
98
+
99
+ // Read counter value for Bob (each user has their own counter)
100
+ const bobValue = await counter.view<string>("get", [
101
+ bob.accountAddress.toString()
102
+ ]);
103
+
104
+ console.log(` Bob's counter value: ${bobValue}`);
105
+ expect(parseInt(bobValue)).to.equal(1);
70
106
  });
71
107
  });
72
- });
108
+
109
+ after(async () => {
110
+ // Cleanup: Stop local node and clear account pool
111
+ await teardownTestFixture();
112
+ });
113
+ });
@@ -32,4 +32,28 @@ export interface MovehatConfig {
32
32
  namedAddresses: Record<string, string>;
33
33
  networkConfig: NetworkConfig;
34
34
  }
35
+ /**
36
+ * Testing mode for local environment
37
+ */
38
+ export type LocalTestingMode = 'local-node' | 'fork';
39
+ /**
40
+ * Options for setting up local testing environment
41
+ */
42
+ export interface LocalTestOptions {
43
+ mode?: LocalTestingMode;
44
+ nodeTestDir?: string;
45
+ nodeForceRestart?: boolean;
46
+ nodeFaucetPort?: number;
47
+ nodeApiPort?: number;
48
+ nodeReadyPort?: number;
49
+ nodeSilent?: boolean;
50
+ forkNetwork?: 'testnet' | string;
51
+ forkName?: string;
52
+ forkPort?: number;
53
+ forkResetState?: boolean;
54
+ autoFund?: boolean;
55
+ defaultBalance?: number;
56
+ autoDeploy?: readonly string[];
57
+ accountLabels?: readonly string[];
58
+ }
35
59
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,aAAa,EAAE,aAAa,CAAC;CAChC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,aAAa,EAAE,aAAa,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,MAAM,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,IAAI,CAAC,EAAE,gBAAgB,CAAC;IAGxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IAGrB,WAAW,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IAGzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "movehat",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "description": "Hardhat-like development framework for Movement L1 and Aptos Move smart contracts",
6
6
  "bin": {
@@ -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
 
6
7
  export default async function runCommand(scriptPath: string) {
7
8
  if (!scriptPath) {
@@ -34,13 +35,52 @@ export default async function runCommand(scriptPath: string) {
34
35
  }
35
36
  console.log();
36
37
 
37
- // Find tsx from movehat's node_modules
38
+ // Find tsx binary - try multiple locations for compatibility
39
+ // Uses require.resolve for cross-platform compatibility (works on Windows, macOS, Linux)
38
40
  const __filename = fileURLToPath(import.meta.url);
39
41
  const __dirname = dirname(__filename);
40
- const tsxPath = join(__dirname, "..", "..", "node_modules", ".bin", "tsx");
42
+
43
+ // Create require function for ESM (needed to use require.resolve in ESM modules)
44
+ const require = createRequire(import.meta.url);
45
+
46
+ let tsxPath: string;
47
+ try {
48
+ // Try to resolve tsx package from user's project first
49
+ const tsxPackagePath = require.resolve("tsx", { paths: [process.cwd()] });
50
+ // require.resolve("tsx") returns .../tsx/dist/loader.mjs
51
+ // We need to go up to the tsx package root, then into dist/cli.mjs
52
+ const tsxPackageRoot = dirname(dirname(tsxPackagePath));
53
+ tsxPath = join(tsxPackageRoot, "dist", "cli.mjs");
54
+
55
+ // Verify the file exists
56
+ if (!existsSync(tsxPath)) {
57
+ throw new Error("cli.mjs not found");
58
+ }
59
+ } catch {
60
+ try {
61
+ // Fallback to movehat's own tsx
62
+ const tsxPackagePath = require.resolve("tsx", { paths: [__dirname] });
63
+ const tsxPackageRoot = dirname(dirname(tsxPackagePath));
64
+ tsxPath = join(tsxPackageRoot, "dist", "cli.mjs");
65
+
66
+ if (!existsSync(tsxPath)) {
67
+ throw new Error("cli.mjs not found");
68
+ }
69
+ } catch {
70
+ tsxPath = "";
71
+ }
72
+ }
73
+
74
+ if (!tsxPath) {
75
+ console.error("❌ Error: tsx binary not found");
76
+ console.error(" Make sure 'tsx' is installed in your project:");
77
+ console.error(" npm install --save-dev tsx");
78
+ process.exit(1);
79
+ }
41
80
 
42
81
  // Execute script with tsx (handles both .ts and .js files)
43
- const child = spawn(tsxPath, [fullPath], {
82
+ // Using 'node' to execute tsx for cross-platform compatibility
83
+ const child = spawn("node", [tsxPath, fullPath], {
44
84
  stdio: "inherit",
45
85
  env: {
46
86
  ...process.env,