@airmoney-degn/airmoney-cli 0.16.1 → 0.17.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/create.js +16 -12
- package/dist/cli/demo.js +1 -1
- package/dist/cli/setup.js +97 -0
- package/dist/cli/upload.js +3 -1
- package/dist/config.json +1 -1
- package/dist/index.js +45 -9
- package/dist/util/network.js +38 -0
- package/package.json +1 -1
package/dist/cli/create.js
CHANGED
|
@@ -38,21 +38,25 @@ const fs = __importStar(require("fs"));
|
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
39
|
const types_1 = require("../types");
|
|
40
40
|
const child_process_1 = require("child_process");
|
|
41
|
-
async function createCommand({ name, template, locationFolder, quiet,
|
|
41
|
+
async function createCommand({ name, template, locationFolder, quiet,
|
|
42
|
+
// ignoreEnvValidation,
|
|
43
|
+
}) {
|
|
42
44
|
// read from env (the .env was placed in config by `setup`).
|
|
43
|
-
const userId = process.env.DEVELOPER_ADDRESS || '';
|
|
44
|
-
const apiKey = process.env.API_KEY || '';
|
|
45
|
-
if (!ignoreEnvValidation) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
// const userId = process.env.DEVELOPER_ADDRESS || '';
|
|
46
|
+
// const apiKey = process.env.API_KEY || '';
|
|
47
|
+
// if (!ignoreEnvValidation) {
|
|
48
|
+
// if (!userId || !apiKey) {
|
|
49
|
+
// console.error(
|
|
50
|
+
// "Missing user or API key from env. Did you run 'airmoney-cli setup'?"
|
|
51
|
+
// );
|
|
52
|
+
// process.exit(1);
|
|
53
|
+
// }
|
|
54
|
+
// }
|
|
51
55
|
const identifier = `com.degn.${name}`;
|
|
52
56
|
console.log(`Initializing project: ${name}`);
|
|
53
|
-
if (!ignoreEnvValidation) {
|
|
54
|
-
|
|
55
|
-
}
|
|
57
|
+
// if (!ignoreEnvValidation) {
|
|
58
|
+
// console.log(`Using .env user: ${userId}`);
|
|
59
|
+
// }
|
|
56
60
|
const folderName = locationFolder || name;
|
|
57
61
|
const projectPath = path.join(process.cwd(), folderName);
|
|
58
62
|
if (template) {
|
package/dist/cli/demo.js
CHANGED
package/dist/cli/setup.js
CHANGED
|
@@ -32,11 +32,17 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
35
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
39
|
exports.setupCommand = setupCommand;
|
|
40
|
+
exports.statusCommand = statusCommand;
|
|
37
41
|
const fs = __importStar(require("fs"));
|
|
38
42
|
const path = __importStar(require("path"));
|
|
43
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
39
44
|
const env_1 = require("../util/env");
|
|
45
|
+
const network_1 = require("../util/network");
|
|
40
46
|
async function setupCommand({ network, userId, apiKey, }) {
|
|
41
47
|
const dir = (0, env_1.configDir)();
|
|
42
48
|
if (!dir)
|
|
@@ -54,3 +60,94 @@ async function setupCommand({ network, userId, apiKey, }) {
|
|
|
54
60
|
process.exit(1);
|
|
55
61
|
}
|
|
56
62
|
}
|
|
63
|
+
async function statusCommand() {
|
|
64
|
+
// Read environment variables (already loaded by loadEnvFromConfig at startup)
|
|
65
|
+
const userId = process.env.DEVELOPER_ADDRESS || '';
|
|
66
|
+
const apiKey = process.env.API_KEY || '';
|
|
67
|
+
const rpc = process.env.RPC || 'devnet';
|
|
68
|
+
// Validate that we have both userId and apiKey
|
|
69
|
+
if (!userId || !apiKey) {
|
|
70
|
+
console.log('\x1b[31mRun "airmoney-cli setup" to configure your credentials\x1b[0m');
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
console.log('User:', userId);
|
|
74
|
+
console.log('Network:', rpc);
|
|
75
|
+
console.log('');
|
|
76
|
+
// Check API key validity
|
|
77
|
+
// RPC should already be a URL (stored from setup), but handle network names for backward compatibility
|
|
78
|
+
let apiUrl = (0, network_1.networkToRpcUrl)(rpc);
|
|
79
|
+
const body = JSON.stringify({
|
|
80
|
+
jsonrpc: '2.0',
|
|
81
|
+
id: 1,
|
|
82
|
+
method: 'checkApiKey',
|
|
83
|
+
params: [userId, apiKey],
|
|
84
|
+
});
|
|
85
|
+
try {
|
|
86
|
+
const res = await (0, node_fetch_1.default)(apiUrl, {
|
|
87
|
+
method: 'POST',
|
|
88
|
+
body,
|
|
89
|
+
headers: {
|
|
90
|
+
'Content-Type': 'application/json',
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
if (!res.ok) {
|
|
94
|
+
console.log('\x1b[31mError: Failed to connect to API\x1b[0m');
|
|
95
|
+
console.log(`\x1b[31mMessage: HTTP ${res.status} - ${await res.text()}\x1b[0m`);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const json = await res.json();
|
|
99
|
+
if (json.error) {
|
|
100
|
+
console.log('\x1b[31mError: Invalid API key\x1b[0m');
|
|
101
|
+
// Combine error message and data if both exist (message first, then data)
|
|
102
|
+
let errorMessageParts = [];
|
|
103
|
+
// Add message field first if it exists
|
|
104
|
+
if (json.error.message) {
|
|
105
|
+
errorMessageParts.push(json.error.message);
|
|
106
|
+
}
|
|
107
|
+
// Parse and add data field if it exists and is different from message
|
|
108
|
+
if (json.error.data !== undefined) {
|
|
109
|
+
let dataMessage = '';
|
|
110
|
+
if (typeof json.error.data === 'string') {
|
|
111
|
+
try {
|
|
112
|
+
const parsed = JSON.parse(json.error.data);
|
|
113
|
+
dataMessage = parsed;
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
dataMessage = json.error.data.replace(/^"|"$/g, '');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
dataMessage = String(json.error.data);
|
|
121
|
+
}
|
|
122
|
+
// Only add data if it's different from message
|
|
123
|
+
if (dataMessage && dataMessage !== json.error.message) {
|
|
124
|
+
errorMessageParts.push(dataMessage);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Combine into final error message
|
|
128
|
+
const combinedMessage = errorMessageParts.length > 0
|
|
129
|
+
? errorMessageParts.join(' - ')
|
|
130
|
+
: 'Invalid API key';
|
|
131
|
+
console.log(`\x1b[31mMessage: ${combinedMessage}\x1b[0m`);
|
|
132
|
+
if (json.error.code === -32602) {
|
|
133
|
+
console.log('');
|
|
134
|
+
console.log('\x1b[3mPlease visit https://dash-devnet.degn.com/ to get a valid API key\x1b[0m');
|
|
135
|
+
}
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (json.result === true) {
|
|
139
|
+
console.log('\x1b[32mStatus: Credentials are valid\x1b[0m');
|
|
140
|
+
console.log('\x1b[32mMessage: Your API key is active and ready to use\x1b[0m');
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
console.log('\x1b[31mError: API key validation failed\x1b[0m');
|
|
144
|
+
console.log(`\x1b[31mMessage: ${JSON.stringify(json)}\x1b[0m`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
console.log('\x1b[31mError: Failed to connect to API\x1b[0m');
|
|
149
|
+
console.log(`\x1b[31mMessage: ${err instanceof Error ? err.message : String(err)}\x1b[0m`);
|
|
150
|
+
console.log('');
|
|
151
|
+
console.log('\x1b[3mPlease check your internet connection and try again\x1b[0m');
|
|
152
|
+
}
|
|
153
|
+
}
|
package/dist/cli/upload.js
CHANGED
|
@@ -42,6 +42,7 @@ const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
|
42
42
|
const md5_1 = __importDefault(require("md5")); // default import fixes TS call
|
|
43
43
|
const metadata_1 = require("../util/metadata");
|
|
44
44
|
const tarball_1 = require("../util/tarball");
|
|
45
|
+
const network_1 = require("../util/network");
|
|
45
46
|
const path_1 = __importDefault(require("path"));
|
|
46
47
|
async function uploadCommand({ network, locationFolder, buttonImages, }) {
|
|
47
48
|
console.log('Loading metadata...');
|
|
@@ -85,7 +86,8 @@ async function uploadCommand({ network, locationFolder, buttonImages, }) {
|
|
|
85
86
|
params: [userId, apiKey, metaJson, encoded],
|
|
86
87
|
});
|
|
87
88
|
try {
|
|
88
|
-
const
|
|
89
|
+
const rpcUrl = (0, network_1.networkToRpcUrl)(network);
|
|
90
|
+
const res = await (0, node_fetch_1.default)(rpcUrl, {
|
|
89
91
|
method: 'POST',
|
|
90
92
|
body,
|
|
91
93
|
headers: {
|
package/dist/config.json
CHANGED
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ const create_1 = require("./cli/create");
|
|
|
8
8
|
const serve_1 = require("./cli/serve");
|
|
9
9
|
const upload_1 = require("./cli/upload");
|
|
10
10
|
const setup_1 = require("./cli/setup");
|
|
11
|
+
const network_1 = require("./util/network");
|
|
11
12
|
const wallet_1 = require("./cli/wallet");
|
|
12
13
|
const config_json_1 = require("./config.json");
|
|
13
14
|
// Load environment from config
|
|
@@ -20,12 +21,31 @@ program
|
|
|
20
21
|
program
|
|
21
22
|
.command('setup')
|
|
22
23
|
.description('Setup env with userAddress, apiKey, rpc')
|
|
23
|
-
.
|
|
24
|
-
.
|
|
24
|
+
.option('-u, --user <string>', 'developer user')
|
|
25
|
+
.option('-k, --key <string>', 'API key')
|
|
25
26
|
.option('-n, --network <string>', 'network devnet|mainnet', 'devnet')
|
|
27
|
+
.option('-s, --status', 'check current credential status')
|
|
26
28
|
.action(opts => {
|
|
27
|
-
const { user, key, network } = opts;
|
|
28
|
-
(
|
|
29
|
+
const { user, key, network, status } = opts;
|
|
30
|
+
if (status) {
|
|
31
|
+
(0, setup_1.statusCommand)();
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
if (!user || !key) {
|
|
35
|
+
console.error('Error: --user and --key are required');
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
if (network) {
|
|
39
|
+
try {
|
|
40
|
+
(0, network_1.validateNetwork)(network);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
console.error('Error:', err instanceof Error ? err.message : String(err));
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
(0, setup_1.setupCommand)({ network, userId: user, apiKey: key });
|
|
48
|
+
}
|
|
29
49
|
});
|
|
30
50
|
program
|
|
31
51
|
.command('create')
|
|
@@ -53,7 +73,11 @@ program
|
|
|
53
73
|
console.error('both --index-app-path and --app-url must not be used simuntaniusly');
|
|
54
74
|
return;
|
|
55
75
|
}
|
|
56
|
-
await (0, serve_1.serveCommand)({
|
|
76
|
+
await (0, serve_1.serveCommand)({
|
|
77
|
+
noBrowser: !browser,
|
|
78
|
+
locationFolder: indexAppPath,
|
|
79
|
+
appUrl,
|
|
80
|
+
});
|
|
57
81
|
});
|
|
58
82
|
program
|
|
59
83
|
.command('wallet')
|
|
@@ -93,16 +117,28 @@ program
|
|
|
93
117
|
program
|
|
94
118
|
.command('upload')
|
|
95
119
|
.description('Publish the app to the DEGN Dapp Store')
|
|
96
|
-
.option('-n, --network <string>', 'network devnet|mainnet', '
|
|
120
|
+
.option('-n, --network <string>', 'network devnet|mainnet', 'devnet')
|
|
97
121
|
.option('-f, --index-app-path <string>', 'path for the index.html', './')
|
|
98
122
|
.option('-i, --button-image <string>', 'path for the button images', 'assets')
|
|
99
|
-
.action(
|
|
123
|
+
.action(opts => {
|
|
100
124
|
let { network, indexAppPath, buttonImage } = opts;
|
|
101
125
|
if (indexAppPath == './') {
|
|
102
126
|
indexAppPath = undefined;
|
|
103
127
|
}
|
|
104
|
-
|
|
105
|
-
|
|
128
|
+
if (network) {
|
|
129
|
+
try {
|
|
130
|
+
(0, network_1.validateNetwork)(network);
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
console.error('Error:', err instanceof Error ? err.message : String(err));
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
(0, upload_1.uploadCommand)({
|
|
138
|
+
network,
|
|
139
|
+
locationFolder: indexAppPath,
|
|
140
|
+
buttonImages: buttonImage,
|
|
141
|
+
});
|
|
106
142
|
});
|
|
107
143
|
program
|
|
108
144
|
.command('demo')
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Network utility functions
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.validateNetwork = validateNetwork;
|
|
7
|
+
exports.networkToRpcUrl = networkToRpcUrl;
|
|
8
|
+
/**
|
|
9
|
+
* Validates that the network is either "devnet" or "mainnet"
|
|
10
|
+
* @param network - The network string to validate
|
|
11
|
+
* @returns true if valid, throws error if invalid
|
|
12
|
+
* @throws Error if network is invalid
|
|
13
|
+
*/
|
|
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"`);
|
|
18
|
+
}
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Maps network name to RPC URL
|
|
23
|
+
* Only accepts "devnet" or "mainnet"
|
|
24
|
+
* @param network - The network name
|
|
25
|
+
* @returns The RPC URL for the network
|
|
26
|
+
* @throws Error if network is invalid
|
|
27
|
+
*/
|
|
28
|
+
function networkToRpcUrl(network) {
|
|
29
|
+
const normalized = network.toLowerCase().trim();
|
|
30
|
+
const networkMap = {
|
|
31
|
+
'devnet': 'https://rpc-dev.air.fun/',
|
|
32
|
+
'mainnet': 'https://rpc.air.fun/',
|
|
33
|
+
};
|
|
34
|
+
if (!(normalized in networkMap)) {
|
|
35
|
+
throw new Error(`Invalid network: ${network}. Must be "devnet" or "mainnet"`);
|
|
36
|
+
}
|
|
37
|
+
return networkMap[normalized];
|
|
38
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@airmoney-degn/airmoney-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.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"
|