@shieldedtech/moth-cli 0.2.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/README.md +67 -0
- package/dist/adapters/passphrase.d.ts +2 -0
- package/dist/adapters/passphrase.d.ts.map +1 -0
- package/dist/adapters/passphrase.js +62 -0
- package/dist/adapters/passphrase.js.map +1 -0
- package/dist/base-command.d.ts +155 -0
- package/dist/base-command.d.ts.map +1 -0
- package/dist/base-command.js +497 -0
- package/dist/base-command.js.map +1 -0
- package/dist/commands/airdrop.d.ts +18 -0
- package/dist/commands/airdrop.d.ts.map +1 -0
- package/dist/commands/airdrop.js +36 -0
- package/dist/commands/airdrop.js.map +1 -0
- package/dist/commands/balance.d.ts +18 -0
- package/dist/commands/balance.d.ts.map +1 -0
- package/dist/commands/balance.js +124 -0
- package/dist/commands/balance.js.map +1 -0
- package/dist/commands/call.d.ts +26 -0
- package/dist/commands/call.d.ts.map +1 -0
- package/dist/commands/call.js +102 -0
- package/dist/commands/call.js.map +1 -0
- package/dist/commands/config.d.ts +22 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +50 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/daemon/call.d.ts +27 -0
- package/dist/commands/daemon/call.d.ts.map +1 -0
- package/dist/commands/daemon/call.js +108 -0
- package/dist/commands/daemon/call.js.map +1 -0
- package/dist/commands/daemon/deploy.d.ts +27 -0
- package/dist/commands/daemon/deploy.d.ts.map +1 -0
- package/dist/commands/daemon/deploy.js +105 -0
- package/dist/commands/daemon/deploy.js.map +1 -0
- package/dist/commands/daemon/dust/deregister.d.ts +19 -0
- package/dist/commands/daemon/dust/deregister.d.ts.map +1 -0
- package/dist/commands/daemon/dust/deregister.js +52 -0
- package/dist/commands/daemon/dust/deregister.js.map +1 -0
- package/dist/commands/daemon/dust/register.d.ts +20 -0
- package/dist/commands/daemon/dust/register.d.ts.map +1 -0
- package/dist/commands/daemon/dust/register.js +60 -0
- package/dist/commands/daemon/dust/register.js.map +1 -0
- package/dist/commands/daemon/key/gen.d.ts +19 -0
- package/dist/commands/daemon/key/gen.d.ts.map +1 -0
- package/dist/commands/daemon/key/gen.js +66 -0
- package/dist/commands/daemon/key/gen.js.map +1 -0
- package/dist/commands/daemon/key/list.d.ts +17 -0
- package/dist/commands/daemon/key/list.d.ts.map +1 -0
- package/dist/commands/daemon/key/list.js +43 -0
- package/dist/commands/daemon/key/list.js.map +1 -0
- package/dist/commands/daemon/key/revoke.d.ts +20 -0
- package/dist/commands/daemon/key/revoke.d.ts.map +1 -0
- package/dist/commands/daemon/key/revoke.js +37 -0
- package/dist/commands/daemon/key/revoke.js.map +1 -0
- package/dist/commands/daemon/maintenance/insert-vk.d.ts +24 -0
- package/dist/commands/daemon/maintenance/insert-vk.d.ts.map +1 -0
- package/dist/commands/daemon/maintenance/insert-vk.js +87 -0
- package/dist/commands/daemon/maintenance/insert-vk.js.map +1 -0
- package/dist/commands/daemon/maintenance/insert-vks-batch.d.ts +24 -0
- package/dist/commands/daemon/maintenance/insert-vks-batch.d.ts.map +1 -0
- package/dist/commands/daemon/maintenance/insert-vks-batch.js +117 -0
- package/dist/commands/daemon/maintenance/insert-vks-batch.js.map +1 -0
- package/dist/commands/daemon/serve.d.ts +23 -0
- package/dist/commands/daemon/serve.d.ts.map +1 -0
- package/dist/commands/daemon/serve.js +289 -0
- package/dist/commands/daemon/serve.js.map +1 -0
- package/dist/commands/daemon/submit-tx.d.ts +22 -0
- package/dist/commands/daemon/submit-tx.d.ts.map +1 -0
- package/dist/commands/daemon/submit-tx.js +89 -0
- package/dist/commands/daemon/submit-tx.js.map +1 -0
- package/dist/commands/daemon/transfer.d.ts +24 -0
- package/dist/commands/daemon/transfer.d.ts.map +1 -0
- package/dist/commands/daemon/transfer.js +135 -0
- package/dist/commands/daemon/transfer.js.map +1 -0
- package/dist/commands/deploy.d.ts +26 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +135 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/dust/deregister.d.ts +18 -0
- package/dist/commands/dust/deregister.d.ts.map +1 -0
- package/dist/commands/dust/deregister.js +48 -0
- package/dist/commands/dust/deregister.js.map +1 -0
- package/dist/commands/dust/register.d.ts +21 -0
- package/dist/commands/dust/register.d.ts.map +1 -0
- package/dist/commands/dust/register.js +120 -0
- package/dist/commands/dust/register.js.map +1 -0
- package/dist/commands/dust/status.d.ts +17 -0
- package/dist/commands/dust/status.d.ts.map +1 -0
- package/dist/commands/dust/status.js +47 -0
- package/dist/commands/dust/status.js.map +1 -0
- package/dist/commands/info.d.ts +17 -0
- package/dist/commands/info.d.ts.map +1 -0
- package/dist/commands/info.js +37 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/maintenance/insert-vk.d.ts +23 -0
- package/dist/commands/maintenance/insert-vk.d.ts.map +1 -0
- package/dist/commands/maintenance/insert-vk.js +92 -0
- package/dist/commands/maintenance/insert-vk.js.map +1 -0
- package/dist/commands/maintenance/insert-vks-batch.d.ts +23 -0
- package/dist/commands/maintenance/insert-vks-batch.d.ts.map +1 -0
- package/dist/commands/maintenance/insert-vks-batch.js +130 -0
- package/dist/commands/maintenance/insert-vks-batch.js.map +1 -0
- package/dist/commands/mint.d.ts +24 -0
- package/dist/commands/mint.d.ts.map +1 -0
- package/dist/commands/mint.js +116 -0
- package/dist/commands/mint.js.map +1 -0
- package/dist/commands/state.d.ts +20 -0
- package/dist/commands/state.d.ts.map +1 -0
- package/dist/commands/state.js +36 -0
- package/dist/commands/state.js.map +1 -0
- package/dist/commands/transfer/batch.d.ts +21 -0
- package/dist/commands/transfer/batch.d.ts.map +1 -0
- package/dist/commands/transfer/batch.js +71 -0
- package/dist/commands/transfer/batch.js.map +1 -0
- package/dist/commands/transfer.d.ts +24 -0
- package/dist/commands/transfer.d.ts.map +1 -0
- package/dist/commands/transfer.js +123 -0
- package/dist/commands/transfer.js.map +1 -0
- package/dist/commands/tui.d.ts +17 -0
- package/dist/commands/tui.d.ts.map +1 -0
- package/dist/commands/tui.js +18 -0
- package/dist/commands/tui.js.map +1 -0
- package/dist/commands/wallet/address.d.ts +25 -0
- package/dist/commands/wallet/address.d.ts.map +1 -0
- package/dist/commands/wallet/address.js +47 -0
- package/dist/commands/wallet/address.js.map +1 -0
- package/dist/commands/wallet/generate.d.ts +20 -0
- package/dist/commands/wallet/generate.d.ts.map +1 -0
- package/dist/commands/wallet/generate.js +75 -0
- package/dist/commands/wallet/generate.js.map +1 -0
- package/dist/commands/wallet/import.d.ts +20 -0
- package/dist/commands/wallet/import.d.ts.map +1 -0
- package/dist/commands/wallet/import.js +85 -0
- package/dist/commands/wallet/import.js.map +1 -0
- package/dist/commands/wallet/list.d.ts +17 -0
- package/dist/commands/wallet/list.d.ts.map +1 -0
- package/dist/commands/wallet/list.js +23 -0
- package/dist/commands/wallet/list.js.map +1 -0
- package/dist/commands/wallet/remove.d.ts +21 -0
- package/dist/commands/wallet/remove.d.ts.map +1 -0
- package/dist/commands/wallet/remove.js +31 -0
- package/dist/commands/wallet/remove.js.map +1 -0
- package/dist/commands/wallet/status.d.ts +18 -0
- package/dist/commands/wallet/status.d.ts.map +1 -0
- package/dist/commands/wallet/status.js +62 -0
- package/dist/commands/wallet/status.js.map +1 -0
- package/dist/commands/wallet/use.d.ts +20 -0
- package/dist/commands/wallet/use.d.ts.map +1 -0
- package/dist/commands/wallet/use.js +19 -0
- package/dist/commands/wallet/use.js.map +1 -0
- package/dist/formatters/index.d.ts +5 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +68 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/package.json +53 -0
- package/templates/dapp/api/package.json +21 -0
- package/templates/dapp/api/src/index.ts +2 -0
- package/templates/dapp/api/src/providers.ts +23 -0
- package/templates/dapp/api/src/types.ts +23 -0
- package/templates/dapp/api/tsconfig.json +11 -0
- package/templates/dapp/root/README.md +20 -0
- package/templates/dapp/root/tsconfig.json +15 -0
- package/templates/dapp/ui/index.html +13 -0
- package/templates/dapp/ui/package.json +24 -0
- package/templates/dapp/ui/public/vite.svg +1 -0
- package/templates/dapp/ui/src/App.tsx +36 -0
- package/templates/dapp/ui/src/index.css +29 -0
- package/templates/dapp/ui/src/main.tsx +10 -0
- package/templates/dapp/ui/tsconfig.json +8 -0
- package/templates/dapp/ui/vite.config.ts +14 -0
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
import { Command, Flags, Errors as OclifErrors } from '@oclif/core';
|
|
2
|
+
import { access } from 'node:fs/promises';
|
|
3
|
+
import { formatOutput, formatError } from './formatters/index.js';
|
|
4
|
+
import { WalletError, WalletManager, DEFAULT_NETWORKS, resolveProverConfig, serverProver, validateNetworkConfig, connectDaemon, connectDaemonTcp, daemonSocketPath, } from '@shieldedtech/moth-wallet';
|
|
5
|
+
import { FilesystemStorageAdapter } from '@shieldedtech/moth-wallet';
|
|
6
|
+
/** Split a `host:port` string into typed parts, or null if malformed.
|
|
7
|
+
* Used by the TCP path of probeDaemon. */
|
|
8
|
+
function parseBindString(bind) {
|
|
9
|
+
const sep = bind.lastIndexOf(':');
|
|
10
|
+
if (sep <= 0)
|
|
11
|
+
return null;
|
|
12
|
+
const host = bind.slice(0, sep);
|
|
13
|
+
const port = Number.parseInt(bind.slice(sep + 1), 10);
|
|
14
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535)
|
|
15
|
+
return null;
|
|
16
|
+
return { host, port };
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Flag set every daemon-mode subcommand mixes in. Lets the operator
|
|
20
|
+
* point at either:
|
|
21
|
+
* - the default Unix daemon for `(network, walletName)` (no flags)
|
|
22
|
+
* - a TCP daemon at `--bind host:port`, with the API token supplied
|
|
23
|
+
* ONLY via the `MOTH_DAEMON_TOKEN` environment variable (never a CLI
|
|
24
|
+
* flag — a flag value is readable from the process list)
|
|
25
|
+
*/
|
|
26
|
+
export const daemonClientFlags = {
|
|
27
|
+
bind: Flags.string({
|
|
28
|
+
description: 'TCP daemon target as `<host>:<port>` (e.g. 127.0.0.1:18820). When set, the subcommand connects via TCP and requires the API token in the MOTH_DAEMON_TOKEN environment variable. When omitted, the subcommand uses the Unix socket for the active wallet.',
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
31
|
+
// Load .env file if present (won't override existing env vars)
|
|
32
|
+
import 'dotenv/config';
|
|
33
|
+
// Patterns that indicate sensitive data — never log these
|
|
34
|
+
const SENSITIVE_PATTERNS = [
|
|
35
|
+
/\b[a-f0-9]{64}\b/gi,
|
|
36
|
+
/\b(?:abandon\s+){11}\w+\b/gi,
|
|
37
|
+
/\bmnemonic\s*[:=]\s*\S+/gi,
|
|
38
|
+
/\bpassphrase\s*[:=]\s*\S+/gi,
|
|
39
|
+
/\bprivate[_-]?key\s*[:=]\s*\S+/gi,
|
|
40
|
+
];
|
|
41
|
+
function sanitizeForLogging(message) {
|
|
42
|
+
let sanitized = message;
|
|
43
|
+
for (const pattern of SENSITIVE_PATTERNS) {
|
|
44
|
+
sanitized = sanitized.replace(pattern, '[REDACTED]');
|
|
45
|
+
}
|
|
46
|
+
return sanitized;
|
|
47
|
+
}
|
|
48
|
+
export class BaseCommand extends Command {
|
|
49
|
+
static baseFlags = {
|
|
50
|
+
output: Flags.string({
|
|
51
|
+
char: 'o',
|
|
52
|
+
options: ['text', 'json'],
|
|
53
|
+
default: 'text',
|
|
54
|
+
description: 'Output format',
|
|
55
|
+
}),
|
|
56
|
+
network: Flags.string({
|
|
57
|
+
char: 'n',
|
|
58
|
+
default: 'devnet',
|
|
59
|
+
description: 'Target network',
|
|
60
|
+
}),
|
|
61
|
+
wallet: Flags.string({
|
|
62
|
+
char: 'w',
|
|
63
|
+
description: 'Wallet name (default: active wallet)',
|
|
64
|
+
}),
|
|
65
|
+
verbose: Flags.boolean({
|
|
66
|
+
char: 'v',
|
|
67
|
+
default: false,
|
|
68
|
+
description: 'Debug output to stderr',
|
|
69
|
+
}),
|
|
70
|
+
timeout: Flags.integer({
|
|
71
|
+
char: 't',
|
|
72
|
+
description: 'Operation timeout in seconds',
|
|
73
|
+
}),
|
|
74
|
+
'proof-server': Flags.string({
|
|
75
|
+
description: 'Proof server URL override',
|
|
76
|
+
}),
|
|
77
|
+
prover: Flags.string({
|
|
78
|
+
options: ['server', 'wasm'],
|
|
79
|
+
description: 'Proof generation mode',
|
|
80
|
+
env: 'MOTH_PROVER',
|
|
81
|
+
}),
|
|
82
|
+
indexer: Flags.string({
|
|
83
|
+
description: 'Indexer GraphQL URL override',
|
|
84
|
+
env: 'MOTH_INDEXER_URL',
|
|
85
|
+
}),
|
|
86
|
+
'node-url': Flags.string({
|
|
87
|
+
description: 'Node WebSocket URL override',
|
|
88
|
+
env: 'MOTH_NODE_URL',
|
|
89
|
+
}),
|
|
90
|
+
};
|
|
91
|
+
outputFormat = 'text';
|
|
92
|
+
verbose = false;
|
|
93
|
+
_storage;
|
|
94
|
+
_walletManager;
|
|
95
|
+
async init() {
|
|
96
|
+
await super.init();
|
|
97
|
+
// Best-effort matrix check — only runs if enabled via config
|
|
98
|
+
await this.checkSupportMatrix();
|
|
99
|
+
}
|
|
100
|
+
get storage() {
|
|
101
|
+
if (!this._storage) {
|
|
102
|
+
this._storage = new FilesystemStorageAdapter();
|
|
103
|
+
}
|
|
104
|
+
return this._storage;
|
|
105
|
+
}
|
|
106
|
+
get walletManager() {
|
|
107
|
+
if (!this._walletManager) {
|
|
108
|
+
this._walletManager = new WalletManager(this.storage);
|
|
109
|
+
}
|
|
110
|
+
return this._walletManager;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Resolve network config with overrides.
|
|
114
|
+
*
|
|
115
|
+
* Precedence (highest to lowest):
|
|
116
|
+
* 1. CLI flags (--indexer, --node-url, --prover, --proof-server)
|
|
117
|
+
* 2. Environment variables (MOTH_INDEXER_URL, MOTH_NODE_URL, MOTH_PROVER, MOTH_PROOF_SERVER_URL)
|
|
118
|
+
* 3. .env file (loaded automatically via dotenv)
|
|
119
|
+
* 4. Persisted config (moth config set indexer-url <url>)
|
|
120
|
+
* 5. Network defaults (devnet, preview, preprod, qanet)
|
|
121
|
+
*/
|
|
122
|
+
async getNetworkConfig(networkId, overrides) {
|
|
123
|
+
// Block mainnet usage — this is a reference wallet
|
|
124
|
+
if (networkId === 'mainnet') {
|
|
125
|
+
process.stderr.write('\n' +
|
|
126
|
+
' ╔══════════════════════════════════════════════════════════════╗\n' +
|
|
127
|
+
' ║ WARNING ║\n' +
|
|
128
|
+
' ║ ║\n' +
|
|
129
|
+
' ║ Moth is a reference wallet for development and testing. ║\n' +
|
|
130
|
+
' ║ It should NOT be used with real funds on mainnet. ║\n' +
|
|
131
|
+
' ║ ║\n' +
|
|
132
|
+
' ║ Use Lace or another commercial wallet for mainnet. ║\n' +
|
|
133
|
+
' ╚══════════════════════════════════════════════════════════════╝\n' +
|
|
134
|
+
'\n');
|
|
135
|
+
this.exit(1);
|
|
136
|
+
}
|
|
137
|
+
const base = DEFAULT_NETWORKS[networkId] ?? {
|
|
138
|
+
id: networkId,
|
|
139
|
+
nodeUrl: 'ws://localhost:9944',
|
|
140
|
+
indexerUrl: 'http://localhost:8088',
|
|
141
|
+
prover: serverProver(),
|
|
142
|
+
};
|
|
143
|
+
// Check persisted config
|
|
144
|
+
const decoder = new TextDecoder();
|
|
145
|
+
const persistedIndexer = await this.storage.read('config/indexer-url').then(d => d ? decoder.decode(d) : null).catch(() => null);
|
|
146
|
+
const persistedNode = await this.storage.read('config/node-url').then(d => d ? decoder.decode(d) : null).catch(() => null);
|
|
147
|
+
const persistedProof = await this.storage.read('config/proof-server-url').then(d => d ? decoder.decode(d) : null).catch(() => null);
|
|
148
|
+
const persistedProver = await this.storage.read('config/prover').then(d => d ? decoder.decode(d) : null).catch(() => null);
|
|
149
|
+
const baseProver = resolveProverConfig(base);
|
|
150
|
+
const proofServerUrl = overrides?.proofServer
|
|
151
|
+
?? process.env.MOTH_PROOF_SERVER_URL
|
|
152
|
+
?? persistedProof
|
|
153
|
+
?? (baseProver.type === 'server' ? baseProver.url : 'http://localhost:6300');
|
|
154
|
+
const proverMode = overrides?.prover
|
|
155
|
+
?? process.env.MOTH_PROVER
|
|
156
|
+
?? persistedProver
|
|
157
|
+
?? baseProver.type;
|
|
158
|
+
if (proverMode !== 'server' && proverMode !== 'wasm') {
|
|
159
|
+
throw new WalletError('INVALID_INPUT', `Invalid prover mode "${proverMode}". Use "server" or "wasm".`);
|
|
160
|
+
}
|
|
161
|
+
const config = {
|
|
162
|
+
id: networkId,
|
|
163
|
+
indexerUrl: overrides?.indexer
|
|
164
|
+
?? process.env.MOTH_INDEXER_URL
|
|
165
|
+
?? persistedIndexer
|
|
166
|
+
?? base.indexerUrl,
|
|
167
|
+
nodeUrl: overrides?.nodeUrl
|
|
168
|
+
?? process.env.MOTH_NODE_URL
|
|
169
|
+
?? persistedNode
|
|
170
|
+
?? base.nodeUrl,
|
|
171
|
+
prover: proverMode === 'wasm' ? { type: 'wasm' } : serverProver(proofServerUrl),
|
|
172
|
+
};
|
|
173
|
+
// CWE-918: Validate URL schemes to prevent SSRF via user-controlled URLs
|
|
174
|
+
validateNetworkConfig(config);
|
|
175
|
+
return config;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Helper to extract network overrides from parsed flags.
|
|
179
|
+
*/
|
|
180
|
+
getNetworkOverrides(flags) {
|
|
181
|
+
return {
|
|
182
|
+
proofServer: flags['proof-server'],
|
|
183
|
+
prover: flags['prover'],
|
|
184
|
+
indexer: flags['indexer'],
|
|
185
|
+
nodeUrl: flags['node-url'],
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Try to connect to a running TUI daemon for (network, wallet). Returns
|
|
190
|
+
* a DaemonClient or null when no daemon is reachable — the calling
|
|
191
|
+
* command should fall through to its standalone path on null. Callers
|
|
192
|
+
* are responsible for closing the client when done.
|
|
193
|
+
*
|
|
194
|
+
* Failure modes folded to null (so commands can branch with a single
|
|
195
|
+
* truthy check): socket file absent (no TUI), socket present but
|
|
196
|
+
* stale (crashed TUI), protocol-version mismatch.
|
|
197
|
+
*/
|
|
198
|
+
async tryConnectDaemon(networkId, walletName, opts = {}) {
|
|
199
|
+
const result = await this.probeDaemon(networkId, walletName, opts);
|
|
200
|
+
return result.client;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Connect with structured diagnostics. Same call as tryConnectDaemon
|
|
204
|
+
* but returns *why* it failed when it did, so commands can render
|
|
205
|
+
* tailored remediation hints. Supports both transports:
|
|
206
|
+
*
|
|
207
|
+
* - default (no `bind`): Unix socket for (network, walletName)
|
|
208
|
+
* - `bind: "host:port"`: TCP, with `token` required
|
|
209
|
+
*
|
|
210
|
+
* Authentication-related failures (refused, bad token) get distinct
|
|
211
|
+
* `failure` codes so the caller's error message can be precise.
|
|
212
|
+
*/
|
|
213
|
+
async probeDaemon(networkId, walletName, opts = {}) {
|
|
214
|
+
const onLog = (level, msg) => this.log_verbose(`[daemon] ${level}: ${msg}`);
|
|
215
|
+
if (opts.bind) {
|
|
216
|
+
const parsed = parseBindString(opts.bind);
|
|
217
|
+
if (!parsed) {
|
|
218
|
+
return {
|
|
219
|
+
client: null,
|
|
220
|
+
failure: 'tcp-refused',
|
|
221
|
+
target: opts.bind,
|
|
222
|
+
socketPath: '',
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
const target = `tcp://${parsed.host}:${parsed.port}`;
|
|
226
|
+
// The API token comes ONLY from the environment, never a CLI flag —
|
|
227
|
+
// a flag value is readable from the process list. Same handling as
|
|
228
|
+
// the wallet passphrase (MOTH_PASSPHRASE).
|
|
229
|
+
const token = process.env.MOTH_DAEMON_TOKEN;
|
|
230
|
+
if (!token) {
|
|
231
|
+
return { client: null, failure: 'auth-failed', target, socketPath: '' };
|
|
232
|
+
}
|
|
233
|
+
const client = await connectDaemonTcp(parsed.host, parsed.port, {
|
|
234
|
+
token,
|
|
235
|
+
onLog,
|
|
236
|
+
});
|
|
237
|
+
if (!client) {
|
|
238
|
+
// `connectDaemonTcp` folds both connect-refused and
|
|
239
|
+
// auth-failure into null. The library separation isn't worth
|
|
240
|
+
// surfacing here; verbose-mode logs will show which it was.
|
|
241
|
+
// We tag the failure as 'tcp-refused' by default; callers
|
|
242
|
+
// that pass a known-valid token can read this as "the host
|
|
243
|
+
// isn't there OR the token is wrong" — the verbose log
|
|
244
|
+
// disambiguates.
|
|
245
|
+
return { client: null, failure: 'tcp-refused', target, socketPath: '' };
|
|
246
|
+
}
|
|
247
|
+
return { client, failure: null, target, socketPath: '' };
|
|
248
|
+
}
|
|
249
|
+
// Unix fallback (default path — preserves stage-1 behaviour).
|
|
250
|
+
const socketPath = daemonSocketPath(networkId, walletName);
|
|
251
|
+
const target = `unix://${socketPath}`;
|
|
252
|
+
try {
|
|
253
|
+
await access(socketPath);
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
return { client: null, failure: 'no-tui', target, socketPath };
|
|
257
|
+
}
|
|
258
|
+
const client = await connectDaemon(socketPath, { onLog });
|
|
259
|
+
if (!client) {
|
|
260
|
+
// File existed at access-time but the connect either refused or
|
|
261
|
+
// the handshake failed. We can't reliably distinguish stale-socket
|
|
262
|
+
// from handshake-failed without surgery in connectDaemon's error
|
|
263
|
+
// path — for now report the more common cause (stale) and let
|
|
264
|
+
// verbose mode show the underlying reason.
|
|
265
|
+
return { client: null, failure: 'stale-socket', target, socketPath };
|
|
266
|
+
}
|
|
267
|
+
return { client, failure: null, target, socketPath };
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Connect to the daemon or print a layered, operator-friendly error and
|
|
271
|
+
* exit. Centralizes the "no daemon" messaging so every daemon-aware
|
|
272
|
+
* command produces consistent output. Returns null on failure (after
|
|
273
|
+
* having already called this.outputError and this.exit on the caller's
|
|
274
|
+
* behalf) — caller can early-return.
|
|
275
|
+
*/
|
|
276
|
+
async connectDaemonOrExit(networkId, walletName, opts = {}) {
|
|
277
|
+
const { client, failure, target, socketPath } = await this.probeDaemon(networkId, walletName, opts);
|
|
278
|
+
if (client)
|
|
279
|
+
return client;
|
|
280
|
+
switch (failure) {
|
|
281
|
+
case 'no-tui':
|
|
282
|
+
this.outputError('WALLET_ERROR', `No TUI is hosting wallet "${walletName}" on ${networkId}. Either start the TUI (moth tui --network ${networkId}) or select this wallet in a running TUI. (Checked: ${socketPath})`);
|
|
283
|
+
break;
|
|
284
|
+
case 'stale-socket':
|
|
285
|
+
this.outputError('WALLET_ERROR', `A socket exists at ${socketPath} but the handshake didn't complete. Possible causes: the TUI is starting up (try again in a few seconds), it's shutting down, the wallet for this socket hasn't been unlocked yet, or the file is left over from a crashed TUI. If retries fail, remove the file and restart the TUI.`);
|
|
286
|
+
break;
|
|
287
|
+
case 'handshake-failed':
|
|
288
|
+
this.outputError('WALLET_ERROR', `Daemon at ${target} rejected the handshake. Likely a version mismatch between the CLI and the daemon — make sure both come from the same build.`);
|
|
289
|
+
break;
|
|
290
|
+
case 'tcp-refused':
|
|
291
|
+
this.outputError('WALLET_ERROR', `Could not reach a daemon at ${target}. Likely causes: (1) no daemon listening on that host:port — start one with \`moth daemon serve --transport tcp --bind <host:port>\`; (2) wrong token — verify --token (or MOTH_DAEMON_TOKEN) matches the key the daemon is configured with; (3) malformed --bind value.`);
|
|
292
|
+
break;
|
|
293
|
+
case 'auth-failed':
|
|
294
|
+
this.outputError('INVALID_INPUT', `--bind requires --token (or MOTH_DAEMON_TOKEN). Generate a key with \`moth daemon key gen --label "<purpose>"\` and pass the printed token.`);
|
|
295
|
+
break;
|
|
296
|
+
default:
|
|
297
|
+
this.outputError('WALLET_ERROR', `Daemon connect failed for unknown reason at ${target}`);
|
|
298
|
+
}
|
|
299
|
+
this.exit(1);
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Map a DaemonProtocolError onto the WalletErrorCategory taxonomy the
|
|
304
|
+
* CLI's outputError understands. Lets daemon-aware commands render
|
|
305
|
+
* RPC failures with the right category and a useful prefix rather
|
|
306
|
+
* than dumping every code as a generic WALLET_ERROR.
|
|
307
|
+
*/
|
|
308
|
+
renderDaemonError(err) {
|
|
309
|
+
const code = err.code;
|
|
310
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
311
|
+
switch (code) {
|
|
312
|
+
case 'UNAUTHORIZED':
|
|
313
|
+
return { category: 'WALLET_ERROR', message: `Denied in TUI: ${msg}` };
|
|
314
|
+
case 'INVALID_PARAMS':
|
|
315
|
+
case 'INVALID_REQUEST':
|
|
316
|
+
case 'METHOD_NOT_FOUND':
|
|
317
|
+
return { category: 'INVALID_INPUT', message: msg };
|
|
318
|
+
case 'TIMEOUT':
|
|
319
|
+
return { category: 'TIMEOUT', message: msg };
|
|
320
|
+
case 'CLOSED':
|
|
321
|
+
return { category: 'NETWORK_ERROR', message: `Daemon connection closed: ${msg}` };
|
|
322
|
+
case 'INTERNAL_ERROR':
|
|
323
|
+
default:
|
|
324
|
+
return { category: 'WALLET_ERROR', message: msg };
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
async resolveWalletName(flags) {
|
|
328
|
+
if (flags.wallet) {
|
|
329
|
+
this.log_verbose(`Using wallet: ${flags.wallet} (from --wallet flag)`);
|
|
330
|
+
process.stderr.write(`Using wallet: ${flags.wallet}\n`);
|
|
331
|
+
return flags.wallet;
|
|
332
|
+
}
|
|
333
|
+
const active = await this.walletManager.getActive();
|
|
334
|
+
if (!active) {
|
|
335
|
+
throw new WalletError('WALLET_ERROR', 'No active wallet. Run: moth wallet generate');
|
|
336
|
+
}
|
|
337
|
+
process.stderr.write(`Using wallet: ${active}\n`);
|
|
338
|
+
return active;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* SR-003: Prompt for explicit confirmation before transaction submission.
|
|
342
|
+
* Shows transaction details and requires user to type 'yes'.
|
|
343
|
+
* In non-interactive mode, requires --yes flag.
|
|
344
|
+
*/
|
|
345
|
+
async confirmTransaction(details, flags) {
|
|
346
|
+
if (flags.yes)
|
|
347
|
+
return;
|
|
348
|
+
if (!process.stdin.isTTY) {
|
|
349
|
+
throw new WalletError('INVALID_INPUT', 'Non-interactive transaction requires --yes flag');
|
|
350
|
+
}
|
|
351
|
+
process.stderr.write('\nTransaction details:\n');
|
|
352
|
+
for (const [key, value] of Object.entries(details)) {
|
|
353
|
+
process.stderr.write(` ${key.padEnd(14)} ${value}\n`);
|
|
354
|
+
}
|
|
355
|
+
process.stderr.write('\n');
|
|
356
|
+
const answer = await this.promptIfMissing(undefined, 'Confirm transaction? (yes/no)');
|
|
357
|
+
if (answer.toLowerCase() !== 'yes' && answer.toLowerCase() !== 'y') {
|
|
358
|
+
throw new WalletError('WALLET_ERROR', 'Transaction cancelled by user');
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
log_verbose(message) {
|
|
362
|
+
if (this.verbose) {
|
|
363
|
+
const ts = new Date().toISOString();
|
|
364
|
+
const sanitized = sanitizeForLogging(message);
|
|
365
|
+
process.stderr.write(`[${ts}] ${sanitized}\n`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
async promptWithDefault(prompt, defaultValue) {
|
|
369
|
+
if (!process.stdin.isTTY) {
|
|
370
|
+
return defaultValue;
|
|
371
|
+
}
|
|
372
|
+
const { createInterface } = await import('node:readline');
|
|
373
|
+
return new Promise((resolve) => {
|
|
374
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
375
|
+
rl.question(`${prompt} [${defaultValue}]: `, (answer) => {
|
|
376
|
+
rl.close();
|
|
377
|
+
resolve(answer?.trim() || defaultValue);
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
async promptIfMissing(value, prompt) {
|
|
382
|
+
if (value)
|
|
383
|
+
return value;
|
|
384
|
+
if (!process.stdin.isTTY) {
|
|
385
|
+
throw new WalletError('INVALID_INPUT', `Missing required input: ${prompt}`);
|
|
386
|
+
}
|
|
387
|
+
const { createInterface } = await import('node:readline');
|
|
388
|
+
return new Promise((resolve, reject) => {
|
|
389
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
390
|
+
rl.question(`${prompt}: `, (answer) => {
|
|
391
|
+
rl.close();
|
|
392
|
+
if (!answer?.trim()) {
|
|
393
|
+
reject(new WalletError('INVALID_INPUT', `${prompt} cannot be empty`));
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
resolve(answer.trim());
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Check installed @midnight-ntwrk/* package versions against the support matrix.
|
|
403
|
+
* Only runs if `moth config set check-matrix true` has been set.
|
|
404
|
+
* Emits warnings to stderr for mismatches — never blocks execution.
|
|
405
|
+
*/
|
|
406
|
+
async checkSupportMatrix() {
|
|
407
|
+
const decoder = new TextDecoder();
|
|
408
|
+
const enabled = await this.storage.read('config/check-matrix').then(d => d ? decoder.decode(d) : null).catch(() => null);
|
|
409
|
+
if (enabled !== 'true')
|
|
410
|
+
return;
|
|
411
|
+
try {
|
|
412
|
+
const matrixModule = '../lib/support-matrix.js';
|
|
413
|
+
const { getMatrix, checkVersions } = await import(/* webpackIgnore: true */ matrixModule);
|
|
414
|
+
const matrixUrl = await this.storage.read('config/matrix-url').then(d => d ? decoder.decode(d) : undefined).catch(() => undefined);
|
|
415
|
+
const matrix = await getMatrix({
|
|
416
|
+
overrideUrl: matrixUrl,
|
|
417
|
+
verbose: this.verbose,
|
|
418
|
+
});
|
|
419
|
+
// Read installed versions from the nearest package.json/node_modules
|
|
420
|
+
const installedVersions = await this.getInstalledMidnightVersions();
|
|
421
|
+
if (Object.keys(installedVersions).length === 0)
|
|
422
|
+
return;
|
|
423
|
+
const mismatches = checkVersions(matrix, installedVersions);
|
|
424
|
+
if (mismatches.length > 0) {
|
|
425
|
+
process.stderr.write('\n Support matrix version warnings:\n');
|
|
426
|
+
for (const m of mismatches) {
|
|
427
|
+
process.stderr.write(` ${m.package}: installed ${m.actual}, matrix recommends ${m.expected}\n`);
|
|
428
|
+
}
|
|
429
|
+
process.stderr.write(' Run `moth config set check-matrix false` to disable this check.\n\n');
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
catch {
|
|
433
|
+
// Matrix check is best-effort — never block the CLI
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Scan node_modules for installed @midnight-ntwrk/* package versions.
|
|
438
|
+
*/
|
|
439
|
+
async getInstalledMidnightVersions() {
|
|
440
|
+
const versions = {};
|
|
441
|
+
try {
|
|
442
|
+
const { readFile } = await import('node:fs/promises');
|
|
443
|
+
const { join } = await import('node:path');
|
|
444
|
+
const { readdirSync, existsSync } = await import('node:fs');
|
|
445
|
+
const nmDir = join(process.cwd(), 'node_modules', '@midnight-ntwrk');
|
|
446
|
+
if (!existsSync(nmDir))
|
|
447
|
+
return versions;
|
|
448
|
+
const pkgs = readdirSync(nmDir);
|
|
449
|
+
for (const pkg of pkgs) {
|
|
450
|
+
try {
|
|
451
|
+
const pkgJson = JSON.parse(await readFile(join(nmDir, pkg, 'package.json'), 'utf-8'));
|
|
452
|
+
if (pkgJson.version) {
|
|
453
|
+
versions[`@midnight-ntwrk/${pkg}`] = pkgJson.version;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
catch { /* skip unreadable */ }
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
catch { /* no node_modules */ }
|
|
460
|
+
return versions;
|
|
461
|
+
}
|
|
462
|
+
outputSuccess(data) {
|
|
463
|
+
this.log(formatOutput(data, this.outputFormat));
|
|
464
|
+
}
|
|
465
|
+
outputError(category, message, hint) {
|
|
466
|
+
process.stderr.write(formatError(category, message, this.outputFormat, hint) + '\n');
|
|
467
|
+
}
|
|
468
|
+
async catch(err) {
|
|
469
|
+
// oclif's `this.exit(code)` throws an ExitError to terminate the
|
|
470
|
+
// command — it isn't a user-facing error. Re-render it the way
|
|
471
|
+
// oclif would have and propagate the original exit code; do NOT
|
|
472
|
+
// call outputError, otherwise every command that uses
|
|
473
|
+
// outputError() + exit(1) prints the original error AND a stray
|
|
474
|
+
// "Error [WALLET_ERROR]: EEXIT: 1" trailer.
|
|
475
|
+
if (err instanceof OclifErrors.ExitError) {
|
|
476
|
+
throw err;
|
|
477
|
+
}
|
|
478
|
+
if (err instanceof WalletError) {
|
|
479
|
+
this.outputError(err.category, err.message);
|
|
480
|
+
if (this.verbose) {
|
|
481
|
+
const origStack = err.originalStack;
|
|
482
|
+
if (origStack)
|
|
483
|
+
this.log_verbose(`Original stack:\n${origStack}`);
|
|
484
|
+
if (err.stack)
|
|
485
|
+
this.log_verbose(`Stack:\n${err.stack}`);
|
|
486
|
+
}
|
|
487
|
+
this.exit(1);
|
|
488
|
+
}
|
|
489
|
+
this.outputError('WALLET_ERROR', err.message);
|
|
490
|
+
if (this.verbose && err.stack) {
|
|
491
|
+
this.log_verbose(`Stack:\n${err.stack}`);
|
|
492
|
+
}
|
|
493
|
+
this.exit(err.exitCode ?? 1);
|
|
494
|
+
return undefined;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
//# sourceMappingURL=base-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-command.js","sourceRoot":"","sources":["../src/base-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,WAAW,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EACL,WAAW,EAEX,aAAa,EACb,gBAAgB,EAEhB,mBAAmB,EACnB,YAAY,EACZ,qBAAqB,EACrB,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GAEjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAgCrE;2CAC2C;AAC3C,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACtD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK;QAAE,OAAO,IAAI,CAAC;IACrE,OAAO,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC;AACtB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;QACjB,WAAW,EAAE,2PAA2P;KACzQ,CAAC;CACM,CAAC;AAEX,+DAA+D;AAC/D,OAAO,eAAe,CAAC;AAEvB,0DAA0D;AAC1D,MAAM,kBAAkB,GAAG;IACzB,oBAAoB;IACpB,6BAA6B;IAC7B,2BAA2B;IAC3B,6BAA6B;IAC7B,kCAAkC;CACnC,CAAC;AAEF,SAAS,kBAAkB,CAAC,OAAe;IACzC,IAAI,SAAS,GAAG,OAAO,CAAC;IACxB,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;QACzC,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,OAAgB,WAAY,SAAQ,OAAO;IAC/C,MAAM,CAAC,SAAS,GAAG;QACjB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;YACnB,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAU;YAClC,OAAO,EAAE,MAAM;YACf,WAAW,EAAE,eAAe;SAC7B,CAAC;QACF,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC;YACpB,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,QAAQ;YACjB,WAAW,EAAE,gBAAgB;SAC9B,CAAC;QACF,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;YACnB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,sCAAsC;SACpD,CAAC;QACF,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;YACrB,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,KAAK;YACd,WAAW,EAAE,wBAAwB;SACtC,CAAC;QACF,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;YACrB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,8BAA8B;SAC5C,CAAC;QACF,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC;YAC3B,WAAW,EAAE,2BAA2B;SACzC,CAAC;QACF,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;YACnB,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;YAC3B,WAAW,EAAE,uBAAuB;YACpC,GAAG,EAAE,aAAa;SACnB,CAAC;QACF,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC;YACpB,WAAW,EAAE,8BAA8B;YAC3C,GAAG,EAAE,kBAAkB;SACxB,CAAC;QACF,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC;YACvB,WAAW,EAAE,6BAA6B;YAC1C,GAAG,EAAE,eAAe;SACrB,CAAC;KACH,CAAC;IAEQ,YAAY,GAAiB,MAAM,CAAC;IACpC,OAAO,GAAG,KAAK,CAAC;IAElB,QAAQ,CAA4B;IACpC,cAAc,CAAiB;IAEvC,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,6DAA6D;QAC7D,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAClC,CAAC;IAED,IAAc,OAAO;QACnB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,CAAC,QAAQ,GAAG,IAAI,wBAAwB,EAAE,CAAC;QACjD,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,IAAc,aAAa;QACzB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,IAAI,CAAC,cAAc,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED;;;;;;;;;OASG;IACO,KAAK,CAAC,gBAAgB,CAC9B,SAAiB,EACjB,SAKC;QAED,mDAAmD;QACnD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI;gBACJ,sEAAsE;gBACtE,oEAAoE;gBACpE,oEAAoE;gBACpE,oEAAoE;gBACpE,oEAAoE;gBACpE,oEAAoE;gBACpE,oEAAoE;gBACpE,sEAAsE;gBACtE,IAAI,CACL,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACf,CAAC;QAED,MAAM,IAAI,GAAG,gBAAgB,CAAC,SAAS,CAAC,IAAI;YAC1C,EAAE,EAAE,SAAS;YACb,OAAO,EAAE,qBAAqB;YAC9B,UAAU,EAAE,uBAAuB;YACnC,MAAM,EAAE,YAAY,EAAE;SACvB,CAAC;QAEF,yBAAyB;QACzB,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,CACzE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAClC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,CACnE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAClC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,IAAI,CAC5E,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAClC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,CACnE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAClC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAEpB,MAAM,UAAU,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,cAAc,GAAG,SAAS,EAAE,WAAW;eACxC,OAAO,CAAC,GAAG,CAAC,qBAAqB;eACjC,cAAc;eACd,CAAC,UAAU,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC;QAC/E,MAAM,UAAU,GAAG,SAAS,EAAE,MAAM;eAC/B,OAAO,CAAC,GAAG,CAAC,WAAW;eACvB,eAAe;eACf,UAAU,CAAC,IAAI,CAAC;QACrB,IAAI,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;YACrD,MAAM,IAAI,WAAW,CAAC,eAAe,EAAE,wBAAwB,UAAU,4BAA4B,CAAC,CAAC;QACzG,CAAC;QAED,MAAM,MAAM,GAAkB;YAC5B,EAAE,EAAE,SAAS;YACb,UAAU,EAAE,SAAS,EAAE,OAAO;mBACzB,OAAO,CAAC,GAAG,CAAC,gBAAgB;mBAC5B,gBAAgB;mBAChB,IAAI,CAAC,UAAU;YACpB,OAAO,EAAE,SAAS,EAAE,OAAO;mBACtB,OAAO,CAAC,GAAG,CAAC,aAAa;mBACzB,aAAa;mBACb,IAAI,CAAC,OAAO;YACjB,MAAM,EAAE,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,EAAC,IAAI,EAAE,MAAM,EAAC,CAAC,CAAC,CAAC,YAAY,CAAC,cAAc,CAAC;SAC9E,CAAC;QAEF,yEAAyE;QACzE,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAE9B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACO,mBAAmB,CAAC,KAA8B;QAC1D,OAAO;YACL,WAAW,EAAE,KAAK,CAAC,cAAc,CAAuB;YACxD,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAuB;YAC7C,OAAO,EAAE,KAAK,CAAC,SAAS,CAAuB;YAC/C,OAAO,EAAE,KAAK,CAAC,UAAU,CAAuB;SACjD,CAAC;IACJ,CAAC;IAED;;;;;;;;;OASG;IACO,KAAK,CAAC,gBAAgB,CAC9B,SAAiB,EACjB,UAAkB,EAClB,OAAyB,EAAE;QAE3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QACnE,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;IAED;;;;;;;;;;OAUG;IACO,KAAK,CAAC,WAAW,CACzB,SAAiB,EACjB,UAAkB,EAClB,OAAyB,EAAE;QAE3B,MAAM,KAAK,GAAG,CAAC,KAAgC,EAAE,GAAW,EAAE,EAAE,CAC9D,IAAI,CAAC,WAAW,CAAC,YAAY,KAAK,KAAK,GAAG,EAAE,CAAC,CAAC;QAEhD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO;oBACL,MAAM,EAAE,IAAI;oBACZ,OAAO,EAAE,aAAa;oBACtB,MAAM,EAAE,IAAI,CAAC,IAAI;oBACjB,UAAU,EAAE,EAAE;iBACf,CAAC;YACJ,CAAC;YACD,MAAM,MAAM,GAAG,SAAS,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YACrD,oEAAoE;YACpE,mEAAmE;YACnE,2CAA2C;YAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;YAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,EAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAC,CAAC;YACxE,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE;gBAC9D,KAAK;gBACL,KAAK;aACN,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,oDAAoD;gBACpD,6DAA6D;gBAC7D,4DAA4D;gBAC5D,0DAA0D;gBAC1D,2DAA2D;gBAC3D,uDAAuD;gBACvD,iBAAiB;gBACjB,OAAO,EAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAC,CAAC;YACxE,CAAC;YACD,OAAO,EAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAC,CAAC;QACzD,CAAC;QAED,8DAA8D;QAC9D,MAAM,UAAU,GAAG,gBAAgB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAC3D,MAAM,MAAM,GAAG,UAAU,UAAU,EAAE,CAAC;QAEtC,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAC,CAAC;QAC/D,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,EAAC,KAAK,EAAC,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,gEAAgE;YAChE,mEAAmE;YACnE,iEAAiE;YACjE,8DAA8D;YAC9D,2CAA2C;YAC3C,OAAO,EAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,UAAU,EAAC,CAAC;QACrE,CAAC;QACD,OAAO,EAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAC,CAAC;IACrD,CAAC;IAED;;;;;;OAMG;IACO,KAAK,CAAC,mBAAmB,CACjC,SAAiB,EACjB,UAAkB,EAClB,OAAyB,EAAE;QAE3B,MAAM,EAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAC,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QAClG,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAE1B,QAAQ,OAAO,EAAE,CAAC;YAChB,KAAK,QAAQ;gBACX,IAAI,CAAC,WAAW,CACd,cAAc,EACd,6BAA6B,UAAU,QAAQ,SAAS,8CAA8C,SAAS,uDAAuD,UAAU,GAAG,CACpL,CAAC;gBACF,MAAM;YACR,KAAK,cAAc;gBACjB,IAAI,CAAC,WAAW,CACd,cAAc,EACd,sBAAsB,UAAU,uRAAuR,CACxT,CAAC;gBACF,MAAM;YACR,KAAK,kBAAkB;gBACrB,IAAI,CAAC,WAAW,CACd,cAAc,EACd,aAAa,MAAM,8HAA8H,CAClJ,CAAC;gBACF,MAAM;YACR,KAAK,aAAa;gBAChB,IAAI,CAAC,WAAW,CACd,cAAc,EACd,+BAA+B,MAAM,0QAA0Q,CAChT,CAAC;gBACF,MAAM;YACR,KAAK,aAAa;gBAChB,IAAI,CAAC,WAAW,CACd,eAAe,EACf,6IAA6I,CAC9I,CAAC;gBACF,MAAM;YACR;gBACE,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,+CAA+C,MAAM,EAAE,CAAC,CAAC;QAC9F,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACO,iBAAiB,CAAC,GAAY;QACtC,MAAM,IAAI,GAAI,GAAuB,CAAC,IAAI,CAAC;QAC3C,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,cAAc;gBACjB,OAAO,EAAC,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,kBAAkB,GAAG,EAAE,EAAC,CAAC;YACtE,KAAK,gBAAgB,CAAC;YACtB,KAAK,iBAAiB,CAAC;YACvB,KAAK,kBAAkB;gBACrB,OAAO,EAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,GAAG,EAAC,CAAC;YACnD,KAAK,SAAS;gBACZ,OAAO,EAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAC,CAAC;YAC7C,KAAK,QAAQ;gBACX,OAAO,EAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,6BAA6B,GAAG,EAAE,EAAC,CAAC;YAClF,KAAK,gBAAgB,CAAC;YACtB;gBACE,OAAO,EAAC,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,EAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAES,KAAK,CAAC,iBAAiB,CAAC,KAA0B;QAC1D,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,CAAC,WAAW,CAAC,iBAAiB,KAAK,CAAC,MAAM,uBAAuB,CAAC,CAAC;YACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;YACxD,OAAO,KAAK,CAAC,MAAM,CAAC;QACtB,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC;QACpD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,WAAW,CAAC,cAAc,EAAE,6CAA6C,CAAC,CAAC;QACvF,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,MAAM,IAAI,CAAC,CAAC;QAClD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACO,KAAK,CAAC,kBAAkB,CAChC,OAA+B,EAC/B,KAAwB;QAExB,IAAI,KAAK,CAAC,GAAG;YAAE,OAAO;QAEtB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,WAAW,CAAC,eAAe,EAAE,iDAAiD,CAAC,CAAC;QAC5F,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QACjD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,+BAA+B,CAAC,CAAC;QACtF,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,KAAK,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAC;YACnE,MAAM,IAAI,WAAW,CAAC,cAAc,EAAE,+BAA+B,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAES,WAAW,CAAC,OAAe;QACnC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACpC,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;YAC9C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,SAAS,IAAI,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAES,KAAK,CAAC,iBAAiB,CAAC,MAAc,EAAE,YAAoB;QACpE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACzB,OAAO,YAAY,CAAC;QACtB,CAAC;QACD,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;QAC1D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7E,EAAE,CAAC,QAAQ,CAAC,GAAG,MAAM,KAAK,YAAY,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE;gBACtD,EAAE,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,YAAY,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAES,KAAK,CAAC,eAAe,CAAC,KAAyB,EAAE,MAAc;QACvE,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QACxB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,WAAW,CAAC,eAAe,EAAE,2BAA2B,MAAM,EAAE,CAAC,CAAC;QAC9E,CAAC;QACD,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;QAC1D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7E,EAAE,CAAC,QAAQ,CAAC,GAAG,MAAM,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE;gBACpC,EAAE,CAAC,KAAK,EAAE,CAAC;gBACX,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;oBACpB,MAAM,CAAC,IAAI,WAAW,CAAC,eAAe,EAAE,GAAG,MAAM,kBAAkB,CAAC,CAAC,CAAC;gBACxE,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACO,KAAK,CAAC,kBAAkB;QAChC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,IAAI,CACjE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAClC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAEpB,IAAI,OAAO,KAAK,MAAM;YAAE,OAAO;QAE/B,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,0BAA0B,CAAC;YAChD,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,YAAY,CAGvF,CAAC;YACF,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,IAAI,CACjE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CACvC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAEzB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC;gBAC7B,WAAW,EAAE,SAAS;gBACtB,OAAO,EAAE,IAAI,CAAC,OAAO;aACtB,CAAC,CAAC;YAEH,qEAAqE;YACrE,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,4BAA4B,EAAE,CAAC;YACpE,IAAI,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YAExD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;YAC5D,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;gBAC/D,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;oBAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,uBAAuB,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC;gBACrG,CAAC;gBACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;YAChG,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,oDAAoD;QACtD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,4BAA4B;QACxC,MAAM,QAAQ,GAA2B,EAAE,CAAC;QAC5C,IAAI,CAAC;YACH,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;YACtD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;YAE5D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,iBAAiB,CAAC,CAAC;YACrE,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;gBAAE,OAAO,QAAQ,CAAC;YAExC,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;YAChC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CACxB,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAC1D,CAAC;oBACF,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;wBACpB,QAAQ,CAAC,mBAAmB,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;oBACvD,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC;QACjC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAES,aAAa,CAAC,IAAa;QACnC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAClD,CAAC;IAES,WAAW,CAAC,QAA6B,EAAE,OAAe,EAAE,IAAa;QACjF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IACvF,CAAC;IAES,KAAK,CAAC,KAAK,CAAC,GAAkC;QACtD,iEAAiE;QACjE,+DAA+D;QAC/D,gEAAgE;QAChE,sDAAsD;QACtD,gEAAgE;QAChE,4CAA4C;QAC5C,IAAI,GAAG,YAAY,WAAW,CAAC,SAAS,EAAE,CAAC;YACzC,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,IAAI,GAAG,YAAY,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,WAAW,CAAE,GAAmB,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YAC7D,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,MAAM,SAAS,GAAI,GAAW,CAAC,aAAa,CAAC;gBAC7C,IAAI,SAAS;oBAAE,IAAI,CAAC,WAAW,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAC;gBACjE,IAAI,GAAG,CAAC,KAAK;oBAAE,IAAI,CAAC,WAAW,CAAC,WAAW,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;YAC1D,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACf,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,IAAI,CAAC,OAAO,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC,WAAW,CAAC,WAAW,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;QAC7B,OAAO,SAAS,CAAC;IACnB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BaseCommand } from '../base-command.js';
|
|
2
|
+
export default class Airdrop extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static flags: {
|
|
5
|
+
amount: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
|
+
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
network: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
wallet: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
timeout: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
'proof-server': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
prover: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
indexer: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
'node-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
};
|
|
16
|
+
run(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=airdrop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"airdrop.d.ts","sourceRoot":"","sources":["../../src/commands/airdrop.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,WAAW;IAC9C,OAAgB,WAAW,SAAiD;IAE5E,OAAgB,KAAK;;;;;;;;;;;MAGnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAkC3B"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import { BaseCommand } from '../base-command.js';
|
|
3
|
+
import { WalletError } from '@shieldedtech/moth-wallet';
|
|
4
|
+
export default class Airdrop extends BaseCommand {
|
|
5
|
+
static description = 'Request test tokens on development networks';
|
|
6
|
+
static flags = {
|
|
7
|
+
...BaseCommand.baseFlags,
|
|
8
|
+
amount: Flags.string({ description: 'Amount to request', default: '1000000' }),
|
|
9
|
+
};
|
|
10
|
+
async run() {
|
|
11
|
+
const { flags } = await this.parse(Airdrop);
|
|
12
|
+
this.outputFormat = flags.output ?? 'text';
|
|
13
|
+
this.verbose = flags.verbose;
|
|
14
|
+
if (flags.network !== 'devnet') {
|
|
15
|
+
throw new WalletError('INVALID_INPUT', `Airdrop is only available on devnet. Current network: ${flags.network}`);
|
|
16
|
+
}
|
|
17
|
+
const walletName = await this.resolveWalletName(flags);
|
|
18
|
+
const wallets = await this.walletManager.list();
|
|
19
|
+
const wallet = wallets.find((w) => w.name === walletName);
|
|
20
|
+
if (!wallet) {
|
|
21
|
+
this.outputError('WALLET_ERROR', `Wallet "${walletName}" not found`);
|
|
22
|
+
this.exit(1);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
this.log_verbose(`Requesting airdrop for ${wallet.address}`);
|
|
26
|
+
// TODO: Implement actual airdrop via devnet faucet endpoint
|
|
27
|
+
// The devnet typically has a faucet or genesis account that can fund wallets
|
|
28
|
+
this.outputSuccess({
|
|
29
|
+
address: wallet.address,
|
|
30
|
+
amount: flags.amount,
|
|
31
|
+
token: 'NIGHT',
|
|
32
|
+
status: 'requested',
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=airdrop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"airdrop.js","sourceRoot":"","sources":["../../src/commands/airdrop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,WAAW;IAC9C,MAAM,CAAU,WAAW,GAAG,6CAA6C,CAAC;IAE5E,MAAM,CAAU,KAAK,GAAG;QACtB,GAAG,WAAW,CAAC,SAAS;QACxB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;KAC/E,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,YAAY,GAAI,KAAK,CAAC,MAA0B,IAAI,MAAM,CAAC;QAChE,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAE7B,IAAI,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,IAAI,WAAW,CACnB,eAAe,EACf,yDAAyD,KAAK,CAAC,OAAO,EAAE,CACzE,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QAChD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAmB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAE5E,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,WAAW,UAAU,aAAa,CAAC,CAAC;YACrE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACb,OAAO;QACT,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,0BAA0B,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAE7D,4DAA4D;QAC5D,6EAA6E;QAE7E,IAAI,CAAC,aAAa,CAAC;YACjB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,KAAK,EAAE,OAAO;YACd,MAAM,EAAE,WAAW;SACpB,CAAC,CAAC;IACL,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BaseCommand } from '../base-command.js';
|
|
2
|
+
export default class Balance extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static flags: {
|
|
5
|
+
'wait-timeout-ms': import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
|
+
output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
network: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
wallet: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
timeout: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
'proof-server': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
prover: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
indexer: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
'node-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
};
|
|
16
|
+
run(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=balance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"balance.d.ts","sourceRoot":"","sources":["../../src/commands/balance.ts"],"names":[],"mappings":"AASA,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AA+B/C,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,WAAW;IAC9C,OAAgB,WAAW,SAC8S;IAEzU,OAAgB,KAAK;;;;;;;;;;;MAOnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAiF3B"}
|