This commit is contained in:
ZOMBIIIIIII
2026-06-11 12:03:51 +03:00
parent 399322973e
commit f8403eb9f6
23 changed files with 3998 additions and 6 deletions

View File

@@ -18,6 +18,7 @@ import { env } from '../config/env';
import { DERIVATION_PATHS, ethAddressToTron } from './wallet-generator.service';
import { pickProxiedEvmProvider } from '../lib/outbound-proxy';
import { logger } from '../lib/logger';
import { WETH_ADDRESS } from '../lib/defi-contracts';
const bip32 = BIP32Factory(ecc);
@@ -130,6 +131,59 @@ export async function signAndBroadcastEvmApprove(p: SignEvmApproveParams): Promi
return { txid: sent.hash };
}
/**
* Wrap native ETH → WETH (WETH.deposit{value}). Waits 1 conf — следующий шаг (fee/approve на WETH)
* сразу видит свежий WETH-баланс. ETH-only. Используется в LP-депозите для пулов с WETH-ногой.
*/
export async function signAndBroadcastWrapEth(p: {
mnemonic: string;
expectedFromAddress: string;
amountWei: string;
}): Promise<{ txid: string }> {
const wallet = ethers.Wallet.fromMnemonic(p.mnemonic, DERIVATION_PATHS.ETH);
if (wallet.address.toLowerCase() !== p.expectedFromAddress.toLowerCase()) {
throw new Error(`Derived ETH address ${wallet.address} ≠ stored ${p.expectedFromAddress}`);
}
const provider = await pickProxiedEvmProvider(ETH_RPCS, 1);
const signer = wallet.connect(provider);
const amount = ethers.BigNumber.from(p.amountWei);
const feeData = await provider.getFeeData();
const capWei = ethers.utils.parseUnits(String(MAX_GAS_PRICE_GWEI), 'gwei');
let maxFeePerGas = feeData.maxFeePerGas ?? ethers.utils.parseUnits('30', 'gwei');
let maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? ethers.utils.parseUnits('1', 'gwei');
if (maxFeePerGas.gt(capWei)) maxFeePerGas = capWei;
if (maxPriorityFeePerGas.gt(maxFeePerGas)) maxPriorityFeePerGas = maxFeePerGas;
const gasLimit = ethers.BigNumber.from(60_000); // WETH.deposit ~27-45k
const bal = await provider.getBalance(wallet.address);
if (bal.lt(amount.add(maxFeePerGas.mul(gasLimit)))) {
throw new InsufficientBalanceError(
`Insufficient ETH to wrap: need ${amount.toString()} wei + gas, have ${bal.toString()}`,
);
}
const nonce = await provider.getTransactionCount(wallet.address, 'pending');
const data = new ethers.utils.Interface(['function deposit() payable']).encodeFunctionData('deposit', []);
const sent = await signer.sendTransaction({
to: ethers.utils.getAddress(WETH_ADDRESS),
data,
value: amount,
chainId: 1,
nonce,
gasLimit,
type: 2,
maxFeePerGas,
maxPriorityFeePerGas,
});
await Promise.race([
sent.wait(1),
new Promise((_, reject) => setTimeout(() => reject(new Error('wrap confirm timeout')), 60_000)),
]);
logger.info(`ETH→WETH wrap confirmed: amount=${p.amountWei} txid=${sent.hash}`);
return { txid: sent.hash };
}
export interface ReadErc20AllowanceParams {
chain: 'ETH' | 'BSC';
token: string;