From 6a92bdc69ce33a11eae482de71c1831bfeda593e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rui=20Sim=C3=A3o?= Date: Tue, 15 Oct 2024 10:57:40 +0100 Subject: [PATCH] fix: final --- sdk/src/gateway/client.ts | 1 + sdk/src/gateway/types.ts | 2 ++ sdk/src/utils.ts | 27 --------------------------- sdk/src/wallet/utxo.ts | 8 ++++---- sdk/test/utils.test.ts | 8 ++------ sdk/test/utxo.test.ts | 4 ++++ 6 files changed, 13 insertions(+), 37 deletions(-) diff --git a/sdk/src/gateway/client.ts b/sdk/src/gateway/client.ts index 72071d4a..c03e2a46 100644 --- a/sdk/src/gateway/client.ts +++ b/sdk/src/gateway/client.ts @@ -203,6 +203,7 @@ export class GatewayApiClient { gatewayQuote.satoshis, params.fromUserPublicKey, data.opReturnHash, + params.feeRate, gatewayQuote.txProofDifficultyFactor ); } diff --git a/sdk/src/gateway/types.ts b/sdk/src/gateway/types.ts index 19965c62..61595e35 100644 --- a/sdk/src/gateway/types.ts +++ b/sdk/src/gateway/types.ts @@ -60,6 +60,8 @@ export interface GatewayQuoteParams { /** @description The percentage of fee charged by partners in Basis Points (BPS) units. This will override the default fee rate configured via platform. 1 BPS = 0.01%. The maximum value is 1000 (which equals 10%). The minimum value is 1 (which equals 0.01%). */ fee?: number; + feeRate?: number; + // NOTE: the following are new fields added by us /** @description Amount of satoshis to swap for ETH */ gasRefill?: number; diff --git a/sdk/src/utils.ts b/sdk/src/utils.ts index 186e17d9..2e61af6b 100644 --- a/sdk/src/utils.ts +++ b/sdk/src/utils.ts @@ -14,11 +14,6 @@ import { hash256 } from 'bitcoinjs-lib/src/crypto'; * @ignore */ import { Output, Transaction } from 'bitcoinjs-lib/src/transaction'; -/** - * @ignore - */ -import * as bitcoin from 'bitcoinjs-lib'; - /** * @ignore */ @@ -187,25 +182,3 @@ export function getMerkleProof(block: Block, txHash: string, forWitness?: boolea root: merkleAndRoot.root.toString('hex'), }; } - -/** - * Estimate the tx inclusion fee for N P2WPKH inputs and 3 P2WPKH outputs. - * - * @param feeRate - The current rate for inclusion, satoshi per byte. - * @param numInputs - The number of inputs to estimate for. - * @returns The estimated fee for transaction inclusion. - */ -export function estimateTxFee(feeRate: number, numInputs: number = 1) { - const tx = new bitcoin.Transaction(); - for (let i = 0; i < numInputs; i++) { - tx.addInput(Buffer.alloc(32, 0), 0, 0xfffffffd, Buffer.alloc(0)); - } - // https://github.com/interlay/interbtc-clients/blob/6bd3e81d695b93180c5aeae4f33910ad4395ff1a/bitcoin/src/light/wallet.rs#L80 - tx.ins.map((tx_input) => (tx_input.witness = [Buffer.alloc(33 + 32 + 7, 0), Buffer.alloc(33, 0)])); - tx.addOutput(Buffer.alloc(22, 0), 1000); // P2WPKH - tx.addOutput(Buffer.alloc(22, 0), 1000); // P2WPKH (change) - tx.addOutput(bitcoin.script.compile([bitcoin.opcodes.OP_RETURN, Buffer.alloc(20, 0)]), 0); - const vsize = tx.virtualSize(); - const satoshis = feeRate * vsize; - return satoshis; -} diff --git a/sdk/src/wallet/utxo.ts b/sdk/src/wallet/utxo.ts index f14ac3ba..12082fcf 100644 --- a/sdk/src/wallet/utxo.ts +++ b/sdk/src/wallet/utxo.ts @@ -2,7 +2,6 @@ import { Transaction, Script, selectUTXO, TEST_NETWORK, NETWORK, p2wpkh, p2sh } import { hex, base64 } from '@scure/base'; import { AddressType, getAddressInfo, Network } from 'bitcoin-address-validation'; import { EsploraClient, UTXO } from '../esplora'; -import { SelectionStrategy } from '@scure/btc-signer/lib/utxo'; export type BitcoinNetworkName = Exclude; @@ -70,7 +69,7 @@ export async function createBitcoinPsbt( const addressInfo = getAddressInfo(fromAddress); // TODO: possibly, allow other strategies to be passed to this function - const utxoSelectionStrategy: SelectionStrategy = 'default'; + const utxoSelectionStrategy = 'default'; if (addressInfo.network === 'regtest') { throw new Error('Bitcoin regtest not supported'); @@ -336,7 +335,7 @@ export async function estimateTxFee( let outputs: Output[] = []; // Select all UTXOs if no amount is specified // Add outputs to the transaction after all UTXOs are selected to prevent tx creation failures - let utxoSelectionStrategy: SelectionStrategy = 'all'; + let utxoSelectionStrategy = 'all'; if (amount) { // Add the target outputs to the transaction // Tx creation might fail if the requested amount is more than the available balance plus fees @@ -349,7 +348,8 @@ export async function estimateTxFee( // https://github.com/paulmillr/scure-btc-signer?tab=readme-ov-file#utxo-selection // default = exactBiggest/accumBiggest creates tx with smallest fees, but it breaks // big outputs to small ones, which in the end will create a lot of outputs close to dust. - const transaction = selectUTXO(possibleInputs, outputs, utxoSelectionStrategy, { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const transaction = selectUTXO(possibleInputs, outputs, utxoSelectionStrategy as any, { changeAddress: fromAddress, // Refund surplus to the payment address feePerByte: BigInt(Math.ceil(feeRate)), // round up to the nearest integer bip69: true, // Sort inputs and outputs according to BIP69 diff --git a/sdk/test/utils.test.ts b/sdk/test/utils.test.ts index a6cb994f..18cae26d 100644 --- a/sdk/test/utils.test.ts +++ b/sdk/test/utils.test.ts @@ -1,7 +1,7 @@ +import { Block } from 'bitcoinjs-lib'; import { assert, describe, it } from 'vitest'; import { MAINNET_ESPLORA_BASE_PATH } from '../src/esplora'; -import { Block } from 'bitcoinjs-lib'; -import { estimateTxFee, getMerkleProof } from '../src/utils'; +import { getMerkleProof } from '../src/utils'; describe('Utils Tests', () => { // NOTE: this is a bit flaky due to slow response times from electrs @@ -19,8 +19,4 @@ describe('Utils Tests', () => { root: '7cee5e99c8f0fc25fb115b7d7d00befca61f59a8544adaf3980f52132baf61ae', }); }); - - it('should estimate fee', async () => { - assert.equal(estimateTxFee(1), 172); - }); }); diff --git a/sdk/test/utxo.test.ts b/sdk/test/utxo.test.ts index 44a621b7..a9fc673e 100644 --- a/sdk/test/utxo.test.ts +++ b/sdk/test/utxo.test.ts @@ -87,17 +87,20 @@ describe('UTXO Tests', () => { // Check the transfer script to the toAddress } else if (output.amount === BigInt(amount)) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any const scriptDecoded = OutScript.decode(output.script!) as any; // Remove "p2" from the address type as it's exluced in the OutScript type assert.equal(scriptDecoded.type, addressType.slice(2)); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const address = Address(NETWORK).decode(toAddress) as any; assert.deepEqual(scriptDecoded.hash, address.hash); // Check the possible change output } else { + // eslint-disable-next-line @typescript-eslint/no-explicit-any const scriptDecoded = OutScript.decode(output.script!) as any; // Remove "p2" from the address type as it's exluced in the OutScript type @@ -256,6 +259,7 @@ describe('UTXO Tests', () => { network: NETWORK, allowUnknownOutputs: true, allowLegacyWitnessUtxo: true, + // eslint-disable-next-line @typescript-eslint/no-explicit-any dust: BigInt(546) as any, } );