11import * as assert from 'assert' ;
2+ import { varuint } from 'bitcoinjs-lib/src/bufferutils' ;
3+ import * as crypto from 'crypto' ;
24
35import {
46 createOutputScriptP2shP2pk ,
@@ -77,7 +79,10 @@ export function toUnspent(
7779 rootWalletKeys : RootWalletKeys
7880) : Unspent < bigint > {
7981 if ( input . scriptType === 'p2shP2pk' ) {
80- return mockReplayProtectionUnspent ( network , input . value , { key : rootWalletKeys [ 'user' ] , vout : index } ) ;
82+ return mockReplayProtectionUnspent ( network , input . value , {
83+ key : rootWalletKeys [ 'user' ] ,
84+ vout : index ,
85+ } ) ;
8186 } else {
8287 const chain = getInternalChainCode ( input . scriptType === 'taprootKeyPathSpend' ? 'p2trMusig2' : input . scriptType ) ;
8388 return mockWalletUnspent ( network , input . value , {
@@ -95,7 +100,10 @@ export function toUnspent(
95100 * user and backup as signer and cosigner respectively for p2trMusig2.
96101 * user and bitgo as signer and cosigner respectively for other input script types.
97102 */
98- export function getSigners ( inputType : InputScriptType ) : { signerName : KeyName ; cosignerName ?: KeyName } {
103+ export function getSigners ( inputType : InputScriptType ) : {
104+ signerName : KeyName ;
105+ cosignerName ?: KeyName ;
106+ } {
99107 return {
100108 signerName : 'user' ,
101109 cosignerName : inputType === 'p2shP2pk' ? undefined : inputType === 'p2trMusig2' ? 'backup' : 'bitgo' ,
@@ -138,7 +146,10 @@ export function signPsbtInput(
138146 if ( sign === 'fullsigned' && cosignerName && input . scriptType !== 'p2shP2pk' ) {
139147 signPsbt (
140148 psbt ,
141- ( ) => psbt . signInputHD ( inputIndex , rootWalletKeys [ cosignerName ] , { deterministic } ) ,
149+ ( ) =>
150+ psbt . signInputHD ( inputIndex , rootWalletKeys [ cosignerName ] , {
151+ deterministic,
152+ } ) ,
142153 skipNonWitnessUtxo
143154 ) ;
144155 }
@@ -161,7 +172,11 @@ export function signAllPsbtInputs(
161172) : void {
162173 const { signers, deterministic, skipNonWitnessUtxo } = params ?? { } ;
163174 inputs . forEach ( ( input , inputIndex ) => {
164- signPsbtInput ( psbt , input , inputIndex , rootWalletKeys , sign , { signers, deterministic, skipNonWitnessUtxo } ) ;
175+ signPsbtInput ( psbt , input , inputIndex , rootWalletKeys , sign , {
176+ signers,
177+ deterministic,
178+ skipNonWitnessUtxo,
179+ } ) ;
165180 } ) ;
166181}
167182
@@ -195,7 +210,9 @@ export function constructPsbt(
195210 } else {
196211 const { redeemScript } = createOutputScriptP2shP2pk ( rootWalletKeys [ signerName ] . publicKey ) ;
197212 assert ( redeemScript ) ;
198- addReplayProtectionUnspentToPsbt ( psbt , u , redeemScript , { skipNonWitnessUtxo } ) ;
213+ addReplayProtectionUnspentToPsbt ( psbt , u , redeemScript , {
214+ skipNonWitnessUtxo,
215+ } ) ;
199216 }
200217 } ) ;
201218
@@ -224,10 +241,17 @@ export function constructPsbt(
224241 psbt . setAllInputsMusig2NonceHD ( rootWalletKeys [ 'user' ] ) ;
225242 psbt . setAllInputsMusig2NonceHD ( rootWalletKeys [ 'bitgo' ] , { deterministic } ) ;
226243
227- signAllPsbtInputs ( psbt , inputs , rootWalletKeys , 'halfsigned' , { signers, skipNonWitnessUtxo } ) ;
244+ signAllPsbtInputs ( psbt , inputs , rootWalletKeys , 'halfsigned' , {
245+ signers,
246+ skipNonWitnessUtxo,
247+ } ) ;
228248
229249 if ( sign === 'fullsigned' ) {
230- signAllPsbtInputs ( psbt , inputs , rootWalletKeys , sign , { signers, deterministic, skipNonWitnessUtxo } ) ;
250+ signAllPsbtInputs ( psbt , inputs , rootWalletKeys , sign , {
251+ signers,
252+ deterministic,
253+ skipNonWitnessUtxo,
254+ } ) ;
231255 }
232256
233257 return psbt ;
@@ -261,3 +285,44 @@ export function verifyFullySignedSignatures(
261285 }
262286 } ) ;
263287}
288+
289+ /** We have a mirrored function similar to our hsm that generates our Bitcoin signed
290+ * message so that we can use for testing. This creates a random entropy as well using
291+ * the nilUUID structure to construct our uuid buffer and given our address we can
292+ * directly encode it into our message.
293+ *
294+ * @param attestationPrvKey
295+ * @param uuid
296+ * @param address
297+ * @returns
298+ */
299+ export function generatePayGoAttestationProof ( uuid : string , address : Buffer ) : Buffer {
300+ // <0x18Bitcoin Signed Message:\n
301+ const prefixByte = Buffer . from ( [ 0x18 ] ) ;
302+ const prefixMessage = Buffer . from ( 'Bitcoin Signed Message:\n' ) ;
303+ const prefixBuffer = Buffer . concat ( [ prefixByte , prefixMessage ] ) ;
304+
305+ // <ENTROPY>
306+ const entropyLength = 64 ;
307+ const entropy = crypto . randomBytes ( entropyLength ) ;
308+
309+ // <UUID>
310+ const uuidBuffer = Buffer . from ( uuid ) ;
311+ const uuidBufferLength = uuidBuffer . length ;
312+
313+ // <ADDRESS>
314+ const addressBufferLength = address . length ;
315+
316+ // <VARINT_LENGTH>
317+ const msgLength = entropyLength + addressBufferLength + uuidBufferLength ;
318+ const msgLengthBuffer = varuint . encode ( msgLength ) ;
319+
320+ // <0x18Bitcoin Signed Message:\n<LENGTH><ENTROPY><ADDRESS><UUID>
321+ const proofMessage = Buffer . concat ( [ prefixBuffer , msgLengthBuffer , entropy , address , uuidBuffer ] ) ;
322+
323+ // we sign this with the priv key
324+ // don't know what sign function to call. Since this is just a mirrored function don't know if we need
325+ // to include this part.
326+ // const signedMsg = sign(attestationPrvKey, proofMessage);
327+ return proofMessage ;
328+ }
0 commit comments