mobilestacks 0.1.17 → 0.1.19

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/cli/index.js CHANGED
@@ -87,7 +87,13 @@ tasks_definitions_1.TaskDefinitions.getInstance().getAllTasks().forEach(task =>
87
87
  const env = new runtime_environment_1.RuntimeEnvironment(config);
88
88
  const result = await task.action(opts, env);
89
89
  if (typeof result === 'object') {
90
- console.log(chalk_1.default.greenBright('Success!'));
90
+ const resObj = result;
91
+ if (resObj.txid) {
92
+ console.log(chalk_1.default.yellowBright('Transaction broadcasted to mempool! (Check explorer for final confirmation)'));
93
+ }
94
+ else {
95
+ console.log(chalk_1.default.greenBright('Success!'));
96
+ }
91
97
  console.dir(result, { depth: null, colors: true });
92
98
  }
93
99
  else {
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const dsl_1 = require("../core/dsl");
7
7
  const node_fetch_1 = __importDefault(require("node-fetch"));
8
+ const transactions_1 = require("@stacks/transactions");
8
9
  (0, dsl_1.task)('call-contract-function', 'Call a public function on a deployed Clarity contract')
9
10
  .addParam('contractAddress', 'Deployed contract address (STX...)', { type: 'string', required: true })
10
11
  .addParam('contractName', 'Contract name', { type: 'string', required: true })
@@ -33,5 +34,13 @@ const node_fetch_1 = __importDefault(require("node-fetch"));
33
34
  if (!res.ok)
34
35
  throw new Error(`Failed to call contract function: ${res.statusText}`);
35
36
  const result = await res.json();
37
+ if (result && result.okay && typeof result.result === 'string' && result.result.startsWith('0x')) {
38
+ try {
39
+ result.decodedResult = (0, transactions_1.cvToJSON)((0, transactions_1.hexToCV)(result.result));
40
+ }
41
+ catch (e) {
42
+ // ignore decode errors, fallback to raw hex
43
+ }
44
+ }
36
45
  return result;
37
46
  });
@@ -44,7 +44,11 @@ function containsSecret(obj) {
44
44
  }
45
45
  // Mask any address fields if present
46
46
  if (result && result.txid) {
47
- result.txid = maskAddress(result.txid);
47
+ const resObj = result;
48
+ resObj.explorerUrl = network === 'mainnet'
49
+ ? `https://explorer.hiro.so/txid/${result.txid}`
50
+ : `https://explorer.hiro.so/txid/${result.txid}?chain=testnet`;
51
+ resObj.txid = maskAddress(result.txid);
48
52
  }
49
53
  return result;
50
54
  });
@@ -63,7 +63,11 @@ function containsSecret(obj) {
63
63
  console.warn('[mobilestacks] Warning: Output may contain sensitive data.');
64
64
  }
65
65
  if (result && result.txid) {
66
- result.txid = maskAddress(result.txid);
66
+ const resObj = result;
67
+ resObj.explorerUrl = networkName === 'mainnet'
68
+ ? `https://explorer.hiro.so/txid/${result.txid}`
69
+ : `https://explorer.hiro.so/txid/${result.txid}?chain=testnet`;
70
+ resObj.txid = maskAddress(result.txid);
67
71
  }
68
72
  // Broadcast transaction returns txid or error details
69
73
  return result;
@@ -5,9 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const dsl_1 = require("../core/dsl");
7
7
  const node_fetch_1 = __importDefault(require("node-fetch"));
