@vultisig/cli 0.1.0-alpha.1

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 (60) hide show
  1. package/README.md +391 -0
  2. package/dist/adapters/cli-context.js +25 -0
  3. package/dist/adapters/cli-context.js.map +1 -0
  4. package/dist/adapters/cli-runner.js +47 -0
  5. package/dist/adapters/cli-runner.js.map +1 -0
  6. package/dist/adapters/index.js +6 -0
  7. package/dist/adapters/index.js.map +1 -0
  8. package/dist/commands/balance.js +65 -0
  9. package/dist/commands/balance.js.map +1 -0
  10. package/dist/commands/chains.js +46 -0
  11. package/dist/commands/chains.js.map +1 -0
  12. package/dist/commands/index.js +12 -0
  13. package/dist/commands/index.js.map +1 -0
  14. package/dist/commands/settings.js +151 -0
  15. package/dist/commands/settings.js.map +1 -0
  16. package/dist/commands/swap.js +180 -0
  17. package/dist/commands/swap.js.map +1 -0
  18. package/dist/commands/tokens.js +116 -0
  19. package/dist/commands/tokens.js.map +1 -0
  20. package/dist/commands/transaction.js +99 -0
  21. package/dist/commands/transaction.js.map +1 -0
  22. package/dist/commands/vault-management.js +360 -0
  23. package/dist/commands/vault-management.js.map +1 -0
  24. package/dist/core/command-context.js +81 -0
  25. package/dist/core/command-context.js.map +1 -0
  26. package/dist/core/index.js +7 -0
  27. package/dist/core/index.js.map +1 -0
  28. package/dist/core/password-manager.js +92 -0
  29. package/dist/core/password-manager.js.map +1 -0
  30. package/dist/core/types.js +2 -0
  31. package/dist/core/types.js.map +1 -0
  32. package/dist/index.js +440 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/interactive/completer.js +170 -0
  35. package/dist/interactive/completer.js.map +1 -0
  36. package/dist/interactive/event-buffer.js +186 -0
  37. package/dist/interactive/event-buffer.js.map +1 -0
  38. package/dist/interactive/index.js +9 -0
  39. package/dist/interactive/index.js.map +1 -0
  40. package/dist/interactive/session.js +525 -0
  41. package/dist/interactive/session.js.map +1 -0
  42. package/dist/interactive/shell-commands.js +167 -0
  43. package/dist/interactive/shell-commands.js.map +1 -0
  44. package/dist/interactive/shell-context.js +112 -0
  45. package/dist/interactive/shell-context.js.map +1 -0
  46. package/dist/lib/completion.js +375 -0
  47. package/dist/lib/completion.js.map +1 -0
  48. package/dist/lib/config.js +172 -0
  49. package/dist/lib/config.js.map +1 -0
  50. package/dist/lib/errors.js +163 -0
  51. package/dist/lib/errors.js.map +1 -0
  52. package/dist/lib/index.js +9 -0
  53. package/dist/lib/index.js.map +1 -0
  54. package/dist/lib/output.js +155 -0
  55. package/dist/lib/output.js.map +1 -0
  56. package/dist/lib/version.js +210 -0
  57. package/dist/lib/version.js.map +1 -0
  58. package/dist/ui.js +286 -0
  59. package/dist/ui.js.map +1 -0
  60. package/package.json +76 -0
