@airmoney-degn/airmoney-cli 0.11.4 → 0.13.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/dist/cli/serve.js CHANGED
@@ -1,37 +1,4 @@
1
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
36
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
4
  };
@@ -47,9 +14,7 @@ const express_ws_1 = __importDefault(require("express-ws"));
47
14
  const metadata_1 = require("../util/metadata");
48
15
  const server_1 = require("../util/server");
49
16
  const http_proxy_middleware_1 = require("http-proxy-middleware");
50
- const ChildProcess = __importStar(require("child_process"));
51
- const fs_1 = require("fs");
52
- const env_1 = require("../util/env");
17
+ const cryptoProcess_1 = require("../util/cryptoProcess");
53
18
  /**
54
19
  * Helper to get the path to the "public/simulator" folder
55
20
  * from the distributed code. We use __dirname, then move
@@ -63,6 +28,17 @@ function getSimulatorDir() {
63
28
  return path_1.default.join(base, 'public', 'simulator');
64
29
  }
65
30
  async function serveCommand(noBrowser, locationFolder, appUrl) {
31
+ // Check if simulator and API ports are already in use (crypto service handles its own port)
32
+ const requiredPorts = [4040, 4041, 5050];
33
+ const inUsePorts = await (0, cryptoProcess_1.checkPortsInUse)(requiredPorts);
34
+ if (inUsePorts.length > 0) {
35
+ console.error('\x1b[31m❌ Port conflict detected!\x1b[0m');
36
+ console.error(`\x1b[31mThe following ports are already in use: ${inUsePorts.join(', ')}\x1b[0m`);
37
+ console.error('\x1b[31m\nPlease kill the processes using these ports before running serve:\x1b[0m');
38
+ const killCommand = `lsof -ti:${inUsePorts.join(',')} | xargs kill -9`;
39
+ console.error(`\x1b[31m ${killCommand}\x1b[0m`);
40
+ process.exit(1);
41
+ }
66
42
  const simulatorPort = 4041;
67
43
  const simulatorExpress = (0, express_ws_1.default)((0, express_1.default)()).app;
68
44
  simulatorExpress.use((0, cors_1.default)());
@@ -73,7 +49,7 @@ async function serveCommand(noBrowser, locationFolder, appUrl) {
73
49
  ws.on('message', function (msg) {
74
50
  console.log(msg);
75
51
  });
76
- console.log('socket', req.body);
52
+ // console.log('socket', req.body);
77
53
  });
78
54
  const simulatorDir = getSimulatorDir();
79
55
  simulatorExpress.use('/simulator', express_1.default.static(simulatorDir));
@@ -84,7 +60,7 @@ async function serveCommand(noBrowser, locationFolder, appUrl) {
84
60
  }
85
61
  const metadata = (0, metadata_1.loadMetadata)();
86
62
  if (!metadata) {
87
- console.log('[Warning] No metadata found. Skipping some possible checks.');
63
+ console.log('\x1b[33mNo metadata found. Skipping some possible checks.\x1b[0m');
88
64
  }
89
65
  if (appUrl != undefined) {
90
66
  const proxyMiddleware = (0, http_proxy_middleware_1.createProxyMiddleware)({
@@ -100,14 +76,14 @@ async function serveCommand(noBrowser, locationFolder, appUrl) {
100
76
  }
101
77
  const simulatorServer = simulatorExpress.listen(simulatorPort, () => {
102
78
  const url = `http://localhost:${simulatorPort}/simulator`;
103
- console.log(`Starting simulator server at ${url}`);
79
+ console.log(`\x1b[32mStarting simulator server at ${url}\x1b[0m`);
104
80
  if (!noBrowser) {
105
81
  (0, open_1.default)(url)
106
82
  .then(() => {
107
83
  // success opening URL
108
84
  })
109
85
  .catch(err => {
110
- console.error('Failed to open web browser', err);
86
+ console.error('\x1b[31mFailed to open web browser\x1b[0m', err);
111
87
  });
112
88
  }
113
89
  });
@@ -134,7 +110,7 @@ async function serveCommand(noBrowser, locationFolder, appUrl) {
134
110
  return;
135
111
  }
136
112
  else {
137
- console.log('Warning: No simulator client connected');
113
+ console.log('\x1b[33mNo simulator client connected\x1b[0m');
138
114
  res.status(503).json({ error: 'Simulator not connected' });
139
115
  return;
140
116
  }
@@ -151,19 +127,8 @@ async function serveCommand(noBrowser, locationFolder, appUrl) {
151
127
  });
152
128
  const airmoneyServiceServer = airmoneyServiceExpress.listen(airmoneyServicePort, () => {
153
129
  const url = `http://localhost:${airmoneyServicePort}`;
154
- console.log(`Starting airmoney service server at ${url}`);
130
+ console.log(`\x1b[32mStarting airmoney service server at ${url}\x1b[0m`);
155
131
  });
156
132
  ////////////////////////////////////////////////////////////////
157
- const cryptoServiceBin = `${process.platform}-${process.arch}`;
158
- const bin = path_1.default.join(__dirname, '..', 'bin', cryptoServiceBin);
159
- if (!(0, fs_1.existsSync)(bin)) {
160
- console.log('crypto service not found at ' + bin);
161
- }
162
- else {
163
- console.log('execing crypto service at http://localhost:5050');
164
- ChildProcess.exec(bin, { env: { SECURE_STORAGE: (0, env_1.configDir)(), RUST_BACKTRACE: '1' } }, (_, stdout, stderr) => {
165
- console.log(stdout);
166
- console.log(stderr);
167
- });
168
- }
133
+ (0, cryptoProcess_1.startCryptoServiceSimple)();
169
134
  }
@@ -41,12 +41,16 @@ exports.listWallet = listWallet;
41
41
  exports.importWalletSk = importWalletSk;
42
42
  exports.importSvmWallet = importSvmWallet;
43
43
  exports.exportWalletSk = exportWalletSk;
44
+ exports.generateWallet = generateWallet;
45
+ exports.setDefaultWallet = setDefaultWallet;
46
+ exports.getDefaultWallet = getDefaultWallet;
44
47
  const fs_1 = require("fs");
45
48
  const env_1 = require("../util/env");
46
49
  const path_1 = __importDefault(require("path"));
47
50
  const ethers_1 = require("ethers");
48
51
  const bs58 = __importStar(require("bs58"));
49
52
  const web3_js_1 = require("@solana/web3.js");
53
+ const cryptoProcess_1 = require("../util/cryptoProcess");
50
54
  async function deleteWallet(address, chainName) {
51
55
  const config = (0, env_1.configDir)();
52
56
  const walletPath = path_1.default.join(config, chainName);
@@ -59,45 +63,32 @@ async function deleteWallet(address, chainName) {
59
63
  (0, fs_1.rmSync)(walletFile);
60
64
  }
61
65
  async function listWallet(chainName) {
62
- const config = (0, env_1.configDir)();
63
- const walletPath = path_1.default.join(config, 'wallet', chainName);
64
- if (!(0, fs_1.existsSync)(walletPath)) {
65
- (0, fs_1.mkdirSync)(walletPath, {
66
- recursive: true,
66
+ try {
67
+ const wallets = await (0, cryptoProcess_1.withCryptoService)(async (cryptoServiceClient) => {
68
+ switch (chainName) {
69
+ case 'evm':
70
+ return await cryptoServiceClient.listEvmWallets();
71
+ case 'svm':
72
+ return await cryptoServiceClient.listSolanaWallets();
73
+ case 'btc':
74
+ return await cryptoServiceClient.listBitcoinWallets();
75
+ default:
76
+ throw new Error(`Unsupported chain: ${chainName}`);
77
+ }
67
78
  });
79
+ // Display wallets
80
+ wallets.wallets.forEach((address) => {
81
+ console.log(address);
82
+ });
83
+ return wallets;
84
+ }
85
+ catch (error) {
86
+ console.error('Failed to list wallets:', error instanceof Error ? error.message : String(error));
87
+ throw error;
68
88
  }
69
- const files = (0, fs_1.readdirSync)(walletPath)
70
- .map(file => file.split('.json')[0])
71
- .reduce((acc, address) => {
72
- if (address === 'default') {
73
- const defaultAddress = (0, fs_1.readFileSync)(path_1.default.join(walletPath, 'default'), 'utf8');
74
- const existingDefaultItem = acc.find(item => item.address === defaultAddress);
75
- if (existingDefaultItem) {
76
- existingDefaultItem.default = true;
77
- }
78
- else {
79
- acc.push({ address: defaultAddress, default: true });
80
- }
81
- return acc;
82
- }
83
- else {
84
- acc.push({ address, default: false });
85
- }
86
- return acc;
87
- }, [])
88
- .forEach(item => {
89
- console.log(`${item.address} ${item.default ? '(default)' : ''}`);
90
- });
91
- return files;
92
89
  }
93
90
  async function importWalletSk(PrivateKey, chainName) {
94
- const config = (0, env_1.configDir)();
95
- const walletPath = path_1.default.join(config, chainName);
96
- if (!(0, fs_1.existsSync)(walletPath)) {
97
- (0, fs_1.mkdirSync)(walletPath, {
98
- recursive: true,
99
- });
100
- }
91
+ (0, cryptoProcess_1.ensureWalletDirectory)(chainName);
101
92
  if (chainName == 'evm') {
102
93
  await importEvmWallet(PrivateKey);
103
94
  }
@@ -106,13 +97,7 @@ async function importWalletSk(PrivateKey, chainName) {
106
97
  }
107
98
  }
108
99
  async function importEvmWallet(PrivateKey) {
109
- const config = (0, env_1.configDir)();
110
- const walletPath = path_1.default.join(config, 'wallet', 'evm');
111
- if (!(0, fs_1.existsSync)(walletPath)) {
112
- (0, fs_1.mkdirSync)(walletPath, {
113
- recursive: true,
114
- });
115
- }
100
+ const walletPath = (0, cryptoProcess_1.ensureWalletDirectory)('evm');
116
101
  if (PrivateKey.startsWith('0x') == false) {
117
102
  PrivateKey = '0x' + PrivateKey;
118
103
  }
@@ -123,13 +108,7 @@ async function importEvmWallet(PrivateKey) {
123
108
  }, null, 2));
124
109
  }
125
110
  async function importSvmWallet(privateKey) {
126
- const config = (0, env_1.configDir)();
127
- const walletPath = path_1.default.join(config, 'wallet', 'svm');
128
- if (!(0, fs_1.existsSync)(walletPath)) {
129
- (0, fs_1.mkdirSync)(walletPath, {
130
- recursive: true,
131
- });
132
- }
111
+ const walletPath = (0, cryptoProcess_1.ensureWalletDirectory)('svm');
133
112
  const bytes = bs58.decode(privateKey);
134
113
  const wallet = web3_js_1.Keypair.fromSecretKey(bytes);
135
114
  (0, fs_1.writeFileSync)(path_1.default.join(walletPath, wallet.publicKey + '.json'), JSON.stringify({
@@ -138,13 +117,7 @@ async function importSvmWallet(privateKey) {
138
117
  }, null, 2));
139
118
  }
140
119
  async function exportWalletSk(address, chainName) {
141
- const config = (0, env_1.configDir)();
142
- const walletPath = path_1.default.join(config, 'wallet', chainName);
143
- if (!(0, fs_1.existsSync)(walletPath)) {
144
- (0, fs_1.mkdirSync)(walletPath, {
145
- recursive: true,
146
- });
147
- }
120
+ const walletPath = (0, cryptoProcess_1.ensureWalletDirectory)(chainName);
148
121
  let walletFile;
149
122
  try {
150
123
  walletFile = (0, fs_1.readFileSync)(path_1.default.join(walletPath, address + '.json'));
@@ -156,3 +129,68 @@ async function exportWalletSk(address, chainName) {
156
129
  const wallet = JSON.parse(walletFile.toString());
157
130
  console.log(wallet.private_key);
158
131
  }
132
+ async function generateWallet(chainName) {
133
+ try {
134
+ const walletData = await (0, cryptoProcess_1.withCryptoService)(async (cryptoServiceClient) => {
135
+ switch (chainName) {
136
+ case 'evm':
137
+ return await cryptoServiceClient.generateEvmWallet();
138
+ case 'svm':
139
+ return await cryptoServiceClient.generateSolanaWallet();
140
+ case 'btc':
141
+ return await cryptoServiceClient.generateBitcoinWallet();
142
+ default:
143
+ throw new Error(`Unsupported chain: ${chainName}`);
144
+ }
145
+ });
146
+ console.log(`Generated ${chainName} wallet: ${walletData.address}`);
147
+ return walletData;
148
+ }
149
+ catch (error) {
150
+ console.error('Failed to generate wallet:', error instanceof Error ? error.message : String(error));
151
+ throw error;
152
+ }
153
+ }
154
+ async function setDefaultWallet(address, chainName) {
155
+ try {
156
+ await (0, cryptoProcess_1.withCryptoService)(async (cryptoServiceClient) => {
157
+ switch (chainName) {
158
+ case 'evm':
159
+ return await cryptoServiceClient.setDefaultEvmWallet(address);
160
+ case 'svm':
161
+ return await cryptoServiceClient.setDefaultSvmWallet(address);
162
+ case 'btc':
163
+ return await cryptoServiceClient.setDefaultBitcoinWallet(address);
164
+ default:
165
+ throw new Error(`Unsupported chain: ${chainName}`);
166
+ }
167
+ });
168
+ console.log(`Set ${chainName} default wallet to: ${address}`);
169
+ }
170
+ catch (error) {
171
+ console.error('Failed to set default wallet:', error instanceof Error ? error.message : String(error));
172
+ throw error;
173
+ }
174
+ }
175
+ async function getDefaultWallet(chainName) {
176
+ try {
177
+ const walletData = await (0, cryptoProcess_1.withCryptoService)(async (cryptoServiceClient) => {
178
+ switch (chainName) {
179
+ case 'evm':
180
+ return await cryptoServiceClient.getDefaultEvmWallet();
181
+ case 'svm':
182
+ return await cryptoServiceClient.getDefaultSvmWallet();
183
+ case 'btc':
184
+ return await cryptoServiceClient.getDefaultBitcoinWallet();
185
+ default:
186
+ throw new Error(`Unsupported chain: ${chainName}`);
187
+ }
188
+ });
189
+ console.log(`Default ${chainName} wallet: ${walletData.address}`);
190
+ return walletData;
191
+ }
192
+ catch (error) {
193
+ console.error('Failed to get default wallet:', error instanceof Error ? error.message : String(error));
194
+ throw error;
195
+ }
196
+ }
package/dist/config.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "0.11.4"
2
+ "version": "0.13.0"
3
3
  }
package/dist/index.js CHANGED
@@ -61,9 +61,12 @@ program
61
61
  .option('-d, --delete <string>', 'delete wallet')
62
62
  .option('-i, --import <string>', 'import wallet')
63
63
  .option('-e, --export <string>', 'export wallet')
64
- .option('-c, --chain [evm | svm]', 'chain name ', 'evm')
64
+ .option('-g, --generate', 'generate new wallet')
65
+ .option('-sd, --set-default <string>', 'set default wallet')
66
+ .option('-gd, --get-default', 'get default wallet')
67
+ .option('-c, --chain [evm | svm | btc]', 'chain name ', 'evm')
65
68
  .action(async (opts) => {
66
- const { list, delete: del, import: importWallet, export: exportWallet, chain, } = opts;
69
+ const { list, delete: del, import: importWallet, export: exportWallet, generate, setDefault, getDefault, chain, } = opts;
67
70
  if (list) {
68
71
  await (0, wallet_1.listWallet)(chain);
69
72
  }
@@ -76,6 +79,15 @@ program
76
79
  else if (exportWallet) {
77
80
  await (0, wallet_1.exportWalletSk)(exportWallet, chain);
78
81
  }
82
+ else if (generate) {
83
+ await (0, wallet_1.generateWallet)(chain);
84
+ }
85
+ else if (setDefault) {
86
+ await (0, wallet_1.setDefaultWallet)(setDefault, chain);
87
+ }
88
+ else if (getDefault) {
89
+ await (0, wallet_1.getDefaultWallet)(chain);
90
+ }
79
91
  });
80
92
  program
81
93
  .command('upload')
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseCryptoService = void 0;
4
+ class BaseCryptoService {
5
+ constructor(baseURL = 'http://localhost:5050') {
6
+ this.createPayload = (method, params) => {
7
+ return {
8
+ id: new Date().getTime().toString(),
9
+ jsonrpc: '2.0',
10
+ method,
11
+ params,
12
+ };
13
+ };
14
+ this.request = async (payload) => {
15
+ const response = await fetch(this.baseURL, {
16
+ method: 'POST',
17
+ body: JSON.stringify(payload),
18
+ headers: {
19
+ Accept: 'application/json',
20
+ 'Content-Type': 'application/json',
21
+ },
22
+ });
23
+ if (!response.ok) {
24
+ throw new Error(`Crypto service error: ${response.status}`);
25
+ }
26
+ const result = (await response.json());
27
+ if ('error' in result) {
28
+ throw new Error(`Crypto service error: ${result.error.message}`);
29
+ }
30
+ return result.result;
31
+ };
32
+ this.baseURL = baseURL;
33
+ }
34
+ }
35
+ exports.BaseCryptoService = BaseCryptoService;
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CryptoService = void 0;
4
+ const BaseCryptoService_1 = require("./BaseCryptoService");
5
+ class CryptoService extends BaseCryptoService_1.BaseCryptoService {
6
+ constructor(baseURL = 'http://localhost:5050') {
7
+ super(baseURL);
8
+ // EVM Operations
9
+ this.generateEvmWallet = async (params = {}) => {
10
+ const payload = this.createPayload('generateEvmWallet', [params]);
11
+ return await this.request(payload);
12
+ };
13
+ this.listEvmWallets = async () => {
14
+ const payload = this.createPayload('listEvmWallets', []);
15
+ return await this.request(payload);
16
+ };
17
+ this.signEvmMessage = async (params) => {
18
+ const payload = this.createPayload('signEvmMessage', [
19
+ params.address,
20
+ params.message,
21
+ ]);
22
+ return await this.request(payload);
23
+ };
24
+ this.signEvmTransaction = async (params) => {
25
+ const payload = this.createPayload('signEvmTransaction', [
26
+ params.address,
27
+ params.transaction,
28
+ params.chainId,
29
+ ]);
30
+ return await this.request(payload);
31
+ };
32
+ this.signGeneralEvmTransaction = async (params) => {
33
+ const payload = this.createPayload('signGeneralEvmTransaction', [
34
+ params.address,
35
+ params.transaction,
36
+ params.chainId,
37
+ ]);
38
+ return await this.request(payload);
39
+ };
40
+ this.signEip712TypedData = async (params) => {
41
+ const payload = this.createPayload('signEip712TypedData', [
42
+ { address: params.address, typed_data: params.typedData },
43
+ ]);
44
+ return await this.request(payload);
45
+ };
46
+ this.verifyEip1271Signature = async (params) => {
47
+ const payload = this.createPayload('verifyEip1271Signature', [
48
+ params.rpcUrl,
49
+ params.contractAddress,
50
+ params.message,
51
+ params.signature,
52
+ ]);
53
+ return await this.request(payload);
54
+ };
55
+ this.signEVMRawTransaction = async (params) => {
56
+ const chainIdHex = typeof params.chainId === 'number'
57
+ ? params.chainId.toString()
58
+ : params.chainId;
59
+ return await this.signGeneralEvmTransaction({
60
+ address: params.address,
61
+ transaction: params.rawTransaction,
62
+ chainId: chainIdHex,
63
+ });
64
+ };
65
+ this.restoreEvmWallet = async (params) => {
66
+ const payload = this.createPayload('restoreEvmWallet', [params]);
67
+ return await this.request(payload);
68
+ };
69
+ this.setDefaultEvmWallet = async (walletAddress) => {
70
+ const payload = this.createPayload('setDefaultEvmWallet', [walletAddress]);
71
+ return await this.request(payload);
72
+ };
73
+ this.getDefaultEvmWallet = async () => {
74
+ const payload = this.createPayload('getDefaultEvmWallet', []);
75
+ return await this.request(payload);
76
+ };
77
+ // Solana Operations
78
+ this.generateSolanaWallet = async (params = {}) => {
79
+ const payload = this.createPayload('generateSolanaWallet', [params]);
80
+ return await this.request(payload);
81
+ };
82
+ this.listSolanaWallets = async () => {
83
+ const payload = this.createPayload('listSolanaWallets', []);
84
+ return await this.request(payload);
85
+ };
86
+ this.getSvmOptions = async () => {
87
+ const payload = this.createPayload('getSvmOptions', []);
88
+ return await this.request(payload);
89
+ };
90
+ this.signSolanaMessage = async (params) => {
91
+ const payload = this.createPayload('signSolanaMessage', [
92
+ params.address,
93
+ params.message,
94
+ ]);
95
+ return await this.request(payload);
96
+ };
97
+ this.signSolanaTransaction = async (params) => {
98
+ const payload = this.createPayload('signSolanaTransaction', [params]);
99
+ return await this.request(payload);
100
+ };
101
+ this.restoreSvmWallet = async (params) => {
102
+ const payload = this.createPayload('restoreSvmWallet', [params]);
103
+ return await this.request(payload);
104
+ };
105
+ this.setDefaultSvmWallet = async (walletAddress) => {
106
+ const payload = this.createPayload('setDefaultSvmWallet', [walletAddress]);
107
+ return await this.request(payload);
108
+ };
109
+ this.getDefaultSvmWallet = async () => {
110
+ const payload = this.createPayload('getDefaultSvmWallet', []);
111
+ return await this.request(payload);
112
+ };
113
+ // Bitcoin Operations
114
+ this.generateBitcoinWallet = async (params = {}) => {
115
+ const payload = this.createPayload('generateBitcoinWallet', [params]);
116
+ return await this.request(payload);
117
+ };
118
+ this.listBitcoinWallets = async () => {
119
+ const payload = this.createPayload('listBitcoinWallets', []);
120
+ return await this.request(payload);
121
+ };
122
+ this.getBitcoinWalletInfo = async (params) => {
123
+ const payload = this.createPayload('getBitcoinWalletInfo', [
124
+ params.address,
125
+ ]);
126
+ return await this.request(payload);
127
+ };
128
+ this.signBitcoinMessage = async (params) => {
129
+ const payload = this.createPayload('signBitcoinMessage', [
130
+ params.address,
131
+ params.message,
132
+ ]);
133
+ return await this.request(payload);
134
+ };
135
+ this.verifyBitcoinSignature = async (params) => {
136
+ const payload = this.createPayload('verifyBitcoinSignature', [
137
+ params.address,
138
+ params.message,
139
+ params.signature,
140
+ ]);
141
+ return await this.request(payload);
142
+ };
143
+ this.signBitcoinTransaction = async (params) => {
144
+ const payload = this.createPayload('signBitcoinTransaction', [params]);
145
+ return await this.request(payload);
146
+ };
147
+ this.restoreBitcoinWallet = async (params) => {
148
+ const payload = this.createPayload('restoreBitcoinWallet', [params]);
149
+ return await this.request(payload);
150
+ };
151
+ this.setDefaultBitcoinWallet = async (walletAddress) => {
152
+ const payload = this.createPayload('setDefaultBitcoinWallet', [
153
+ walletAddress,
154
+ ]);
155
+ return await this.request(payload);
156
+ };
157
+ this.getDefaultBitcoinWallet = async () => {
158
+ const payload = this.createPayload('getDefaultBitcoinWallet', []);
159
+ return await this.request(payload);
160
+ };
161
+ this.getBitcoinOptions = async () => {
162
+ const payload = this.createPayload('getBitcoinOptions', []);
163
+ return await this.request(payload);
164
+ };
165
+ // Universal Wallet Operations
166
+ this.generateUniversalWallet = async (params = {}) => {
167
+ const payload = this.createPayload('generateUniversalWallet', [params]);
168
+ return await this.request(payload);
169
+ };
170
+ this.restoreUniversalWallet = async (params) => {
171
+ const payload = this.createPayload('restoreUniversalWallet', [params]);
172
+ return await this.request(payload);
173
+ };
174
+ }
175
+ }
176
+ exports.CryptoService = CryptoService;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,206 @@
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.isPortInUse = isPortInUse;
7
+ exports.checkPortsInUse = checkPortsInUse;
8
+ exports.isCryptoServiceRunning = isCryptoServiceRunning;
9
+ exports.startCryptoService = startCryptoService;
10
+ exports.getCryptoServicePath = getCryptoServicePath;
11
+ exports.startCryptoServiceSimple = startCryptoServiceSimple;
12
+ exports.ensureWalletDirectory = ensureWalletDirectory;
13
+ exports.withCryptoService = withCryptoService;
14
+ const fs_1 = require("fs");
15
+ const path_1 = __importDefault(require("path"));
16
+ const child_process_1 = require("child_process");
17
+ const env_1 = require("./env");
18
+ const CryptoService_1 = require("../service/crypto/CryptoService");
19
+ // Utility functions for port management
20
+ function isPortInUse(port) {
21
+ return new Promise(resolve => {
22
+ const net = require('net');
23
+ const socket = new net.Socket();
24
+ socket.setTimeout(1000);
25
+ socket.on('connect', () => {
26
+ socket.destroy();
27
+ resolve(true); // Port is in use
28
+ });
29
+ socket.on('timeout', () => {
30
+ socket.destroy();
31
+ resolve(false); // Port is free
32
+ });
33
+ socket.on('error', () => {
34
+ resolve(false); // Port is free
35
+ });
36
+ socket.connect(port, 'localhost');
37
+ });
38
+ }
39
+ async function checkPortsInUse(ports) {
40
+ const inUsePorts = [];
41
+ for (const port of ports) {
42
+ if (await isPortInUse(port)) {
43
+ inUsePorts.push(port);
44
+ }
45
+ }
46
+ return inUsePorts;
47
+ }
48
+ async function isCryptoServiceRunning(port = 5050) {
49
+ try {
50
+ // Check if crypto service is running by making a simple HTTP request
51
+ const response = await fetch(`http://localhost:${port}/`, {
52
+ method: 'GET',
53
+ signal: AbortSignal.timeout(1000), // 1 second timeout
54
+ });
55
+ // Accept any response (200, 404, 405, etc.) as long as we get a response
56
+ // This means the crypto service is running
57
+ return true;
58
+ }
59
+ catch {
60
+ return false;
61
+ }
62
+ }
63
+ function startCryptoService() {
64
+ return new Promise(async (resolve, reject) => {
65
+ const bin = getCryptoServicePath();
66
+ if (!(0, fs_1.existsSync)(bin)) {
67
+ reject(new Error(`Crypto service binary not found: ${bin}`));
68
+ return;
69
+ }
70
+ // Check if port 5050 is already in use before starting the binary
71
+ const portInUse = await isPortInUse(5050);
72
+ if (portInUse) {
73
+ // Check if it's our crypto service
74
+ const isCryptoRunning = await isCryptoServiceRunning(5050);
75
+ if (isCryptoRunning) {
76
+ // console.log('Reusing existing crypto service on port 5050');
77
+ // Return a mock process that doesn't need to be killed
78
+ resolve({
79
+ process: null,
80
+ kill: () => {
81
+ // console.log('Crypto service is managed externally, not stopping');
82
+ },
83
+ });
84
+ return;
85
+ }
86
+ else {
87
+ reject(new Error('Port 5050 is already in use by another service that is not the crypto service.\n' +
88
+ 'Please free up port 5050 or kill the conflicting process:\n' +
89
+ ' lsof -ti:5050 | xargs kill -9'));
90
+ return;
91
+ }
92
+ }
93
+ // console.log('Starting crypto service...');
94
+ let isKilled = false;
95
+ let hasResolved = false;
96
+ const cryptoProcess = (0, child_process_1.exec)(bin, {
97
+ env: {
98
+ ...process.env,
99
+ SECURE_STORAGE: (0, env_1.configDir)(),
100
+ RUST_BACKTRACE: '1',
101
+ },
102
+ }, (error, stdout, stderr) => {
103
+ // Ignore errors if the process was intentionally killed
104
+ 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);
107
+ // Check for specific Rust panic errors
108
+ if (stderr &&
109
+ 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`);
116
+ }
117
+ else if (stderr) {
118
+ console.error('Stderr:', stderr);
119
+ }
120
+ reject(new Error(`Crypto service failed: ${error.message}`));
121
+ return;
122
+ }
123
+ if (stdout) {
124
+ // console.log('Crypto service stdout:', stdout);
125
+ }
126
+ if (stderr && !isKilled) {
127
+ console.error('\x1b[31mCrypto service stderr:\x1b[0m', stderr);
128
+ }
129
+ });
130
+ // Wait 2 seconds before resolving to ensure service is ready
131
+ setTimeout(() => {
132
+ if (!hasResolved) {
133
+ hasResolved = true;
134
+ resolve({
135
+ process: cryptoProcess,
136
+ kill: () => {
137
+ isKilled = true;
138
+ if (cryptoProcess && !cryptoProcess.killed) {
139
+ cryptoProcess.kill();
140
+ }
141
+ },
142
+ });
143
+ }
144
+ }, 2000);
145
+ });
146
+ }
147
+ function getCryptoServicePath() {
148
+ const cryptoServiceBin = `${process.platform}-${process.arch}`;
149
+ let packageRoot = __dirname;
150
+ const binPath = path_1.default.join(packageRoot, '..', 'bin', cryptoServiceBin);
151
+ return binPath;
152
+ }
153
+ function startCryptoServiceSimple() {
154
+ const bin = getCryptoServicePath();
155
+ if (!(0, fs_1.existsSync)(bin)) {
156
+ console.log('\x1b[31mcrypto service not found at ' + bin + '\x1b[0m');
157
+ return;
158
+ }
159
+ console.log('\x1b[32mStarting crypto service at http://localhost:5050\x1b[0m');
160
+ (0, child_process_1.exec)(bin, { env: { SECURE_STORAGE: (0, env_1.configDir)(), RUST_BACKTRACE: '1' } }, (_, stdout, stderr) => {
161
+ // console.log("stdout", stdout);
162
+ // console.log("stderr", stderr);
163
+ });
164
+ }
165
+ function ensureWalletDirectory(chainName) {
166
+ const config = (0, env_1.configDir)();
167
+ const walletPath = path_1.default.join(config, 'wallet', chainName);
168
+ if (!(0, fs_1.existsSync)(walletPath)) {
169
+ (0, fs_1.mkdirSync)(walletPath, {
170
+ recursive: true,
171
+ });
172
+ }
173
+ return walletPath;
174
+ }
175
+ async function withCryptoService(operation) {
176
+ let cryptoService = null;
177
+ let startedCryptoService = false;
178
+ try {
179
+ // Start crypto service (this will check ports and reuse if available)
180
+ try {
181
+ cryptoService = await startCryptoService();
182
+ startedCryptoService = true;
183
+ }
184
+ 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');
192
+ throw error;
193
+ }
194
+ const cryptoServiceClient = new CryptoService_1.CryptoService();
195
+ // console.log('Crypto service client created');
196
+ return await operation(cryptoServiceClient);
197
+ }
198
+ catch (error) {
199
+ throw error;
200
+ }
201
+ finally {
202
+ if (startedCryptoService && cryptoService) {
203
+ cryptoService.kill();
204
+ }
205
+ }
206
+ }
@@ -42,7 +42,7 @@ function loadMetadata(projectPath = '.') {
42
42
  try {
43
43
  const filePath = path.join(projectPath, 'metadata.json');
44
44
  if (!fs.existsSync(filePath)) {
45
- console.log('Please run this command in Project directory');
45
+ console.log('\x1b[33mPlease run this command in Project directory\x1b[0m');
46
46
  return null;
47
47
  }
48
48
  const raw = fs.readFileSync(filePath, 'utf8');
@@ -50,7 +50,7 @@ function loadMetadata(projectPath = '.') {
50
50
  return data;
51
51
  }
52
52
  catch (err) {
53
- console.log('Please run this command in Project directory');
53
+ console.log('\x1b[33mPlease run this command in Project directory\x1b[0m');
54
54
  return null;
55
55
  }
56
56
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@airmoney-degn/airmoney-cli",
3
- "version": "0.11.4",
3
+ "version": "0.13.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"
@@ -10,8 +10,8 @@
10
10
  },
11
11
  "scripts": {
12
12
  "format": "prettier --write \"src/**/*\"",
13
- "start": "npm run update-version &&npm run build && node dist/index.js",
14
- "build": "npm run update-version && rm -rf dist && tsc && cp -r bin/ dist/bin/ && chmod -R +x dist",
13
+ "dev": "npm run build && node dist/index.js",
14
+ "build": "npm run update-version && rm -rf dist && tsc && cp -r src/bin dist/bin && chmod -R +x dist",
15
15
  "release": "npm run build && npm publish",
16
16
  "version": "changeset version",
17
17
  "changeset": "changeset",
@@ -67,8 +67,5 @@
67
67
  "prettier": "^3.6.1",
68
68
  "typescript": "^5.0.4"
69
69
  },
70
- "packageManager": "npm@>=10.9.3 <11",
71
- "engines": {
72
- "node": ">=22.19.0 <23"
73
- }
70
+ "packageManager": "npm@>=10.9.3 <11"
74
71
  }