neozip-cli 0.80.0 → 0.95.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/AGENTS.md +93 -0
- package/CHANGELOG.md +117 -12
- package/DOCUMENTATION.md +33 -38
- package/README.md +137 -63
- package/dist/src/account/account-state.js +95 -0
- package/dist/src/account/format-account-status.js +62 -0
- package/dist/src/account/identity-provision.js +79 -0
- package/dist/src/account/identity-wrap.js +106 -0
- package/dist/src/account/profile-crypto.js +85 -0
- package/dist/src/account/profile-store.js +129 -0
- package/dist/src/account/require-account.js +32 -0
- package/dist/src/account/types.js +3 -0
- package/dist/src/account/wallet-evm.js +46 -0
- package/dist/src/account/wallet-setup.js +33 -0
- package/dist/src/archive/crypto-self.js +117 -0
- package/dist/src/archive/identity-key.js +217 -0
- package/dist/src/archive/recipient-lookup.js +61 -0
- package/dist/src/cli/output.js +100 -0
- package/dist/src/cli/params.js +122 -0
- package/dist/src/cli/schema.js +186 -0
- package/dist/src/cli/validate.js +119 -0
- package/dist/src/commands/mintTimestampProof.js +26 -14
- package/dist/src/config/ConfigSetup.js +82 -423
- package/dist/src/connect/command.js +364 -0
- package/dist/src/connection/bootstrap.js +50 -0
- package/dist/src/connection/cli-guidance.js +101 -0
- package/dist/src/connection/cli-prefs.js +180 -0
- package/dist/src/connection/cli-settings.js +140 -0
- package/dist/src/connection/cli-types.js +14 -0
- package/dist/src/connection/coordinator.js +83 -0
- package/dist/src/connection/credentials.js +33 -0
- package/dist/src/connection/crypto.js +96 -0
- package/dist/src/connection/dump.js +117 -0
- package/dist/src/connection/funding.js +187 -0
- package/dist/src/connection/incomplete-setup.js +89 -0
- package/dist/src/connection/interactive.js +871 -0
- package/dist/src/connection/legacy-profile-reader.js +87 -0
- package/dist/src/connection/magic-link.js +142 -0
- package/dist/src/connection/migrate.js +115 -0
- package/dist/src/connection/onboarding.js +616 -0
- package/dist/src/connection/origin.js +69 -0
- package/dist/src/connection/phase.js +101 -0
- package/dist/src/connection/phone.js +26 -0
- package/dist/src/connection/promote-active.js +56 -0
- package/dist/src/connection/reset.js +56 -0
- package/dist/src/connection/status-report.js +52 -0
- package/dist/src/connection/store.js +406 -0
- package/dist/src/connection/token-auth.js +44 -0
- package/dist/src/connection/types.js +3 -0
- package/dist/src/connection/wallet-json-migration.js +155 -0
- package/dist/src/connection/wallet-login.js +65 -0
- package/dist/src/connection/wallet-setup.js +83 -0
- package/dist/src/constants/wallet-identity.js +14 -0
- package/dist/src/exit-codes.js +54 -10
- package/dist/src/neolist.js +100 -10
- package/dist/src/neounzip.js +236 -65
- package/dist/src/neozip/blockchain.js +18 -18
- package/dist/src/neozip/createZip.js +118 -94
- package/dist/src/neozip/upgradeZip.js +14 -11
- package/dist/src/neozip.js +269 -91
- package/dist/src/skills/command.js +256 -0
- package/dist/src/skills/locate.js +99 -0
- package/dist/src/util/mask.js +34 -0
- package/dist/src/util/token-service-fetch.js +26 -0
- package/env.example +18 -85
- package/package.json +89 -73
- package/skills/neozip-connect/SKILL.md +95 -0
- package/skills/neozip-create/SKILL.md +57 -0
- package/skills/neozip-extract/SKILL.md +58 -0
- package/skills/neozip-legacy/SKILL.md +48 -0
- package/skills/neozip-list/SKILL.md +56 -0
- package/skills/neozip-shared/SKILL.md +60 -0
- package/dist/src/commands/verifyEmail.js +0 -146
- package/dist/src/config/ConfigStore.js +0 -406
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.connectUsage = connectUsage;
|
|
4
|
+
exports.runConnectCommand = runConnectCommand;
|
|
5
|
+
/**
|
|
6
|
+
* neozip connect — Token Service account setup (vendored from neozip-mcp connect-cli).
|
|
7
|
+
*/
|
|
8
|
+
const onboarding_1 = require("../connection/onboarding");
|
|
9
|
+
const funding_1 = require("../connection/funding");
|
|
10
|
+
const dump_1 = require("../connection/dump");
|
|
11
|
+
const reset_1 = require("../connection/reset");
|
|
12
|
+
const interactive_1 = require("../connection/interactive");
|
|
13
|
+
const status_report_1 = require("../connection/status-report");
|
|
14
|
+
const cli_settings_1 = require("../connection/cli-settings");
|
|
15
|
+
function parseConnectArgs(argv) {
|
|
16
|
+
const flags = { json: false };
|
|
17
|
+
const positional = [];
|
|
18
|
+
let command = null;
|
|
19
|
+
for (let i = 0; i < argv.length; i++) {
|
|
20
|
+
const arg = argv[i];
|
|
21
|
+
if (arg === '--json') {
|
|
22
|
+
flags.json = true;
|
|
23
|
+
}
|
|
24
|
+
else if (arg === '--token-service-url' && argv[i + 1]) {
|
|
25
|
+
flags.tokenServiceUrl = argv[++i];
|
|
26
|
+
}
|
|
27
|
+
else if (arg === '--label' && argv[i + 1]) {
|
|
28
|
+
flags.label = argv[++i];
|
|
29
|
+
}
|
|
30
|
+
else if (arg === '--email' && argv[i + 1]) {
|
|
31
|
+
flags.email = argv[++i];
|
|
32
|
+
}
|
|
33
|
+
else if (arg === '--code' && argv[i + 1]) {
|
|
34
|
+
flags.code = argv[++i];
|
|
35
|
+
}
|
|
36
|
+
else if (arg === '--phone' && argv[i + 1]) {
|
|
37
|
+
flags.phone = argv[++i];
|
|
38
|
+
}
|
|
39
|
+
else if (arg === '--mnemonic' && argv[i + 1]) {
|
|
40
|
+
flags.mnemonic = argv[++i];
|
|
41
|
+
}
|
|
42
|
+
else if (arg === '--private-key' && argv[i + 1]) {
|
|
43
|
+
flags.privateKey = argv[++i];
|
|
44
|
+
}
|
|
45
|
+
else if (arg === '--ack-backup') {
|
|
46
|
+
flags.ackBackup = true;
|
|
47
|
+
}
|
|
48
|
+
else if (arg === '--create-wallet') {
|
|
49
|
+
flags.createWallet = true;
|
|
50
|
+
}
|
|
51
|
+
else if (arg === '--force') {
|
|
52
|
+
flags.force = true;
|
|
53
|
+
}
|
|
54
|
+
else if (arg === '--verbose' || arg === '-v') {
|
|
55
|
+
flags.verbose = true;
|
|
56
|
+
}
|
|
57
|
+
else if (arg === '--resend') {
|
|
58
|
+
flags.resend = true;
|
|
59
|
+
}
|
|
60
|
+
else if (arg === '--magic-token' && argv[i + 1]) {
|
|
61
|
+
flags.magicToken = argv[++i];
|
|
62
|
+
}
|
|
63
|
+
else if (arg === '--connection-id' && argv[i + 1]) {
|
|
64
|
+
flags.connectionId = argv[++i];
|
|
65
|
+
}
|
|
66
|
+
else if (arg === '--network' && argv[i + 1]) {
|
|
67
|
+
flags.network = argv[++i];
|
|
68
|
+
}
|
|
69
|
+
else if (arg === '--chain' && argv[i + 1]) {
|
|
70
|
+
flags.chain = argv[++i];
|
|
71
|
+
}
|
|
72
|
+
else if (arg === '--help' || arg === '-h') {
|
|
73
|
+
command = 'help';
|
|
74
|
+
}
|
|
75
|
+
else if (arg.startsWith('-')) {
|
|
76
|
+
throw new Error(`Unknown flag: ${arg}`);
|
|
77
|
+
}
|
|
78
|
+
else if (command === null) {
|
|
79
|
+
command = arg;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
positional.push(arg);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return { command: command ?? 'interactive', flags, positional };
|
|
86
|
+
}
|
|
87
|
+
function printResult(res, json) {
|
|
88
|
+
if (json) {
|
|
89
|
+
console.log(JSON.stringify(res, null, 2));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const lines = [`Phase: ${res.phase}`];
|
|
93
|
+
if (res.tokenServiceOrigin)
|
|
94
|
+
lines.push(`Token Service: ${res.tokenServiceOrigin}`);
|
|
95
|
+
if (res.connectionId)
|
|
96
|
+
lines.push(`Connection: ${res.connectionId}`);
|
|
97
|
+
if (res.message)
|
|
98
|
+
lines.push(res.message);
|
|
99
|
+
if (res.nextCommand)
|
|
100
|
+
lines.push(`Next: ${res.nextCommand}`);
|
|
101
|
+
if (res.accounts?.length) {
|
|
102
|
+
lines.push('');
|
|
103
|
+
lines.push((0, status_report_1.formatVerboseStatusText)(res.accounts));
|
|
104
|
+
}
|
|
105
|
+
console.log(lines.join('\n'));
|
|
106
|
+
}
|
|
107
|
+
function connectUsage() {
|
|
108
|
+
console.error(`NeoZip Connect — Token Service account setup
|
|
109
|
+
|
|
110
|
+
Usage:
|
|
111
|
+
neozip connect Interactive wizard (default)
|
|
112
|
+
neozip connect wizard Same as running with no subcommand
|
|
113
|
+
neozip connect status [--verbose] [--json] [--token-service-url URL]
|
|
114
|
+
neozip connect select --connection-id ID [--json]
|
|
115
|
+
neozip connect rename --label NAME [--connection-id ID] [--json]
|
|
116
|
+
neozip connect dump [--connection-id ID] Print manifest + public.json (no secrets)
|
|
117
|
+
neozip connect register --email EMAIL [--resend] [--json] [--token-service-url URL] [--label NAME]
|
|
118
|
+
neozip connect verify --email EMAIL --code CODE [--json] [--token-service-url URL]
|
|
119
|
+
neozip connect verify --magic-token LINK_OR_TOKEN [--email EMAIL] [--json]
|
|
120
|
+
neozip connect refresh [--email EMAIL] Renew an expired access token (sends a code)
|
|
121
|
+
neozip connect refresh --email EMAIL --code CODE Complete the token refresh
|
|
122
|
+
neozip connect refresh --magic-token LINK_OR_TOKEN [--json]
|
|
123
|
+
neozip connect fund [request|status|policy] [--network NAME | --chain ID] [--json]
|
|
124
|
+
Request native gas for your Data Wallet (default: request)
|
|
125
|
+
neozip connect phone request --phone +14155551234 [--json] [--token-service-url URL]
|
|
126
|
+
neozip connect phone verify --phone +14155551234 --code CODE [--json] [--token-service-url URL]
|
|
127
|
+
neozip connect wallet create --ack-backup [--json] [--token-service-url URL]
|
|
128
|
+
neozip connect wallet import-mnemonic --mnemonic "word1 word2 ..." [--force] [--json]
|
|
129
|
+
neozip connect wallet import-key --private-key 0x... [--force] [--json]
|
|
130
|
+
neozip connect finish [--create-wallet] [--json] [--token-service-url URL]
|
|
131
|
+
neozip connect setup --email EMAIL --code CODE [--json] [--token-service-url URL]
|
|
132
|
+
neozip connect logout [--json]
|
|
133
|
+
neozip connect delete [--json] [--connection-id ID]
|
|
134
|
+
neozip connect settings Change on-chain prefs (network, RPC, gas)
|
|
135
|
+
neozip connect migrate [--json]
|
|
136
|
+
neozip connect reset [--force] Remove connection data (re-run setup)
|
|
137
|
+
|
|
138
|
+
Environment:
|
|
139
|
+
NEOZIP_UNLOCK_PASSPHRASE — optional custom passphrase (default: machine-local key)
|
|
140
|
+
NEOZIP_CONNECTION_DIR — override connection store path (~/.neozip/connection/)
|
|
141
|
+
`);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Run connect subcommand. Pass argv after "connect" (e.g. ['status'] or [] for wizard).
|
|
145
|
+
*/
|
|
146
|
+
async function runConnectCommand(connectArgv) {
|
|
147
|
+
const { command, flags, positional } = parseConnectArgs(connectArgv);
|
|
148
|
+
const json = Boolean(flags.json);
|
|
149
|
+
const tokenServiceUrl = typeof flags.tokenServiceUrl === 'string' ? flags.tokenServiceUrl : undefined;
|
|
150
|
+
const label = typeof flags.label === 'string' ? flags.label : undefined;
|
|
151
|
+
let res;
|
|
152
|
+
switch (command) {
|
|
153
|
+
case 'interactive':
|
|
154
|
+
case 'wizard':
|
|
155
|
+
if (json) {
|
|
156
|
+
throw new Error('Interactive setup requires a TTY; omit --json or use subcommands (register, verify, finish).');
|
|
157
|
+
}
|
|
158
|
+
if (!process.stdin.isTTY) {
|
|
159
|
+
throw new Error('Interactive setup requires a TTY. Use subcommands with --json for scripted setup.');
|
|
160
|
+
}
|
|
161
|
+
res = await (0, interactive_1.runInteractiveConnect)({ tokenServiceUrl, label });
|
|
162
|
+
return res.success ? 0 : 1;
|
|
163
|
+
case 'status':
|
|
164
|
+
res = await (0, onboarding_1.connectStatus)({
|
|
165
|
+
tokenServiceUrl,
|
|
166
|
+
autoMigrate: true,
|
|
167
|
+
verbose: Boolean(flags.verbose),
|
|
168
|
+
});
|
|
169
|
+
break;
|
|
170
|
+
case 'select': {
|
|
171
|
+
const connectionId = String(flags.connectionId || '');
|
|
172
|
+
if (!connectionId)
|
|
173
|
+
throw new Error('--connection-id is required');
|
|
174
|
+
res = (0, onboarding_1.connectSelect)({ connectionId });
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
case 'rename': {
|
|
178
|
+
const renameLabel = String(flags.label || '');
|
|
179
|
+
if (!renameLabel)
|
|
180
|
+
throw new Error('--label is required');
|
|
181
|
+
const connectionId = typeof flags.connectionId === 'string' ? flags.connectionId : undefined;
|
|
182
|
+
res = (0, onboarding_1.connectRename)({ label: renameLabel, connectionId });
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
case 'dump': {
|
|
186
|
+
const connectionId = typeof flags.connectionId === 'string' ? flags.connectionId : undefined;
|
|
187
|
+
const snapshot = (0, dump_1.buildConnectionDump)({ connectionId });
|
|
188
|
+
console.log((0, dump_1.formatConnectionDump)(snapshot));
|
|
189
|
+
return 0;
|
|
190
|
+
}
|
|
191
|
+
case 'register': {
|
|
192
|
+
const email = String(flags.email || '');
|
|
193
|
+
if (!email)
|
|
194
|
+
throw new Error('--email is required');
|
|
195
|
+
res = await (0, onboarding_1.connectRegister)({
|
|
196
|
+
email,
|
|
197
|
+
tokenServiceUrl,
|
|
198
|
+
label,
|
|
199
|
+
resend: Boolean(flags.resend),
|
|
200
|
+
});
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
case 'verify': {
|
|
204
|
+
const email = typeof flags.email === 'string' ? flags.email : undefined;
|
|
205
|
+
const code = typeof flags.code === 'string' ? flags.code : undefined;
|
|
206
|
+
const magicToken = typeof flags.magicToken === 'string' ? flags.magicToken : undefined;
|
|
207
|
+
if (!magicToken && (!email || !code)) {
|
|
208
|
+
throw new Error('Provide --email and --code, or --magic-token (optionally with --email)');
|
|
209
|
+
}
|
|
210
|
+
res = await (0, onboarding_1.connectVerify)({ email, code, magicToken, tokenServiceUrl });
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
case 'refresh': {
|
|
214
|
+
const email = typeof flags.email === 'string' ? flags.email : undefined;
|
|
215
|
+
const code = typeof flags.code === 'string' ? flags.code : undefined;
|
|
216
|
+
const magicToken = typeof flags.magicToken === 'string' ? flags.magicToken : undefined;
|
|
217
|
+
res = await (0, onboarding_1.connectRefresh)({ email, code, magicToken, tokenServiceUrl });
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
case 'fund': {
|
|
221
|
+
const sub = positional[0];
|
|
222
|
+
const allowed = ['request', 'status', 'policy'];
|
|
223
|
+
const action = sub && allowed.includes(sub) ? sub : 'request';
|
|
224
|
+
if (sub && !allowed.includes(sub)) {
|
|
225
|
+
throw new Error('Usage: neozip connect fund [request|status|policy] [--network NAME | --chain ID]');
|
|
226
|
+
}
|
|
227
|
+
const network = typeof flags.network === 'string' ? flags.network : undefined;
|
|
228
|
+
const chainRaw = typeof flags.chain === 'string' ? flags.chain : undefined;
|
|
229
|
+
const chainId = chainRaw ? Number.parseInt(chainRaw, 10) : undefined;
|
|
230
|
+
if (chainRaw && (!Number.isFinite(chainId) || chainId <= 0)) {
|
|
231
|
+
throw new Error(`Invalid --chain value: ${chainRaw}`);
|
|
232
|
+
}
|
|
233
|
+
const fundRes = await (0, funding_1.connectFund)({ action, network, chainId, tokenServiceUrl });
|
|
234
|
+
if (json) {
|
|
235
|
+
console.log(JSON.stringify(fundRes, null, 2));
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
console.log((0, funding_1.formatFundResult)(fundRes));
|
|
239
|
+
}
|
|
240
|
+
return fundRes.success ? 0 : 1;
|
|
241
|
+
}
|
|
242
|
+
case 'phone': {
|
|
243
|
+
const action = positional[0];
|
|
244
|
+
const phone = String(flags.phone || '');
|
|
245
|
+
if (action === 'request') {
|
|
246
|
+
if (!phone)
|
|
247
|
+
throw new Error('--phone is required');
|
|
248
|
+
res = await (0, onboarding_1.connectPhoneRequest)({ phone, tokenServiceUrl });
|
|
249
|
+
}
|
|
250
|
+
else if (action === 'verify') {
|
|
251
|
+
const code = String(flags.code || '');
|
|
252
|
+
if (!phone || !code)
|
|
253
|
+
throw new Error('--phone and --code are required');
|
|
254
|
+
res = await (0, onboarding_1.connectPhoneVerify)({ phone, code, tokenServiceUrl });
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
throw new Error('Usage: neozip connect phone request|verify ...');
|
|
258
|
+
}
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
case 'wallet': {
|
|
262
|
+
const action = positional[0];
|
|
263
|
+
if (action === 'create') {
|
|
264
|
+
res = await (0, onboarding_1.connectWalletCreate)({
|
|
265
|
+
ackBackup: Boolean(flags.ackBackup),
|
|
266
|
+
tokenServiceUrl,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
else if (action === 'import-mnemonic') {
|
|
270
|
+
const mnemonic = String(flags.mnemonic || '');
|
|
271
|
+
if (!mnemonic)
|
|
272
|
+
throw new Error('--mnemonic is required');
|
|
273
|
+
res = await (0, onboarding_1.connectWalletImportMnemonic)({
|
|
274
|
+
mnemonic,
|
|
275
|
+
force: Boolean(flags.force),
|
|
276
|
+
tokenServiceUrl,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
else if (action === 'import-key') {
|
|
280
|
+
const privateKey = String(flags.privateKey || '');
|
|
281
|
+
if (!privateKey)
|
|
282
|
+
throw new Error('--private-key is required');
|
|
283
|
+
res = await (0, onboarding_1.connectWalletImportKey)({
|
|
284
|
+
privateKey,
|
|
285
|
+
force: Boolean(flags.force),
|
|
286
|
+
tokenServiceUrl,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
throw new Error('Usage: neozip connect wallet create|import-mnemonic|import-key ...');
|
|
291
|
+
}
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
case 'finish':
|
|
295
|
+
res = await (0, onboarding_1.connectFinish)({
|
|
296
|
+
tokenServiceUrl,
|
|
297
|
+
createWallet: Boolean(flags.createWallet),
|
|
298
|
+
});
|
|
299
|
+
break;
|
|
300
|
+
case 'setup': {
|
|
301
|
+
const email = String(flags.email || '');
|
|
302
|
+
const code = String(flags.code || '');
|
|
303
|
+
if (!email || !code)
|
|
304
|
+
throw new Error('--email and --code are required');
|
|
305
|
+
res = await (0, onboarding_1.connectSetup)({ email, code, tokenServiceUrl, label });
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
case 'logout':
|
|
309
|
+
res = (0, onboarding_1.connectLogout)();
|
|
310
|
+
break;
|
|
311
|
+
case 'delete': {
|
|
312
|
+
const connectionId = typeof flags.connectionId === 'string' ? flags.connectionId : undefined;
|
|
313
|
+
res = (0, onboarding_1.connectDelete)({ connectionId });
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
case 'settings':
|
|
317
|
+
if (json) {
|
|
318
|
+
throw new Error('Interactive settings requires a TTY; omit --json.');
|
|
319
|
+
}
|
|
320
|
+
if (!process.stdin.isTTY) {
|
|
321
|
+
throw new Error('Interactive settings requires a TTY.');
|
|
322
|
+
}
|
|
323
|
+
return await (0, cli_settings_1.runConnectSettingsInteractive)();
|
|
324
|
+
case 'migrate':
|
|
325
|
+
res = (0, onboarding_1.connectMigrate)();
|
|
326
|
+
break;
|
|
327
|
+
case 'reset': {
|
|
328
|
+
const force = connectArgv.includes('--force') || connectArgv.includes('-f');
|
|
329
|
+
if (!force && process.stdin.isTTY) {
|
|
330
|
+
console.error('This removes all NeoZip connection data.', 'Run: neozip connect reset --force');
|
|
331
|
+
return 1;
|
|
332
|
+
}
|
|
333
|
+
const out = (0, reset_1.resetConnectionStore)();
|
|
334
|
+
res = {
|
|
335
|
+
success: out.removedConnection || out.removedLegacy,
|
|
336
|
+
phase: 'no_profile',
|
|
337
|
+
message: [
|
|
338
|
+
out.removedConnection ? `Removed ${out.connectionDir}` : null,
|
|
339
|
+
out.removedLegacy ? `Removed ${out.legacyMcpDir}` : null,
|
|
340
|
+
'Run neozip connect to set up again.',
|
|
341
|
+
]
|
|
342
|
+
.filter(Boolean)
|
|
343
|
+
.join(' '),
|
|
344
|
+
};
|
|
345
|
+
if (!json) {
|
|
346
|
+
console.error(res.message);
|
|
347
|
+
return 0;
|
|
348
|
+
}
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
case 'help':
|
|
352
|
+
connectUsage();
|
|
353
|
+
return 0;
|
|
354
|
+
default:
|
|
355
|
+
connectUsage();
|
|
356
|
+
throw new Error(`Unknown command: ${command}`);
|
|
357
|
+
}
|
|
358
|
+
printResult(res, json);
|
|
359
|
+
if (!res.success && res.phase !== 'awaiting_code') {
|
|
360
|
+
return 1;
|
|
361
|
+
}
|
|
362
|
+
return 0;
|
|
363
|
+
}
|
|
364
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bootstrapConnectionContext = bootstrapConnectionContext;
|
|
4
|
+
exports.readCliConnectionCredentials = readCliConnectionCredentials;
|
|
5
|
+
exports.getTokenServiceRuntimeOptions = getTokenServiceRuntimeOptions;
|
|
6
|
+
exports.resolveVerifyServerUrl = resolveVerifyServerUrl;
|
|
7
|
+
const credentials_1 = require("./credentials");
|
|
8
|
+
const promote_active_1 = require("./promote-active");
|
|
9
|
+
const store_1 = require("./store");
|
|
10
|
+
const phase_1 = require("./phase");
|
|
11
|
+
/** Non-blocking first-pass: promote ready account if needed, read connection store. */
|
|
12
|
+
function bootstrapConnectionContext() {
|
|
13
|
+
try {
|
|
14
|
+
(0, promote_active_1.promoteReadyActiveConnection)();
|
|
15
|
+
(0, store_1.applyActiveConnectionToEnv)();
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// Ignore promotion errors — normal zip ops must still run
|
|
19
|
+
}
|
|
20
|
+
const creds = (0, credentials_1.readConnectionCredentials)();
|
|
21
|
+
const phase = (0, phase_1.computeConnectionPhase)();
|
|
22
|
+
return {
|
|
23
|
+
applied: creds.connectionId !== null,
|
|
24
|
+
connectionId: creds.connectionId,
|
|
25
|
+
phase,
|
|
26
|
+
creds,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function readCliConnectionCredentials() {
|
|
30
|
+
return (0, credentials_1.readConnectionCredentials)();
|
|
31
|
+
}
|
|
32
|
+
function getTokenServiceRuntimeOptions(debug = false) {
|
|
33
|
+
const creds = (0, credentials_1.readConnectionCredentials)();
|
|
34
|
+
if (!creds.tokenServiceUrl || !creds.recipientEmail) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
serverUrl: creds.tokenServiceUrl,
|
|
39
|
+
recipientEmail: creds.recipientEmail,
|
|
40
|
+
debug,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** Server URL for verifyDigest: archive metadata first, then active connection. */
|
|
44
|
+
function resolveVerifyServerUrl(metadataServerUrl) {
|
|
45
|
+
if (metadataServerUrl?.trim()) {
|
|
46
|
+
return metadataServerUrl.trim();
|
|
47
|
+
}
|
|
48
|
+
return (0, credentials_1.readConnectionCredentials)().tokenServiceUrl ?? undefined;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=bootstrap.js.map
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isTokenServiceConfigured = isTokenServiceConfigured;
|
|
4
|
+
exports.formatConnectGuidance = formatConnectGuidance;
|
|
5
|
+
exports.formatTokenExpiredGuidance = formatTokenExpiredGuidance;
|
|
6
|
+
exports.requireConnectionReady = requireConnectionReady;
|
|
7
|
+
exports.requireTimestampReady = requireTimestampReady;
|
|
8
|
+
exports.requireWalletReady = requireWalletReady;
|
|
9
|
+
const token_service_1 = require("neozip-blockchain/token-service");
|
|
10
|
+
const credentials_1 = require("./credentials");
|
|
11
|
+
const phase_1 = require("./phase");
|
|
12
|
+
const store_1 = require("./store");
|
|
13
|
+
const token_auth_1 = require("./token-auth");
|
|
14
|
+
const incomplete_setup_1 = require("./incomplete-setup");
|
|
15
|
+
function isTokenServiceConfigured() {
|
|
16
|
+
if ((0, phase_1.computeConnectionPhase)() === 'ready')
|
|
17
|
+
return true;
|
|
18
|
+
const meta = (0, store_1.getActiveConnection)();
|
|
19
|
+
const secrets = (0, store_1.readActiveConnectionSecrets)();
|
|
20
|
+
if (meta?.emailVerified && secrets?.accessToken?.trim()) {
|
|
21
|
+
if ((0, token_auth_1.isAccessTokenExpired)(secrets))
|
|
22
|
+
return false;
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
function formatConnectGuidance(ability) {
|
|
28
|
+
const phase = (0, phase_1.computeConnectionPhase)();
|
|
29
|
+
const next = (0, incomplete_setup_1.recommendedConnectCommand)();
|
|
30
|
+
const creds = (0, credentials_1.readConnectionCredentials)();
|
|
31
|
+
const infoUrl = creds.tokenServiceUrl
|
|
32
|
+
? `${(0, token_service_1.getTokenServiceUrl)({ serverUrl: creds.tokenServiceUrl }).replace(/\/+$/, '')}/info`
|
|
33
|
+
: 'https://testnet.token-service.neozip.io/info';
|
|
34
|
+
return [
|
|
35
|
+
`${ability} requires Token Service setup via neozip connect (current phase: ${phase}).`,
|
|
36
|
+
'',
|
|
37
|
+
'Run:',
|
|
38
|
+
` ${next}`,
|
|
39
|
+
'',
|
|
40
|
+
'Or check status:',
|
|
41
|
+
' neozip connect status',
|
|
42
|
+
'',
|
|
43
|
+
`More information: ${infoUrl}`,
|
|
44
|
+
].join('\n');
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Guidance for the specific case where the account is otherwise set up but the
|
|
48
|
+
* Token Service access token has expired. Points at `neozip connect refresh`
|
|
49
|
+
* rather than the generic setup flow.
|
|
50
|
+
*/
|
|
51
|
+
function formatTokenExpiredGuidance(ability) {
|
|
52
|
+
const email = (0, store_1.getActiveConnection)()?.email ?? null;
|
|
53
|
+
const refreshCmd = email
|
|
54
|
+
? `neozip connect refresh --email ${email}`
|
|
55
|
+
: 'neozip connect refresh';
|
|
56
|
+
return [
|
|
57
|
+
`${ability} needs a current Token Service access token, but the saved token has expired.`,
|
|
58
|
+
'',
|
|
59
|
+
'Refresh it (a 6-digit code is emailed to you):',
|
|
60
|
+
` ${refreshCmd}`,
|
|
61
|
+
` ${refreshCmd} --code 123456`,
|
|
62
|
+
'',
|
|
63
|
+
'Or check status:',
|
|
64
|
+
' neozip connect status',
|
|
65
|
+
].join('\n');
|
|
66
|
+
}
|
|
67
|
+
/** Unified preflight for -b, -ts, mint, and other gated blockchain operations. */
|
|
68
|
+
function requireConnectionReady(ability, kind = 'tokenService') {
|
|
69
|
+
const phase = (0, phase_1.computeConnectionPhase)();
|
|
70
|
+
if (phase !== 'ready') {
|
|
71
|
+
return formatConnectGuidance(ability);
|
|
72
|
+
}
|
|
73
|
+
const creds = (0, credentials_1.readConnectionCredentials)();
|
|
74
|
+
// Every gated operation needs the local wallet key (phase 'ready' guarantees
|
|
75
|
+
// it exists, but a one-off connection without it should still be caught).
|
|
76
|
+
if (!creds.walletKey?.trim()) {
|
|
77
|
+
return formatConnectGuidance(ability);
|
|
78
|
+
}
|
|
79
|
+
// Token Service requirements apply only to Token Service operations. On-chain
|
|
80
|
+
// operations (-b, mint) sign locally and do not use the access token, so an
|
|
81
|
+
// expired/absent Token Service token must not block them.
|
|
82
|
+
if (kind === 'tokenService') {
|
|
83
|
+
const secrets = (0, store_1.readActiveConnectionSecrets)();
|
|
84
|
+
if ((0, token_auth_1.isAccessTokenExpired)(secrets)) {
|
|
85
|
+
return formatTokenExpiredGuidance(ability);
|
|
86
|
+
}
|
|
87
|
+
if (!creds.recipientEmail?.trim() || !creds.tokenServiceUrl?.trim()) {
|
|
88
|
+
return formatConnectGuidance(ability);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
/** @deprecated Use requireConnectionReady */
|
|
94
|
+
function requireTimestampReady() {
|
|
95
|
+
return requireConnectionReady('Blockchain timestamp (-ts)', 'tokenService');
|
|
96
|
+
}
|
|
97
|
+
/** @deprecated Use requireConnectionReady */
|
|
98
|
+
function requireWalletReady() {
|
|
99
|
+
return requireConnectionReady('On-chain blockchain operation', 'wallet');
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=cli-guidance.js.map
|