mobilestacks 0.1.1 → 0.1.3
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/dist/mobilestacks.config.js +3 -1
- package/dist/src/cli/index.js +38 -33
- package/dist/src/cli/init.js +21 -15
- package/dist/src/config/config-loading.js +20 -14
- package/dist/src/core/dsl.js +13 -7
- package/dist/src/core/dsl.test.js +29 -27
- package/dist/src/core/env.js +9 -3
- package/dist/src/core/extender.js +7 -2
- package/dist/src/core/runtime-environment.js +14 -10
- package/dist/src/core/simnet.js +7 -3
- package/dist/src/core/tasks-definitions.js +4 -1
- package/dist/src/index.js +26 -4
- package/dist/src/tasks/call-contract-function.js +9 -4
- package/dist/src/tasks/deploy-contract.js +15 -10
- package/dist/src/tasks/example-task.js +4 -2
- package/dist/src/tasks/faucet-request.js +9 -4
- package/dist/src/tasks/get-balance.js +9 -4
- package/dist/src/tasks/get-contract-info.js +9 -4
- package/dist/src/tasks/get-tx-history.js +9 -4
- package/dist/src/tasks/list-accounts.js +6 -4
- package/dist/src/tasks/send-stx.js +7 -5
- package/dist/src/tasks/verify-contract.js +11 -6
- package/dist/src/types/config.js +18 -15
- package/package.json +10 -7
package/dist/src/cli/index.js
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const commander_1 = require("commander");
|
|
9
|
+
const config_loading_1 = require("../config/config-loading");
|
|
10
|
+
const runtime_environment_1 = require("../core/runtime-environment");
|
|
11
|
+
const tasks_definitions_1 = require("../core/tasks-definitions");
|
|
12
|
+
const init_1 = require("./init");
|
|
13
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
9
14
|
// Import all user tasks
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
16
|
+
const path_1 = __importDefault(require("path"));
|
|
12
17
|
// Auto-load all tasks in src/tasks
|
|
13
|
-
const tasksDir =
|
|
14
|
-
|
|
18
|
+
const tasksDir = path_1.default.join(__dirname, '../tasks');
|
|
19
|
+
fs_1.default.readdirSync(tasksDir)
|
|
15
20
|
.filter(f => f.endsWith('.ts') || f.endsWith('.js'))
|
|
16
21
|
.forEach(f => {
|
|
17
|
-
require(
|
|
22
|
+
require(path_1.default.join(tasksDir, f));
|
|
18
23
|
});
|
|
19
|
-
const program = new Command();
|
|
24
|
+
const program = new commander_1.Command();
|
|
20
25
|
program
|
|
21
26
|
.name('mobilestacks')
|
|
22
27
|
.description('Professional Task Runner for Stacks')
|
|
@@ -26,27 +31,27 @@ program
|
|
|
26
31
|
.command('init')
|
|
27
32
|
.description('Scaffold a new mobilestacks project and config')
|
|
28
33
|
.action(async () => {
|
|
29
|
-
await runInit();
|
|
34
|
+
await (0, init_1.runInit)();
|
|
30
35
|
process.exit(0);
|
|
31
36
|
});
|
|
32
37
|
// List all tasks if no command is given
|
|
33
38
|
program.action(() => {
|
|
34
|
-
console.log(
|
|
35
|
-
console.log(
|
|
36
|
-
console.log(
|
|
37
|
-
TaskDefinitions.getInstance().getAllTasks().forEach(task => {
|
|
38
|
-
const params = task.params.map(p =>
|
|
39
|
-
console.log(' ' +
|
|
40
|
-
console.log(' ' +
|
|
39
|
+
console.log(chalk_1.default.bold.blue('\nMobilestacks - Professional Task Runner for Stacks\n'));
|
|
40
|
+
console.log(chalk_1.default.white('USAGE: ') + chalk_1.default.green('mobilestacks <task> [options]\n'));
|
|
41
|
+
console.log(chalk_1.default.bold('Available tasks:'));
|
|
42
|
+
tasks_definitions_1.TaskDefinitions.getInstance().getAllTasks().forEach(task => {
|
|
43
|
+
const params = task.params.map(p => chalk_1.default.yellow(`--${p.name}`)).join(' ');
|
|
44
|
+
console.log(' ' + chalk_1.default.cyan(task.name) + ' ' + params);
|
|
45
|
+
console.log(' ' + chalk_1.default.gray(task.description));
|
|
41
46
|
});
|
|
42
|
-
console.log('\n' +
|
|
43
|
-
console.log(
|
|
44
|
-
console.log(' ' +
|
|
45
|
-
console.log(
|
|
47
|
+
console.log('\n' + chalk_1.default.white('Use ') + chalk_1.default.green('mobilestacks <task> --help') + chalk_1.default.white(' for more info on a task.'));
|
|
48
|
+
console.log(chalk_1.default.white('\nExample:'));
|
|
49
|
+
console.log(' ' + chalk_1.default.green('mobilestacks deploy-contract --contractName my-contract --file ./contracts/my-contract.clar --network testnet'));
|
|
50
|
+
console.log(chalk_1.default.white('\nDocs: ') + chalk_1.default.underline('https://github.com/your-org/mobilestacks#readme'));
|
|
46
51
|
program.help({ error: false });
|
|
47
52
|
});
|
|
48
53
|
// Dynamically add all registered tasks
|
|
49
|
-
TaskDefinitions.getInstance().getAllTasks().forEach(task => {
|
|
54
|
+
tasks_definitions_1.TaskDefinitions.getInstance().getAllTasks().forEach(task => {
|
|
50
55
|
const cmd = program.command(task.name)
|
|
51
56
|
.description(task.description);
|
|
52
57
|
task.params.forEach(param => {
|
|
@@ -63,7 +68,7 @@ TaskDefinitions.getInstance().getAllTasks().forEach(task => {
|
|
|
63
68
|
// Prompt for missing required params
|
|
64
69
|
const missing = task.params.filter(p => p.required !== false && !opts[p.name]);
|
|
65
70
|
if (missing.length > 0) {
|
|
66
|
-
const answers = await
|
|
71
|
+
const answers = await inquirer_1.default.prompt(missing.map(p => ({
|
|
67
72
|
type: p.type === 'boolean' ? 'confirm' : 'input',
|
|
68
73
|
name: p.name,
|
|
69
74
|
message: p.description,
|
|
@@ -78,22 +83,22 @@ TaskDefinitions.getInstance().getAllTasks().forEach(task => {
|
|
|
78
83
|
if (opts[p.name] && p.type === 'boolean')
|
|
79
84
|
opts[p.name] = Boolean(opts[p.name]);
|
|
80
85
|
});
|
|
81
|
-
const config = loadConfig();
|
|
82
|
-
const env = new RuntimeEnvironment(config);
|
|
86
|
+
const config = (0, config_loading_1.loadConfig)();
|
|
87
|
+
const env = new runtime_environment_1.RuntimeEnvironment(config);
|
|
83
88
|
const result = await task.action(opts, env);
|
|
84
89
|
if (typeof result === 'object') {
|
|
85
|
-
console.log(
|
|
90
|
+
console.log(chalk_1.default.greenBright('Success!'));
|
|
86
91
|
console.dir(result, { depth: null, colors: true });
|
|
87
92
|
}
|
|
88
93
|
else {
|
|
89
|
-
console.log(
|
|
94
|
+
console.log(chalk_1.default.greenBright(result));
|
|
90
95
|
}
|
|
91
96
|
}
|
|
92
97
|
catch (err) {
|
|
93
98
|
const error = err;
|
|
94
|
-
console.error(
|
|
99
|
+
console.error(chalk_1.default.redBright('Task failed:'), error.message || error);
|
|
95
100
|
if (error && typeof error === 'object' && 'stack' in error && error.stack) {
|
|
96
|
-
console.error(
|
|
101
|
+
console.error(chalk_1.default.gray(error.stack));
|
|
97
102
|
}
|
|
98
103
|
process.exit(1);
|
|
99
104
|
}
|
package/dist/src/cli/init.js
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runInit = runInit;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
10
|
+
async function runInit() {
|
|
5
11
|
console.log('Welcome to mobilestacks project initialization!');
|
|
6
|
-
const answers = await
|
|
12
|
+
const answers = await inquirer_1.default.prompt([
|
|
7
13
|
{
|
|
8
14
|
type: 'input',
|
|
9
15
|
name: 'projectName',
|
|
10
16
|
message: 'Project name:',
|
|
11
|
-
default:
|
|
17
|
+
default: path_1.default.basename(process.cwd()),
|
|
12
18
|
},
|
|
13
19
|
{
|
|
14
20
|
type: 'input',
|
|
@@ -40,16 +46,16 @@ export async function runInit() {
|
|
|
40
46
|
},
|
|
41
47
|
]);
|
|
42
48
|
const config = `export default {\n networks: {\n mainnet: { url: '${answers.mainnetUrl}', name: 'mainnet' },\n testnet: { url: '${answers.testnetUrl}', name: 'testnet' }\n },\n defaultNetwork: 'testnet',\n wallet: {\n ${answers.privateKey ? `privateKey: '${answers.privateKey}',` : ''}\n ${answers.seedPhrase ? `seedPhrase: '${answers.seedPhrase}',` : ''}\n derivationPath: '${answers.derivationPath}'\n }\n};\n`;
|
|
43
|
-
|
|
49
|
+
fs_1.default.writeFileSync(path_1.default.join(process.cwd(), 'mobilestacks.config.ts'), config);
|
|
44
50
|
// Scaffold example contract
|
|
45
|
-
const contractsDir =
|
|
46
|
-
if (!
|
|
47
|
-
|
|
48
|
-
|
|
51
|
+
const contractsDir = path_1.default.join(process.cwd(), 'contracts');
|
|
52
|
+
if (!fs_1.default.existsSync(contractsDir))
|
|
53
|
+
fs_1.default.mkdirSync(contractsDir);
|
|
54
|
+
fs_1.default.writeFileSync(path_1.default.join(contractsDir, 'sample-contract.clar'), '(define-public (hello-world)\n (ok "Hello, Stacks!"))\n');
|
|
49
55
|
// Scaffold example user task
|
|
50
|
-
const tasksDir =
|
|
51
|
-
if (!
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
const tasksDir = path_1.default.join(process.cwd(), 'src', 'tasks');
|
|
57
|
+
if (!fs_1.default.existsSync(tasksDir))
|
|
58
|
+
fs_1.default.mkdirSync(tasksDir, { recursive: true });
|
|
59
|
+
fs_1.default.writeFileSync(path_1.default.join(tasksDir, 'example-task.ts'), "import { task } from '../core/dsl';\n\ntask('example', 'An example user task for onboarding')\n .addParam('name', 'Your name', { type: 'string', required: false, defaultValue: 'World' })\n .setAction(async (args) => {\n return `Hello, ${args.name}! Welcome to mobilestacks.`;\n });\n");
|
|
54
60
|
console.log('Created mobilestacks.config.ts, contracts/sample-contract.clar, and src/tasks/example-task.ts!');
|
|
55
61
|
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loadConfig = loadConfig;
|
|
7
|
+
const config_1 = require("../types/config");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const env_1 = require("../core/env");
|
|
11
|
+
function loadConfig(configPath, cliOverrides = {}) {
|
|
12
|
+
const configFile = configPath || path_1.default.resolve(process.cwd(), 'mobilestacks.config.ts');
|
|
13
|
+
if (!fs_1.default.existsSync(configFile)) {
|
|
8
14
|
throw new Error(`Config file not found: ${configFile}`);
|
|
9
15
|
}
|
|
10
16
|
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
|
|
@@ -13,15 +19,15 @@ export function loadConfig(configPath, cliOverrides = {}) {
|
|
|
13
19
|
const userConfig = require(configFile);
|
|
14
20
|
let config = userConfig.default || userConfig;
|
|
15
21
|
// .env override
|
|
16
|
-
if (env.privateKey)
|
|
17
|
-
config.wallet.privateKey = env.privateKey;
|
|
18
|
-
if (env.mainnetUrl)
|
|
19
|
-
config.networks.mainnet.url = env.mainnetUrl;
|
|
20
|
-
if (env.testnetUrl)
|
|
21
|
-
config.networks.testnet.url = env.testnetUrl;
|
|
22
|
+
if (env_1.env.privateKey)
|
|
23
|
+
config.wallet.privateKey = env_1.env.privateKey;
|
|
24
|
+
if (env_1.env.mainnetUrl)
|
|
25
|
+
config.networks.mainnet.url = env_1.env.mainnetUrl;
|
|
26
|
+
if (env_1.env.testnetUrl)
|
|
27
|
+
config.networks.testnet.url = env_1.env.testnetUrl;
|
|
22
28
|
// CLI overrides
|
|
23
29
|
config = { ...config, ...cliOverrides };
|
|
24
|
-
const parsed = MobilestacksConfigSchema.safeParse(config);
|
|
30
|
+
const parsed = config_1.MobilestacksConfigSchema.safeParse(config);
|
|
25
31
|
if (!parsed.success) {
|
|
26
32
|
throw new Error('Invalid mobilestacks.config.ts: ' + JSON.stringify(parsed.error.format(), null, 2));
|
|
27
33
|
}
|
package/dist/src/core/dsl.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extendEnvironment = void 0;
|
|
4
|
+
exports.runWorkflow = runWorkflow;
|
|
5
|
+
exports.task = task;
|
|
6
|
+
exports.subtask = subtask;
|
|
7
|
+
const tasks_definitions_1 = require("./tasks-definitions");
|
|
8
|
+
const extender_1 = require("./extender");
|
|
9
|
+
Object.defineProperty(exports, "extendEnvironment", { enumerable: true, get: function () { return extender_1.extendEnvironment; } });
|
|
3
10
|
function task(name, description) {
|
|
4
11
|
const params = [];
|
|
5
12
|
return {
|
|
@@ -34,7 +41,7 @@ function task(name, description) {
|
|
|
34
41
|
return action(args, env);
|
|
35
42
|
},
|
|
36
43
|
};
|
|
37
|
-
TaskDefinitions.getInstance().addTask(def);
|
|
44
|
+
tasks_definitions_1.TaskDefinitions.getInstance().addTask(def);
|
|
38
45
|
return def;
|
|
39
46
|
},
|
|
40
47
|
};
|
|
@@ -44,19 +51,18 @@ function subtask(name, description, parentTaskName) {
|
|
|
44
51
|
const sub = task(name, description);
|
|
45
52
|
if (parentTaskName) {
|
|
46
53
|
// Attach parent info for future use (e.g., dependency graph, CLI grouping)
|
|
47
|
-
const def = TaskDefinitions.getInstance().getTask(name);
|
|
54
|
+
const def = tasks_definitions_1.TaskDefinitions.getInstance().getTask(name);
|
|
48
55
|
if (def)
|
|
49
56
|
def.parent = parentTaskName;
|
|
50
57
|
}
|
|
51
58
|
return sub;
|
|
52
59
|
}
|
|
53
|
-
|
|
60
|
+
async function runWorkflow(workflow, env) {
|
|
54
61
|
for (const step of workflow) {
|
|
55
|
-
const def = TaskDefinitions.getInstance().getTask(step.taskName);
|
|
62
|
+
const def = tasks_definitions_1.TaskDefinitions.getInstance().getTask(step.taskName);
|
|
56
63
|
if (!def)
|
|
57
64
|
throw new Error(`Task not found: ${step.taskName}`);
|
|
58
65
|
// eslint-disable-next-line no-await-in-loop
|
|
59
66
|
await def.action(step.args || {}, env);
|
|
60
67
|
}
|
|
61
68
|
}
|
|
62
|
-
export { task, subtask, extendEnvironment };
|
|
@@ -1,48 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const dsl_1 = require("./dsl");
|
|
5
|
+
const tasks_definitions_1 = require("./tasks-definitions");
|
|
6
|
+
const zod_1 = require("zod");
|
|
7
|
+
const extender_1 = require("./extender");
|
|
8
|
+
(0, vitest_1.describe)('DSL', () => {
|
|
9
|
+
(0, vitest_1.beforeEach)(() => {
|
|
8
10
|
// Clear tasks before each test
|
|
9
|
-
TaskDefinitions.getInstance()._tasks = [];
|
|
11
|
+
tasks_definitions_1.TaskDefinitions.getInstance()._tasks = [];
|
|
10
12
|
});
|
|
11
|
-
it('should register a task with generic parameters', () => {
|
|
12
|
-
task('test-task', 'A test task')
|
|
13
|
+
(0, vitest_1.it)('should register a task with generic parameters', () => {
|
|
14
|
+
(0, dsl_1.task)('test-task', 'A test task')
|
|
13
15
|
.addParam('p1', 'param 1')
|
|
14
16
|
.setAction(async () => { return 'done'; });
|
|
15
|
-
const def = TaskDefinitions.getInstance().getTask('test-task');
|
|
16
|
-
expect(def).toBeDefined();
|
|
17
|
-
expect(def?.name).toBe('test-task');
|
|
18
|
-
expect(def?.params.length).toBe(1);
|
|
17
|
+
const def = tasks_definitions_1.TaskDefinitions.getInstance().getTask('test-task');
|
|
18
|
+
(0, vitest_1.expect)(def).toBeDefined();
|
|
19
|
+
(0, vitest_1.expect)(def?.name).toBe('test-task');
|
|
20
|
+
(0, vitest_1.expect)(def?.params.length).toBe(1);
|
|
19
21
|
});
|
|
20
|
-
it('should validate Zod schema', async () => {
|
|
21
|
-
task('zod-task', 'Task with validation')
|
|
22
|
-
.addParam('age', 'Age param', { schema: z.number().min(18) })
|
|
22
|
+
(0, vitest_1.it)('should validate Zod schema', async () => {
|
|
23
|
+
(0, dsl_1.task)('zod-task', 'Task with validation')
|
|
24
|
+
.addParam('age', 'Age param', { schema: zod_1.z.number().min(18) })
|
|
23
25
|
.setAction(async (args) => {
|
|
24
26
|
return args.age;
|
|
25
27
|
});
|
|
26
|
-
const def = TaskDefinitions.getInstance().getTask('zod-task');
|
|
27
|
-
expect(def).toBeDefined();
|
|
28
|
+
const def = tasks_definitions_1.TaskDefinitions.getInstance().getTask('zod-task');
|
|
29
|
+
(0, vitest_1.expect)(def).toBeDefined();
|
|
28
30
|
// Mock environment
|
|
29
31
|
const env = {};
|
|
30
32
|
// Valid call
|
|
31
33
|
const result = await def?.action({ age: 20 }, env);
|
|
32
|
-
expect(result).toBe(20);
|
|
34
|
+
(0, vitest_1.expect)(result).toBe(20);
|
|
33
35
|
// Invalid call
|
|
34
|
-
await expect(def?.action({ age: 10 }, env)).rejects.toThrow('Invalid value for parameter \'age\'');
|
|
36
|
+
await (0, vitest_1.expect)(def?.action({ age: 10 }, env)).rejects.toThrow('Invalid value for parameter \'age\'');
|
|
35
37
|
});
|
|
36
|
-
it('should support environment extensions', () => {
|
|
38
|
+
(0, vitest_1.it)('should support environment extensions', () => {
|
|
37
39
|
// Clear extensions
|
|
38
|
-
Extender.getInstance()._extensions = [];
|
|
39
|
-
extendEnvironment((env) => {
|
|
40
|
+
extender_1.Extender.getInstance()._extensions = [];
|
|
41
|
+
(0, extender_1.extendEnvironment)((env) => {
|
|
40
42
|
env['foo'] = 'bar';
|
|
41
43
|
});
|
|
42
|
-
const extensions = Extender.getInstance().getExtensions();
|
|
43
|
-
expect(extensions.length).toBe(1);
|
|
44
|
+
const extensions = extender_1.Extender.getInstance().getExtensions();
|
|
45
|
+
(0, vitest_1.expect)(extensions.length).toBe(1);
|
|
44
46
|
const mockEnv = {};
|
|
45
47
|
extensions[0](mockEnv);
|
|
46
|
-
expect(mockEnv['foo']).toBe('bar');
|
|
48
|
+
(0, vitest_1.expect)(mockEnv['foo']).toBe('bar');
|
|
47
49
|
});
|
|
48
50
|
});
|
package/dist/src/core/env.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.env = void 0;
|
|
7
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
8
|
+
dotenv_1.default.config();
|
|
9
|
+
exports.env = {
|
|
4
10
|
privateKey: process.env.STACKS_PRIVATE_KEY,
|
|
5
11
|
mainnetUrl: process.env.STACKS_MAINNET_URL,
|
|
6
12
|
testnetUrl: process.env.STACKS_TESTNET_URL,
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Extender = void 0;
|
|
4
|
+
exports.extendEnvironment = extendEnvironment;
|
|
5
|
+
class Extender {
|
|
2
6
|
constructor() {
|
|
3
7
|
this._extensions = [];
|
|
4
8
|
}
|
|
@@ -15,6 +19,7 @@ export class Extender {
|
|
|
15
19
|
return this._extensions;
|
|
16
20
|
}
|
|
17
21
|
}
|
|
18
|
-
|
|
22
|
+
exports.Extender = Extender;
|
|
23
|
+
function extendEnvironment(func) {
|
|
19
24
|
Extender.getInstance().addExtension(func);
|
|
20
25
|
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RuntimeEnvironment = void 0;
|
|
4
|
+
const transactions_1 = require("@stacks/transactions");
|
|
5
|
+
const wallet_sdk_1 = require("@stacks/wallet-sdk");
|
|
6
|
+
const network_1 = require("@stacks/network");
|
|
7
|
+
const extender_1 = require("./extender");
|
|
8
|
+
class RuntimeEnvironment {
|
|
6
9
|
constructor(config) {
|
|
7
10
|
this.config = config;
|
|
8
11
|
const networkName = config.defaultNetwork;
|
|
@@ -12,14 +15,14 @@ export class RuntimeEnvironment {
|
|
|
12
15
|
}
|
|
13
16
|
// Instantiate proper StacksNetwork
|
|
14
17
|
if (networkName === 'mainnet' || networkName === 'testnet') {
|
|
15
|
-
this.network = createNetwork({
|
|
18
|
+
this.network = (0, network_1.createNetwork)({
|
|
16
19
|
network: networkName,
|
|
17
20
|
client: { baseUrl: networkConfig.url }
|
|
18
21
|
});
|
|
19
22
|
}
|
|
20
23
|
else {
|
|
21
24
|
// Default to testnet structure for custom networks
|
|
22
|
-
this.network = createNetwork({
|
|
25
|
+
this.network = (0, network_1.createNetwork)({
|
|
23
26
|
network: 'testnet',
|
|
24
27
|
client: { baseUrl: networkConfig.url }
|
|
25
28
|
});
|
|
@@ -27,7 +30,7 @@ export class RuntimeEnvironment {
|
|
|
27
30
|
// Wallet: support privateKey, seedPhrase+derivationPath, or both (prefer privateKey)
|
|
28
31
|
if (config.wallet.privateKey) {
|
|
29
32
|
// Derive address from privateKey
|
|
30
|
-
const address = getAddressFromPrivateKey(config.wallet.privateKey, networkName === 'mainnet' ? 'mainnet' : 'testnet');
|
|
33
|
+
const address = (0, transactions_1.getAddressFromPrivateKey)(config.wallet.privateKey, networkName === 'mainnet' ? 'mainnet' : 'testnet');
|
|
31
34
|
this.wallet = {
|
|
32
35
|
privateKey: config.wallet.privateKey,
|
|
33
36
|
address,
|
|
@@ -36,7 +39,7 @@ export class RuntimeEnvironment {
|
|
|
36
39
|
else if (config.wallet.seedPhrase) {
|
|
37
40
|
const path = config.wallet.derivationPath || "m/44'/5757'/0'/0/0"; // Stacks main path
|
|
38
41
|
// generateWallet requires a password param
|
|
39
|
-
generateWallet({ secretKey: config.wallet.seedPhrase, password: '' }).then(wallet => {
|
|
42
|
+
(0, wallet_sdk_1.generateWallet)({ secretKey: config.wallet.seedPhrase, password: '' }).then(wallet => {
|
|
40
43
|
const index = parseInt(path.split('/').pop() || '0', 10);
|
|
41
44
|
const account = wallet.accounts[index] || wallet.accounts[0];
|
|
42
45
|
// Use getStxAddress to get the address
|
|
@@ -58,8 +61,9 @@ export class RuntimeEnvironment {
|
|
|
58
61
|
}
|
|
59
62
|
this.stacks = {};
|
|
60
63
|
// Apply extensions
|
|
61
|
-
for (const extension of Extender.getInstance().getExtensions()) {
|
|
64
|
+
for (const extension of extender_1.Extender.getInstance().getExtensions()) {
|
|
62
65
|
extension(this);
|
|
63
66
|
}
|
|
64
67
|
}
|
|
65
68
|
}
|
|
69
|
+
exports.RuntimeEnvironment = RuntimeEnvironment;
|
package/dist/src/core/simnet.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Simnet = void 0;
|
|
4
|
+
const clarinet_sdk_1 = require("@hirosystems/clarinet-sdk");
|
|
5
|
+
class Simnet {
|
|
3
6
|
constructor() { }
|
|
4
7
|
static async init() {
|
|
5
8
|
if (!Simnet._instance) {
|
|
@@ -7,7 +10,7 @@ export class Simnet {
|
|
|
7
10
|
// Initialize SDK - auto-detects Clarinet.toml from CWD
|
|
8
11
|
try {
|
|
9
12
|
console.log('Initializing Simnet...');
|
|
10
|
-
Simnet._instance.simnet = await initSimnet();
|
|
13
|
+
Simnet._instance.simnet = await (0, clarinet_sdk_1.initSimnet)();
|
|
11
14
|
// Get accounts
|
|
12
15
|
Simnet._instance.accounts = Simnet._instance.simnet.getAccounts();
|
|
13
16
|
}
|
|
@@ -40,3 +43,4 @@ export class Simnet {
|
|
|
40
43
|
return this.simnet.mineBlock(txs);
|
|
41
44
|
}
|
|
42
45
|
}
|
|
46
|
+
exports.Simnet = Simnet;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TaskDefinitions = void 0;
|
|
1
4
|
class TaskDefinitions {
|
|
2
5
|
constructor() {
|
|
3
6
|
this._tasks = [];
|
|
@@ -18,4 +21,4 @@ class TaskDefinitions {
|
|
|
18
21
|
return this._tasks;
|
|
19
22
|
}
|
|
20
23
|
}
|
|
21
|
-
|
|
24
|
+
exports.TaskDefinitions = TaskDefinitions;
|
package/dist/src/index.js
CHANGED
|
@@ -1,4 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.RuntimeEnvironment = exports.Simnet = exports.extendEnvironment = exports.subtask = exports.task = void 0;
|
|
18
|
+
var dsl_1 = require("./core/dsl");
|
|
19
|
+
Object.defineProperty(exports, "task", { enumerable: true, get: function () { return dsl_1.task; } });
|
|
20
|
+
Object.defineProperty(exports, "subtask", { enumerable: true, get: function () { return dsl_1.subtask; } });
|
|
21
|
+
Object.defineProperty(exports, "extendEnvironment", { enumerable: true, get: function () { return dsl_1.extendEnvironment; } });
|
|
22
|
+
var simnet_1 = require("./core/simnet");
|
|
23
|
+
Object.defineProperty(exports, "Simnet", { enumerable: true, get: function () { return simnet_1.Simnet; } });
|
|
24
|
+
var runtime_environment_1 = require("./core/runtime-environment");
|
|
25
|
+
Object.defineProperty(exports, "RuntimeEnvironment", { enumerable: true, get: function () { return runtime_environment_1.RuntimeEnvironment; } });
|
|
26
|
+
__exportStar(require("./core/tasks-definitions"), exports);
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const dsl_1 = require("../core/dsl");
|
|
7
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
8
|
+
(0, dsl_1.task)('call-contract-function', 'Call a public function on a deployed Clarity contract')
|
|
4
9
|
.addParam('contractAddress', 'Deployed contract address (STX...)', { type: 'string', required: true })
|
|
5
10
|
.addParam('contractName', 'Contract name', { type: 'string', required: true })
|
|
6
11
|
.addParam('functionName', 'Function name', { type: 'string', required: true })
|
|
@@ -19,7 +24,7 @@ task('call-contract-function', 'Call a public function on a deployed Clarity con
|
|
|
19
24
|
const body = fnArgs
|
|
20
25
|
? { arguments: fnArgs.split(',').map((a) => a.trim()) }
|
|
21
26
|
: { arguments: [] };
|
|
22
|
-
const res = await
|
|
27
|
+
const res = await (0, node_fetch_1.default)(url, {
|
|
23
28
|
method: 'POST',
|
|
24
29
|
headers: { 'Content-Type': 'application/json' },
|
|
25
30
|
body: JSON.stringify(body)
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const dsl_1 = require("../core/dsl");
|
|
7
|
+
const transactions_1 = require("@stacks/transactions");
|
|
8
|
+
const network_1 = require("@stacks/network");
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
5
10
|
function maskAddress(address) {
|
|
6
11
|
return address ? address.slice(0, 6) + '...' + address.slice(-4) : '';
|
|
7
12
|
}
|
|
@@ -10,7 +15,7 @@ function containsSecret(obj) {
|
|
|
10
15
|
return /[A-Za-z0-9]{32,}/.test(str); // crude check for long secrets
|
|
11
16
|
}
|
|
12
17
|
// Deploy a Clarity contract to Stacks mainnet or testnet
|
|
13
|
-
task('deploy-contract', 'Deploy a Clarity smart contract to Stacks blockchain')
|
|
18
|
+
(0, dsl_1.task)('deploy-contract', 'Deploy a Clarity smart contract to Stacks blockchain')
|
|
14
19
|
.addParam('contractName', 'Name of the contract', { type: 'string', required: true })
|
|
15
20
|
.addParam('file', 'Path to Clarity contract file', { type: 'string', required: true })
|
|
16
21
|
.addParam('network', 'Network to deploy to (mainnet|testnet)', { type: 'string', required: false, defaultValue: 'testnet' })
|
|
@@ -18,21 +23,21 @@ task('deploy-contract', 'Deploy a Clarity smart contract to Stacks blockchain')
|
|
|
18
23
|
const contractName = args.contractName;
|
|
19
24
|
const file = args.file;
|
|
20
25
|
const network = args.network;
|
|
21
|
-
const codeBody =
|
|
26
|
+
const codeBody = fs_1.default.readFileSync(file, 'utf8');
|
|
22
27
|
// Switch network if needed
|
|
23
28
|
if (network === 'mainnet') {
|
|
24
|
-
env.network = createNetwork({ network: 'mainnet', client: { baseUrl: env.config.networks.mainnet.url } });
|
|
29
|
+
env.network = (0, network_1.createNetwork)({ network: 'mainnet', client: { baseUrl: env.config.networks.mainnet.url } });
|
|
25
30
|
}
|
|
26
31
|
else {
|
|
27
|
-
env.network = createNetwork({ network: 'testnet', client: { baseUrl: env.config.networks.testnet.url } });
|
|
32
|
+
env.network = (0, network_1.createNetwork)({ network: 'testnet', client: { baseUrl: env.config.networks.testnet.url } });
|
|
28
33
|
}
|
|
29
|
-
const tx = await makeContractDeploy({
|
|
34
|
+
const tx = await (0, transactions_1.makeContractDeploy)({
|
|
30
35
|
contractName,
|
|
31
36
|
codeBody,
|
|
32
37
|
senderKey: env.wallet.privateKey,
|
|
33
38
|
network: env.network,
|
|
34
39
|
});
|
|
35
|
-
const result = await broadcastTransaction({ transaction: tx, network: env.network });
|
|
40
|
+
const result = await (0, transactions_1.broadcastTransaction)({ transaction: tx, network: env.network });
|
|
36
41
|
if (containsSecret(result)) {
|
|
37
42
|
console.warn('[mobilestacks] Warning: Output may contain sensitive data.');
|
|
38
43
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const dsl_1 = require("../core/dsl");
|
|
4
|
+
(0, dsl_1.task)('example', 'An example user task for onboarding')
|
|
3
5
|
.addParam('name', 'Your name', { type: 'string', required: false, defaultValue: 'World' })
|
|
4
6
|
.setAction(async (args) => {
|
|
5
7
|
return `Hello, ${args.name}! Welcome to mobilestacks.`;
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const dsl_1 = require("../core/dsl");
|
|
7
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
8
|
+
(0, dsl_1.task)('faucet-request', 'Request STX from the testnet faucet')
|
|
4
9
|
.addParam('address', 'STX address to fund', { type: 'string', required: true })
|
|
5
10
|
.setAction(async (args, env) => {
|
|
6
11
|
if (env.network.client.baseUrl && env.network.client.baseUrl.includes('testnet')) {
|
|
7
12
|
const url = `https://stacks-node-api.testnet.stacks.co/extended/v1/faucet/stx`; // Default testnet faucet
|
|
8
|
-
const res = await
|
|
13
|
+
const res = await (0, node_fetch_1.default)(url, {
|
|
9
14
|
method: 'POST',
|
|
10
15
|
headers: { 'Content-Type': 'application/json' },
|
|
11
16
|
body: JSON.stringify({ address: args.address })
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const dsl_1 = require("../core/dsl");
|
|
7
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
3
8
|
function maskAddress(address) {
|
|
4
9
|
return address ? address.slice(0, 6) + '...' + address.slice(-4) : '';
|
|
5
10
|
}
|
|
@@ -7,7 +12,7 @@ function containsSecret(obj) {
|
|
|
7
12
|
const str = JSON.stringify(obj);
|
|
8
13
|
return /[A-Za-z0-9]{32,}/.test(str); // crude check for long secrets
|
|
9
14
|
}
|
|
10
|
-
task('get-balance', 'Get STX balance for the configured wallet address or a provided address')
|
|
15
|
+
(0, dsl_1.task)('get-balance', 'Get STX balance for the configured wallet address or a provided address')
|
|
11
16
|
.addParam('address', 'STX address to check (optional, defaults to wallet main address)', { type: 'string', required: false })
|
|
12
17
|
.setAction(async (args, env) => {
|
|
13
18
|
const address = args.address || env.wallet.address;
|
|
@@ -16,7 +21,7 @@ task('get-balance', 'Get STX balance for the configured wallet address or a prov
|
|
|
16
21
|
const network = env.network;
|
|
17
22
|
const apiUrl = network.client.baseUrl;
|
|
18
23
|
const url = `${apiUrl}/extended/v1/address/${address}/balances`;
|
|
19
|
-
const res = await
|
|
24
|
+
const res = await (0, node_fetch_1.default)(url);
|
|
20
25
|
if (!res.ok)
|
|
21
26
|
throw new Error(`Failed to fetch balance: ${res.statusText}`);
|
|
22
27
|
const data = await res.json();
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const dsl_1 = require("../core/dsl");
|
|
7
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
8
|
+
(0, dsl_1.task)('get-contract-info', 'Get contract attributes and details from Stacks blockchain')
|
|
4
9
|
.addParam('contractAddress', 'Deployed contract address (STX...)', { type: 'string', required: true })
|
|
5
10
|
.addParam('contractName', 'Contract name', { type: 'string', required: true })
|
|
6
11
|
.addParam('network', 'Network (mainnet|testnet)', { type: 'string', required: false, defaultValue: 'testnet' })
|
|
@@ -10,7 +15,7 @@ task('get-contract-info', 'Get contract attributes and details from Stacks block
|
|
|
10
15
|
? 'https://stacks-node-api.mainnet.stacks.co'
|
|
11
16
|
: 'https://stacks-node-api.testnet.stacks.co';
|
|
12
17
|
const url = `${apiUrl}/extended/v1/contract/${contractAddress}/${contractName}`;
|
|
13
|
-
const res = await
|
|
18
|
+
const res = await (0, node_fetch_1.default)(url);
|
|
14
19
|
if (!res.ok)
|
|
15
20
|
throw new Error(`Failed to fetch contract info: ${res.statusText}`);
|
|
16
21
|
const info = await res.json();
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const dsl_1 = require("../core/dsl");
|
|
7
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
3
8
|
function maskAddress(address) {
|
|
4
9
|
return address ? address.slice(0, 6) + '...' + address.slice(-4) : '';
|
|
5
10
|
}
|
|
@@ -7,7 +12,7 @@ function containsSecret(obj) {
|
|
|
7
12
|
const str = JSON.stringify(obj);
|
|
8
13
|
return /[A-Za-z0-9]{32,}/.test(str); // crude check for long secrets
|
|
9
14
|
}
|
|
10
|
-
task('get-tx-history', 'Get transaction history for the configured wallet address')
|
|
15
|
+
(0, dsl_1.task)('get-tx-history', 'Get transaction history for the configured wallet address')
|
|
11
16
|
.addParam('limit', 'Number of transactions to fetch', { type: 'number', required: false, defaultValue: 10 })
|
|
12
17
|
.setAction(async (args, env) => {
|
|
13
18
|
const address = env.wallet.address;
|
|
@@ -16,7 +21,7 @@ task('get-tx-history', 'Get transaction history for the configured wallet addres
|
|
|
16
21
|
const network = env.network;
|
|
17
22
|
const apiUrl = network.client.baseUrl;
|
|
18
23
|
const url = `${apiUrl}/extended/v1/address/${address}/transactions?limit=${args.limit}`;
|
|
19
|
-
const res = await
|
|
24
|
+
const res = await (0, node_fetch_1.default)(url);
|
|
20
25
|
if (!res.ok)
|
|
21
26
|
throw new Error(`Failed to fetch tx history: ${res.statusText}`);
|
|
22
27
|
const data = await res.json();
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const dsl_1 = require("../core/dsl");
|
|
4
|
+
const wallet_sdk_1 = require("@stacks/wallet-sdk");
|
|
3
5
|
function maskAddress(address) {
|
|
4
6
|
return address ? address.slice(0, 6) + '...' + address.slice(-4) : '';
|
|
5
7
|
}
|
|
@@ -7,12 +9,12 @@ function containsSecret(obj) {
|
|
|
7
9
|
const str = JSON.stringify(obj);
|
|
8
10
|
return /[A-Za-z0-9]{32,}/.test(str); // crude check for long secrets
|
|
9
11
|
}
|
|
10
|
-
task('list-accounts', 'List all accounts derived from the configured seed phrase')
|
|
12
|
+
(0, dsl_1.task)('list-accounts', 'List all accounts derived from the configured seed phrase')
|
|
11
13
|
.setAction(async (args, env) => {
|
|
12
14
|
if (!env.config.wallet.seedPhrase) {
|
|
13
15
|
throw new Error('No seed phrase configured.');
|
|
14
16
|
}
|
|
15
|
-
const wallet = await generateWallet({ secretKey: env.config.wallet.seedPhrase, password: '' });
|
|
17
|
+
const wallet = await (0, wallet_sdk_1.generateWallet)({ secretKey: env.config.wallet.seedPhrase, password: '' });
|
|
16
18
|
const result = wallet.accounts.map((a) => ({
|
|
17
19
|
address: maskAddress(a.address || a.stxAddress),
|
|
18
20
|
index: a.index
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const dsl_1 = require("../core/dsl");
|
|
4
|
+
const transactions_1 = require("@stacks/transactions");
|
|
3
5
|
function maskAddress(address) {
|
|
4
6
|
return address ? address.slice(0, 6) + '...' + address.slice(-4) : '';
|
|
5
7
|
}
|
|
@@ -8,7 +10,7 @@ function containsSecret(obj) {
|
|
|
8
10
|
return /[A-Za-z0-9]{32,}/.test(str); // crude check for long secrets
|
|
9
11
|
}
|
|
10
12
|
// This task sends STX to an address using the loaded SRE (env)
|
|
11
|
-
task('send-stx', 'Sends STX to an address')
|
|
13
|
+
(0, dsl_1.task)('send-stx', 'Sends STX to an address')
|
|
12
14
|
.addParam('to', 'Recipient STX address', { type: 'string', required: true })
|
|
13
15
|
.addParam('amount', 'Amount in microSTX', { type: 'number', required: true })
|
|
14
16
|
.addParam('memo', 'Optional memo', { type: 'string', required: false, defaultValue: '' })
|
|
@@ -17,14 +19,14 @@ task('send-stx', 'Sends STX to an address')
|
|
|
17
19
|
const amount = args.amount;
|
|
18
20
|
const memo = args.memo;
|
|
19
21
|
const { wallet, network } = env;
|
|
20
|
-
const tx = await makeSTXTokenTransfer({
|
|
22
|
+
const tx = await (0, transactions_1.makeSTXTokenTransfer)({
|
|
21
23
|
recipient: to,
|
|
22
24
|
amount: BigInt(amount),
|
|
23
25
|
senderKey: wallet.privateKey,
|
|
24
26
|
network,
|
|
25
27
|
memo: memo || undefined
|
|
26
28
|
});
|
|
27
|
-
const result = await broadcastTransaction({ transaction: tx, network });
|
|
29
|
+
const result = await (0, transactions_1.broadcastTransaction)({ transaction: tx, network });
|
|
28
30
|
if (containsSecret(result)) {
|
|
29
31
|
console.warn('[mobilestacks] Warning: Output may contain sensitive data.');
|
|
30
32
|
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const dsl_1 = require("../core/dsl");
|
|
7
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
(0, dsl_1.task)('verify-contract', 'Verify a deployed Clarity contract on the Stacks explorer')
|
|
5
10
|
.addParam('contractAddress', 'Deployed contract address (STX...)', { type: 'string', required: true })
|
|
6
11
|
.addParam('contractName', 'Contract name', { type: 'string', required: true })
|
|
7
12
|
.addParam('source', 'Path to contract source file', { type: 'string', required: true })
|
|
@@ -11,13 +16,13 @@ task('verify-contract', 'Verify a deployed Clarity contract on the Stacks explor
|
|
|
11
16
|
const contractName = args.contractName;
|
|
12
17
|
const source = args.source;
|
|
13
18
|
const network = args.network;
|
|
14
|
-
const codeBody =
|
|
19
|
+
const codeBody = fs_1.default.readFileSync(source, 'utf8');
|
|
15
20
|
const apiUrl = network === 'mainnet'
|
|
16
21
|
? 'https://stacks-node-api.mainnet.stacks.co'
|
|
17
22
|
: 'https://stacks-node-api.testnet.stacks.co';
|
|
18
23
|
// Fetch contract source from chain
|
|
19
24
|
const url = `${apiUrl}/extended/v1/contract/source/${contractAddress}/${contractName}`;
|
|
20
|
-
const res = await
|
|
25
|
+
const res = await (0, node_fetch_1.default)(url);
|
|
21
26
|
if (!res.ok)
|
|
22
27
|
throw new Error(`Failed to fetch on-chain contract source: ${res.statusText}`);
|
|
23
28
|
const onChain = await res.json();
|
package/dist/src/types/config.js
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MobilestacksConfigSchema = exports.WalletConfigSchema = exports.NetworkConfigSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.NetworkConfigSchema = zod_1.z.object({
|
|
6
|
+
url: zod_1.z.string().url(),
|
|
7
|
+
name: zod_1.z.string(),
|
|
8
|
+
explorerUrl: zod_1.z.string().url().optional(),
|
|
9
|
+
faucetUrl: zod_1.z.string().url().nullable().optional(),
|
|
7
10
|
});
|
|
8
11
|
// Wallet config: allow privateKey, seedPhrase, or both. If both, privateKey is used.
|
|
9
|
-
|
|
10
|
-
privateKey: z.string().min(1, "Private key is required").optional(),
|
|
11
|
-
seedPhrase: z.string().optional(),
|
|
12
|
-
derivationPath: z.string().optional(),
|
|
13
|
-
address: z.string().optional(),
|
|
12
|
+
exports.WalletConfigSchema = zod_1.z.object({
|
|
13
|
+
privateKey: zod_1.z.string().min(1, "Private key is required").optional(),
|
|
14
|
+
seedPhrase: zod_1.z.string().optional(),
|
|
15
|
+
derivationPath: zod_1.z.string().optional(),
|
|
16
|
+
address: zod_1.z.string().optional(),
|
|
14
17
|
}).refine((data) => data.privateKey || data.seedPhrase, { message: "Either privateKey or seedPhrase is required" });
|
|
15
|
-
|
|
16
|
-
networks: z.record(NetworkConfigSchema),
|
|
17
|
-
defaultNetwork: z.string(),
|
|
18
|
-
wallet: WalletConfigSchema,
|
|
18
|
+
exports.MobilestacksConfigSchema = zod_1.z.object({
|
|
19
|
+
networks: zod_1.z.record(exports.NetworkConfigSchema),
|
|
20
|
+
defaultNetwork: zod_1.z.string(),
|
|
21
|
+
wallet: exports.WalletConfigSchema,
|
|
19
22
|
});
|
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mobilestacks",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Professional Task Runner & CLI for the Stacks Blockchain",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
7
7
|
"bin": {
|
|
8
8
|
"mobilestacks": "dist/src/cli/index.js"
|
|
9
9
|
},
|
|
10
|
-
"type": "module",
|
|
11
10
|
"files": [
|
|
12
11
|
"dist/",
|
|
13
12
|
"src/",
|
|
@@ -34,15 +33,15 @@
|
|
|
34
33
|
"web3",
|
|
35
34
|
"bitcoin"
|
|
36
35
|
],
|
|
37
|
-
"author": "
|
|
36
|
+
"author": "Wizbisy",
|
|
38
37
|
"license": "MIT",
|
|
39
38
|
"repository": {
|
|
40
39
|
"type": "git",
|
|
41
|
-
"url": "https://github.com/
|
|
40
|
+
"url": "https://github.com/Wizbisy/mobilestacks.git"
|
|
42
41
|
},
|
|
43
|
-
"homepage": "https://github.com/
|
|
42
|
+
"homepage": "https://github.com/Wizbisy/mobilestacks#readme",
|
|
44
43
|
"bugs": {
|
|
45
|
-
"url": "https://github.com/
|
|
44
|
+
"url": "https://github.com/Wizbisy/mobilestacks/issues"
|
|
46
45
|
},
|
|
47
46
|
"engines": {
|
|
48
47
|
"node": ">=18"
|
|
@@ -50,6 +49,7 @@
|
|
|
50
49
|
"devDependencies": {
|
|
51
50
|
"@hirosystems/clarinet-sdk": "^3.8.1",
|
|
52
51
|
"@types/inquirer": "^8.2.6",
|
|
52
|
+
"@types/node-fetch": "^2.6.13",
|
|
53
53
|
"@typescript-eslint/eslint-plugin": "^6.20.0",
|
|
54
54
|
"@typescript-eslint/parser": "^6.20.0",
|
|
55
55
|
"eslint": "^8.56.0",
|
|
@@ -62,8 +62,11 @@
|
|
|
62
62
|
"@stacks/network": "latest",
|
|
63
63
|
"@stacks/transactions": "latest",
|
|
64
64
|
"@stacks/wallet-sdk": "latest",
|
|
65
|
+
"chalk": "^4.1.2",
|
|
65
66
|
"commander": "^11.0.0",
|
|
66
|
-
"
|
|
67
|
+
"dotenv": "^17.3.1",
|
|
68
|
+
"inquirer": "^8.2.7",
|
|
69
|
+
"node-fetch": "^2.7.0",
|
|
67
70
|
"ts-node": "^10.9.1",
|
|
68
71
|
"zod": "^3.25.76"
|
|
69
72
|
}
|