@darksol/terminal 0.5.1 → 0.5.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.
- package/package.json +1 -1
- package/src/trading/swap.js +46 -16
- package/src/web/commands.js +6 -6
package/package.json
CHANGED
package/src/trading/swap.js
CHANGED
|
@@ -58,7 +58,8 @@ const TOKENS = {
|
|
|
58
58
|
OP: '0x4200000000000000000000000000000000000042',
|
|
59
59
|
},
|
|
60
60
|
polygon: {
|
|
61
|
-
|
|
61
|
+
MATIC: ethers.ZeroAddress,
|
|
62
|
+
POL: ethers.ZeroAddress,
|
|
62
63
|
WETH: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619',
|
|
63
64
|
WMATIC: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',
|
|
64
65
|
USDC: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
|
|
@@ -76,12 +77,20 @@ const ERC20_ABI = [
|
|
|
76
77
|
'function name() view returns (string)',
|
|
77
78
|
];
|
|
78
79
|
|
|
79
|
-
// Uniswap V3 SwapRouter
|
|
80
|
-
|
|
80
|
+
// Uniswap V3 SwapRouter ABIs
|
|
81
|
+
// V1 SwapRouter (ETH, Arb, OP, Polygon) — has deadline IN the struct
|
|
82
|
+
const SWAP_ROUTER_V1_ABI = [
|
|
81
83
|
'function exactInputSingle((address tokenIn, address tokenOut, uint24 fee, address recipient, uint256 deadline, uint256 amountIn, uint256 amountOutMinimum, uint160 sqrtPriceLimitX96)) external payable returns (uint256 amountOut)',
|
|
84
|
+
];
|
|
85
|
+
// V2 SwapRouter02 (Base) — NO deadline in struct, uses multicall wrapper
|
|
86
|
+
const SWAP_ROUTER_V2_ABI = [
|
|
87
|
+
'function exactInputSingle((address tokenIn, address tokenOut, uint24 fee, address recipient, uint256 amountIn, uint256 amountOutMinimum, uint160 sqrtPriceLimitX96)) external payable returns (uint256 amountOut)',
|
|
82
88
|
'function multicall(uint256 deadline, bytes[] data) external payable returns (bytes[])',
|
|
83
89
|
];
|
|
84
90
|
|
|
91
|
+
// Which chains use V2 SwapRouter02 (no deadline in struct)
|
|
92
|
+
const V2_ROUTER_CHAINS = new Set(['base']);
|
|
93
|
+
|
|
85
94
|
// Uniswap V3 Quoter V2 ABI (for getting expected output)
|
|
86
95
|
const QUOTER_ABI = [
|
|
87
96
|
'function quoteExactInputSingle((address tokenIn, address tokenOut, uint256 amountIn, uint24 fee, uint160 sqrtPriceLimitX96)) external returns (uint256 amountOut, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)',
|
|
@@ -232,7 +241,6 @@ export async function executeSwap(opts = {}) {
|
|
|
232
241
|
|
|
233
242
|
// Execute swap
|
|
234
243
|
swapSpin.text = 'Getting quote for slippage protection...';
|
|
235
|
-
const swapRouter = new ethers.Contract(router, SWAP_ROUTER_ABI, signer);
|
|
236
244
|
const actualTokenOut = tokenOutAddr === ethers.ZeroAddress ? TOKENS[chain]?.WETH : tokenOutAddr;
|
|
237
245
|
|
|
238
246
|
const deadline = Math.floor(Date.now() / 1000) + 300; // 5 min
|
|
@@ -276,19 +284,41 @@ export async function executeSwap(opts = {}) {
|
|
|
276
284
|
}
|
|
277
285
|
|
|
278
286
|
swapSpin.text = 'Sending swap transaction...';
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
fee: 3000, // 0.3% fee tier
|
|
283
|
-
recipient: address,
|
|
284
|
-
deadline,
|
|
285
|
-
amountIn,
|
|
286
|
-
amountOutMinimum: amountOutMin,
|
|
287
|
-
sqrtPriceLimitX96: 0,
|
|
288
|
-
};
|
|
289
|
-
|
|
287
|
+
const isV2Router = V2_ROUTER_CHAINS.has(chain);
|
|
288
|
+
const routerABI = isV2Router ? SWAP_ROUTER_V2_ABI : SWAP_ROUTER_V1_ABI;
|
|
289
|
+
const swapRouter = new ethers.Contract(router, routerABI, signer);
|
|
290
290
|
const txOpts = isNativeIn ? { value: amountIn } : {};
|
|
291
|
-
|
|
291
|
+
|
|
292
|
+
let tx;
|
|
293
|
+
if (isV2Router) {
|
|
294
|
+
// SwapRouter02: no deadline in struct, use multicall wrapper
|
|
295
|
+
const swapParams = {
|
|
296
|
+
tokenIn: actualTokenIn,
|
|
297
|
+
tokenOut: actualTokenOut,
|
|
298
|
+
fee: 3000,
|
|
299
|
+
recipient: address,
|
|
300
|
+
amountIn,
|
|
301
|
+
amountOutMinimum: amountOutMin,
|
|
302
|
+
sqrtPriceLimitX96: 0,
|
|
303
|
+
};
|
|
304
|
+
// Encode the swap call, then wrap in multicall with deadline
|
|
305
|
+
const swapIface = new ethers.Interface(SWAP_ROUTER_V2_ABI);
|
|
306
|
+
const swapData = swapIface.encodeFunctionData('exactInputSingle', [swapParams]);
|
|
307
|
+
tx = await swapRouter.multicall(deadline, [swapData], txOpts);
|
|
308
|
+
} else {
|
|
309
|
+
// V1 SwapRouter: deadline is in the struct
|
|
310
|
+
const swapParams = {
|
|
311
|
+
tokenIn: actualTokenIn,
|
|
312
|
+
tokenOut: actualTokenOut,
|
|
313
|
+
fee: 3000,
|
|
314
|
+
recipient: address,
|
|
315
|
+
deadline,
|
|
316
|
+
amountIn,
|
|
317
|
+
amountOutMinimum: amountOutMin,
|
|
318
|
+
sqrtPriceLimitX96: 0,
|
|
319
|
+
};
|
|
320
|
+
tx = await swapRouter.exactInputSingle(swapParams, txOpts);
|
|
321
|
+
}
|
|
292
322
|
|
|
293
323
|
swapSpin.text = 'Waiting for confirmation...';
|
|
294
324
|
const receipt = await tx.wait();
|
package/src/web/commands.js
CHANGED
|
@@ -331,15 +331,15 @@ export async function handlePromptResponse(id, value, meta, ws) {
|
|
|
331
331
|
const amount = meta.amount || '100';
|
|
332
332
|
const email = value.trim();
|
|
333
333
|
|
|
334
|
-
// Ask for crypto selection
|
|
334
|
+
// Ask for crypto selection — only verified working combos
|
|
335
335
|
ws.sendMenu('cards_crypto', `◆ Pay With (${provider} $${amount} → ${email})`, [
|
|
336
336
|
{ value: 'usdc_base', label: 'USDC on Base', desc: 'Default · fast & cheap', meta: { provider, amount, email, ticker: 'usdc', network: 'base' } },
|
|
337
|
-
{ value: '
|
|
337
|
+
{ value: 'usdc_erc20', label: 'USDC on Ethereum', desc: 'ERC-20', meta: { provider, amount, email, ticker: 'usdc', network: 'ERC20' } },
|
|
338
338
|
{ value: 'usdt_trc20', label: 'USDT on Tron', desc: 'TRC-20', meta: { provider, amount, email, ticker: 'usdt', network: 'trc20' } },
|
|
339
|
-
{ value: 'btc', label: 'Bitcoin', desc: 'BTC
|
|
340
|
-
{ value: 'eth', label: 'Ethereum', desc: 'ETH
|
|
341
|
-
{ value: 'sol', label: 'Solana', desc: 'SOL', meta: { provider, amount, email, ticker: 'sol', network: '
|
|
342
|
-
{ value: 'xmr', label: 'Monero', desc: 'XMR', meta: { provider, amount, email, ticker: 'xmr', network: '
|
|
339
|
+
{ value: 'btc', label: 'Bitcoin', desc: 'BTC', meta: { provider, amount, email, ticker: 'btc', network: 'Mainnet' } },
|
|
340
|
+
{ value: 'eth', label: 'Ethereum', desc: 'ETH ERC-20', meta: { provider, amount, email, ticker: 'eth', network: 'ERC20' } },
|
|
341
|
+
{ value: 'sol', label: 'Solana', desc: 'SOL', meta: { provider, amount, email, ticker: 'sol', network: 'Mainnet' } },
|
|
342
|
+
{ value: 'xmr', label: 'Monero', desc: 'XMR', meta: { provider, amount, email, ticker: 'xmr', network: 'Mainnet' } },
|
|
343
343
|
{ value: 'default', label: 'Default (USDC/Base)', desc: 'Let API choose', meta: { provider, amount, email } },
|
|
344
344
|
]);
|
|
345
345
|
return {};
|