@@ -8,9 +8,35 @@ export type AddressDetails = {
88 witnessScript ?: Buffer ;
99 scriptPubKey : Buffer ;
1010} ;
11+ export const MAX_NUM_BIP322_INPUTS = 200 ;
1112
1213/**
13- * Construct the toSign PSBT for a BIP322 verification.
14+ * Create the base PSBT for the to_sign transaction for BIP322 signing.
15+ * There will be ever 1 output.
16+ */
17+ export function createBaseToSignPsbt ( rootWalletKeys ?: bitgo . RootWalletKeys ) : Psbt {
18+ // Create PSBT object for constructing the transaction
19+ const psbt = new Psbt ( ) ;
20+ // Set default value for nVersion and nLockTime
21+ psbt . setVersion ( 0 ) ; // nVersion = 0
22+ psbt . setLocktime ( 0 ) ; // nLockTime = 0
23+
24+ // Set the output
25+ psbt . addOutput ( {
26+ value : BigInt ( 0 ) , // vout[0].nValue = 0
27+ script : Buffer . from ( [ 0x6a ] ) , // vout[0].scriptPubKey = OP_RETURN
28+ } ) ;
29+
30+ // If rootWalletKeys are provided, add them to the PSBT as global xpubs
31+ if ( rootWalletKeys ) {
32+ bitgo . addXpubsToPsbt ( psbt , rootWalletKeys ) ;
33+ }
34+
35+ return psbt ;
36+ }
37+
38+ /**
39+ * Add a BIP322 input to the PSBT.
1440 * Source implementation:
1541 * https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki#full
1642 *
@@ -19,44 +45,38 @@ export type AddressDetails = {
1945 * @param {string } [tag=BIP322_TAG] - The tag to use for hashing, defaults to BIP322_TAG.
2046 * @returns {Psbt } - The hex representation of the constructed PSBT.
2147 */
22- export function buildToSignPsbt ( message : string , addressDetails : AddressDetails , tag = BIP322_TAG ) : Psbt {
48+ export function addBip322Input ( psbt : Psbt , message : string , addressDetails : AddressDetails , tag = BIP322_TAG ) : void {
2349 const toSpendTx = buildToSpendTransaction ( addressDetails . scriptPubKey , message , tag ) ;
50+ if ( psbt . data . inputs . length >= MAX_NUM_BIP322_INPUTS ) {
51+ throw new Error ( `Exceeded maximum number of BIP322 inputs (${ MAX_NUM_BIP322_INPUTS } )` ) ;
52+ }
2453
25- // Create PSBT object for constructing the transaction
26- const psbt = new Psbt ( ) ;
27- // Set default value for nVersion and nLockTime
28- psbt . setVersion ( 0 ) ; // nVersion = 0
29- psbt . setLocktime ( 0 ) ; // nLockTime = 0
30- // Set the input
3154 psbt . addInput ( {
3255 hash : toSpendTx . getId ( ) , // vin[0].prevout.hash = to_spend.txid
3356 index : 0 , // vin[0].prevout.n = 0
3457 sequence : 0 , // vin[0].nSequence = 0
3558 nonWitnessUtxo : toSpendTx . toBuffer ( ) , // previous transaction for us to rebuild later to verify
3659 } ) ;
37- psbt . updateInput ( 0 , {
60+ const inputIndex = psbt . data . inputs . length - 1 ;
61+ psbt . updateInput ( inputIndex , {
3862 witnessUtxo : { value : BigInt ( 0 ) , script : addressDetails . scriptPubKey } ,
3963 } ) ;
4064
4165 if ( addressDetails . redeemScript ) {
42- psbt . updateInput ( 0 , { redeemScript : addressDetails . redeemScript } ) ;
66+ psbt . updateInput ( inputIndex , { redeemScript : addressDetails . redeemScript } ) ;
4367 }
4468 if ( addressDetails . witnessScript ) {
45- psbt . updateInput ( 0 , { witnessScript : addressDetails . witnessScript } ) ;
69+ psbt . updateInput ( inputIndex , {
70+ witnessScript : addressDetails . witnessScript ,
71+ } ) ;
4672 }
4773
4874 // Add the message as a proprietary key value to the PSBT so we can verify it later
49- addBip322ProofMessage ( psbt , 0 , Buffer . from ( message ) ) ;
50-
51- // Set the output
52- psbt . addOutput ( {
53- value : BigInt ( 0 ) , // vout[0].nValue = 0
54- script : Buffer . from ( [ 0x6a ] ) , // vout[0].scriptPubKey = OP_RETURN
55- } ) ;
56- return psbt ;
75+ addBip322ProofMessage ( psbt , inputIndex , Buffer . from ( message ) ) ;
5776}
5877
59- export function buildToSignPsbtForChainAndIndex (
78+ export function addBip322InputWithChainAndIndex (
79+ psbt : Psbt ,
6080 message : string ,
6181 rootWalletKeys : bitgo . RootWalletKeys ,
6282 chain : bitgo . ChainCode ,
@@ -68,17 +88,17 @@ export function buildToSignPsbtForChainAndIndex(
6888 const walletKeys = rootWalletKeys . deriveForChainAndIndex ( chain , index ) ;
6989 const output = bitgo . outputScripts . createOutputScript2of3 ( walletKeys . publicKeys , bitgo . scriptTypeForChain ( chain ) ) ;
7090
71- const psbt = buildToSignPsbt ( message , {
91+ addBip322Input ( psbt , message , {
7292 scriptPubKey : output . scriptPubKey ,
7393 redeemScript : output . redeemScript ,
7494 witnessScript : output . witnessScript ,
7595 } ) ;
7696
97+ const inputIndex = psbt . data . inputs . length - 1 ;
7798 psbt . updateInput (
78- 0 ,
99+ inputIndex ,
79100 bitgo . getPsbtBip32DerivationOutputUpdate ( rootWalletKeys , walletKeys , bitgo . scriptTypeForChain ( chain ) )
80101 ) ;
81- bitgo . addXpubsToPsbt ( psbt , rootWalletKeys ) ;
82102
83103 return psbt ;
84104}
0 commit comments