8
- function maskAddress(address) {
9
- return address ? address.slice(0, 6) + '...' + address.slice(-4) : '';
10
- }
8
+ const transactions_1 = require("@stacks/transactions");
11
9
  function containsSecret(obj) {
12
10
  const str = JSON.stringify(obj);
13
11
  return /[A-Za-z0-9]{32,}/.test(str); // crude check for long secrets
@@ -16,10 +14,14 @@ function containsSecret(obj) {
16
14
  .addParam('address', 'STX address to check (optional, defaults to wallet main address)', { type: 'string', required: false })
17
15
  .addParam('network', 'Network (mainnet|testnet)', { type: 'string', required: false, defaultValue: 'testnet' })
18
16
  .setAction(async (args, env) => {
19
- const address = args.address || env.wallet.address;
20
17
  const networkName = args.network;
21
- if (!address)
22
- throw new Error('No wallet address found.');
18
+ // dynamically derive address if not provided
19
+ let address = args.address;
20
+ if (!address) {
21
+ if (!env.wallet.privateKey)
22
+ throw new Error('No wallet address or private key found.');
23
+ address = (0, transactions_1.getAddressFromPrivateKey)(env.wallet.privateKey, networkName === 'mainnet' ? 'mainnet' : 'testnet');
24
+ }
23
25
  const apiUrl = networkName === 'mainnet'
24
26
  ? env.config.networks.mainnet.url
25
27
  : env.config.networks.testnet.url;
@@ -28,12 +30,16 @@ function containsSecret(obj) {
28
30
  if (!res.ok)
29
31
  throw new Error(`Failed to fetch balance: ${res.statusText}`);
30
32
  const data = await res.json();
33
+ const stxData = data.stx;
34
+ const stxFormatted = (parseInt(stxData.balance || '0', 10) / 1_000_000).toString() + ' STX';
31
35
  const result = {
32
- address: maskAddress(address),
33
- stx: data.stx.balance,
34
- locked: data.stx.locked,
35
- unlock_height: data.stx.unlock_height
36
+ address,
37
+ stx: stxFormatted,
38
+ locked: stxData.locked === '0' ? '0' : stxData.locked,
36
39
  };
40
+ if (stxData.unlock_height !== undefined && stxData.unlock_height !== 0) {
41
+ result.unlock_height = stxData.unlock_height;
42
+ }
37
43
  if (containsSecret(result)) {
38
44
  console.warn('[mobilestacks] Warning: Output may contain sensitive data.');
39
45
  }
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const dsl_1 = require("../core/dsl");
7
7
  const node_fetch_1 = __importDefault(require("node-fetch"));
8
+ const transactions_1 = require("@stacks/transactions");
8
9
  function maskAddress(address) {
9
10
  return address ? address.slice(0, 6) + '...' + address.slice(-4) : '';
10
11
  }
@@ -16,8 +17,11 @@ function containsSecret(obj) {
16
17
  .addParam('limit', 'Number of transactions to fetch', { type: 'number', required: false, defaultValue: 10 })
17
18
  .addParam('network', 'Network (mainnet|testnet)', { type: 'string', required: false, defaultValue: 'testnet' })
18
19
  .setAction(async (args, env) => {
19
- const address = env.wallet.address;
20
20
  const networkName = args.network;
21
+ let address = env.wallet.address;
22
+ if (env.wallet.privateKey) {
23
+ address = (0, transactions_1.getAddressFromPrivateKey)(env.wallet.privateKey, networkName === 'mainnet' ? 'mainnet' : 'testnet');
24
+ }
21
25
  if (!address)
22
26
  throw new Error('No wallet address found.');
23
27
  const apiUrl = networkName === 'mainnet'
@@ -2,23 +2,27 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const dsl_1 = require("../core/dsl");
4
4
  const wallet_sdk_1 = require("@stacks/wallet-sdk");
5
- function maskAddress(address) {
6
- return address ? address.slice(0, 6) + '...' + address.slice(-4) : '';
7
- }
5
+ const transactions_1 = require("@stacks/transactions");
8
6
  function containsSecret(obj) {
9
7
  const str = JSON.stringify(obj);
10
8
  return /[A-Za-z0-9]{32,}/.test(str); // crude check for long secrets
11
9
  }
12
10
  (0, dsl_1.task)('list-accounts', 'List all accounts derived from the configured seed phrase')
11
+ .addParam('network', 'Network (mainnet|testnet)', { type: 'string', required: false, defaultValue: 'testnet' })
13
12
  .setAction(async (args, env) => {
13
+ const networkName = args.network;
14
14
  if (!env.config.wallet.seedPhrase) {
15
15
  throw new Error('No seed phrase configured.');
16
16
  }
17
17
  const wallet = await (0, wallet_sdk_1.generateWallet)({ secretKey: env.config.wallet.seedPhrase, password: '' });
18
- const result = wallet.accounts.map((a) => ({
19
- address: maskAddress(a.address || a.stxAddress),
20
- index: a.index
21
- }));
18
+ const result = wallet.accounts.map((a) => {
19
+ const account = a;
20
+ const address = (0, transactions_1.getAddressFromPrivateKey)(account.stxPrivateKey, networkName === 'mainnet' ? 'mainnet' : 'testnet');
21
+ return {
22
+ address,
23
+ index: account.index
24
+ };
25
+ });
22
26
  if (containsSecret(result)) {
23
27
  console.warn('[mobilestacks] Warning: Output may contain sensitive data.');
24
28
  }
@@ -44,7 +44,11 @@ function containsSecret(obj) {
44
44
  }
45
45
  // Mask any address fields if present
46
46
  if (result && result.txid) {
47
- result.txid = maskAddress(result.txid);
47
+ const resObj = result;
48
+ resObj.explorerUrl = networkName === 'mainnet'
49
+ ? `https://explorer.hiro.so/txid/${result.txid}`
50
+ : `https://explorer.hiro.so/txid/${result.txid}?chain=testnet`;
51
+ resObj.txid = maskAddress(result.txid);
48
52
  }
49
53
  return result;
50
54
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobilestacks",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "Professional Task Runner & CLI for the Stacks Blockchain",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",