@airmoney-degn/airmoney-cli 0.17.0 → 0.18.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.
@@ -16,6 +16,7 @@ const path_1 = __importDefault(require("path"));
16
16
  const child_process_1 = require("child_process");
17
17
  const env_1 = require("./env");
18
18
  const CryptoService_1 = require("../service/crypto/CryptoService");
19
+ const LogService_1 = require("../service/log/LogService");
19
20
  // Utility functions for port management
20
21
  function isPortInUse(port) {
21
22
  return new Promise(resolve => {
@@ -102,29 +103,29 @@ function startCryptoService() {
102
103
  }, (error, stdout, stderr) => {
103
104
  // Ignore errors if the process was intentionally killed
104
105
  if (error && !isKilled && !hasResolved) {
105
- console.error('\x1b[31m❌ Crypto service failed to start:\x1b[0m');
106
- console.error('\x1b[31mError details:\x1b[0m', error.message);
106
+ (0, LogService_1.log)('Crypto service failed to start:').red();
107
+ (0, LogService_1.log)(`Error details: ${error.message}`).red();
107
108
  // Check for specific Rust panic errors
108
109
  if (stderr &&
109
110
  stderr.includes('Cannot drop a runtime in a context where blocking is not allowed')) {
110
- console.error('\x1b[31m\n🔧 This appears to be a Rust/tokio runtime issue in the crypto service binary.\x1b[0m');
111
- console.error('\x1b[31mPossible solutions:\x1b[0m');
112
- console.error('\x1b[31m1. The binary may be corrupted - try rebuilding: npm run build\x1b[0m');
113
- console.error('\x1b[31m2. There may be a compatibility issue with your system\x1b[0m');
114
- console.error('\x1b[31m3. Try running the binary directly to see more details:\x1b[0m');
115
- console.error(`\x1b[31m ${bin}\x1b[0m`);
111
+ (0, LogService_1.log)('\n🔧 This appears to be a Rust/tokio runtime issue in the crypto service binary.').red();
112
+ (0, LogService_1.log)('Possible solutions:').red();
113
+ (0, LogService_1.log)('1. The binary may be corrupted - try rebuilding: npm run build').red();
114
+ (0, LogService_1.log)('2. There may be a compatibility issue with your system').red();
115
+ (0, LogService_1.log)('3. Try running the binary directly to see more details:').red();
116
+ (0, LogService_1.log)(` ${bin}`).red();
116
117
  }
117
118
  else if (stderr) {
118
- console.error('Stderr:', stderr);
119
+ (0, LogService_1.log)(`Stderr: ${stderr}`).red();
119
120
  }
120
121
  reject(new Error(`Crypto service failed: ${error.message}`));
121
122
  return;
122
123
  }
123
124
  if (stdout) {
124
- // console.log('Crypto service stdout:', stdout);
125
+ // log(`Crypto service stdout: ${stdout}`).white();
125
126
  }
126
127
  if (stderr && !isKilled) {
127
- console.error('\x1b[31mCrypto service stderr:\x1b[0m', stderr);
128
+ (0, LogService_1.log)(`Crypto service stderr: ${stderr}`).red();
128
129
  }
129
130
  });
130
131
  // Wait 2 seconds before resolving to ensure service is ready
@@ -153,10 +154,10 @@ function getCryptoServicePath() {
153
154
  function startCryptoServiceSimple() {
154
155
  const bin = getCryptoServicePath();
155
156
  if (!(0, fs_1.existsSync)(bin)) {
156
- console.log('\x1b[31mcrypto service not found at ' + bin + '\x1b[0m');
157
+ (0, LogService_1.log)(`crypto service not found at ${bin}`).red();
157
158
  return;
158
159
  }
159
- console.log('\x1b[32mStarting crypto service at http://localhost:5050\x1b[0m');
160
+ (0, LogService_1.log)('Starting crypto service at http://localhost:5050').green();
160
161
  (0, child_process_1.exec)(bin, { env: { SECURE_STORAGE: (0, env_1.configDir)(), RUST_BACKTRACE: '1' } }, (_, stdout, stderr) => {
161
162
  // console.log("stdout", stdout);
162
163
  // console.log("stderr", stderr);
@@ -182,17 +183,17 @@ async function withCryptoService(operation) {
182
183
  startedCryptoService = true;
183
184
  }
184
185
  catch (error) {
185
- console.error('\x1b[31m❌ Failed to start crypto service:\x1b[0m');
186
- console.error('\x1b[31mThis might be due to:\x1b[0m');
187
- console.error('\x1b[31m- Missing or corrupted binary files\x1b[0m');
188
- console.error('\x1b[31m- Insufficient permissions\x1b[0m');
189
- console.error('\x1b[31m- System compatibility issues\x1b[0m');
190
- console.error('\x1b[31m- Port conflicts\x1b[0m');
191
- console.error('\x1b[31m\nTry running: npm run build\x1b[0m');
186
+ (0, LogService_1.log)('Failed to start crypto service:').red();
187
+ (0, LogService_1.log)('This might be due to:').red();
188
+ (0, LogService_1.log)('- Missing or corrupted binary files').red();
189
+ (0, LogService_1.log)('- Insufficient permissions').red();
190
+ (0, LogService_1.log)('- System compatibility issues').red();
191
+ (0, LogService_1.log)('- Port conflicts').red();
192
+ (0, LogService_1.log)('\nTry running: npm run build').red();
192
193
  throw error;
193
194
  }
194
195
  const cryptoServiceClient = new CryptoService_1.CryptoService();
195
- // console.log('Crypto service client created');
196
+ // log('Crypto service client created').white();
196
197
  return await operation(cryptoServiceClient);
197
198
  }
198
199
  catch (error) {
package/dist/util/env.js CHANGED
@@ -35,10 +35,15 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.configDir = configDir;
37
37
  exports.loadEnvFromConfig = loadEnvFromConfig;
38
+ exports.getDeveloperAddress = getDeveloperAddress;
39
+ exports.getApiKey = getApiKey;
40
+ exports.getRpc = getRpc;
41
+ exports.validateCredential = validateCredential;
38
42
  const fs = __importStar(require("fs"));
39
43
  const path = __importStar(require("path"));
40
44
  const os = __importStar(require("os"));
41
45
  const dotenv = __importStar(require("dotenv"));
46
+ const network_1 = require("./network");
42
47
  function configDir() {
43
48
  // similar to Rust's ProjectDirs::from("fun", "air", "simulator");
44
49
  // We'll do a rough approach
@@ -54,3 +59,42 @@ function loadEnvFromConfig() {
54
59
  dotenv.config({ path: envPath });
55
60
  }
56
61
  }
62
+ /**
63
+ * Gets the developer address from environment variables
64
+ */
65
+ function getDeveloperAddress() {
66
+ return process.env.DEVELOPER_ADDRESS || '';
67
+ }
68
+ /**
69
+ * Gets the API key from environment variables
70
+ */
71
+ function getApiKey() {
72
+ return process.env.API_KEY || '';
73
+ }
74
+ /**
75
+ * Gets the RPC/network from environment variables
76
+ */
77
+ function getRpc() {
78
+ return process.env.RPC;
79
+ }
80
+ /**
81
+ * Validates that credentials exist and returns them
82
+ * Throws error if credentials are missing
83
+ */
84
+ function validateCredential() {
85
+ const userId = getDeveloperAddress();
86
+ const apiKey = getApiKey();
87
+ const rpc = getRpc();
88
+ if (!userId || !apiKey) {
89
+ throw new Error('Missing credentials. Run "airmoney-cli setup" to configure your credentials.');
90
+ }
91
+ if ((0, network_1.validateNetwork)(rpc)) {
92
+ return {
93
+ userId,
94
+ apiKey,
95
+ rpc,
96
+ };
97
+ }
98
+ throw new Error('Invalid network. Must be "devnet" or "mainnet". Your current network is: ' +
99
+ rpc);
100
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ /**
3
+ * Formatting utilities for CLI output
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.stripAnsiCodes = stripAnsiCodes;
7
+ exports.padString = padString;
8
+ exports.printTableRow = printTableRow;
9
+ exports.printSeparator = printSeparator;
10
+ exports.shortenString = shortenString;
11
+ const LogService_1 = require("../service/log/LogService");
12
+ /**
13
+ * Strips ANSI color codes from a string
14
+ */
15
+ function stripAnsiCodes(str) {
16
+ // Remove ANSI escape codes (CSI escape sequences)
17
+ return str.replace(/\x1b\[[0-9;]*m/g, '');
18
+ }
19
+ /**
20
+ * Formats a string to fixed width for table display
21
+ * Handles ANSI color codes by only counting visible characters for width calculation
22
+ */
23
+ function padString(str, width) {
24
+ const s = String(str || 'N/A');
25
+ const visibleLength = stripAnsiCodes(s).length;
26
+ if (visibleLength > width) {
27
+ // Truncate the visible text, keeping color codes
28
+ const visibleText = stripAnsiCodes(s);
29
+ const truncated = visibleText.substring(0, width - 3) + '...';
30
+ // Try to preserve color codes at the beginning
31
+ const colorMatch = s.match(/^(\x1b\[[0-9;]*m)/);
32
+ const resetCode = '\x1b[0m';
33
+ if (colorMatch) {
34
+ return colorMatch[1] + truncated + resetCode;
35
+ }
36
+ return truncated;
37
+ }
38
+ // Pad with spaces, but only count visible characters
39
+ const padding = ' '.repeat(width - visibleLength);
40
+ return s + padding;
41
+ }
42
+ /**
43
+ * Prints a table row
44
+ */
45
+ function printTableRow(columns, widths, isHeader = false) {
46
+ const row = columns.map((col, i) => padString(col, widths[i])).join(' | ');
47
+ if (isHeader) {
48
+ (0, LogService_1.log)(row).bold().white();
49
+ }
50
+ else {
51
+ (0, LogService_1.log)(row).white();
52
+ }
53
+ }
54
+ /**
55
+ * Prints a separator line
56
+ */
57
+ function printSeparator(widths) {
58
+ const line = widths.map(w => '-'.repeat(w)).join('-|-');
59
+ (0, LogService_1.log)(line).white();
60
+ }
61
+ /**
62
+ * Shortens a string to show first N and last N characters with ellipsis
63
+ * @param str - The string to shorten
64
+ * @param maxLength - Maximum length before shortening (default: 14)
65
+ * @param prefixLength - Number of characters to show at start (default: 6)
66
+ * @param suffixLength - Number of characters to show at end (default: 6)
67
+ * @returns Shortened string or original if not long enough
68
+ */
69
+ function shortenString(str, maxLength = 14, prefixLength = 6, suffixLength = 6) {
70
+ if (!str || str.length <= maxLength) {
71
+ return str;
72
+ }
73
+ return str.substring(0, prefixLength) + '…' + str.substring(str.length - suffixLength);
74
+ }
@@ -38,11 +38,12 @@ exports.saveMetadata = saveMetadata;
38
38
  exports.getPackageName = getPackageName;
39
39
  const fs = __importStar(require("fs"));
40
40
  const path = __importStar(require("path"));
41
+ const LogService_1 = require("../service/log/LogService");
41
42
  function loadMetadata(projectPath = '.') {
42
43
  try {
43
44
  const filePath = path.join(projectPath, 'metadata.json');
44
45
  if (!fs.existsSync(filePath)) {
45
- console.log('\x1b[33mPlease run this command in Project directory\x1b[0m');
46
+ (0, LogService_1.log)('Please run this command in Project directory').white();
46
47
  return null;
47
48
  }
48
49
  const raw = fs.readFileSync(filePath, 'utf8');
@@ -50,7 +51,7 @@ function loadMetadata(projectPath = '.') {
50
51
  return data;
51
52
  }
52
53
  catch (err) {
53
- console.log('\x1b[33mError loading metadata\x1b[0m');
54
+ (0, LogService_1.log)('Error loading metadata').red();
54
55
  return null;
55
56
  }
56
57
  }
@@ -12,12 +12,18 @@ exports.networkToRpcUrl = networkToRpcUrl;
12
12
  * @throws Error if network is invalid
13
13
  */
14
14
  function validateNetwork(network) {
15
- const normalized = network.toLowerCase().trim();
16
- if (normalized !== 'devnet' && normalized !== 'mainnet') {
17
- throw new Error(`Invalid network: ${network}. Must be "devnet" or "mainnet"`);
15
+ if (network) {
16
+ const normalized = network.toLowerCase().trim();
17
+ if (normalized !== 'devnet' && normalized !== 'mainnet') {
18
+ throw new Error(`Invalid network: ${network}. Must be "devnet" or "mainnet"`);
19
+ }
18
20
  }
19
21
  return true;
20
22
  }
23
+ const networkMap = {
24
+ devnet: 'https://rpc-dev.air.fun/',
25
+ mainnet: 'https://rpc.air.fun/',
26
+ };
21
27
  /**
22
28
  * Maps network name to RPC URL
23
29
  * Only accepts "devnet" or "mainnet"
@@ -26,11 +32,10 @@ function validateNetwork(network) {
26
32
  * @throws Error if network is invalid
27
33
  */
28
34
  function networkToRpcUrl(network) {
35
+ if (!network) {
36
+ return networkMap.devnet;
37
+ }
29
38
  const normalized = network.toLowerCase().trim();
30
- const networkMap = {
31
- 'devnet': 'https://rpc-dev.air.fun/',
32
- 'mainnet': 'https://rpc.air.fun/',
33
- };
34
39
  if (!(normalized in networkMap)) {
35
40
  throw new Error(`Invalid network: ${network}. Must be "devnet" or "mainnet"`);
36
41
  }
@@ -42,6 +42,7 @@ const path = __importStar(require("path"));
42
42
  const tar = __importStar(require("tar"));
43
43
  const md5_1 = __importDefault(require("md5")); // default import
44
44
  const metadata_1 = require("./metadata");
45
+ const LogService_1 = require("../service/log/LogService");
45
46
  /**
46
47
  * Reproduces the `pack()` logic, creating a tar.gz from the project's assets
47
48
  */
@@ -63,7 +64,7 @@ async function packProject(pkg, projectPath, assetsPath) {
63
64
  files.push('@assets.tar.gz');
64
65
  }
65
66
  else {
66
- console.log('No assets directory found.');
67
+ (0, LogService_1.log)('No assets directory found.').white();
67
68
  }
68
69
  // this is bad, but couldn't figure out how to get files from different folders without the absolute path messing with the tar file structure
69
70
  await tar.create({
@@ -83,14 +84,14 @@ async function packProject(pkg, projectPath, assetsPath) {
83
84
  // read it in memory for MD5
84
85
  const buffer = fs.readFileSync(absOutputPath);
85
86
  const digest = (0, md5_1.default)(buffer);
86
- console.log(`MD5: ${digest}`);
87
- console.log(`Tarball created at ${absOutputPath}`);
88
- console.log('cleaning up...');
87
+ (0, LogService_1.log)(`MD5: ${digest}`).white();
88
+ (0, LogService_1.log)(`Tarball created at ${absOutputPath}`).white();
89
+ (0, LogService_1.log)('cleaning up...').white();
89
90
  fs.rmSync('projectFiles.tar.gz');
90
91
  fs.rmSync('assets.tar.gz');
91
92
  }
92
93
  catch (err) {
93
- console.error(`Failed to create tarball: ${err.message}`);
94
+ (0, LogService_1.log)(`Failed to create tarball: ${err.message}`).red();
94
95
  if (fs.existsSync('projectFiles.tar.gz'))
95
96
  fs.rmSync('projectFiles.tar.gz');
96
97
  if (fs.existsSync('assets.tar.gz'))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@airmoney-degn/airmoney-cli",
3
- "version": "0.17.0",
3
+ "version": "0.18.0",
4
4
  "description": "airmoney-cli is a command-line interface tool designed to facilitate the development and management of decentralized applications (DApps) for Airmoney.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -16,7 +16,8 @@
16
16
  "version": "changeset version",
17
17
  "changeset": "changeset",
18
18
  "bump": "changeset && changeset version",
19
- "update-version": "node scripts/update-version.js"
19
+ "update-version": "node scripts/update-version.js",
20
+ "check-types": "tsc --noEmit"
20
21
  },
21
22
  "keywords": [
22
23
  "CLI"