diff --git a/package.json b/package.json index 783a0e9..b51aff1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "dlc-btc-lib", - "version": "1.0.7", + "version": "1.0.9", "description": "This library provides a comprehensive set of interfaces and functions for minting dlcBTC tokens on supported blockchains.", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/functions/bitcoin/bitcoin-functions.ts b/src/functions/bitcoin/bitcoin-functions.ts index 8b839dc..4bccae9 100644 --- a/src/functions/bitcoin/bitcoin-functions.ts +++ b/src/functions/bitcoin/bitcoin-functions.ts @@ -15,6 +15,7 @@ import { taprootTweakPubkey } from '@scure/btc-signer/utils'; import { BIP32Factory, BIP32Interface } from 'bip32'; import { Network } from 'bitcoinjs-lib'; import { bitcoin, regtest, testnet } from 'bitcoinjs-lib/src/networks.js'; +import { Decimal } from 'decimal.js'; import * as ellipticCurveCryptography from 'tiny-secp256k1'; import { @@ -33,6 +34,11 @@ const ECDSA_PUBLIC_KEY_LENGTH = 33; const bip32 = BIP32Factory(ellipticCurveCryptography); +export function getFeeAmount(bitcoinAmount: number, feeBasisPoints: number): number { + const feePercentage = new Decimal(feeBasisPoints).dividedBy(100); + return new Decimal(bitcoinAmount).times(feePercentage.dividedBy(100)).toNumber(); +} + /** * Derives the Public Key at the Unhardened Path (0/0) from a given Extended Public Key. * @param extendedPublicKey - The base58-encoded Extended Public Key. diff --git a/src/functions/bitcoin/psbt-functions.ts b/src/functions/bitcoin/psbt-functions.ts index e615b07..4fb468b 100644 --- a/src/functions/bitcoin/psbt-functions.ts +++ b/src/functions/bitcoin/psbt-functions.ts @@ -1,5 +1,5 @@ import { hexToBytes } from '@noble/hashes/utils'; -import { p2wpkh, selectUTXO } from '@scure/btc-signer'; +import { selectUTXO } from '@scure/btc-signer'; import { P2Ret, P2TROut } from '@scure/btc-signer/payment'; import { Network, Psbt } from 'bitcoinjs-lib'; import { PartialSignature } from 'ledger-bitcoin/build/main/lib/appClient.js'; @@ -8,6 +8,7 @@ import { BitcoinInputSigningConfig, PaymentTypes } from '../../models/bitcoin-mo import { reverseBytes } from '../../utilities/index.js'; import { ecdsaPublicKeyToSchnorr, + getFeeAmount, getFeeRecipientAddressFromPublicKey, getUTXOs, } from '../bitcoin/bitcoin-functions.js'; @@ -35,7 +36,7 @@ export async function createFundingTransaction( bitcoinBlockchainAPIURL: string ): Promise { const feeAddress = getFeeRecipientAddressFromPublicKey(feePublicKey, bitcoinNetwork); - const feeRecipientOutputValue = bitcoinAmount / feeBasisPoints; + const feeAmount = getFeeAmount(Number(bitcoinAmount), Number(feeBasisPoints)); const userUTXOs = await getUTXOs(bitcoinNativeSegwitTransaction, bitcoinBlockchainAPIURL); @@ -43,7 +44,7 @@ export async function createFundingTransaction( { address: multisigAddress, amount: bitcoinAmount }, { address: feeAddress, - amount: feeRecipientOutputValue, + amount: BigInt(feeAmount), }, ]; @@ -59,6 +60,10 @@ export async function createFundingTransaction( if (!fundingTX) throw new Error('Could not create Funding Transaction'); + fundingTX.updateInput(0, { + sequence: 0xfffffff0, + }); + const fundingPSBT = fundingTX.toPSBT(); return fundingPSBT; @@ -89,10 +94,8 @@ export function createClosingTransaction( feePublicKey: string, feeBasisPoints: bigint ): Uint8Array { - const feePublicKeyBuffer = Buffer.from(feePublicKey, 'hex'); - const { address: feeAddress } = p2wpkh(feePublicKeyBuffer, bitcoinNetwork); - - if (!feeAddress) throw new Error('Could not create Fee Address'); + const feeAddress = getFeeRecipientAddressFromPublicKey(feePublicKey, bitcoinNetwork); + const feeAmount = getFeeAmount(Number(bitcoinAmount), Number(feeBasisPoints)); const inputs = [ { @@ -109,7 +112,7 @@ export function createClosingTransaction( const outputs = [ { address: feeAddress, - amount: bitcoinAmount / feeBasisPoints, + amount: BigInt(feeAmount), }, ]; @@ -121,9 +124,15 @@ export function createClosingTransaction( network: bitcoinNetwork, }); - if (!selected?.tx) throw new Error('Could not create Closing Transaction'); + const closingTX = selected?.tx; + + if (!closingTX) throw new Error('Could not create Closing Transaction'); + + closingTX.updateInput(0, { + sequence: 0xfffffff0, + }); - const closingPSBT = selected.tx.toPSBT(); + const closingPSBT = closingTX.toPSBT(); return closingPSBT; }