hodl-wallet 2.0.2 → 2.0.3

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.
Files changed (62) hide show
  1. package/README.md +42 -3
  2. package/dist/agent-cli.d.ts +11 -0
  3. package/dist/agent-cli.js +310 -0
  4. package/dist/agent-cli.js.map +1 -0
  5. package/dist/agent-errors.d.ts +7 -0
  6. package/dist/agent-errors.js +13 -0
  7. package/dist/agent-errors.js.map +1 -0
  8. package/dist/amounts.d.ts +3 -0
  9. package/dist/amounts.js +51 -0
  10. package/dist/amounts.js.map +1 -0
  11. package/dist/index.d.ts +6 -0
  12. package/dist/index.js +95 -37
  13. package/dist/index.js.map +1 -1
  14. package/dist/network/arb.d.ts +3 -0
  15. package/dist/network/arb.js +4 -1
  16. package/dist/network/arb.js.map +1 -1
  17. package/dist/network/avax.d.ts +3 -0
  18. package/dist/network/avax.js +3 -0
  19. package/dist/network/avax.js.map +1 -1
  20. package/dist/network/bsc.d.ts +3 -0
  21. package/dist/network/bsc.js +3 -0
  22. package/dist/network/bsc.js.map +1 -1
  23. package/dist/network/btc.d.ts +3 -0
  24. package/dist/network/btc.js +3 -0
  25. package/dist/network/btc.js.map +1 -1
  26. package/dist/network/eth.d.ts +3 -0
  27. package/dist/network/eth.js +3 -0
  28. package/dist/network/eth.js.map +1 -1
  29. package/dist/network/ftm.d.ts +3 -0
  30. package/dist/network/ftm.js +3 -0
  31. package/dist/network/ftm.js.map +1 -1
  32. package/dist/network/hyperliquid.d.ts +2 -0
  33. package/dist/network/hyperliquid.js +2 -0
  34. package/dist/network/hyperliquid.js.map +1 -1
  35. package/dist/network/lib/BaseNetwork.d.ts +8 -4
  36. package/dist/network/lib/BaseNetwork.js +1 -1
  37. package/dist/network/lib/BaseNetwork.js.map +1 -1
  38. package/dist/network/lib/BitcoinNetwork.d.ts +9 -4
  39. package/dist/network/lib/BitcoinNetwork.js +92 -8
  40. package/dist/network/lib/BitcoinNetwork.js.map +1 -1
  41. package/dist/network/lib/Web3Network.d.ts +6 -2
  42. package/dist/network/lib/Web3Network.js +156 -58
  43. package/dist/network/lib/Web3Network.js.map +1 -1
  44. package/dist/network/op.d.ts +3 -0
  45. package/dist/network/op.js +4 -1
  46. package/dist/network/op.js.map +1 -1
  47. package/dist/network/pol.d.ts +3 -0
  48. package/dist/network/pol.js +3 -0
  49. package/dist/network/pol.js.map +1 -1
  50. package/dist/network/types.d.ts +33 -3
  51. package/dist/network-registry.d.ts +9 -0
  52. package/dist/network-registry.js +50 -0
  53. package/dist/network-registry.js.map +1 -0
  54. package/dist/persist.js +1 -1
  55. package/dist/persist.js.map +1 -1
  56. package/dist/profile-lock.d.ts +14 -0
  57. package/dist/profile-lock.js +84 -0
  58. package/dist/profile-lock.js.map +1 -0
  59. package/dist/wallet-service.d.ts +73 -0
  60. package/dist/wallet-service.js +633 -0
  61. package/dist/wallet-service.js.map +1 -0
  62. package/package.json +8 -8
package/README.md CHANGED
@@ -2,8 +2,7 @@
2
2
 
3
3
  #### 📦 Install and try!
4
4
  ```bash
5
- npm install -g hodl-wallet
6
- hodl
5
+ npm i -g hodl-wallet && hodl
7
6
  ```
8
7
 