@@ -0,0 +1,151 @@
1
+ import { Chain, fiatCurrencies, fiatCurrencyNameRecord } from '@vultisig/sdk';
2
+ import chalk from 'chalk';
3
+ import inquirer from 'inquirer';
4
+ import { createSpinner, error, info, isJsonOutput, outputJson, printResult, printTable, success, warn, } from '../lib/output';
5
+ /**
6
+ * Execute currency command - view or set currency preference
7
+ */
8
+ export async function executeCurrency(ctx, newCurrency) {
9
+ const vault = await ctx.ensureActiveVault();
10
+ if (!newCurrency) {
11
+ const currentCurrency = vault.currency;
12
+ const currencyName = fiatCurrencyNameRecord[currentCurrency];
13
+ printResult(chalk.cyan('\nCurrent Currency Preference:'));
14
+ printResult(` ${chalk.green(currentCurrency.toUpperCase())} - ${currencyName}`);
15
+ info(chalk.gray(`\nSupported currencies: ${fiatCurrencies.join(', ')}`));
16
+ info(chalk.gray('Use "npm run wallet currency <code>" to change'));
17
+ return currentCurrency;
18
+ }
19
+ const currency = newCurrency.toLowerCase();
20
+ if (!fiatCurrencies.includes(currency)) {
21
+ error(`x Invalid currency: ${newCurrency}`);
22
+ warn(`Supported currencies: ${fiatCurrencies.join(', ')}`);
23
+ throw new Error('Invalid currency');
24
+ }
25
+ const spinner = createSpinner('Updating currency preference...');
26
+ await vault.setCurrency(currency);
27
+ spinner.succeed('Currency updated');
28
+ const currencyName = fiatCurrencyNameRecord[currency];
29
+ success(`\n+ Currency preference set to ${currency.toUpperCase()} (${currencyName})`);
30
+ return currency;
31
+ }
32
+ /**
33
+ * Execute server status command
34
+ */
35
+ export async function executeServer(ctx) {
36
+ const spinner = createSpinner('Checking server status...');
37
+ try {
38
+ const status = await ctx.sdk.getServerStatus();
39
+ spinner.succeed('Server status retrieved');
40
+ if (isJsonOutput()) {
41
+ outputJson({ server: status });
42
+ return status;
43
+ }
44
+ printResult(chalk.cyan('\nServer Status:\n'));
45
+ printResult(chalk.bold('Fast Vault Server:'));
46
+ printResult(` Online: ${status.fastVault.online ? chalk.green('Yes') : chalk.red('No')}`);
47
+ if (status.fastVault.latency) {
48
+ printResult(` Latency: ${status.fastVault.latency}ms`);
49
+ }
50
+ printResult(chalk.bold('\nMessage Relay:'));
51
+ printResult(` Online: ${status.messageRelay.online ? chalk.green('Yes') : chalk.red('No')}`);
52
+ if (status.messageRelay.latency) {
53
+ printResult(` Latency: ${status.messageRelay.latency}ms`);
54
+ }
55
+ return status;
56
+ }
57
+ catch (err) {
58
+ spinner.fail('Failed to check server status');
59
+ error(`\nx ${err.message}`);
60
+ throw err;
61
+ }
62
+ }
63
+ /**
64
+ * Execute address-book command - manage address book
65
+ */
66
+ export async function executeAddressBook(ctx, options = {}) {
67
+ if (options.add) {
68
+ // Use CLI options if provided, otherwise prompt
69
+ let chain = options.chain;
70
+ let address = options.address;
71
+ let name = options.name;
72
+ const prompts = [];
73
+ if (!chain) {
74
+ prompts.push({
75
+ type: 'list',
76
+ name: 'chain',
77
+ message: 'Select chain:',
78
+ choices: Object.values(Chain),
79
+ });
80
+ }
81
+ if (!address) {
82
+ prompts.push({
83
+ type: 'input',
84
+ name: 'address',
85
+ message: 'Enter address:',
86
+ validate: (input) => input.trim() !== '' || 'Address is required',
87
+ });
88
+ }
89
+ if (!name) {
90
+ prompts.push({
91
+ type: 'input',
92
+ name: 'name',
93
+ message: 'Enter name/label:',
94
+ validate: (input) => input.trim() !== '' || 'Name is required',
95
+ });
96
+ }
97
+ if (prompts.length > 0) {
98
+ const answers = await inquirer.prompt(prompts);
99
+ chain = chain || answers.chain;
100
+ address = address || answers.address?.trim();
101
+ name = name || answers.name?.trim();
102
+ }
103
+ const spinner = createSpinner('Adding address to address book...');
104
+ await ctx.sdk.addAddressBookEntry([
105
+ {
106
+ chain: chain,
107
+ address: address,
108
+ name: name,
109
+ source: 'saved',
110
+ dateAdded: Date.now(),
111
+ },
112
+ ]);
113
+ spinner.succeed('Address added');
114
+ success(`\n+ Added ${name} (${chain}: ${address})`);
115
+ return [];
116
+ }
117
+ if (options.remove) {
118
+ const spinner = createSpinner('Removing address from address book...');
119
+ await ctx.sdk.removeAddressBookEntry([{ address: options.remove, chain: options.chain }]);
120
+ spinner.succeed('Address removed');
121
+ success(`\n+ Removed ${options.remove}`);
122
+ return [];
123
+ }
124
+ // List address book
125
+ const spinner = createSpinner('Loading address book...');
126
+ const addressBook = await ctx.sdk.getAddressBook(options.chain);
127
+ spinner.succeed('Address book loaded');
128
+ // Combine saved and vault addresses
129
+ const allEntries = [...addressBook.saved, ...addressBook.vaults];
130
+ if (isJsonOutput()) {
131
+ outputJson({ addressBook: allEntries, chain: options.chain });
132
+ return allEntries;
133
+ }
134
+ if (allEntries.length === 0) {
135
+ warn(`\nNo addresses in address book${options.chain ? ` for ${options.chain}` : ''}`);
136
+ info(chalk.gray('\nUse --add to add an address to the address book'));
137
+ }
138
+ else {
139
+ printResult(chalk.cyan(`\nAddress Book${options.chain ? ` (${options.chain})` : ''}:\n`));
140
+ const table = allEntries.map(entry => ({
141
+ Name: entry.name,
142
+ Chain: entry.chain,
143
+ Address: entry.address,
144
+ Source: entry.source,
145
+ }));
146
+ printTable(table);
147
+ info(chalk.gray('\nUse --add to add or --remove <address> to remove an address'));
148
+ }
149
+ return allEntries;
150
+ }
151
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/commands/settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,180 @@
1
+ import { createSpinner, info, isJsonOutput, outputJson, warn } from '../lib/output';
2
+ import { confirmSwap, displaySwapChains, displaySwapPreview, displaySwapResult } from '../ui';
3
+ /**
4
+ * Execute swap-chains command - list supported swap chains
5
+ */
6
+ export async function executeSwapChains(ctx) {
7
+ const vault = await ctx.ensureActiveVault();
8
+ const spinner = createSpinner('Loading supported swap chains...');
9
+ const chains = await vault.getSupportedSwapChains();
10
+ spinner.succeed('Swap chains loaded');
11
+ if (isJsonOutput()) {
12
+ outputJson({ swapChains: [...chains] });
13
+ return chains;
14
+ }
15
+ displaySwapChains(chains);
16
+ return chains;
17
+ }
18
+ /**
19
+ * Execute swap-quote command - get quote without executing
20
+ */
21
+ export async function executeSwapQuote(ctx, options) {
22
+ const vault = await ctx.ensureActiveVault();
23
+ if (isNaN(options.amount) || options.amount <= 0) {
24
+ throw new Error('Invalid amount');
25
+ }
26
+ // Check swap support
27
+ const isSupported = await vault.isSwapSupported(options.fromChain, options.toChain);
28
+ if (!isSupported) {
29
+ throw new Error(`Swaps from ${options.fromChain} to ${options.toChain} are not supported`);
30
+ }
31
+ const spinner = createSpinner('Getting swap quote...');
32
+ const quote = await vault.getSwapQuote({
33
+ fromCoin: { chain: options.fromChain, token: options.fromToken },
34
+ toCoin: { chain: options.toChain, token: options.toToken },
35
+ amount: options.amount,
36
+ fiatCurrency: 'usd', // Request fiat conversion
37
+ });
38
+ spinner.succeed('Quote received');
39
+ if (isJsonOutput()) {
40
+ outputJson({
41
+ fromChain: options.fromChain,
42
+ toChain: options.toChain,
43
+ amount: options.amount,
44
+ quote,
45
+ });
46
+ return quote;
47
+ }
48
+ // Get native token for fee display (fees are paid in native token)
49
+ const feeBalance = await vault.balance(options.fromChain);
50
+ // Use coin info from quote for accurate decimals and symbols
51
+ displaySwapPreview(quote, String(options.amount), quote.fromCoin.ticker, quote.toCoin.ticker, {
52
+ fromDecimals: quote.fromCoin.decimals,
53
+ toDecimals: quote.toCoin.decimals,
54
+ feeDecimals: feeBalance.decimals,
55
+ feeSymbol: feeBalance.symbol,
56
+ });
57
+ info('\nTo execute this swap, use the "swap" command');
58
+ return quote;
59
+ }
60
+ /**
61
+ * Execute swap command - perform a cross-chain swap
62
+ */
63
+ export async function executeSwap(ctx, options) {
64
+ const vault = await ctx.ensureActiveVault();
65
+ if (isNaN(options.amount) || options.amount <= 0) {
66
+ throw new Error('Invalid amount');
67
+ }
68
+ // Check swap support
69
+ const isSupported = await vault.isSwapSupported(options.fromChain, options.toChain);
70
+ if (!isSupported) {
71
+ throw new Error(`Swaps from ${options.fromChain} to ${options.toChain} are not supported`);
72
+ }
73
+ // 1. Get swap quote
74
+ const quoteSpinner = createSpinner('Getting swap quote...');
75
+ const quote = await vault.getSwapQuote({
76
+ fromCoin: { chain: options.fromChain, token: options.fromToken },
77
+ toCoin: { chain: options.toChain, token: options.toToken },
78
+ amount: options.amount,
79
+ fiatCurrency: 'usd', // Request fiat conversion
80
+ });
81
+ quoteSpinner.succeed('Quote received');
82
+ // Get native token for fee display (fees are paid in native token)
83
+ const feeBalance = await vault.balance(options.fromChain);
84
+ // 2. Display preview using coin info from quote for accurate decimals (skip in JSON mode)
85
+ if (!isJsonOutput()) {
86
+ displaySwapPreview(quote, String(options.amount), quote.fromCoin.ticker, quote.toCoin.ticker, {
87
+ fromDecimals: quote.fromCoin.decimals,
88
+ toDecimals: quote.toCoin.decimals,
89
+ feeDecimals: feeBalance.decimals,
90
+ feeSymbol: feeBalance.symbol,
91
+ });
92
+ }
93
+ // 3. Confirm with user (skip if --yes flag is set or JSON mode)
94
+ if (!options.yes && !isJsonOutput()) {
95
+ const confirmed = await confirmSwap();
96
+ if (!confirmed) {
97
+ warn('Swap cancelled');
98
+ throw new Error('Swap cancelled by user');
99
+ }
100
+ }
101
+ // 4. Prepare swap transaction
102
+ const prepSpinner = createSpinner('Preparing swap transaction...');
103
+ const { keysignPayload, approvalPayload } = await vault.prepareSwapTx({
104
+ fromCoin: { chain: options.fromChain, token: options.fromToken },
105
+ toCoin: { chain: options.toChain, token: options.toToken },
106
+ amount: options.amount,
107
+ swapQuote: quote,
108
+ autoApprove: false,
109
+ });
110
+ prepSpinner.succeed('Swap prepared');
111
+ // 5. Handle approval if needed
112
+ if (approvalPayload) {
113
+ info('\nToken approval required before swap...');
114
+ const approvalSpinner = createSpinner('Signing approval transaction...');
115
+ vault.on('signingProgress', ({ step }) => {
116
+ approvalSpinner.text = `Approval: ${step.message} (${step.progress}%)`;
117
+ });
118
+ try {
119
+ const approvalHashes = await vault.extractMessageHashes(approvalPayload);
120
+ const approvalSig = await vault.sign({
121
+ transaction: approvalPayload,
122
+ chain: options.fromChain,
123
+ messageHashes: approvalHashes,
124
+ });
125
+ approvalSpinner.succeed('Approval signed');
126
+ const broadcastApprovalSpinner = createSpinner('Broadcasting approval...');
127
+ const approvalTxHash = await vault.broadcastTx({
128
+ chain: options.fromChain,
129
+ keysignPayload: approvalPayload,
130
+ signature: approvalSig,
131
+ });
132
+ broadcastApprovalSpinner.succeed(`Approval broadcast: ${approvalTxHash}`);
133
+ info('Waiting for approval to confirm...');
134
+ // Wait a bit for approval to be mined
135
+ await new Promise(resolve => setTimeout(resolve, 5000));
136
+ }
137
+ finally {
138
+ vault.removeAllListeners('signingProgress');
139
+ }
140
+ }
141
+ // 6. Sign main swap transaction
142
+ const signSpinner = createSpinner('Signing swap transaction...');
143
+ vault.on('signingProgress', ({ step }) => {
144
+ signSpinner.text = `${step.message} (${step.progress}%)`;
145
+ });
146
+ try {
147
+ const messageHashes = await vault.extractMessageHashes(keysignPayload);
148
+ const signature = await vault.sign({
149
+ transaction: keysignPayload,
150
+ chain: options.fromChain,
151
+ messageHashes,
152
+ });
153
+ signSpinner.succeed('Swap transaction signed');
154
+ // 7. Broadcast swap
155
+ const broadcastSpinner = createSpinner('Broadcasting swap transaction...');
156
+ const txHash = await vault.broadcastTx({
157
+ chain: options.fromChain,
158
+ keysignPayload,
159
+ signature,
160
+ });
161
+ broadcastSpinner.succeed(`Swap broadcast: ${txHash}`);
162
+ // 8. Display result
163
+ if (isJsonOutput()) {
164
+ outputJson({
165
+ txHash,
166
+ fromChain: options.fromChain,
167
+ toChain: options.toChain,
168
+ quote,
169
+ });
170
+ }
171
+ else {
172
+ displaySwapResult(options.fromChain, options.toChain, txHash, quote, quote.toCoin.decimals);
173
+ }
174
+ return { txHash, quote };
175
+ }
176
+ finally {
177
+ vault.removeAllListeners('signingProgress');
178
+ }
179
+ }
180
+ //# sourceMappingURL=swap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swap.js","sourceRoot":"","sources":["../../src/commands/swap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ import chalk from 'chalk';
2
+ import inquirer from 'inquirer';
3
+ import { createSpinner, info, isJsonOutput, outputJson, printResult, printTable, success, warn } from '../lib/output';
4
+ /**
5
+ * Execute tokens command - list, add, or remove tokens
6
+ */
7
+ export async function executeTokens(ctx, options) {
8
+ // Ensure vault is active before any operation
9
+ await ctx.ensureActiveVault();
10
+ if (options.add) {
11
+ // Use CLI options if provided, otherwise prompt
12
+ let symbol = options.symbol;
13
+ let name = options.name;
14
+ let decimals = options.decimals;
15
+ // Only prompt for missing values
16
+ const prompts = [];
17
+ if (!symbol) {
18
+ prompts.push({
19
+ type: 'input',
20
+ name: 'symbol',
21
+ message: 'Enter token symbol (e.g., USDT):',
22
+ validate: (input) => input.trim() !== '' || 'Symbol is required',
23
+ });
24
+ }
25
+ if (!name) {
26
+ prompts.push({
27
+ type: 'input',
28
+ name: 'name',
29
+ message: 'Enter token name (e.g., Tether USD):',
30
+ validate: (input) => input.trim() !== '' || 'Name is required',
31
+ });
32
+ }
33
+ if (decimals === undefined) {
34
+ prompts.push({
35
+ type: 'number',
36
+ name: 'decimals',
37
+ message: 'Enter token decimals:',
38
+ default: 18,
39
+ validate: (input) => input >= 0 || 'Decimals must be non-negative',
40
+ });
41
+ }
42
+ if (prompts.length > 0) {
43
+ const answers = await inquirer.prompt(prompts);
44
+ symbol = symbol || answers.symbol?.trim();
45
+ name = name || answers.name?.trim();
46
+ decimals = decimals ?? answers.decimals;
47
+ }
48
+ await addToken(ctx, {
49
+ chain: options.chain,
50
+ contractAddress: options.add,
51
+ symbol: symbol,
52
+ name: name,
53
+ decimals: decimals,
54
+ });
55
+ }
56
+ else if (options.remove) {
57
+ await removeToken(ctx, options.chain, options.remove);
58
+ }
59
+ else {
60
+ await listTokens(ctx, options.chain);
61
+ }
62
+ }
63
+ /**
64
+ * Add a token to a chain
65
+ */
66
+ export async function addToken(ctx, options) {
67
+ const vault = await ctx.ensureActiveVault();
68
+ await vault.addToken(options.chain, {
69
+ id: `${options.chain}-${options.contractAddress}`,
70
+ contractAddress: options.contractAddress,
71
+ symbol: options.symbol,
72
+ name: options.name,
73
+ decimals: options.decimals,
74
+ chainId: options.chain,
75
+ isNative: false,
76
+ });
77
+ success(`\n+ Added token ${options.symbol} on ${options.chain}`);
78
+ }
79
+ /**
80
+ * Remove a token from a chain
81
+ */
82
+ export async function removeToken(ctx, chain, tokenId) {
83
+ const vault = await ctx.ensureActiveVault();
84
+ await vault.removeToken(chain, tokenId);
85
+ success(`\n+ Removed token ${tokenId} from ${chain}`);
86
+ }
87
+ /**
88
+ * List tokens for a chain
89
+ */
90
+ export async function listTokens(ctx, chain) {
91
+ const vault = await ctx.ensureActiveVault();
92
+ const spinner = createSpinner(`Loading tokens for ${chain}...`);
93
+ const tokens = vault.getTokens(chain);
94
+ spinner.succeed(`Tokens loaded for ${chain}`);
95
+ if (isJsonOutput()) {
96
+ outputJson({ chain, tokens: tokens || [] });
97
+ return;
98
+ }
99
+ if (!tokens || tokens.length === 0) {
100
+ warn(`\nNo tokens configured for ${chain}`);
101
+ info(chalk.gray(`\nUse --add <contractAddress> to add a token`));
102
+ }
103
+ else {
104
+ printResult(chalk.cyan(`\nTokens for ${chain}:\n`));
105
+ const table = tokens.map(token => ({
106
+ Symbol: token.symbol,
107
+ Name: token.name,
108
+ Contract: token.contractAddress || 'N/A',
109
+ Decimals: token.decimals,
110
+ Native: token.isNative ? 'Yes' : 'No',
111
+ }));
112
+ printTable(table);
113
+ info(chalk.gray(`\nUse --add <contractAddress> to add or --remove <tokenId> to remove`));
114
+ }
115
+ }
116
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/commands/tokens.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ import { Chain, Vultisig } from '@vultisig/sdk';
2
+ import { createSpinner, isJsonOutput, outputJson, warn } from '../lib/output';
3
+ import { confirmTransaction, displayTransactionPreview, displayTransactionResult } from '../ui';
4
+ /**
5
+ * Execute send command - send tokens to an address
6
+ */
7
+ export async function executeSend(ctx, params) {
8
+ const vault = await ctx.ensureActiveVault();
9
+ if (!Object.values(Chain).includes(params.chain)) {
10
+ throw new Error(`Invalid chain: ${params.chain}`);
11
+ }
12
+ if (isNaN(parseFloat(params.amount)) || parseFloat(params.amount) <= 0) {
13
+ throw new Error('Invalid amount');
14
+ }
15
+ return sendTransaction(vault, params);
16
+ }
17
+ /**
18
+ * Send transaction with full flow: prepare -> confirm -> sign -> broadcast
19
+ */
20
+ export async function sendTransaction(vault, params) {
21
+ // 1. Prepare transaction
22
+ const prepareSpinner = createSpinner('Preparing transaction...');
23
+ const address = await vault.address(params.chain);
24
+ const balance = await vault.balance(params.chain, params.tokenId);
25
+ const coin = {
26
+ chain: params.chain,
27
+ address,
28
+ decimals: balance.decimals,
29
+ ticker: balance.symbol,
30
+ id: params.tokenId,
31
+ };
32
+ const amount = BigInt(Math.floor(parseFloat(params.amount) * Math.pow(10, balance.decimals)));
33
+ const payload = await vault.prepareSendTx({
34
+ coin,
35
+ receiver: params.to,
36
+ amount,
37
+ memo: params.memo,
38
+ });
39
+ prepareSpinner.succeed('Transaction prepared');
40
+ // 2. Get gas estimate
41
+ let gas;
42
+ try {
43
+ gas = await vault.gas(params.chain);
44
+ }
45
+ catch {
46
+ warn('\nGas estimation unavailable');
47
+ }
48
+ // 3. Show transaction preview (skip in JSON mode)
49
+ if (!isJsonOutput()) {
50
+ displayTransactionPreview(payload.coin.address, params.to, params.amount, payload.coin.ticker, params.chain, params.memo, gas);
51
+ }
52
+ // 4. Confirm with user (skip if --yes flag is set or JSON mode)
53
+ if (!params.yes && !isJsonOutput()) {
54
+ const confirmed = await confirmTransaction();
55
+ if (!confirmed) {
56
+ warn('Transaction cancelled');
57
+ throw new Error('Transaction cancelled by user');
58
+ }
59
+ }
60
+ // 5. Sign transaction
61
+ const signSpinner = createSpinner('Signing transaction...');
62
+ vault.on('signingProgress', ({ step }) => {
63
+ signSpinner.text = `${step.message} (${step.progress}%)`;
64
+ });
65
+ try {
66
+ const messageHashes = await vault.extractMessageHashes(payload);
67
+ const signature = await vault.sign({
68
+ transaction: payload,
69
+ chain: payload.coin.chain,
70
+ messageHashes,
71
+ });
72
+ signSpinner.succeed('Transaction signed');
73
+ // 6. Broadcast transaction
74
+ const broadcastSpinner = createSpinner('Broadcasting transaction...');
75
+ const txHash = await vault.broadcastTx({
76
+ chain: params.chain,
77
+ keysignPayload: payload,
78
+ signature,
79
+ });
80
+ broadcastSpinner.succeed(`Transaction broadcast: ${txHash}`);
81
+ const result = {
82
+ txHash,
83
+ chain: params.chain,
84
+ explorerUrl: Vultisig.getTxExplorerUrl(params.chain, txHash),
85
+ };
86
+ // 7. Display result
87
+ if (isJsonOutput()) {
88
+ outputJson(result);
89
+ }
90
+ else {
91
+ displayTransactionResult(params.chain, txHash);
92
+ }
93
+ return result;
94
+ }
95
+ finally {
96
+ vault.removeAllListeners('signingProgress');
97
+ }
98
+ }
99
+ //# sourceMappingURL=transaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/commands/transaction.ts"],"names":[],"mappings":"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"}