initalll
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user