UNPKG

@biconomy/sdk

Version:

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

119 lines 4.86 kB
import { parseAbi } from "abitype"; import { encodeFunctionData, erc20Abi } from "viem"; import { createHttpClient } from "../../clients/createHttpClient.js"; // Create HTTP client instance const acrossClient = createHttpClient("https://app.across.to/api"); /** * Fetches suggested fees from Across bridge API * @param {AcrossSuggestedFeesParams} params - Parameters for fee calculation * @param {Address} params.inputToken - Source token address * @param {Address} params.outputToken - Destination token address * @param {number} params.originChainId - Source chain ID * @param {number} params.destinationChainId - Destination chain ID * @param {bigint} params.amount - Amount to bridge * @returns {Promise<AcrossRelayFeeResponse>} Suggested fees and related information */ const acrossGetSuggestedFees = async ({ inputToken, outputToken, originChainId, destinationChainId, amount }) => acrossClient.request({ path: "suggested-fees", method: "GET", params: { inputToken, outputToken, originChainId: originChainId.toString(), destinationChainId: destinationChainId.toString(), amount: amount.toString() } }); /** * Encodes a bridging operation for the Across protocol into a user operation * @param {BridgingUserOpParams} params - Parameters for the bridge operation * @param {bigint} params.bridgingAmount - Amount to bridge * @param {Chain} params.fromChain - Source chain information * @param {Account} params.account - User's account information * @param {Chain} params.toChain - Destination chain information * @param {TokenMapping} params.tokenMapping - Token address mapping across chains * @returns {Promise<BridgingPluginResult>} Encoded user operation and bridging details * @throws {Error} When depositor or recipient address cannot be found */ export const acrossEncodeBridgingUserOp = async (params) => { const { bridgingAmount, fromChain, account, toChain, tokenMapping } = params; const inputToken = tokenMapping.on(fromChain.id); const outputToken = tokenMapping.on(toChain.id); const depositor = account.deploymentOn(fromChain.id)?.address; const recipient = account.deploymentOn(toChain.id)?.address; if (!depositor || !recipient) { throw new Error("No depositor or recipient found"); } const suggestedFees = await acrossGetSuggestedFees({ amount: bridgingAmount, destinationChainId: toChain.id, inputToken: inputToken, outputToken: outputToken, originChainId: fromChain.id }); const depositV3abi = parseAbi([ "function depositV3(address depositor, address recipient, address inputToken, address outputToken, uint256 inputAmount, uint256 outputAmount, uint256 destinationChainId, address exclusiveRelayer, uint32 quoteTimestamp, uint32 fillDeadline, uint32 exclusivityDeadline, bytes message) external" ]); const outputAmount = BigInt(bridgingAmount) - BigInt(suggestedFees.totalRelayFee.total); const fillDeadlineBuffer = 18000; const fillDeadline = Math.round(Date.now() / 1000) + fillDeadlineBuffer; const approveCall = { to: inputToken, gasLimit: 100000n, data: encodeFunctionData({ abi: erc20Abi, functionName: "approve", args: [suggestedFees.spokePoolAddress, bridgingAmount] }) }; const depositCall = { to: suggestedFees.spokePoolAddress, gasLimit: 150000n, data: encodeFunctionData({ abi: depositV3abi, args: [ depositor, recipient, inputToken, outputToken, bridgingAmount, outputAmount, BigInt(toChain.id), suggestedFees.exclusiveRelayer, Number.parseInt(suggestedFees.timestamp), fillDeadline, Number.parseInt(suggestedFees.exclusivityDeadline), "0x" // message ] }) }; const userOp = { calls: [approveCall, depositCall], chainId: fromChain.id }; return { userOp: userOp, receivedAtDestination: outputAmount, bridgingDurationExpectedMs: undefined }; }; /** * Creates an Across bridging plugin instance * @returns {BridgingPlugin} Plugin instance implementing the Across bridge protocol * * @example * const acrossPlugin = toAcrossPlugin() * const bridgeResult = await acrossPlugin.encodeBridgeUserOp({ * bridgingAmount: 1000000n, * fromChain: sourceChain, * toChain: destChain, * account: userAccount, * tokenMapping: tokens * }) */ export const toAcrossPlugin = () => ({ encodeBridgeUserOp: async (params) => { return await acrossEncodeBridgingUserOp(params); } }); //# sourceMappingURL=toAcrossPlugin.js.map