fuego-cli 1.3.1 → 1.4.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 +56 -5
- package/fuego-cli-1.4.0.tgz +0 -0
- package/package.json +1 -1
- package/src/commands/balance.ts +51 -34
- package/src/commands/create.ts +2 -1
- package/src/commands/jupiter-quote.ts +122 -0
- package/src/commands/jupiter-swap.ts +146 -0
- package/src/index.ts +21 -0
- package/fuego-cli-1.3.1.tgz +0 -0
package/README.md
CHANGED
|
@@ -69,11 +69,13 @@ fuego dashboard
|
|
|
69
69
|
|---------|-------------|
|
|
70
70
|
| `fuego create` | Create a new Solana wallet |
|
|
71
71
|
| `fuego address` | Show your wallet address |
|
|
72
|
-
| `fuego balance` | Check SOL
|
|
72
|
+
| `fuego balance` | Check all token balances (SOL + SPL tokens) |
|
|
73
73
|
| `fuego rpc` | Show or configure your Solana RPC endpoint |
|
|
74
74
|
| `fuego contacts` | Manage your contacts |
|
|
75
75
|
| `fuego fund` | Show funding options: MoonPay link + QR code |
|
|
76
76
|
| `fuego send` | Send SOL, USDC, or USDT to an address or contact |
|
|
77
|
+
| `fuego jupiter quote` | Get swap quotes from Jupiter |
|
|
78
|
+
| `fuego jupiter swap` | Execute token swaps via Jupiter |
|
|
77
79
|
| `fuego purch` | Purchase products via x402 (Amazon, Shopify, etc.) |
|
|
78
80
|
|
|
79
81
|
### Project Management
|
|
@@ -115,7 +117,7 @@ fuego create --name prod-wallet
|
|
|
115
117
|
|
|
116
118
|
### `fuego balance`
|
|
117
119
|
|
|
118
|
-
Check balances via the Fuego server.
|
|
120
|
+
Check all token balances via the Fuego server. Shows SOL plus all SPL tokens in your wallet.
|
|
119
121
|
|
|
120
122
|
```bash
|
|
121
123
|
fuego balance
|
|
@@ -129,9 +131,9 @@ fuego bal
|
|
|
129
131
|
|
|
130
132
|
Address: DmFy...eUZF
|
|
131
133
|
|
|
132
|
-
- SOL:
|
|
133
|
-
- USDC:
|
|
134
|
-
-
|
|
134
|
+
- SOL: 0.105113976
|
|
135
|
+
- USDC: 28.85
|
|
136
|
+
- BONK: 712,687.68
|
|
135
137
|
```
|
|
136
138
|
|
|
137
139
|
---
|
|
@@ -306,6 +308,55 @@ fuego send melanie 5 --token USDT --yes
|
|
|
306
308
|
|
|
307
309
|
---
|
|
308
310
|
|
|
311
|
+
### `fuego jupiter quote <amount>`
|
|
312
|
+
|
|
313
|
+
Get a swap quote from Jupiter for any supported token pair.
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
# Quote SOL to USDC
|
|
317
|
+
fuego jupiter quote 0.5 --input SOL --output USDC
|
|
318
|
+
|
|
319
|
+
# Quote USDC to BONK
|
|
320
|
+
fuego jupiter quote 100 --input USDC --output BONK
|
|
321
|
+
|
|
322
|
+
# Quote using full mint addresses
|
|
323
|
+
fuego jupiter quote 1.0 --input SOL --output DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Options:**
|
|
327
|
+
- `-i, --input <token>` — **Required.** Input token symbol (SOL, USDC, USDT, BONK, JUP) or full mint address
|
|
328
|
+
- `-o, --output <token>` — **Required.** Output token symbol or full mint address
|
|
329
|
+
|
|
330
|
+
**Output:** Shows expected output amount, price impact, and routing information.
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
### `fuego jupiter swap <amount>`
|
|
335
|
+
|
|
336
|
+
Execute a token swap via Jupiter.
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
# Swap SOL to USDC (preview only)
|
|
340
|
+
fuego jupiter swap 0.5 --input SOL --output USDC
|
|
341
|
+
|
|
342
|
+
# Swap SOL to BONK (with confirmation)
|
|
343
|
+
fuego jupiter swap 0.05 --input SOL --output BONK --yes
|
|
344
|
+
|
|
345
|
+
# Swap USDC to random token by mint address
|
|
346
|
+
fuego jupiter swap 10 --input USDC --output <mint-address> --yes
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**Options:**
|
|
350
|
+
- `-i, --input <token>` — **Required.** Input token symbol or full mint address
|
|
351
|
+
- `-o, --output <token>` — **Required.** Output token symbol or full mint address
|
|
352
|
+
- `-y, --yes` — Skip confirmation and execute immediately
|
|
353
|
+
|
|
354
|
+
**Supported Tokens:** SOL, USDC, USDT, BONK, JUP (or any token by full mint address)
|
|
355
|
+
|
|
356
|
+
**Note:** For unknown tokens, provide the full 44-character mint address. The dashboard caches the top 100 tokens for symbol lookups.
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
309
360
|
### `fuego purch <product-url>`
|
|
310
361
|
|
|
311
362
|
Purchase products via x402/Purch.xyz (Amazon, Shopify, etc.) using USDC on Solana.
|
|
Binary file
|
package/package.json
CHANGED
package/src/commands/balance.ts
CHANGED
|
@@ -5,17 +5,24 @@ import ora from 'ora';
|
|
|
5
5
|
|
|
6
6
|
const FUEGO_SERVER_URL = 'http://127.0.0.1:8080';
|
|
7
7
|
|
|
8
|
-
interface
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
interface Token {
|
|
9
|
+
symbol: string;
|
|
10
|
+
ui_amount: number;
|
|
11
|
+
decimals: number;
|
|
12
|
+
mint: string;
|
|
13
|
+
token_account: string;
|
|
14
|
+
amount: string;
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
interface
|
|
17
|
+
interface TokensResponse {
|
|
16
18
|
success: boolean;
|
|
17
19
|
data?: {
|
|
18
|
-
|
|
20
|
+
wallet: string;
|
|
21
|
+
network: string;
|
|
22
|
+
sol_balance: number;
|
|
23
|
+
sol_lamports: number;
|
|
24
|
+
token_count: number;
|
|
25
|
+
tokens: Token[];
|
|
19
26
|
};
|
|
20
27
|
}
|
|
21
28
|
|
|
@@ -35,48 +42,58 @@ export async function balanceCommand(): Promise<void> {
|
|
|
35
42
|
const publicKey = config.publicKey;
|
|
36
43
|
const network = 'mainnet-beta';
|
|
37
44
|
|
|
38
|
-
// Query
|
|
39
|
-
const
|
|
45
|
+
// Query all tokens via /tokens endpoint
|
|
46
|
+
const tokensResponse = await fetch(`${FUEGO_SERVER_URL}/tokens`, {
|
|
40
47
|
method: 'POST',
|
|
41
48
|
headers: { 'Content-Type': 'application/json' },
|
|
42
49
|
body: JSON.stringify({ network, address: publicKey })
|
|
43
50
|
});
|
|
44
|
-
const
|
|
45
|
-
const solBalance = solData.success ? solData.data!.sol : 0;
|
|
51
|
+
const tokensData = await tokensResponse.json() as TokensResponse;
|
|
46
52
|
|
|
47
|
-
|
|
48
|
-
const usdcResponse = await fetch(`${FUEGO_SERVER_URL}/usdc-balance`, {
|
|
49
|
-
method: 'POST',
|
|
50
|
-
headers: { 'Content-Type': 'application/json' },
|
|
51
|
-
body: JSON.stringify({ network, address: publicKey })
|
|
52
|
-
});
|
|
53
|
-
const usdcData = await usdcResponse.json() as TokenBalanceResponse;
|
|
54
|
-
const usdcBalance = usdcData.success ? parseFloat(usdcData.data!.ui_amount) : 0;
|
|
53
|
+
spinner.stop();
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
body: JSON.stringify({ network, address: publicKey })
|
|
61
|
-
});
|
|
62
|
-
const usdtData = await usdtResponse.json() as TokenBalanceResponse;
|
|
63
|
-
const usdtBalance = usdtData.success ? parseFloat(usdtData.data!.ui_amount) : 0;
|
|
55
|
+
if (!tokensData.success || !tokensData.data) {
|
|
56
|
+
console.log(chalk.red('❌ Failed to fetch balances from server'));
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
64
59
|
|
|
65
|
-
|
|
60
|
+
const { sol_balance, tokens } = tokensData.data;
|
|
66
61
|
|
|
67
|
-
|
|
62
|
+
// Build balance lines
|
|
63
|
+
const balanceLines: string[] = [
|
|
68
64
|
`Address: ${formatPublicKey(publicKey)}`,
|
|
69
65
|
'',
|
|
70
|
-
`${chalk.yellow('- SOL:')} ${chalk.white(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
66
|
+
`${chalk.yellow('- SOL:')} ${chalk.white(sol_balance.toFixed(9))}`,
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
// Add each token balance
|
|
70
|
+
for (const token of tokens) {
|
|
71
|
+
const formattedAmount = token.ui_amount.toLocaleString('en-US', {
|
|
72
|
+
minimumFractionDigits: 2,
|
|
73
|
+
maximumFractionDigits: token.decimals > 6 ? 6 : token.decimals
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Color-code common tokens
|
|
77
|
+
let tokenColor = chalk.white;
|
|
78
|
+
if (token.symbol === 'USDC') tokenColor = chalk.green;
|
|
79
|
+
else if (token.symbol === 'USDT') tokenColor = chalk.cyan;
|
|
80
|
+
else if (token.symbol === 'BONK') tokenColor = chalk.magenta;
|
|
81
|
+
|
|
82
|
+
balanceLines.push(`${tokenColor(`- ${token.symbol}:`)} ${chalk.white(formattedAmount)}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// If no tokens found, note that
|
|
86
|
+
if (tokens.length === 0) {
|
|
87
|
+
balanceLines.push(chalk.gray('(No SPL tokens found)'));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
showInfo('💰 Your Balances', balanceLines);
|
|
74
91
|
|
|
75
92
|
flameDivider();
|
|
76
93
|
} catch (error) {
|
|
77
94
|
spinner.stop();
|
|
78
95
|
console.log(chalk.red(`\n❌ Failed to fetch balances: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
79
|
-
console.log(chalk.gray('\nMake sure the Fuego server is running:
|
|
96
|
+
console.log(chalk.gray('\nMake sure the Fuego server is running: fuego serve'));
|
|
80
97
|
process.exit(1);
|
|
81
98
|
}
|
|
82
99
|
}
|
package/src/commands/create.ts
CHANGED
|
@@ -53,7 +53,8 @@ export async function createCommand(options: CreateOptions): Promise<void> {
|
|
|
53
53
|
fs.writeJsonSync(configPath, {
|
|
54
54
|
...existingConfig,
|
|
55
55
|
network: existingConfig.network || 'mainnet',
|
|
56
|
-
rpcUrl: existingConfig.rpcUrl || 'https://api.mainnet-beta.solana.com'
|
|
56
|
+
rpcUrl: existingConfig.rpcUrl || 'https://api.mainnet-beta.solana.com',
|
|
57
|
+
jupiterKey: existingConfig.jupiterKey || ''
|
|
57
58
|
}, { spaces: 2 });
|
|
58
59
|
|
|
59
60
|
// Create address book directory and empty file
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { spawn } from 'child_process';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { loadWalletConfig, findFuegoPath } from '../lib/config.js';
|
|
5
|
+
import { showSuccess, showInfo, showError, flameDivider } from '../lib/ascii.js';
|
|
6
|
+
|
|
7
|
+
interface QuoteOptions {
|
|
8
|
+
input?: string;
|
|
9
|
+
output?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const TOKEN_MINTS: { [key: string]: string } = {
|
|
13
|
+
'SOL': 'So11111111111111111111111111111111111111112',
|
|
14
|
+
'USDC': 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
15
|
+
'USDT': 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
|
|
16
|
+
'BONK': 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263',
|
|
17
|
+
'JUP': 'JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
function resolveToken(token: string): string {
|
|
21
|
+
const upper = token.toUpperCase();
|
|
22
|
+
if (TOKEN_MINTS[upper]) {
|
|
23
|
+
return TOKEN_MINTS[upper];
|
|
24
|
+
}
|
|
25
|
+
// If it's a full mint address, use it directly
|
|
26
|
+
if (token.length === 44) {
|
|
27
|
+
return token;
|
|
28
|
+
}
|
|
29
|
+
return '';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function jupiterQuoteCommand(amount: string, options: QuoteOptions): Promise<void> {
|
|
33
|
+
console.log();
|
|
34
|
+
|
|
35
|
+
// Validate amount
|
|
36
|
+
if (!amount) {
|
|
37
|
+
console.log(chalk.red('❌ Usage: fuego jupiter quote <amount> --input SOL --output USDC'));
|
|
38
|
+
console.log(chalk.gray('\nExamples:'));
|
|
39
|
+
console.log(chalk.gray(' fuego jupiter quote 0.5 --input SOL --output USDC'));
|
|
40
|
+
console.log(chalk.gray(' fuego jupiter quote 10 --input USDC --output BONK'));
|
|
41
|
+
console.log(chalk.gray('\nSupported tokens: SOL, USDC, USDT, BONK, JUP'));
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const amountNum = parseFloat(amount);
|
|
46
|
+
if (isNaN(amountNum) || amountNum <= 0) {
|
|
47
|
+
console.log(chalk.red('❌ Invalid amount. Please provide a positive number.'));
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Validate tokens
|
|
52
|
+
if (!options.input || !options.output) {
|
|
53
|
+
console.log(chalk.red('❌ Both --input and --output tokens are required.'));
|
|
54
|
+
console.log(chalk.gray('Example: --input SOL --output USDC'));
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const inputMint = resolveToken(options.input);
|
|
59
|
+
const outputMint = resolveToken(options.output);
|
|
60
|
+
|
|
61
|
+
if (!inputMint) {
|
|
62
|
+
console.log(chalk.red(`❌ Unknown input token: ${options.input}`));
|
|
63
|
+
console.log(chalk.gray('Supported: SOL, USDC, USDT, BONK, JUP'));
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (!outputMint) {
|
|
68
|
+
console.log(chalk.red(`❌ Unknown output token: ${options.output}`));
|
|
69
|
+
console.log(chalk.gray('Supported: SOL, USDC, USDT, BONK, JUP'));
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Load wallet
|
|
74
|
+
const walletConfig = loadWalletConfig();
|
|
75
|
+
if (!walletConfig) {
|
|
76
|
+
console.log(chalk.red('❌ No wallet found. Run "fuego create" first.'));
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
showInfo('🪐 Jupiter Quote', [
|
|
81
|
+
`From: ${chalk.cyan(options.input.toUpperCase())}`,
|
|
82
|
+
`To: ${chalk.cyan(options.output.toUpperCase())}`,
|
|
83
|
+
`Amount: ${chalk.yellow(amount)}`,
|
|
84
|
+
`Network: ${chalk.gray('mainnet-beta')}`
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
console.log();
|
|
88
|
+
console.log(chalk.blue('⏳ Fetching quote from Jupiter...'));
|
|
89
|
+
|
|
90
|
+
// Find fuego path and call script
|
|
91
|
+
const fuegoPath = findFuegoPath();
|
|
92
|
+
if (!fuegoPath) {
|
|
93
|
+
showError('Fuego installation not found. Run "fuego install" first.');
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const scriptPath = path.join(fuegoPath, 'scripts', 'jupiter', 'jupiter_price.mjs');
|
|
98
|
+
|
|
99
|
+
const nodeProcess = spawn('node', [
|
|
100
|
+
scriptPath,
|
|
101
|
+
'--input', options.input,
|
|
102
|
+
'--output', options.output,
|
|
103
|
+
'--amount', amount
|
|
104
|
+
]);
|
|
105
|
+
|
|
106
|
+
nodeProcess.stdout.on('data', (data) => {
|
|
107
|
+
process.stdout.write(data);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
nodeProcess.stderr.on('data', (data) => {
|
|
111
|
+
process.stderr.write(data);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
nodeProcess.on('close', (code) => {
|
|
115
|
+
if (code === 0) {
|
|
116
|
+
flameDivider();
|
|
117
|
+
} else {
|
|
118
|
+
showError('Failed to fetch quote');
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { spawn } from 'child_process';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { loadWalletConfig, findFuegoPath } from '../lib/config.js';
|
|
5
|
+
import { showSuccess, showInfo, showError, flameDivider } from '../lib/ascii.js';
|
|
6
|
+
|
|
7
|
+
interface SwapOptions {
|
|
8
|
+
input?: string;
|
|
9
|
+
output?: string;
|
|
10
|
+
yes?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const TOKEN_MINTS: { [key: string]: string } = {
|
|
14
|
+
'SOL': 'So11111111111111111111111111111111111111112',
|
|
15
|
+
'USDC': 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
16
|
+
'USDT': 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
|
|
17
|
+
'BONK': 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263',
|
|
18
|
+
'JUP': 'JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function resolveToken(token: string): string {
|
|
22
|
+
const upper = token.toUpperCase();
|
|
23
|
+
if (TOKEN_MINTS[upper]) {
|
|
24
|
+
return TOKEN_MINTS[upper];
|
|
25
|
+
}
|
|
26
|
+
if (token.length === 44) {
|
|
27
|
+
return token;
|
|
28
|
+
}
|
|
29
|
+
return '';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function jupiterSwapCommand(amount: string, options: SwapOptions): Promise<void> {
|
|
33
|
+
console.log();
|
|
34
|
+
|
|
35
|
+
// Validate amount
|
|
36
|
+
if (!amount) {
|
|
37
|
+
console.log(chalk.red('❌ Usage: fuego jupiter swap <amount> --input SOL --output USDC [--yes]'));
|
|
38
|
+
console.log(chalk.gray('\nExamples:'));
|
|
39
|
+
console.log(chalk.gray(' fuego jupiter swap 0.5 --input SOL --output USDC'));
|
|
40
|
+
console.log(chalk.gray(' fuego jupiter swap 10 --input USDC --output BONK --yes'));
|
|
41
|
+
console.log(chalk.gray('\nSupported tokens: SOL, USDC, USDT, BONK, JUP'));
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const amountNum = parseFloat(amount);
|
|
46
|
+
if (isNaN(amountNum) || amountNum <= 0) {
|
|
47
|
+
console.log(chalk.red('❌ Invalid amount. Please provide a positive number.'));
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Validate tokens
|
|
52
|
+
if (!options.input || !options.output) {
|
|
53
|
+
console.log(chalk.red('❌ Both --input and --output tokens are required.'));
|
|
54
|
+
console.log(chalk.gray('Example: --input SOL --output USDC'));
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const inputMint = resolveToken(options.input);
|
|
59
|
+
const outputMint = resolveToken(options.output);
|
|
60
|
+
|
|
61
|
+
if (!inputMint) {
|
|
62
|
+
console.log(chalk.red(`❌ Unknown input token: ${options.input}`));
|
|
63
|
+
console.log(chalk.gray('Supported: SOL, USDC, USDT, BONK, JUP'));
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (!outputMint) {
|
|
68
|
+
console.log(chalk.red(`❌ Unknown output token: ${options.output}`));
|
|
69
|
+
console.log(chalk.gray('Supported: SOL, USDC, USDT, BONK, JUP'));
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Load wallet
|
|
74
|
+
const walletConfig = loadWalletConfig();
|
|
75
|
+
if (!walletConfig) {
|
|
76
|
+
console.log(chalk.red('❌ No wallet found. Run "fuego create" first.'));
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Show transaction preview
|
|
81
|
+
showInfo('🪐 Jupiter Swap Preview', [
|
|
82
|
+
`From: ${chalk.yellow(amount)} ${chalk.cyan(options.input.toUpperCase())}`,
|
|
83
|
+
`To: ${chalk.cyan(options.output.toUpperCase())}`,
|
|
84
|
+
`Wallet: ${chalk.gray(walletConfig.publicKey.substring(0, 16))}...`,
|
|
85
|
+
`Network: ${chalk.gray('mainnet-beta')}`
|
|
86
|
+
]);
|
|
87
|
+
|
|
88
|
+
// Confirm unless --yes
|
|
89
|
+
if (!options.yes) {
|
|
90
|
+
console.log();
|
|
91
|
+
console.log(chalk.yellow('⚠️ Add --yes to confirm and execute swap'));
|
|
92
|
+
console.log(chalk.gray('Or run first: fuego jupiter quote ' + amount + ' --input ' + options.input + ' --output ' + options.output));
|
|
93
|
+
flameDivider();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
console.log();
|
|
98
|
+
console.log(chalk.blue('⏳ Executing Jupiter swap...'));
|
|
99
|
+
console.log(chalk.gray('This may take a moment...'));
|
|
100
|
+
|
|
101
|
+
// Find fuego path and call script
|
|
102
|
+
const fuegoPath = findFuegoPath();
|
|
103
|
+
if (!fuegoPath) {
|
|
104
|
+
showError('Fuego installation not found. Run "fuego install" first.');
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const scriptPath = path.join(fuegoPath, 'scripts', 'jupiter', 'jupiter_swap_regular.mjs');
|
|
109
|
+
|
|
110
|
+
const nodeProcess = spawn('node', [
|
|
111
|
+
scriptPath,
|
|
112
|
+
'--input', options.input,
|
|
113
|
+
'--output', options.output,
|
|
114
|
+
'--amount', amount
|
|
115
|
+
]);
|
|
116
|
+
|
|
117
|
+
let output = '';
|
|
118
|
+
|
|
119
|
+
nodeProcess.stdout.on('data', (data) => {
|
|
120
|
+
output += data.toString();
|
|
121
|
+
process.stdout.write(data);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
nodeProcess.stderr.on('data', (data) => {
|
|
125
|
+
process.stderr.write(data);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
nodeProcess.on('close', (code) => {
|
|
129
|
+
if (code === 0) {
|
|
130
|
+
// Extract signature from output if present
|
|
131
|
+
const sigMatch = output.match(/Signature: ([A-Za-z0-9]+)/);
|
|
132
|
+
if (sigMatch) {
|
|
133
|
+
showSuccess(
|
|
134
|
+
'✅ Swap Complete!',
|
|
135
|
+
`${chalk.yellow(amount)} ${chalk.cyan(options.input.toUpperCase())} → ${chalk.cyan(options.output.toUpperCase())}`
|
|
136
|
+
);
|
|
137
|
+
} else {
|
|
138
|
+
showSuccess('✅ Swap Executed!', '');
|
|
139
|
+
}
|
|
140
|
+
flameDivider();
|
|
141
|
+
} else {
|
|
142
|
+
showError('Swap failed. Check output above for details.');
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,8 @@ import { contactsAddCommand, contactsListCommand, contactsShowCommand, contactsR
|
|
|
14
14
|
import { sendCommand } from './commands/send.js';
|
|
15
15
|
import { fundCommand } from './commands/fund.js';
|
|
16
16
|
import { purchCommand } from './commands/purch.js';
|
|
17
|
+
import { jupiterQuoteCommand } from './commands/jupiter-quote.js';
|
|
18
|
+
import { jupiterSwapCommand } from './commands/jupiter-swap.js';
|
|
17
19
|
import { showBanner } from './lib/ascii.js';
|
|
18
20
|
import { getFuegoCliVersion } from './lib/config.js';
|
|
19
21
|
|
|
@@ -136,6 +138,25 @@ async function main() {
|
|
|
136
138
|
.option('--country <code>', 'Country code (default: US)', 'US')
|
|
137
139
|
.action(purchCommand);
|
|
138
140
|
|
|
141
|
+
const jupiter = program
|
|
142
|
+
.command('jupiter')
|
|
143
|
+
.description('🪐 Jupiter swap commands');
|
|
144
|
+
|
|
145
|
+
jupiter
|
|
146
|
+
.command('quote <amount>')
|
|
147
|
+
.description('Get a swap quote from Jupiter')
|
|
148
|
+
.requiredOption('-i, --input <token>', 'Input token (SOL, USDC, USDT, BONK, JUP)')
|
|
149
|
+
.requiredOption('-o, --output <token>', 'Output token (SOL, USDC, USDT, BONK, JUP)')
|
|
150
|
+
.action(jupiterQuoteCommand);
|
|
151
|
+
|
|
152
|
+
jupiter
|
|
153
|
+
.command('swap <amount>')
|
|
154
|
+
.description('Execute a swap via Jupiter')
|
|
155
|
+
.requiredOption('-i, --input <token>', 'Input token (SOL, USDC, USDT, BONK, JUP)')
|
|
156
|
+
.requiredOption('-o, --output <token>', 'Output token (SOL, USDC, USDT, BONK, JUP)')
|
|
157
|
+
.option('-y, --yes', 'Skip confirmation and execute immediately')
|
|
158
|
+
.action(jupiterSwapCommand);
|
|
159
|
+
|
|
139
160
|
await program.parseAsync(process.argv);
|
|
140
161
|
}
|
|
141
162
|
|
package/fuego-cli-1.3.1.tgz
DELETED
|
Binary file
|