@@ -19,9 +19,11 @@ import {
1919 StandardUnlockableUtxo ,
2020 VmResourceUsage ,
2121 isContractUnlocker ,
22+ isPlaceholderUnlocker ,
2223 BchChangeOutputOptions ,
2324 TokenChangeOutputOptions ,
2425} from './interfaces.js' ;
26+ import { PLACEHOLDER_P2PKH_UNLOCKING_SIZE } from './constants.js' ;
2527import { NetworkProvider } from './network/index.js' ;
2628import {
2729 calculateDust ,
@@ -278,12 +280,19 @@ export class TransactionBuilder {
278280
279281 /**
280282 * Build the transaction (skipping fee and burn checks) and return its encoded byte length.
283+ * Inputs with a placeholder unlocker are counted at the size they take up once the wallet signs them.
281284 *
282285 * @returns The size of the transaction in bytes.
283286 */
284287 getTransactionSize ( ) : bigint {
285288 const transaction = this . buildLibauthTransaction ( true ) ;
286- return BigInt ( encodeTransaction ( transaction ) . byteLength ) ;
289+ return BigInt ( this . getEncodedTransactionSize ( transaction ) ) ;
290+ }
291+
292+ // Placeholder unlockers serialise as an empty unlocking script, so their eventual signed size is added here
293+ private getEncodedTransactionSize ( transaction : LibauthTransaction ) : number {
294+ const placeholderInputCount = this . inputs . filter ( ( input ) => isPlaceholderUnlocker ( input . unlocker ) ) . length ;
295+ return encodeTransaction ( transaction ) . byteLength + placeholderInputCount * PLACEHOLDER_P2PKH_UNLOCKING_SIZE ;
287296 }
288297
289298 /**
@@ -561,7 +570,7 @@ export class TransactionBuilder {
561570 private checkFee ( transaction : LibauthTransaction ) : void {
562571 const totalInputAmount = this . inputs . reduce ( ( total , input ) => total + input . satoshis , 0n ) ;
563572 const totalOutputAmount = this . outputs . reduce ( ( total , output ) => total + output . amount , 0n ) ;
564- const transactionSize = encodeTransaction ( transaction ) . byteLength ;
573+ const transactionSize = this . getEncodedTransactionSize ( transaction ) ;
565574
566575 const fee = totalInputAmount - totalOutputAmount ;
567576 const feePerByte = Number ( ( Number ( fee ) / transactionSize ) . toFixed ( 2 ) ) ;
@@ -623,7 +632,7 @@ export class TransactionBuilder {
623632 }
624633
625634 private checkTransactionSize ( transaction : LibauthTransaction ) : void {
626- const transactionSize = encodeTransaction ( transaction ) . byteLength ;
635+ const transactionSize = this . getEncodedTransactionSize ( transaction ) ;
627636
628637 const TX_MAX_STANDARD_SIZE = 100_000 ;
629638 if ( transactionSize > TX_MAX_STANDARD_SIZE ) {
0 commit comments