movehat 0.0.5-alpha.0 → 0.0.7-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -7
- package/dist/commands/compile.d.ts.map +1 -1
- package/dist/commands/compile.js +79 -8
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +17 -11
- package/dist/commands/init.js.map +1 -1
- package/dist/templates/README.md +49 -26
- package/dist/templates/move/Move.toml +3 -1
- package/dist/templates/package.json +1 -1
- package/package.json +1 -1
- package/src/commands/compile.ts +93 -8
- package/src/commands/init.ts +17 -11
- package/src/templates/README.md +49 -26
- package/src/templates/move/Move.toml +3 -1
- package/src/templates/package.json +1 -1
- /package/dist/templates/move/{Counter.move → sources/Counter.move} +0 -0
- /package/src/templates/move/{Counter.move → sources/Counter.move} +0 -0
package/README.md
CHANGED
|
@@ -7,12 +7,26 @@
|
|
|
7
7
|
|
|
8
8
|
## Features
|
|
9
9
|
|
|
10
|
+
- **Auto-detection of Named Addresses** - Automatically detects and configures addresses from Move code (like Hardhat)
|
|
10
11
|
- **Quick Start** - Scaffold new Move projects in seconds
|
|
11
12
|
- **TypeScript Testing** - Write integration tests with familiar tools (Mocha, Chai)
|
|
12
13
|
- **Built-in Helpers** - Interact with contracts easily
|
|
13
14
|
- **Movement CLI Integration** - Seamless compilation and deployment
|
|
14
15
|
- **Hot Reload** - Test changes instantly with watch mode
|
|
15
16
|
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
Before installing Movehat, ensure you have:
|
|
20
|
+
|
|
21
|
+
- **Node.js v18+** - [Download](https://nodejs.org/)
|
|
22
|
+
- **Movement CLI** - **REQUIRED** for compiling Move contracts
|
|
23
|
+
|
|
24
|
+
Install from: [Movement CLI Installation Guide](https://docs.movementnetwork.xyz/devs/movementCLI)
|
|
25
|
+
|
|
26
|
+
Verify: `movement --version`
|
|
27
|
+
|
|
28
|
+
**⚠️ Without Movement CLI:** Compilation will fail with "movement: command not found"
|
|
29
|
+
|
|
16
30
|
## Installation
|
|
17
31
|
|
|
18
32
|
```bash
|
|
@@ -33,16 +47,15 @@ cd my-move-project
|
|
|
33
47
|
# Install dependencies
|
|
34
48
|
npm install
|
|
35
49
|
|
|
36
|
-
# Compile contracts
|
|
50
|
+
# Compile contracts (auto-detects named addresses)
|
|
37
51
|
npx movehat compile
|
|
38
52
|
|
|
39
|
-
# Deploy contracts
|
|
40
|
-
npx movehat deploy
|
|
41
|
-
|
|
42
53
|
# Run tests
|
|
43
54
|
npm test
|
|
44
55
|
```
|
|
45
56
|
|
|
57
|
+
**Note:** Movehat automatically detects named addresses from your Move files, so no manual configuration is needed for compilation!
|
|
58
|
+
|
|
46
59
|
## Project Structure
|
|
47
60
|
|
|
48
61
|
```
|
|
@@ -70,8 +83,11 @@ export default {
|
|
|
70
83
|
account: process.env.MH_ACCOUNT || "",
|
|
71
84
|
privateKey: process.env.MH_PRIVATE_KEY || "",
|
|
72
85
|
moveDir: "./move",
|
|
86
|
+
|
|
87
|
+
// Named addresses are auto-detected from your Move files
|
|
88
|
+
// Only specify if you need specific production addresses
|
|
73
89
|
namedAddresses: {
|
|
74
|
-
counter:
|
|
90
|
+
// Optional: counter: "0xYourProductionAddress",
|
|
75
91
|
},
|
|
76
92
|
};
|
|
77
93
|
```
|
|
@@ -213,10 +229,20 @@ npx movehat deploy # Deploy contracts
|
|
|
213
229
|
npx movehat test # Run tests
|
|
214
230
|
```
|
|
215
231
|
|
|
216
|
-
##
|
|
232
|
+
## System Requirements
|
|
217
233
|
|
|
234
|
+
**Required:**
|
|
218
235
|
- Node.js v18+
|
|
219
|
-
-
|
|
236
|
+
- Movement CLI - **REQUIRED** ([Installation Guide](https://docs.movementnetwork.xyz/devs/movementCLI))
|
|
237
|
+
- npm or pnpm
|
|
238
|
+
|
|
239
|
+
**What fails without Movement CLI:**
|
|
240
|
+
- `movehat compile` → "movement: command not found"
|
|
241
|
+
- Contract building and deployment will not work
|
|
242
|
+
|
|
243
|
+
**Recommended:**
|
|
244
|
+
- Git
|
|
245
|
+
- VS Code with Move syntax extension
|
|
220
246
|
|
|
221
247
|
## Documentation
|
|
222
248
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/commands/compile.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/commands/compile.ts"],"names":[],"mappings":"AAsFA,wBAA8B,cAAc,kBAkF3C"}
|
package/dist/commands/compile.js
CHANGED
|
@@ -3,6 +3,61 @@ import path from "path";
|
|
|
3
3
|
import { exec } from "child_process";
|
|
4
4
|
import { loadUserConfig } from "../core/config.js";
|
|
5
5
|
import { validateAndEscapePath, escapeShellArg } from "../core/shell.js";
|
|
6
|
+
/**
|
|
7
|
+
* Recursively find all .move files in a directory
|
|
8
|
+
* @param dir - Directory to search
|
|
9
|
+
* @param maxDepth - Maximum recursion depth (default: 10)
|
|
10
|
+
* @param currentDepth - Current recursion depth (internal use)
|
|
11
|
+
*/
|
|
12
|
+
function findMoveFiles(dir, maxDepth = 10, currentDepth = 0) {
|
|
13
|
+
const files = [];
|
|
14
|
+
// Prevent infinite loops from excessive recursion
|
|
15
|
+
if (currentDepth > maxDepth) {
|
|
16
|
+
return files;
|
|
17
|
+
}
|
|
18
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
19
|
+
for (const entry of entries) {
|
|
20
|
+
const fullPath = path.join(dir, entry.name);
|
|
21
|
+
if (entry.isDirectory()) {
|
|
22
|
+
// Skip symlinks to prevent directory traversal and infinite loops
|
|
23
|
+
if (entry.isSymbolicLink()) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
files.push(...findMoveFiles(fullPath, maxDepth, currentDepth + 1));
|
|
27
|
+
}
|
|
28
|
+
else if (entry.name.endsWith('.move')) {
|
|
29
|
+
files.push(fullPath);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return files;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Extract named addresses used in Move files
|
|
36
|
+
* Looks for patterns like: module <address>::<module_name>
|
|
37
|
+
*/
|
|
38
|
+
function extractNamedAddresses(moveDir) {
|
|
39
|
+
const addresses = new Set();
|
|
40
|
+
const moveFiles = findMoveFiles(moveDir);
|
|
41
|
+
for (const file of moveFiles) {
|
|
42
|
+
let content = fs.readFileSync(file, 'utf-8');
|
|
43
|
+
// Strip comments to avoid false positives
|
|
44
|
+
// Remove block comments /* ... */ (non-greedy, handles newlines)
|
|
45
|
+
content = content.replace(/\/\*[\s\S]*?\*\//g, ' ');
|
|
46
|
+
// Remove line comments // ... to end of line
|
|
47
|
+
content = content.replace(/\/\/.*$/gm, ' ');
|
|
48
|
+
// Match: module <address>::<module_name>
|
|
49
|
+
const moduleRegex = /module\s+([a-zA-Z_][a-zA-Z0-9_]*)::/g;
|
|
50
|
+
let match;
|
|
51
|
+
while ((match = moduleRegex.exec(content)) !== null) {
|
|
52
|
+
const address = match[1];
|
|
53
|
+
// Skip standard addresses
|
|
54
|
+
if (address !== 'std' && address !== 'aptos_framework' && address !== 'aptos_std') {
|
|
55
|
+
addresses.add(address);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return addresses;
|
|
60
|
+
}
|
|
6
61
|
function run(command, cwd) {
|
|
7
62
|
return new Promise((resolve, reject) => {
|
|
8
63
|
exec(command, { cwd }, (error, stdout, stderr) => {
|
|
@@ -22,17 +77,27 @@ export default async function compileCommand() {
|
|
|
22
77
|
try {
|
|
23
78
|
// Compile is network-independent - only uses global config
|
|
24
79
|
const userConfig = await loadUserConfig();
|
|
25
|
-
console.log("
|
|
80
|
+
console.log("Compiling Move contracts...");
|
|
26
81
|
const moveDir = path.resolve(process.cwd(), userConfig.moveDir || "./move");
|
|
27
82
|
if (!fs.existsSync(moveDir)) {
|
|
28
|
-
console.error(
|
|
83
|
+
console.error(`Move directory not found: ${moveDir}`);
|
|
29
84
|
console.error(` Update movehat.config.ts -> moveDir`);
|
|
30
85
|
return;
|
|
31
86
|
}
|
|
32
87
|
// Validate and escape to prevent command injection
|
|
33
88
|
const safeMoveDir = validateAndEscapePath(moveDir, "Move directory");
|
|
34
|
-
//
|
|
35
|
-
const
|
|
89
|
+
// Auto-detect named addresses from Move files
|
|
90
|
+
const detectedAddresses = extractNamedAddresses(moveDir);
|
|
91
|
+
// Merge user-configured addresses with auto-detected ones
|
|
92
|
+
const namedAddresses = { ...(userConfig.namedAddresses ?? {}) };
|
|
93
|
+
const autoAssignedAddresses = [];
|
|
94
|
+
// For any detected address not in config, use a dev address
|
|
95
|
+
for (const addr of detectedAddresses) {
|
|
96
|
+
if (!namedAddresses[addr]) {
|
|
97
|
+
namedAddresses[addr] = "0xcafe"; // Dev address for compilation
|
|
98
|
+
autoAssignedAddresses.push(addr);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
36
101
|
let namedAddressesArg = "";
|
|
37
102
|
if (Object.keys(namedAddresses).length > 0) {
|
|
38
103
|
// Validate and escape each address name and value
|
|
@@ -56,15 +121,21 @@ export default async function compileCommand() {
|
|
|
56
121
|
}
|
|
57
122
|
const command = `movement move build --package-dir ${safeMoveDir} ${namedAddressesArg}`.trim();
|
|
58
123
|
console.log(` Move directory: ${moveDir}`);
|
|
59
|
-
if (
|
|
60
|
-
console.log(`
|
|
124
|
+
if (detectedAddresses.size > 0) {
|
|
125
|
+
console.log(` Detected addresses: ${Array.from(detectedAddresses).join(", ")}`);
|
|
126
|
+
}
|
|
127
|
+
if (Object.keys(userConfig.namedAddresses ?? {}).length > 0) {
|
|
128
|
+
console.log(` Configured addresses: ${Object.keys(userConfig.namedAddresses).join(", ")}`);
|
|
129
|
+
}
|
|
130
|
+
if (autoAssignedAddresses.length > 0) {
|
|
131
|
+
console.log(` Auto-assigned dev address (0xcafe): ${autoAssignedAddresses.join(", ")}`);
|
|
61
132
|
}
|
|
62
133
|
console.log();
|
|
63
134
|
await run(command, moveDir);
|
|
64
|
-
console.log("
|
|
135
|
+
console.log("Compilation finished successfully.");
|
|
65
136
|
}
|
|
66
137
|
catch (err) {
|
|
67
|
-
console.error("
|
|
138
|
+
console.error("Compilation failed:", err.message ?? err);
|
|
68
139
|
process.exit(1);
|
|
69
140
|
}
|
|
70
141
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/commands/compile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEzE,SAAS,GAAG,CAAC,OAAe,EAAE,GAAW;IACvC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAC/C,IAAI,MAAM;gBAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YACvC,IAAI,MAAM;gBAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YACzC,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,CAAC,KAAK,CAAC,CAAC;gBACd,OAAO;YACT,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,cAAc;IAC1C,IAAI,CAAC;QACH,2DAA2D;QAC3D,MAAM,UAAU,GAAG,MAAM,cAAc,EAAE,CAAC;QAE1C,OAAO,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/commands/compile.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AASA,wBAA8B,WAAW,CAAC,WAAW,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AASA,wBAA8B,WAAW,CAAC,WAAW,CAAC,EAAE,MAAM,iBAwG7D"}
|
package/dist/commands/init.js
CHANGED
|
@@ -18,7 +18,7 @@ export default async function initCommand(projectName) {
|
|
|
18
18
|
});
|
|
19
19
|
// If the user cancels (Ctrl+C), exit
|
|
20
20
|
if (!response.projectName) {
|
|
21
|
-
console.log('\
|
|
21
|
+
console.log('\nProject initialization cancelled.');
|
|
22
22
|
process.exit(0);
|
|
23
23
|
}
|
|
24
24
|
projectName = response.projectName;
|
|
@@ -29,7 +29,7 @@ export default async function initCommand(projectName) {
|
|
|
29
29
|
try {
|
|
30
30
|
await fs.mkdir(projectPath, { recursive: true });
|
|
31
31
|
const templatesDir = path.join(__dirname, "..", "templates");
|
|
32
|
-
console.log("
|
|
32
|
+
console.log("Creating project structure...");
|
|
33
33
|
await copyFile(path.join(templatesDir, "package.json"), path.join(projectPath, "package.json"), { projectName: projectName });
|
|
34
34
|
await copyFile(path.join(templatesDir, "tsconfig.json"), path.join(projectPath, "tsconfig.json"));
|
|
35
35
|
await copyFile(path.join(templatesDir, ".mocharc.json"), path.join(projectPath, ".mocharc.json"));
|
|
@@ -38,16 +38,16 @@ export default async function initCommand(projectName) {
|
|
|
38
38
|
await copyFile(path.join(templatesDir, "gitignore"), path.join(projectPath, ".gitignore"));
|
|
39
39
|
await copyFile(path.join(templatesDir, "README.md"), path.join(projectPath, "README.md"), { projectName: projectName });
|
|
40
40
|
// 3. Copiar carpeta move/
|
|
41
|
-
console.log("
|
|
42
|
-
await copyDir(path.join(templatesDir, "move"), path.join(projectPath, "move"));
|
|
41
|
+
console.log("Setting up Move project...");
|
|
42
|
+
await copyDir(path.join(templatesDir, "move"), path.join(projectPath, "move"), { projectName: projectName });
|
|
43
43
|
// 4. Copiar scripts/
|
|
44
|
-
console.log("
|
|
44
|
+
console.log("Adding deployment scripts...");
|
|
45
45
|
await copyDir(path.join(templatesDir, "scripts"), path.join(projectPath, "scripts"));
|
|
46
46
|
// 5. Copiar tests/
|
|
47
|
-
console.log("
|
|
47
|
+
console.log("Adding test files...");
|
|
48
48
|
await copyDir(path.join(templatesDir, "tests"), path.join(projectPath, "tests"));
|
|
49
|
-
console.log("\
|
|
50
|
-
console.log("
|
|
49
|
+
console.log("\nProject created successfully!\n");
|
|
50
|
+
console.log("Next steps:\n");
|
|
51
51
|
console.log(` cd ${projectName}`);
|
|
52
52
|
console.log(` cp .env.example .env`);
|
|
53
53
|
console.log(` # Edit .env with your credentials`);
|
|
@@ -69,7 +69,7 @@ async function copyFile(src, dest, replacements) {
|
|
|
69
69
|
}
|
|
70
70
|
await fs.writeFile(dest, content);
|
|
71
71
|
}
|
|
72
|
-
async function copyDir(src, dest) {
|
|
72
|
+
async function copyDir(src, dest, replacements) {
|
|
73
73
|
await fs.mkdir(dest, { recursive: true });
|
|
74
74
|
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
75
75
|
for (const entry of entries) {
|
|
@@ -80,10 +80,16 @@ async function copyDir(src, dest) {
|
|
|
80
80
|
const srcPath = path.join(src, entry.name);
|
|
81
81
|
const destPath = path.join(dest, entry.name);
|
|
82
82
|
if (entry.isDirectory()) {
|
|
83
|
-
await copyDir(srcPath, destPath);
|
|
83
|
+
await copyDir(srcPath, destPath, replacements);
|
|
84
84
|
}
|
|
85
85
|
else {
|
|
86
|
-
|
|
86
|
+
// Apply replacements to text files
|
|
87
|
+
if (replacements && (entry.name.endsWith('.toml') || entry.name.endsWith('.move'))) {
|
|
88
|
+
await copyFile(srcPath, destPath, replacements);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
await fs.copyFile(srcPath, destPath);
|
|
92
|
+
}
|
|
87
93
|
}
|
|
88
94
|
}
|
|
89
95
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,WAAW,CAAC,WAAoB;IAC5D,mCAAmC;IACnC,kBAAkB,EAAE,CAAC;IAErB,uBAAuB;IACvB,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;YAC7B,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,eAAe;YACxB,OAAO,EAAE,eAAe;SACzB,CAAC,CAAC;QAEH,qCAAqC;QACrC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
package/dist/templates/README.md
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
# {{
|
|
1
|
+
# {{projectName}}
|
|
2
2
|
|
|
3
3
|
A Move smart contract project built with Movehat.
|
|
4
4
|
|
|
5
5
|
## Prerequisites
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- [
|
|
7
|
+
**Required:**
|
|
8
|
+
- **Node.js v18+** - [Download](https://nodejs.org/)
|
|
9
|
+
- **Movement CLI** - **REQUIRED** for compiling contracts
|
|
10
|
+
|
|
11
|
+
Install: [Movement CLI Installation Guide](https://docs.movementnetwork.xyz/devs/movementCLI)
|
|
12
|
+
|
|
13
|
+
Verify: `movement --version`
|
|
14
|
+
|
|
15
|
+
**⚠️ Important:** Without Movement CLI, compilation will fail!
|
|
9
16
|
|
|
10
17
|
## Getting Started
|
|
11
18
|
|
|
@@ -25,41 +32,30 @@ cp .env.example .env
|
|
|
25
32
|
|
|
26
33
|
Edit `.env`:
|
|
27
34
|
```
|
|
28
|
-
|
|
29
|
-
MH_ACCOUNT=your_account_address_here
|
|
30
|
-
MH_NETWORK=testnet
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### 3. Update Move.toml
|
|
34
|
-
|
|
35
|
-
Edit `move/Move.toml` and set the `counter` address to your account address:
|
|
36
|
-
|
|
37
|
-
```toml
|
|
38
|
-
[addresses]
|
|
39
|
-
counter = "0xYOUR_ACCOUNT_ADDRESS"
|
|
35
|
+
PRIVATE_KEY=your_private_key_here
|
|
40
36
|
```
|
|
41
37
|
|
|
42
|
-
###
|
|
38
|
+
### 3. Compile contracts
|
|
43
39
|
|
|
44
40
|
```bash
|
|
45
41
|
npm run compile
|
|
46
42
|
```
|
|
47
43
|
|
|
48
|
-
|
|
44
|
+
**How it works:**
|
|
45
|
+
- Movehat automatically detects named addresses from your Move files
|
|
46
|
+
- No need to manually configure addresses in `Move.toml`
|
|
47
|
+
- Just add any new `.move` file and it will compile automatically (like Hardhat!)
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
npx tsx scripts/deploy-counter.ts
|
|
52
|
-
```
|
|
49
|
+
### 4. Run tests
|
|
53
50
|
|
|
54
|
-
Or use the Movement CLI directly:
|
|
55
51
|
```bash
|
|
56
|
-
|
|
52
|
+
npm test
|
|
57
53
|
```
|
|
58
54
|
|
|
59
|
-
###
|
|
55
|
+
### 5. Deploy (optional)
|
|
60
56
|
|
|
61
57
|
```bash
|
|
62
|
-
|
|
58
|
+
npx movehat run scripts/deploy-counter.ts
|
|
63
59
|
```
|
|
64
60
|
|
|
65
61
|
## Project Structure
|
|
@@ -80,10 +76,37 @@ npm test
|
|
|
80
76
|
|
|
81
77
|
## Available Commands
|
|
82
78
|
|
|
83
|
-
- `npm run compile` - Compile Move contracts
|
|
79
|
+
- `npm run compile` - Compile Move contracts (auto-detects addresses)
|
|
84
80
|
- `npm test` - Run integration tests
|
|
85
81
|
- `npm run test:watch` - Run tests in watch mode
|
|
86
|
-
- `npx
|
|
82
|
+
- `npx movehat run scripts/deploy-counter.ts` - Deploy and initialize counter
|
|
83
|
+
|
|
84
|
+
## How Named Addresses Work
|
|
85
|
+
|
|
86
|
+
Movehat automatically detects named addresses from your Move code:
|
|
87
|
+
|
|
88
|
+
```move
|
|
89
|
+
module counter::counter { // ← "counter" is auto-detected
|
|
90
|
+
// ...
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
- **For development:** Movehat uses temp addresses (`0xcafe`) automatically
|
|
95
|
+
- **For production:** Specify real addresses in `movehat.config.ts`
|
|
96
|
+
|
|
97
|
+
**Adding new contracts:**
|
|
98
|
+
1. Create `move/sources/MyContract.move`
|
|
99
|
+
2. Write: `module mycontract::mycontract { ... }`
|
|
100
|
+
3. Run `npm run compile`
|
|
101
|
+
4. It just works! (like Hardhat)
|
|
102
|
+
|
|
103
|
+
## Troubleshooting
|
|
104
|
+
|
|
105
|
+
| Error | Solution |
|
|
106
|
+
|-------|----------|
|
|
107
|
+
| `movement: command not found` | Install Movement CLI (see Prerequisites) |
|
|
108
|
+
| `Cannot find package 'dotenv'` | Run `npm install` |
|
|
109
|
+
| Compilation failed | Ensure Movement CLI is installed: `movement --version` |
|
|
87
110
|
|
|
88
111
|
## Learn More
|
|
89
112
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[package]
|
|
2
|
-
name = "{{
|
|
2
|
+
name = "{{projectName}}"
|
|
3
3
|
version = "1.0.0"
|
|
4
4
|
authors = []
|
|
5
5
|
|
|
@@ -7,6 +7,8 @@ authors = []
|
|
|
7
7
|
counter = "_"
|
|
8
8
|
|
|
9
9
|
[dev-addresses]
|
|
10
|
+
# Dev addresses are auto-detected by movehat during compilation
|
|
11
|
+
# You can also add them manually here if needed
|
|
10
12
|
|
|
11
13
|
[dependencies.AptosFramework]
|
|
12
14
|
git = "https://github.com/movementlabsxyz/aptos-core.git"
|
package/package.json
CHANGED
package/src/commands/compile.ts
CHANGED
|
@@ -4,6 +4,72 @@ import { exec } from "child_process";
|
|
|
4
4
|
import { loadUserConfig } from "../core/config.js";
|
|
5
5
|
import { validateAndEscapePath, escapeShellArg } from "../core/shell.js";
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Recursively find all .move files in a directory
|
|
9
|
+
* @param dir - Directory to search
|
|
10
|
+
* @param maxDepth - Maximum recursion depth (default: 10)
|
|
11
|
+
* @param currentDepth - Current recursion depth (internal use)
|
|
12
|
+
*/
|
|
13
|
+
function findMoveFiles(dir: string, maxDepth: number = 10, currentDepth: number = 0): string[] {
|
|
14
|
+
const files: string[] = [];
|
|
15
|
+
|
|
16
|
+
// Prevent infinite loops from excessive recursion
|
|
17
|
+
if (currentDepth > maxDepth) {
|
|
18
|
+
return files;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
22
|
+
|
|
23
|
+
for (const entry of entries) {
|
|
24
|
+
const fullPath = path.join(dir, entry.name);
|
|
25
|
+
|
|
26
|
+
if (entry.isDirectory()) {
|
|
27
|
+
// Skip symlinks to prevent directory traversal and infinite loops
|
|
28
|
+
if (entry.isSymbolicLink()) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
files.push(...findMoveFiles(fullPath, maxDepth, currentDepth + 1));
|
|
32
|
+
} else if (entry.name.endsWith('.move')) {
|
|
33
|
+
files.push(fullPath);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return files;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Extract named addresses used in Move files
|
|
42
|
+
* Looks for patterns like: module <address>::<module_name>
|
|
43
|
+
*/
|
|
44
|
+
function extractNamedAddresses(moveDir: string): Set<string> {
|
|
45
|
+
const addresses = new Set<string>();
|
|
46
|
+
const moveFiles = findMoveFiles(moveDir);
|
|
47
|
+
|
|
48
|
+
for (const file of moveFiles) {
|
|
49
|
+
let content = fs.readFileSync(file, 'utf-8');
|
|
50
|
+
|
|
51
|
+
// Strip comments to avoid false positives
|
|
52
|
+
// Remove block comments /* ... */ (non-greedy, handles newlines)
|
|
53
|
+
content = content.replace(/\/\*[\s\S]*?\*\//g, ' ');
|
|
54
|
+
// Remove line comments // ... to end of line
|
|
55
|
+
content = content.replace(/\/\/.*$/gm, ' ');
|
|
56
|
+
|
|
57
|
+
// Match: module <address>::<module_name>
|
|
58
|
+
const moduleRegex = /module\s+([a-zA-Z_][a-zA-Z0-9_]*)::/g;
|
|
59
|
+
let match;
|
|
60
|
+
|
|
61
|
+
while ((match = moduleRegex.exec(content)) !== null) {
|
|
62
|
+
const address = match[1];
|
|
63
|
+
// Skip standard addresses
|
|
64
|
+
if (address !== 'std' && address !== 'aptos_framework' && address !== 'aptos_std') {
|
|
65
|
+
addresses.add(address);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return addresses;
|
|
71
|
+
}
|
|
72
|
+
|
|
7
73
|
function run(command: string, cwd: string) {
|
|
8
74
|
return new Promise<void>((resolve, reject) => {
|
|
9
75
|
exec(command, { cwd }, (error, stdout, stderr) => {
|
|
@@ -23,11 +89,11 @@ export default async function compileCommand() {
|
|
|
23
89
|
// Compile is network-independent - only uses global config
|
|
24
90
|
const userConfig = await loadUserConfig();
|
|
25
91
|
|
|
26
|
-
console.log("
|
|
92
|
+
console.log("Compiling Move contracts...");
|
|
27
93
|
|
|
28
94
|
const moveDir = path.resolve(process.cwd(), userConfig.moveDir || "./move");
|
|
29
95
|
if (!fs.existsSync(moveDir)) {
|
|
30
|
-
console.error(
|
|
96
|
+
console.error(`Move directory not found: ${moveDir}`);
|
|
31
97
|
console.error(` Update movehat.config.ts -> moveDir`);
|
|
32
98
|
return;
|
|
33
99
|
}
|
|
@@ -35,8 +101,21 @@ export default async function compileCommand() {
|
|
|
35
101
|
// Validate and escape to prevent command injection
|
|
36
102
|
const safeMoveDir = validateAndEscapePath(moveDir, "Move directory");
|
|
37
103
|
|
|
38
|
-
//
|
|
39
|
-
const
|
|
104
|
+
// Auto-detect named addresses from Move files
|
|
105
|
+
const detectedAddresses = extractNamedAddresses(moveDir);
|
|
106
|
+
|
|
107
|
+
// Merge user-configured addresses with auto-detected ones
|
|
108
|
+
const namedAddresses = { ...(userConfig.namedAddresses ?? {}) };
|
|
109
|
+
const autoAssignedAddresses: string[] = [];
|
|
110
|
+
|
|
111
|
+
// For any detected address not in config, use a dev address
|
|
112
|
+
for (const addr of detectedAddresses) {
|
|
113
|
+
if (!namedAddresses[addr]) {
|
|
114
|
+
namedAddresses[addr] = "0xcafe"; // Dev address for compilation
|
|
115
|
+
autoAssignedAddresses.push(addr);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
40
119
|
let namedAddressesArg = "";
|
|
41
120
|
|
|
42
121
|
if (Object.keys(namedAddresses).length > 0) {
|
|
@@ -70,15 +149,21 @@ export default async function compileCommand() {
|
|
|
70
149
|
const command = `movement move build --package-dir ${safeMoveDir} ${namedAddressesArg}`.trim();
|
|
71
150
|
|
|
72
151
|
console.log(` Move directory: ${moveDir}`);
|
|
73
|
-
if (
|
|
74
|
-
console.log(`
|
|
152
|
+
if (detectedAddresses.size > 0) {
|
|
153
|
+
console.log(` Detected addresses: ${Array.from(detectedAddresses).join(", ")}`);
|
|
154
|
+
}
|
|
155
|
+
if (Object.keys(userConfig.namedAddresses ?? {}).length > 0) {
|
|
156
|
+
console.log(` Configured addresses: ${Object.keys(userConfig.namedAddresses!).join(", ")}`);
|
|
157
|
+
}
|
|
158
|
+
if (autoAssignedAddresses.length > 0) {
|
|
159
|
+
console.log(` Auto-assigned dev address (0xcafe): ${autoAssignedAddresses.join(", ")}`);
|
|
75
160
|
}
|
|
76
161
|
console.log();
|
|
77
162
|
|
|
78
163
|
await run(command, moveDir);
|
|
79
|
-
console.log("
|
|
164
|
+
console.log("Compilation finished successfully.");
|
|
80
165
|
} catch (err: any) {
|
|
81
|
-
console.error("
|
|
166
|
+
console.error("Compilation failed:", err.message ?? err);
|
|
82
167
|
process.exit(1);
|
|
83
168
|
}
|
|
84
169
|
}
|
package/src/commands/init.ts
CHANGED
|
@@ -22,7 +22,7 @@ export default async function initCommand(projectName?: string) {
|
|
|
22
22
|
|
|
23
23
|
// If the user cancels (Ctrl+C), exit
|
|
24
24
|
if (!response.projectName) {
|
|
25
|
-
console.log('\
|
|
25
|
+
console.log('\nProject initialization cancelled.');
|
|
26
26
|
process.exit(0);
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -39,7 +39,7 @@ export default async function initCommand(projectName?: string) {
|
|
|
39
39
|
|
|
40
40
|
const templatesDir = path.join(__dirname, "..", "templates");
|
|
41
41
|
|
|
42
|
-
console.log("
|
|
42
|
+
console.log("Creating project structure...");
|
|
43
43
|
|
|
44
44
|
await copyFile(
|
|
45
45
|
path.join(templatesDir, "package.json"),
|
|
@@ -79,28 +79,29 @@ export default async function initCommand(projectName?: string) {
|
|
|
79
79
|
);
|
|
80
80
|
|
|
81
81
|
// 3. Copiar carpeta move/
|
|
82
|
-
console.log("
|
|
82
|
+
console.log("Setting up Move project...");
|
|
83
83
|
await copyDir(
|
|
84
84
|
path.join(templatesDir, "move"),
|
|
85
|
-
path.join(projectPath, "move")
|
|
85
|
+
path.join(projectPath, "move"),
|
|
86
|
+
{ projectName: projectName! }
|
|
86
87
|
);
|
|
87
88
|
|
|
88
89
|
// 4. Copiar scripts/
|
|
89
|
-
console.log("
|
|
90
|
+
console.log("Adding deployment scripts...");
|
|
90
91
|
await copyDir(
|
|
91
92
|
path.join(templatesDir, "scripts"),
|
|
92
93
|
path.join(projectPath, "scripts")
|
|
93
94
|
);
|
|
94
95
|
|
|
95
96
|
// 5. Copiar tests/
|
|
96
|
-
console.log("
|
|
97
|
+
console.log("Adding test files...");
|
|
97
98
|
await copyDir(
|
|
98
99
|
path.join(templatesDir, "tests"),
|
|
99
100
|
path.join(projectPath, "tests")
|
|
100
101
|
);
|
|
101
102
|
|
|
102
|
-
console.log("\
|
|
103
|
-
console.log("
|
|
103
|
+
console.log("\nProject created successfully!\n");
|
|
104
|
+
console.log("Next steps:\n");
|
|
104
105
|
console.log(` cd ${projectName}`);
|
|
105
106
|
console.log(` cp .env.example .env`);
|
|
106
107
|
console.log(` # Edit .env with your credentials`);
|
|
@@ -128,7 +129,7 @@ async function copyFile(
|
|
|
128
129
|
await fs.writeFile(dest, content);
|
|
129
130
|
}
|
|
130
131
|
|
|
131
|
-
async function copyDir(src: string, dest: string) {
|
|
132
|
+
async function copyDir(src: string, dest: string, replacements?: Record<string, string>) {
|
|
132
133
|
await fs.mkdir(dest, { recursive: true });
|
|
133
134
|
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
134
135
|
|
|
@@ -142,9 +143,14 @@ async function copyDir(src: string, dest: string) {
|
|
|
142
143
|
const destPath = path.join(dest, entry.name);
|
|
143
144
|
|
|
144
145
|
if (entry.isDirectory()) {
|
|
145
|
-
await copyDir(srcPath, destPath);
|
|
146
|
+
await copyDir(srcPath, destPath, replacements);
|
|
146
147
|
} else {
|
|
147
|
-
|
|
148
|
+
// Apply replacements to text files
|
|
149
|
+
if (replacements && (entry.name.endsWith('.toml') || entry.name.endsWith('.move'))) {
|
|
150
|
+
await copyFile(srcPath, destPath, replacements);
|
|
151
|
+
} else {
|
|
152
|
+
await fs.copyFile(srcPath, destPath);
|
|
153
|
+
}
|
|
148
154
|
}
|
|
149
155
|
}
|
|
150
156
|
}
|
package/src/templates/README.md
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
# {{
|
|
1
|
+
# {{projectName}}
|
|
2
2
|
|
|
3
3
|
A Move smart contract project built with Movehat.
|
|
4
4
|
|
|
5
5
|
## Prerequisites
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- [
|
|
7
|
+
**Required:**
|
|
8
|
+
- **Node.js v18+** - [Download](https://nodejs.org/)
|
|
9
|
+
- **Movement CLI** - **REQUIRED** for compiling contracts
|
|
10
|
+
|
|
11
|
+
Install: [Movement CLI Installation Guide](https://docs.movementnetwork.xyz/devs/movementCLI)
|
|
12
|
+
|
|
13
|
+
Verify: `movement --version`
|
|
14
|
+
|
|
15
|
+
**⚠️ Important:** Without Movement CLI, compilation will fail!
|
|
9
16
|
|
|
10
17
|
## Getting Started
|
|
11
18
|
|
|
@@ -25,41 +32,30 @@ cp .env.example .env
|
|
|
25
32
|
|
|
26
33
|
Edit `.env`:
|
|
27
34
|
```
|
|
28
|
-
|
|
29
|
-
MH_ACCOUNT=your_account_address_here
|
|
30
|
-
MH_NETWORK=testnet
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### 3. Update Move.toml
|
|
34
|
-
|
|
35
|
-
Edit `move/Move.toml` and set the `counter` address to your account address:
|
|
36
|
-
|
|
37
|
-
```toml
|
|
38
|
-
[addresses]
|
|
39
|
-
counter = "0xYOUR_ACCOUNT_ADDRESS"
|
|
35
|
+
PRIVATE_KEY=your_private_key_here
|
|
40
36
|
```
|
|
41
37
|
|
|
42
|
-
###
|
|
38
|
+
### 3. Compile contracts
|
|
43
39
|
|
|
44
40
|
```bash
|
|
45
41
|
npm run compile
|
|
46
42
|
```
|
|
47
43
|
|
|
48
|
-
|
|
44
|
+
**How it works:**
|
|
45
|
+
- Movehat automatically detects named addresses from your Move files
|
|
46
|
+
- No need to manually configure addresses in `Move.toml`
|
|
47
|
+
- Just add any new `.move` file and it will compile automatically (like Hardhat!)
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
npx tsx scripts/deploy-counter.ts
|
|
52
|
-
```
|
|
49
|
+
### 4. Run tests
|
|
53
50
|
|
|
54
|
-
Or use the Movement CLI directly:
|
|
55
51
|
```bash
|
|
56
|
-
|
|
52
|
+
npm test
|
|
57
53
|
```
|
|
58
54
|
|
|
59
|
-
###
|
|
55
|
+
### 5. Deploy (optional)
|
|
60
56
|
|
|
61
57
|
```bash
|
|
62
|
-
|
|
58
|
+
npx movehat run scripts/deploy-counter.ts
|
|
63
59
|
```
|
|
64
60
|
|
|
65
61
|
## Project Structure
|
|
@@ -80,10 +76,37 @@ npm test
|
|
|
80
76
|
|
|
81
77
|
## Available Commands
|
|
82
78
|
|
|
83
|
-
- `npm run compile` - Compile Move contracts
|
|
79
|
+
- `npm run compile` - Compile Move contracts (auto-detects addresses)
|
|
84
80
|
- `npm test` - Run integration tests
|
|
85
81
|
- `npm run test:watch` - Run tests in watch mode
|
|
86
|
-
- `npx
|
|
82
|
+
- `npx movehat run scripts/deploy-counter.ts` - Deploy and initialize counter
|
|
83
|
+
|
|
84
|
+
## How Named Addresses Work
|
|
85
|
+
|
|
86
|
+
Movehat automatically detects named addresses from your Move code:
|
|
87
|
+
|
|
88
|
+
```move
|
|
89
|
+
module counter::counter { // ← "counter" is auto-detected
|
|
90
|
+
// ...
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
- **For development:** Movehat uses temp addresses (`0xcafe`) automatically
|
|
95
|
+
- **For production:** Specify real addresses in `movehat.config.ts`
|
|
96
|
+
|
|
97
|
+
**Adding new contracts:**
|
|
98
|
+
1. Create `move/sources/MyContract.move`
|
|
99
|
+
2. Write: `module mycontract::mycontract { ... }`
|
|
100
|
+
3. Run `npm run compile`
|
|
101
|
+
4. It just works! (like Hardhat)
|
|
102
|
+
|
|
103
|
+
## Troubleshooting
|
|
104
|
+
|
|
105
|
+
| Error | Solution |
|
|
106
|
+
|-------|----------|
|
|
107
|
+
| `movement: command not found` | Install Movement CLI (see Prerequisites) |
|
|
108
|
+
| `Cannot find package 'dotenv'` | Run `npm install` |
|
|
109
|
+
| Compilation failed | Ensure Movement CLI is installed: `movement --version` |
|
|
87
110
|
|
|
88
111
|
## Learn More
|
|
89
112
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[package]
|
|
2
|
-
name = "{{
|
|
2
|
+
name = "{{projectName}}"
|
|
3
3
|
version = "1.0.0"
|
|
4
4
|
authors = []
|
|
5
5
|
|
|
@@ -7,6 +7,8 @@ authors = []
|
|
|
7
7
|
counter = "_"
|
|
8
8
|
|
|
9
9
|
[dev-addresses]
|
|
10
|
+
# Dev addresses are auto-detected by movehat during compilation
|
|
11
|
+
# You can also add them manually here if needed
|
|
10
12
|
|
|
11
13
|
[dependencies.AptosFramework]
|
|
12
14
|
git = "https://github.com/movementlabsxyz/aptos-core.git"
|
|
File without changes
|
|
File without changes
|