UNPKG

@molecularlabs/nucleus-frontend

Version:
180 lines 6.11 kB
import { erc20Abi, parseUnits } from "viem"; import { getRateInQuoteWithAssetDecimals } from "../../api/accountant"; import { getErc20Decimals } from "../../api/erc20"; import { toChainId } from "../../api/vault-config"; import { DEFAULT_APPROVAL_AMOUNT, DEFAULT_DEPOSIT_SLIPPAGE } from "../../constants"; import { TellerAbi } from "../../contracts/teller-abi"; import { tryCatch } from "../../utils/try-catch"; import { prepareBridgeContractArg } from "../bridge"; import { getVaultByKey } from "../index"; import { calculateMinimumMint } from "./utils"; const prepareDepositTransactionData = async ({ vaultKey, depositTokenSymbol, depositAmount, chainId, slippage = DEFAULT_DEPOSIT_SLIPPAGE }) => { try { const normalizedChainId = toChainId(chainId); const vault = await getVaultByKey(vaultKey); const depositAssetAddress = vault.deposit.sourceChains[normalizedChainId].depositTokens[depositTokenSymbol].address; if (!vault) { throw new Error(`Invalid vault key: ${vaultKey}`); } if (!depositAssetAddress) { throw new Error( `Couldn't find address for ${depositTokenSymbol} on ${chainId}` ); } if (!vault.contracts) { throw new Error(`Contracts not configured for vault ${vaultKey}`); } if (!vault.contracts.teller) { throw new Error(`Teller contract not configured for vault ${vaultKey}`); } const [depositAssetDecimals, rate] = await getRateInQuoteWithAssetDecimals({ assetAddress: depositAssetAddress, accountantAddress: vault.contracts.accountant, chainId: normalizedChainId }); if (depositAssetDecimals.status === "failure") { throw new Error(depositAssetDecimals.error.message); } if (rate.status === "failure") { throw new Error(rate.error.message); } const depositAmountAsBitInt = parseUnits( depositAmount, depositAssetDecimals.result ); const minimumMint = calculateMinimumMint( depositAmountAsBitInt, rate.result, slippage ); return { abi: TellerAbi, address: vault.contracts.teller, functionName: "deposit", args: [depositAssetAddress, depositAmountAsBitInt, minimumMint], chainId: normalizedChainId }; } catch (error) { console.error(error); throw new Error(`Failed to get rate in quote for vault ${vaultKey}`); } }; const prepareDepositAndBridgeTransactionData = async ({ depositAmount, depositTokenSymbol, destinationChainId, slippage = DEFAULT_DEPOSIT_SLIPPAGE, sourceChainId, userAddress, vaultKey }) => { const normalizedSourceChainId = toChainId(sourceChainId); const normalizedDestinationChainId = toChainId(destinationChainId); const vault = await getVaultByKey(vaultKey); const depositAssetAddress = vault.deposit.sourceChains[normalizedSourceChainId].depositTokens[depositTokenSymbol].address; if (!vault) { throw new Error(`Invalid vault key: ${vaultKey}`); } if (!vault.contracts) { throw new Error(`Contracts not configured for vault ${vaultKey}`); } if (!vault.contracts.accountant) { throw new Error(`Accountant contract not configured for vault ${vaultKey}`); } const bridgeIdentifier = vault.deposit.sourceChains[normalizedSourceChainId].destinationChains[normalizedDestinationChainId].bridge.chainIdentifier; const [depositAssetDecimals, rate] = await getRateInQuoteWithAssetDecimals({ assetAddress: depositAssetAddress, accountantAddress: vault.contracts.accountant, chainId: normalizedSourceChainId }); if (depositAssetDecimals.status === "failure") { throw new Error(depositAssetDecimals.error.message); } if (rate.status === "failure") { throw new Error(rate.error.message); } const depositAmountAsBitInt = parseUnits( depositAmount, depositAssetDecimals.result ); const minimumMint = calculateMinimumMint( depositAmountAsBitInt, rate.result, slippage ); const bridgeData = prepareBridgeContractArg({ bridgeChainIdentifier: bridgeIdentifier, userAddress }); return { abi: TellerAbi, address: vault.contracts.teller, functionName: "depositAndBridge", args: [depositAssetAddress, depositAmountAsBitInt, minimumMint, bridgeData], chainId: normalizedSourceChainId, value: BigInt(0) // This will be updated with actual bridge fee when executing }; }; const prepareApproveDepositToken = async ({ vaultKey, depositTokenSymbol, depositAmount, chainId }) => { const normalizedChainId = toChainId(chainId); const vault = await getVaultByKey(vaultKey); if (!vault) { throw new Error(`Invalid vault key: ${vaultKey}`); } if (!vault.contracts) { throw new Error(`Contracts not configured for vault ${vaultKey}`); } if (!vault.contracts.boringVault) { throw new Error(`Teller contract not configured for vault ${vaultKey}`); } const depositAssetAddress = vault.deposit.sourceChains[normalizedChainId].depositTokens[depositTokenSymbol].address; if (!depositAssetAddress) { throw new Error(`Invalid deposit token symbol: ${depositTokenSymbol}`); } const { data: depositAssetDecimals, error: depositAssetDecimalsError, success: depositAssetDecimalsSuccess } = await tryCatch( getErc20Decimals({ chainId: normalizedChainId, tokenAddress: depositAssetAddress }) ); if (depositAssetDecimalsSuccess === false) { throw new Error( `Error getting deposit asset decimals. ${depositAssetDecimalsError.name}: ${depositAssetDecimalsError.message}` ); } if (!depositAssetDecimals) { throw new Error(`Invalid deposit token symbol: ${depositTokenSymbol}`); } const depositAmountAsBitInt = depositAmount ? parseUnits(depositAmount, depositAssetDecimals) : DEFAULT_APPROVAL_AMOUNT; return { abi: erc20Abi, address: depositAssetAddress, functionName: "approve", args: [vault.contracts.boringVault, depositAmountAsBitInt] }; }; export { prepareApproveDepositToken, prepareDepositAndBridgeTransactionData, prepareDepositTransactionData }; //# sourceMappingURL=deposit.mjs.map