@biconomy/abstractjs
Version:
SDK for Biconomy integration with support for account abstraction, smart accounts, ERC-4337.
109 lines • 4.57 kB
JavaScript
;
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