UNPKG

@biconomy/abstractjs

Version:

SDK for Biconomy integration with support for account abstraction, smart accounts, ERC-4337.

109 lines 4.57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildBridgeInstructions = void 0; const toAcrossPlugin_1 = require("../utils/toAcrossPlugin.js"); const queryBridge_1 = require("./queryBridge.js"); const buildBridgeInstructions = async (params) => { const { account, amount: targetAmount, toChain, unifiedBalance, bridgingPlugins = [(0, toAcrossPlugin_1.toAcrossPlugin)()], feeData, mode = "DEBIT" } = params; const tokenMapping = { on: (chainId) => unifiedBalance.mcToken.deployments.get(chainId) || "0x", deployments: Array.from(unifiedBalance.mcToken.deployments.entries(), ([chainId, address]) => ({ chainId, address })) }; const destinationBalance = unifiedBalance.breakdown.find((b) => b.chainId === toChain.id)?.balance || 0n; if (destinationBalance >= targetAmount) { return { instructions: [], meta: { bridgingInstructions: [], totalAvailableOnDestination: destinationBalance } }; } const amountToBridge = targetAmount - destinationBalance; const sourceBalances = unifiedBalance.breakdown .filter((balance) => balance.chainId !== toChain.id) .map((balance_) => { const balancePerChain = mode === "DEBIT" ? balance_ : { ...balance_, balance: targetAmount }; const isFeeChain = feeData && feeData.txFeeChainId === balancePerChain.chainId; const availableBalance = isFeeChain && "txFeeAmount" in feeData ? balancePerChain.balance > feeData.txFeeAmount ? balancePerChain.balance - feeData.txFeeAmount : 0n : balancePerChain.balance; return { chainId: balancePerChain.chainId, balance: availableBalance }; }) .filter((balance) => balance.balance > 0n); const chains = Object.fromEntries(account.deployments.map((deployment) => { const chain = deployment.client.chain; if (!chain) { throw new Error(`Client not configured with chain for deployment at ${deployment.address}`); } return [chain.id, chain]; })); const bridgeQueries = sourceBalances.flatMap((source) => { const fromChain = chains[source.chainId]; if (!fromChain) return []; return bridgingPlugins.map((plugin) => (0, queryBridge_1.queryBridge)({ fromChain, toChain, plugin, amount: source.balance, account, tokenMapping })); }); const bridgeResults = (await Promise.all(bridgeQueries)) .filter((result) => result !== null) .sort((a, b) => Number((b.receivedAtDestination * 10000n) / b.amount) - Number((a.receivedAtDestination * 10000n) / a.amount)); const { bridgingInstructions, instructions, totalBridged, remainingNeeded } = bridgeResults.reduce((acc, result) => { if (acc.remainingNeeded <= 0n) return acc; const amountToTake = result.amount >= acc.remainingNeeded ? acc.remainingNeeded : result.amount; const receivedFromRoute = (result.receivedAtDestination * amountToTake) / result.amount; return { bridgingInstructions: [ ...acc.bridgingInstructions, { userOp: result.userOp, receivedAtDestination: receivedFromRoute, bridgingDurationExpectedMs: result.bridgingDurationExpectedMs } ], instructions: [...acc.instructions, result.userOp], totalBridged: acc.totalBridged + receivedFromRoute, remainingNeeded: acc.remainingNeeded - amountToTake }; }, { bridgingInstructions: [], instructions: [], totalBridged: 0n, remainingNeeded: amountToBridge }); if (remainingNeeded > 0n) { throw new Error(`Insufficient balance for bridging: Required: ${targetAmount.toString()} Available to bridge: ${totalBridged.toString()} Shortfall: ${remainingNeeded.toString()}`); } return { instructions, meta: { bridgingInstructions, totalAvailableOnDestination: destinationBalance + totalBridged } }; }; exports.buildBridgeInstructions = buildBridgeInstructions; exports.default = exports.buildBridgeInstructions; //# sourceMappingURL=buildBridgeInstructions.js.map