9
8
  ![HODL Wallet](https://raw.githubusercontent.com/clasen/HODL/refs/heads/master/example.jpg)
@@ -13,7 +12,8 @@ hodl
13
12
  Let's face it, Trust Wallet's sluggishness and annoying ads are so last season. HODL Wallet is here to agilize your crypto experience.
14
13
 
15
14
  - 🏎️ Lightning-fast operations
16
- - 🧊 Cool, minimalist CLI interface
15
+ - 🖥️ Interactive TUI and direct CLI commands
16
+ - 🤖 Agent-ready, non-interactive JSON interface
17
17
  - 🚫 Zero ads, zero BS
18
18
  - 🔒 Create wallets offline (because paranoia is just good sense in crypto)
19
19
  - 🔍 Fully transparent, open-source code
@@ -67,6 +67,45 @@ These files are encrypted using your wallet password, providing an additional la
67
67
 
68
68
  The main advantage of exporting a HODL file is that to access the private key, you need BOTH the file AND the password. This two-factor approach significantly enhances security. However, keep in mind that this solution is only compatible with HODL Wallet.
69
69
 
70
+ ## Agent-friendly JSON CLI
71
+
72
+ Running `hodl` without arguments keeps the interactive wallet. Subcommands are
73
+ non-interactive: they emit one JSON object, use stable network IDs, and never
74
+ accept passwords, mnemonics, or private keys as command-line arguments.
75
+ Protected commands receive the password as JSON through stdin:
76
+
77
+ ```bash
78
+ hodl networks
79
+ hodl wallet list
80
+
81
+ echo '{"password":"vault-password"}' |
82
+ hodl wallet create --wallet treasury --words 24
83
+
84
+ echo '{"password":"vault-password"}' |
85
+ hodl balance --wallet treasury --network eth
86
+
87
+ echo '{"password":"vault-password"}' |
88
+ hodl send --wallet treasury --network eth \
89
+ --to "$RECIPIENT_ADDRESS" \
90
+ --asset ETH --amount 0.01 --dry-run
91
+
92
+ echo '{"password":"vault-password"}' |
93
+ hodl send --wallet treasury --network eth \
94
+ --to "$RECIPIENT_ADDRESS" \
95
+ --asset ETH --amount 0.01 --yes --request-id payment-001
96
+ ```
97
+
98
+ Successful commands write an envelope such as
99
+ `{"version":1,"ok":true,"command":"balance","data":{...}}` to stdout.
100
+ Failures write the equivalent `ok:false` envelope to stderr and return a
101
+ non-zero exit code. Amounts, balances, fees, and base units are JSON strings so
102
+ large values and token decimals remain exact.
103
+
104
+ Named profiles live under `~/.HODL/profiles/`. The special profile `default`
105
+ continues to use the existing `~/.HODL/persist.json` vault. A real transfer
106
+ requires both `--yes` and a unique `--request-id`; retries reuse the previously
107
+ prepared signed transaction instead of creating a second payment.
108
+
70
109
  ## 🔒 Security
71
110
 
72
111
  ### 🔍 Security Audit
@@ -0,0 +1,11 @@
1
+ import { WalletService } from './wallet-service.js';
2
+ export type AgentCliIO = {
3
+ readStdin(): Promise<string>;
4
+ writeStdout(value: string): void;
5
+ writeStderr(value: string): void;
6
+ };
7
+ export type AgentCliOptions = {
8
+ service?: WalletService;
9
+ io?: AgentCliIO;
10
+ };
11
+ export declare function runAgentCli(argv: string[], options?: AgentCliOptions): Promise<number>;
@@ -0,0 +1,310 @@
1
+ import { parseArgs } from 'node:util';
2
+ import { AgentError } from './agent-errors.js';
3
+ import { WalletService } from './wallet-service.js';
4
+ const defaultIO = {
5
+ async readStdin() {
6
+ if (process.stdin.isTTY) {
7
+ throw new AgentError('STDIN_REQUIRED', 'A JSON object is required on stdin.', 2);
8
+ }
9
+ const chunks = [];
10
+ for await (const chunk of process.stdin) {
11
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
12
+ }
13
+ const input = Buffer.concat(chunks);
14
+ try {
15
+ return input.toString('utf8');
16
+ }
17
+ finally {
18
+ input.fill(0);
19
+ chunks.forEach(chunk => chunk.fill(0));
20
+ }
21
+ },
22
+ writeStdout(value) {
23
+ process.stdout.write(value);
24
+ },
25
+ writeStderr(value) {
26
+ process.stderr.write(value);
27
+ }
28
+ };
29
+ export async function runAgentCli(argv, options = {}) {
30
+ const service = options.service || new WalletService();
31
+ const io = options.io || defaultIO;
32
+ let command = argv.slice(0, 2).join('.');
33
+ try {
34
+ const result = await execute(argv, service, io, value => {
35
+ command = value;
36
+ });
37
+ io.writeStdout(`${JSON.stringify({
38
+ version: 1,
39
+ ok: true,
40
+ command,
41
+ data: result
42
+ })}\n`);
43
+ return 0;
44
+ }
45
+ catch (error) {
46
+ const agentError = error instanceof AgentError
47
+ ? error
48
+ : new AgentError('INTERNAL_ERROR', 'Unexpected internal error.', 5);
49
+ io.writeStderr(`${JSON.stringify({
50
+ version: 1,
51
+ ok: false,
52
+ error: {
53
+ code: agentError.code,
54
+ message: agentError.message,
55
+ ...(agentError.details ? { details: agentError.details } : {})
56
+ }
57
+ })}\n`);
58
+ return agentError.exitCode;
59
+ }
60
+ }
61
+ async function execute(argv, service, io, setCommand) {
62
+ if (argv[0] === 'networks') {
63
+ setCommand('networks');
64
+ requireNoArguments(argv.slice(1));
65
+ return { networks: service.listNetworks() };
66
+ }
67
+ if (argv[0] === 'wallet') {
68
+ return executeWallet(argv.slice(1), service, io, setCommand);
69
+ }
70
+ if (argv[0] === 'balance') {
71
+ setCommand('balance');
72
+ const values = parseOptions(argv.slice(1), {
73
+ network: { type: 'string' },
74
+ wallet: { type: 'string' },
75
+ address: { type: 'string' },
76
+ asset: { type: 'string' }
77
+ });
78
+ const network = requiredString(values, 'network');
79
+ const wallet = optionalString(values, 'wallet');
80
+ const address = optionalString(values, 'address');
81
+ if ((wallet ? 1 : 0) + (address ? 1 : 0) !== 1) {
82
+ throw new AgentError('INVALID_ARGUMENT', 'Balance requires exactly one of --wallet or --address.', 2);
83
+ }
84
+ let input;
85
+ try {
86
+ input = wallet ? await readSecretInput(io, ['password'], ['password']) : undefined;
87
+ return await service.getBalances({
88
+ network,
89
+ wallet,
90
+ password: input?.password,
91
+ address,
92
+ asset: optionalString(values, 'asset')
93
+ });
94
+ }
95
+ finally {
96
+ clearSecrets(input);
97
+ }
98
+ }
99
+ if (argv[0] === 'send') {
100
+ setCommand('send');
101
+ const values = parseOptions(argv.slice(1), {
102
+ wallet: { type: 'string' },
103
+ network: { type: 'string' },
104
+ to: { type: 'string' },
105
+ asset: { type: 'string' },
106
+ amount: { type: 'string' },
107
+ 'dry-run': { type: 'boolean' },
108
+ yes: { type: 'boolean' },
109
+ 'request-id': { type: 'string' }
110
+ });
111
+ const dryRun = values['dry-run'] === true;
112
+ const yes = values.yes === true;
113
+ const requestId = optionalString(values, 'request-id');
114
+ if (dryRun === yes) {
115
+ throw new AgentError('INVALID_ARGUMENT', 'Send requires either --dry-run or --yes, but not both.', 2);
116
+ }
117
+ if ((dryRun && requestId) || (yes && !requestId)) {
118
+ throw new AgentError('INVALID_ARGUMENT', '--request-id is required with --yes and forbidden with --dry-run.', 2);
119
+ }
120
+ let input;
121
+ try {
122
+ input = await readSecretInput(io, ['password'], ['password']);
123
+ return await service.send({
124
+ wallet: requiredString(values, 'wallet'),
125
+ password: input.password,
126
+ network: requiredString(values, 'network'),
127
+ to: requiredString(values, 'to'),
128
+ asset: requiredString(values, 'asset'),
129
+ amount: requiredString(values, 'amount'),
130
+ dryRun,
131
+ requestId
132
+ });
133
+ }
134
+ finally {
135
+ clearSecrets(input);
136
+ }
137
+ }
138
+ throw new AgentError('INVALID_ARGUMENT', `Unknown command: ${argv[0] || ''}.`, 2);
139
+ }
140
+ async function executeWallet(argv, service, io, setCommand) {
141
+ const action = argv[0];
142
+ setCommand(`wallet.${action || ''}`);
143
+ if (action === 'list') {
144
+ requireNoArguments(argv.slice(1));
145
+ return { wallets: service.listProfiles() };
146
+ }
147
+ if (action === 'create') {
148
+ const values = parseOptions(argv.slice(1), {
149
+ wallet: { type: 'string' },
150
+ words: { type: 'string' },
151
+ 'reveal-secrets': { type: 'boolean' }
152
+ });
153
+ const wordsValue = requiredString(values, 'words');
154
+ if (wordsValue !== '12' && wordsValue !== '24') {
155
+ throw new AgentError('INVALID_ARGUMENT', '--words must be 12 or 24.', 2);
156
+ }
157
+ let input;
158
+ try {
159
+ input = await readSecretInput(io, ['password'], ['password']);
160
+ return await service.createProfile(requiredString(values, 'wallet'), input.password, Number(wordsValue), values['reveal-secrets'] === true);
161
+ }
162
+ finally {
163
+ clearSecrets(input);
164
+ }
165
+ }
166
+ if (action === 'import') {
167
+ const values = parseOptions(argv.slice(1), {
168
+ wallet: { type: 'string' },
169
+ type: { type: 'string' },
170
+ network: { type: 'string' }
171
+ });
172
+ const wallet = requiredString(values, 'wallet');
173
+ const type = requiredString(values, 'type');
174
+ const network = optionalString(values, 'network');
175
+ if (type === 'mnemonic') {
176
+ if (network) {
177
+ throw new AgentError('INVALID_ARGUMENT', '--network is forbidden for mnemonic import.', 2);
178
+ }
179
+ let input;
180
+ try {
181
+ input = await readSecretInput(io, ['password', 'mnemonic'], ['password', 'mnemonic']);
182
+ return await service.importMnemonic(wallet, input.password, input.mnemonic);
183
+ }
184
+ finally {
185
+ clearSecrets(input);
186
+ }
187
+ }
188
+ if (type === 'private-key') {
189
+ if (!network) {
190
+ throw new AgentError('INVALID_ARGUMENT', '--network is required for private-key import.', 2);
191
+ }
192
+ let input;
193
+ try {
194
+ input = await readSecretInput(io, ['password', 'privateKey'], ['password', 'privateKey']);
195
+ return await service.importPrivateKey(wallet, input.password, network, input.privateKey);
196
+ }
197
+ finally {
198
+ clearSecrets(input);
199
+ }
200
+ }
201
+ throw new AgentError('INVALID_ARGUMENT', '--type must be mnemonic or private-key.', 2);
202
+ }
203
+ if (action === 'address') {
204
+ const values = parseOptions(argv.slice(1), {
205
+ wallet: { type: 'string' },
206
+ network: { type: 'string' }
207
+ });
208
+ let input;
209
+ try {
210
+ input = await readSecretInput(io, ['password'], ['password']);
211
+ return await service.getAddress(requiredString(values, 'wallet'), input.password, requiredString(values, 'network'));
212
+ }
213
+ finally {
214
+ clearSecrets(input);
215
+ }
216
+ }
217
+ throw new AgentError('INVALID_ARGUMENT', `Unknown wallet command: ${action || ''}.`, 2);
218
+ }
219
+ function parseOptions(args, options) {
220
+ ensureNoDuplicateOptions(args);
221
+ try {
222
+ const parsed = parseArgs({
223
+ args,
224
+ options,
225
+ strict: true,
226
+ allowPositionals: false
227
+ });
228
+ return parsed.values;
229
+ }
230
+ catch (error) {
231
+ throw new AgentError('INVALID_ARGUMENT', error.message, 2);
232
+ }
233
+ }
234
+ function ensureNoDuplicateOptions(args) {
235
+ const seen = new Set();
236
+ for (const argument of args) {
237
+ if (!argument.startsWith('--')) {
238
+ continue;
239
+ }
240
+ const name = argument.slice(2).split('=', 1)[0];
241
+ if (seen.has(name)) {
242
+ throw new AgentError('INVALID_ARGUMENT', `Option --${name} was provided more than once.`, 2);
243
+ }
244
+ seen.add(name);
245
+ }
246
+ }
247
+ function requireNoArguments(args) {
248
+ if (args.length > 0) {
249
+ throw new AgentError('INVALID_ARGUMENT', 'Command does not accept arguments.', 2);
250
+ }
251
+ }
252
+ function requiredString(values, name) {
253
+ const value = optionalString(values, name);
254
+ if (!value) {
255
+ throw new AgentError('INVALID_ARGUMENT', `--${name} is required.`, 2);
256
+ }
257
+ return value;
258
+ }
259
+ function optionalString(values, name) {
260
+ const value = values[name];
261
+ return typeof value === 'string' && value.length > 0 ? value : undefined;
262
+ }
263
+ async function readSecretInput(io, allowedKeys, requiredKeys) {
264
+ const raw = await io.readStdin();
265
+ if (!raw.trim()) {
266
+ throw new AgentError('STDIN_REQUIRED', 'A JSON object is required on stdin.', 2);
267
+ }
268
+ let value;
269
+ try {
270
+ value = JSON.parse(raw);
271
+ }
272
+ catch {
273
+ throw new AgentError('INVALID_STDIN', 'stdin must contain one valid JSON object.', 2);
274
+ }
275
+ if (!isRecord(value)) {
276
+ throw new AgentError('INVALID_STDIN', 'stdin must contain a JSON object.', 2);
277
+ }
278
+ const unknownKeys = Object.keys(value).filter(key => !allowedKeys.includes(key));
279
+ if (unknownKeys.length > 0) {
280
+ throw new AgentError('INVALID_STDIN', `Unknown stdin fields: ${unknownKeys.join(', ')}.`, 2);
281
+ }
282
+ const result = {};
283
+ for (const key of allowedKeys) {
284
+ const field = value[key];
285
+ if (field !== undefined && (typeof field !== 'string' || field.length === 0)) {
286
+ throw new AgentError('INVALID_STDIN', `${key} must be a non-empty string.`, 2);
287
+ }
288
+ if (typeof field === 'string') {
289
+ result[key] = field;
290
+ }
291
+ }
292
+ for (const key of requiredKeys) {
293
+ if (!result[key]) {
294
+ throw new AgentError('INVALID_STDIN', `${key} is required on stdin.`, 2);
295
+ }
296
+ }
297
+ return result;
298
+ }
299
+ function clearSecrets(input) {
300
+ if (!input) {
301
+ return;
302
+ }
303
+ for (const key of Object.keys(input)) {
304
+ input[key] = '';
305
+ }
306
+ }
307
+ function isRecord(value) {
308
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
309
+ }
310
+ //# sourceMappingURL=agent-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-cli.js","sourceRoot":"","sources":["../agent-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export type AgentErrorCode = 'INVALID_ARGUMENT' | 'INVALID_STDIN' | 'STDIN_REQUIRED' | 'PROFILE_EXISTS' | 'PROFILE_NOT_FOUND' | 'WRONG_PASSWORD' | 'ACCOUNT_NOT_FOUND' | 'PROFILE_LOCKED' | 'IDEMPOTENCY_CONFLICT' | 'NETWORK_ERROR' | 'TRANSFER_FAILED' | 'BROADCAST_UNKNOWN' | 'INTERNAL_ERROR';
2
+ export declare class AgentError extends Error {
3
+ readonly code: AgentErrorCode;
4
+ readonly exitCode: 2 | 3 | 4 | 5;
5
+ readonly details?: Record<string, unknown>;
6
+ constructor(code: AgentErrorCode, message: string, exitCode: 2 | 3 | 4 | 5, details?: Record<string, unknown>);
7
+ }
@@ -0,0 +1,13 @@
1
+ export class AgentError extends Error {
2
+ code;
3
+ exitCode;
4
+ details;
5
+ constructor(code, message, exitCode, details) {
6
+ super(message);
7
+ this.name = 'AgentError';
8
+ this.code = code;
9
+ this.exitCode = exitCode;
10
+ this.details = details;
11
+ }
12
+ }
13
+ //# sourceMappingURL=agent-errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-errors.js","sourceRoot":"","sources":["../agent-errors.ts"],"names":[],"mappings":"AAeA,MAAM,OAAO,UAAW,SAAQ,KAAK;IACxB,IAAI,CAAiB;IACrB,QAAQ,CAAgB;IACxB,OAAO,CAA2B;IAE3C,YACI,IAAoB,EACpB,OAAe,EACf,QAAuB,EACvB,OAAiC;QAEjC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;CACJ"}
@@ -0,0 +1,3 @@
1
+ export declare function parseDecimalToUnits(amount: string, decimals: number): bigint;
2
+ export declare function formatUnits(units: bigint | string, decimals: number): string;
3
+ export declare function normalizeDecimal(amount: string): string;
@@ -0,0 +1,51 @@
1
+ const DECIMAL_PATTERN = /^(0|[1-9]\d*)(?:\.(\d+))?$/;
2
+ export function parseDecimalToUnits(amount, decimals) {
3
+ if (!Number.isInteger(decimals) || decimals < 0) {
4
+ throw new TypeError('Decimals must be a non-negative integer.');
5
+ }
6
+ const match = DECIMAL_PATTERN.exec(amount);
7
+ if (!match) {
8
+ throw new TypeError('Amount must be a plain positive decimal string.');
9
+ }
10
+ const fraction = match[2] || '';
11
+ if (fraction.length > decimals) {
12
+ throw new TypeError(`Amount supports at most ${decimals} decimal places.`);
13
+ }
14
+ const wholeUnits = BigInt(match[1]) * (10n ** BigInt(decimals));
15
+ const fractionalUnits = fraction
16
+ ? BigInt(fraction.padEnd(decimals, '0'))
17
+ : 0n;
18
+ const units = wholeUnits + fractionalUnits;
19
+ if (units <= 0n) {
20
+ throw new TypeError('Amount must be greater than zero.');
21
+ }
22
+ return units;
23
+ }
24
+ export function formatUnits(units, decimals) {
25
+ if (!Number.isInteger(decimals) || decimals < 0) {
26
+ throw new TypeError('Decimals must be a non-negative integer.');
27
+ }
28
+ const value = typeof units === 'bigint' ? units : BigInt(units);
29
+ const negative = value < 0n;
30
+ const absolute = negative ? -value : value;
31
+ if (decimals === 0) {
32
+ return `${negative ? '-' : ''}${absolute}`;
33
+ }
34
+ const padded = absolute.toString().padStart(decimals + 1, '0');
35
+ const whole = padded.slice(0, -decimals);
36
+ const fraction = padded.slice(-decimals).replace(/0+$/, '');
37
+ return `${negative ? '-' : ''}${whole}${fraction ? `.${fraction}` : ''}`;
38
+ }
39
+ export function normalizeDecimal(amount) {
40
+ const match = DECIMAL_PATTERN.exec(amount);
41
+ if (!match) {
42
+ throw new TypeError('Amount must be a plain positive decimal string.');
43
+ }
44
+ const fraction = (match[2] || '').replace(/0+$/, '');
45
+ const normalized = fraction ? `${match[1]}.${fraction}` : match[1];
46
+ if (BigInt(match[1]) === 0n && !/[1-9]/.test(fraction)) {
47
+ throw new TypeError('Amount must be greater than zero.');
48
+ }
49
+ return normalized;
50
+ }
51
+ //# sourceMappingURL=amounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"amounts.js","sourceRoot":"","sources":["../amounts.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,8 @@
1
1
  #!/usr/bin/env node
2
+ export declare function selectCliMode(argv: string[]): 'interactive' | 'agent';
3
+ interface CliDependencies {
4
+ runInteractive?: () => Promise<void>;
5
+ runAgent?: (argv: string[]) => Promise<number>;
6
+ }
7
+ export declare function runCli(argv: string[], dependencies?: CliDependencies): Promise<number>;
2
8
  export {};