UNPKG

@xlink-network/xlink-sdk

Version:
103 lines (94 loc) 3.06 kB
import { estimateInputVSizeAfterSign } from "@c4/btc-utils" import { toHex } from "viem" import { requestAPI } from "../../utils/apiHelpers" import { BigNumber } from "../../utils/BigNumber" import { UnsupportedBridgeRouteError } from "../../utils/errors" import { decodeHex } from "../../utils/hexHelpers" import { KnownChainId, KnownTokenId } from "../../utils/types/knownIds" import { SDKGlobalContext } from "../../xlinkSdkUtils/types.internal" import { getBTCPegInAddress } from "../btcAddresses" import { calculateFee } from "../prepareTransaction" const REVEAL_TX_OUTPUT_AMOUNT = 546n export async function createBitcoinPegInRecipients( sdkContext: Pick<SDKGlobalContext, "backendAPI">, info: { fromChain: KnownChainId.BitcoinChain toChain: KnownChainId.StacksChain | KnownChainId.EVMChain fromToken: KnownTokenId.BitcoinToken toToken: KnownTokenId.StacksToken | KnownTokenId.EVMToken fromAddress: { address: string scriptPubKey: Uint8Array } toAddress: string fromAmount: BigNumber feeRate: bigint orderData: Uint8Array }, ): Promise<{ address: string scriptPubKey: Uint8Array satsAmount: bigint }> { const pegInAddress = await getBTCPegInAddress(info.fromChain, info.toChain) if (pegInAddress == null) { throw new UnsupportedBridgeRouteError( info.fromChain, info.toChain, KnownTokenId.Bitcoin.BTC, ) } const resp = await requestAPI<{ addresses: BitcoinPegInRecipient[] }>(sdkContext, { path: `/2024-10-01/bitcoin/peg-in-recipients`, method: "POST", body: { fromChain: info.fromChain, toChain: info.toChain, fromToken: info.fromToken, toToken: info.toToken, fromAddress: { address: info.fromAddress.address, scriptPubKeyHex: toHex(info.fromAddress.scriptPubKey), }, toAddress: info.toAddress, fromAmount: BigNumber.toString(info.fromAmount), orderDataHex: toHex(info.orderData), }, }) const recipient = resp.addresses.find( address => address.type === "commitOrder", )! const revealInputSize = estimateInputVSizeAfterSign({ addressType: "p2tr-leafScript", tapLeafScriptArgumentByteLengths: [/* signature */ 64], tapLeafScriptByteLength: recipient.tapScriptHex.length / 2, controlBlockByteLength: 33, }) const { fee: newTxFee } = await calculateFee({ recipientAddressScriptPubKeys: [pegInAddress.scriptPubKey], opReturnData: [], selectedUTXOs: [], feeRate: info.feeRate, extraSize: revealInputSize.inputSize + revealInputSize.witnessDataSize / 4, }) const revealUTXOSatsAmount = BigNumber.sum([ newTxFee, REVEAL_TX_OUTPUT_AMOUNT, ]) return { address: recipient.address, scriptPubKey: decodeHex(recipient.scriptPubKeyHex), satsAmount: BigNumber.toBigInt( { roundingMode: BigNumber.roundUp }, revealUTXOSatsAmount, ), } } export interface BitcoinPegInRecipient { type: "commitOrder" address: string scriptPubKeyHex: string tapScriptHex: `0x${string}` }