1
1
import * as assert from 'assert'
2
- import { testutil , networks } from 'modules/utxo-lib/src' ;
3
- import { addPaygoAddressProof , verifyPaygoAddressProof , getPaygoAddressProofIndex } from "modules/utxo-lib/src/bitgo/psbt/paygoAddressProof" ;
4
- import { getDefaultWalletKeys , inputScriptTypes , outputScriptTypes } from 'modules/utxo-lib/src/testutil' ;
5
-
6
- import { SignatureTargetType } from './Psbt' ;
7
- import { PSBT_PROPRIETARY_IDENTIFIER , UtxoPsbt } from 'modules/utxo-lib/src/bitgo' ;
8
2
import { decodeProprietaryKey } from 'bip174/src/lib/proprietaryKeyVal' ;
9
3
import { KeyValue } from 'bip174/src/lib/interfaces' ;
4
+ import { checkForOutput } from 'bip174/src/lib/utils' ;
5
+
6
+ import { bip32 , networks , testutil } from '../../../src'
7
+ import { addPaygoAddressProof , verifyPaygoAddressProof , getPaygoAddressProofIndex , psbtIncludesPaygoAddressProof } from "../../../src/bitgo/psbt/paygoAddressProof" ;
8
+ import { inputScriptTypes , outputScriptTypes } from '../../../src/testutil' ;
9
+ import { ProprietaryKeySubtype , PSBT_PROPRIETARY_IDENTIFIER , RootWalletKeys } from '../../../src/bitgo' ;
10
+
10
11
11
12
const network = networks . bitcoin ;
12
- const rootWalletKeys = getDefaultWalletKeys ( ) ;
13
+ const keys = [ 1 , 2 , 3 ] . map ( ( v ) => bip32 . fromSeed ( Buffer . alloc ( 16 , `test/2/${ v } ` ) , network ) )
14
+ const rootWalletKeys = new RootWalletKeys ( [ keys [ 0 ] , keys [ 1 ] , keys [ 2 ] ] )
15
+ const dummyKey1 = rootWalletKeys . deriveForChainAndIndex ( 50 , 200 ) ;
16
+ const dummyKey2 = rootWalletKeys . deriveForChainAndIndex ( 60 , 201 ) ;
17
+ const dumm1yXPubs = dummyKey1 . publicKeys ;
18
+ const dummy1PubKey = dummyKey1 . user . publicKey ;
13
19
14
20
const psbtInputs = inputScriptTypes . map ( ( scriptType ) => ( { scriptType, value : BigInt ( 1000 ) } ) )
15
21
const psbtOutputs = outputScriptTypes . map ( ( scriptType ) => ( { scriptType, value : BigInt ( 900 ) } ) )
16
- const sig = 'paygoaddresssig'
22
+ const sig = dummyKey1 . user . privateKey ! ;
23
+ const sig2 = dummyKey2 . user . privateKey ! ;
17
24
18
- function getTestPsbt ( inputs : testutil . Input [ ] , outputs : testutil . Output [ ] , signed : SignatureTargetType ) {
25
+ function getTestPsbt ( ) {
19
26
return testutil . constructPsbt (
20
- inputs , outputs , network , rootWalletKeys , signed
27
+ psbtInputs , psbtOutputs , network , rootWalletKeys , 'unsigned'
21
28
)
22
29
}
23
30
24
- function addPaygoAddressProofToPsbt ( index : number , hasInput : boolean , hasOutput : boolean ) : UtxoPsbt {
25
- // will update this function accordingly, just have this for now to help to simple testing
26
- const psbt = getTestPsbt ( hasInput ? psbtInputs : [ ] , hasOutput ? psbtOutputs : [ ] , hasInput && hasOutput ? 'unsigned' : 'fullsigned' ) ;
27
- addPaygoAddressProof ( psbt , index , Buffer . from ( sig ) ) ;
28
- return psbt ;
29
- }
30
-
31
- describe ( 'addPaygoAddressProof function' , ( ) => {
31
+ describe ( 'addPaygoAddressProof and verifyPaygoAddressProof' , ( ) => {
32
32
function getPaygoProprietaryKey ( proprietaryKeyVals : KeyValue [ ] ) {
33
33
return proprietaryKeyVals . map ( ( { key, value} ) => {
34
34
return { key : decodeProprietaryKey ( key ) , value } ;
35
35
} ) . filter ( ( keyValue ) => {
36
- return keyValue . key . identifier === PSBT_PROPRIETARY_IDENTIFIER && keyValue . value === Buffer . from ( sig )
36
+ return keyValue . key . identifier === PSBT_PROPRIETARY_IDENTIFIER && keyValue . key . subtype === ProprietaryKeySubtype . PAYGO_ADDRESS_PROOF
37
37
} ) ;
38
38
}
39
- it ( 'should add PayGo Address proof to empty PSBT' , ( ) => {
40
- const inputIndex = 0 ;
41
- const psbt = getTestPsbt ( [ ] , [ ] , 'unsigned' ) ;
42
- // better sig test replacement, i just have random string as test
43
- addPaygoAddressProof ( psbt , inputIndex , Buffer . from ( sig ) ) ;
44
- const proprietaryKeyVals = psbt . data . globalMap . unknownKeyVals ;
45
- assert ( proprietaryKeyVals )
46
- // I assume that the proprietaryKeyVal should be properly added
47
- // to the unknownKeyVals globalmap
48
- const proofInPsbt = getPaygoProprietaryKey ( proprietaryKeyVals )
49
- assert ( proofInPsbt . length === 1 ) ;
50
- } ) ;
51
39
52
- it ( ' should add Paygo Adress Proof to non-empty PSBT' , ( ) => {
53
- const inputIndex = 0 ;
54
- const psbt = getTestPsbt ( psbtInputs , psbtOutputs , 'fullsigned' ) ;
55
- addPaygoAddressProof ( psbt , inputIndex , Buffer . from ( sig ) ) ;
56
- const proprietaryKeyVals = psbt . data . globalMap . unknownKeyVals ;
57
- assert ( proprietaryKeyVals ) ;
58
- const proofInPsbt = getPaygoProprietaryKey ( proprietaryKeyVals ) ;
59
- assert ( proofInPsbt . length === 1 ) ;
40
+ it ( " should fail a proof verification if the proof isn't valid" , ( ) => {
41
+ const outputIndex = 0 ;
42
+ const psbt = getTestPsbt ( ) ;
43
+ addPaygoAddressProof ( psbt , outputIndex , Buffer . from ( sig ) , dummy1PubKey ) ;
44
+ const output = checkForOutput ( psbt . data . outputs , outputIndex ) ;
45
+ const proofInPsbt = getPaygoProprietaryKey ( output . unknownKeyVals ! ) ;
46
+ assert ( proofInPsbt . length === 1 )
47
+ assert . throws ( ( ) => verifyPaygoAddressProof ( psbt , 0 , dummyKey2 . user . publicKey ) , ( e : any ) => e . message === 'Cannot verify the paygo address signature with the provided pubkey.' ) ;
60
48
} ) ;
61
49
62
- // do we have an error check with the original addProprietaryKeyValToInput
63
- // to see if there are duplicates of the same? if not I will add the test case here.
64
- } )
65
-
66
-
67
- describe ( 'verifyPaygoAddressProof' , ( ) => {
68
- const pubkey = 'pubkeytestforpaygopsbt'
69
-
70
- it ( 'should verify a valid PayGo address proof' , ( ) => {
71
- const indexInput = 0 ;
72
- const psbt = addPaygoAddressProofToPsbt ( indexInput , false , false ) ;
73
- verifyPaygoAddressProof ( psbt , 0 , Buffer . from ( pubkey ) )
74
- // nothing happens if verification is successful
50
+ it ( "should add and verify a valid paygo address proof on the PSBT" , ( ) => {
51
+ const outputIndex = 0 ;
52
+ const psbt = getTestPsbt ( ) ;
53
+ addPaygoAddressProof ( psbt , outputIndex , Buffer . from ( sig ) , dummy1PubKey ) ;
54
+ // should verify function return a boolean? that way we can assert
55
+ // if this is verified, throws an error otherwise or false + error msg as an object
56
+ verifyPaygoAddressProof ( psbt , outputIndex , dummy1PubKey ) ;
75
57
} ) ;
76
58
77
- it ( 'should throw an error if there is no PayGo address in PSBT' , ( ) => {
78
- const psbt = getTestPsbt ( psbtInputs , psbtOutputs , 'fullsigned' ) ;
79
- assert . throws ( ( ) => verifyPaygoAddressProof ( psbt , 0 , Buffer . from ( pubkey ) ) , ( e : any ) => e . message === 'here is no paygo address proof encoded in the PSBT.' )
59
+ it ( "should throw an error if there are multiple PayGo proprietary keys in the PSBT" , ( ) => {
60
+ const outputIndex = 0 ;
61
+ const psbt = getTestPsbt ( ) ;
62
+ addPaygoAddressProof ( psbt , outputIndex , Buffer . from ( sig ) , dummy1PubKey ) ;
63
+ addPaygoAddressProof ( psbt , outputIndex , Buffer . from ( sig2 ) , dummy1PubKey ) ;
64
+ const output = checkForOutput ( psbt . data . outputs , outputIndex ) ;
65
+ const proofInPsbt = getPaygoProprietaryKey ( output . unknownKeyVals ! ) ;
66
+ assert ( proofInPsbt . length !== 0 )
67
+ assert ( proofInPsbt . length <= 1 )
68
+ assert . throws ( ( ) => verifyPaygoAddressProof ( psbt , outputIndex , dummy1PubKey ) , ( e : any ) => e . message === 'There are multiple paygo address proofs encoded in the PSBT. Something went wrong.' ) ;
80
69
} ) ;
70
+ } ) ;
81
71
82
- it ( 'should throw an error if there is multiple PayGo address in PSBT' , ( ) => {
83
- const psbt = getTestPsbt ( psbtInputs , psbtOutputs , 'fullsigned' ) ;
84
- const sig2 = 'paygoaddresssig2'
85
- addPaygoAddressProof ( psbt , 0 , Buffer . from ( sig ) )
86
- addPaygoAddressProof ( psbt , 1 , Buffer . from ( sig2 ) )
87
- assert . throws ( ( ) => verifyPaygoAddressProof ( psbt , 0 , Buffer . from ( pubkey ) ) , ( e : any ) => e . message === 'There are multiple paygo address proofs encoded in the PSBT. Something went wrong.' )
88
- } ) ;
89
72
90
- // Once we think of what message should be signing, we can generate a test case
91
- // to test this error message properly
92
- it ( 'should throw an error if the verification fails' , ( ) => {
93
- const psbt = addPaygoAddressProofToPsbt ( 0 , false , false ) ;
94
- assert . throws ( ( ) => verifyPaygoAddressProof ( psbt , 0 , Buffer . from ( pubkey + 's' ) ) , ( e : any ) => e . message === 'Cannot verify the paygo address signature with the provided pubkey.' )
73
+ describe ( 'verifyPaygoAddressProof' , ( ) => {
74
+ it ( 'should throw an error if there is no PayGo address in PSBT' , ( ) => {
75
+ const psbt = getTestPsbt ( ) ;
76
+ assert . throws ( ( ) => verifyPaygoAddressProof ( psbt , 0 , dummy1PubKey ) , ( e : any ) => e . message === 'here is no paygo address proof encoded in the PSBT.' ) ;
95
77
} ) ;
96
78
} ) ;
97
79
98
80
describe ( 'getPaygoAddressProofIndex' , ( ) => {
99
- it ( 'should get PayGo address proof index from PSBT' , ( ) => {
81
+ it ( 'should get PayGo address proof index from PSBT if there is one' , ( ) => {
82
+ const psbt = getTestPsbt ( ) ;
83
+ const outputIndex = 0 ;
84
+ addPaygoAddressProof ( psbt , outputIndex , Buffer . from ( sig ) , dummy1PubKey ) ;
85
+ assert ( psbtIncludesPaygoAddressProof ( psbt ) ) ;
86
+ assert ( getPaygoAddressProofIndex ( psbt ) === 1 )
87
+ } ) ;
88
+
89
+ it ( "should return undefined if there is no PayGo address proof in PSBT" , ( ) => {
90
+ const psbt = getTestPsbt ( ) ;
91
+ assert ( getPaygoAddressProofIndex ( psbt ) === undefined )
92
+ assert ( ! psbtIncludesPaygoAddressProof ( psbt ) )
100
93
} ) ;
101
94
} ) ;
0 commit comments