@@ -7,7 +7,7 @@ import assert from 'assert';
77
88import buildDebug from 'debug' ;
99import { BIP32 , message } from '@bitgo/wasm-utxo' ;
10- import { BitGoBase , decryptKeychainPrivateKey , KeyIndices } from '@bitgo/sdk-core' ;
10+ import { BitGoBase , decryptKeychainPrivateKey , decryptKeychainPrivateKeyAsync , KeyIndices } from '@bitgo/sdk-core' ;
1111
1212import { VerifyKeySignaturesOptions , VerifyUserPublicKeyOptions } from './abstractUtxoCoin' ;
1313import { ParsedTransaction } from './transaction/types' ;
@@ -81,39 +81,65 @@ export function verifyCustomChangeKeySignatures<TNumber extends number | bigint>
8181 return true ;
8282}
8383
84+ function verifyUserPublicKeyWithPrv (
85+ userKeychain : NonNullable < VerifyUserPublicKeyOptions [ 'userKeychain' ] > ,
86+ userPrv : string | undefined ,
87+ disableNetworking : boolean | undefined
88+ ) : boolean {
89+ const userPub = userKeychain . pub ;
90+
91+ if ( ! userPrv ) {
92+ const errorMessage = 'user private key unavailable for verification' ;
93+ if ( disableNetworking ) {
94+ console . log ( errorMessage ) ;
95+ return false ;
96+ } else {
97+ throw new Error ( errorMessage ) ;
98+ }
99+ }
100+
101+ const userPrivateKey = BIP32 . fromBase58 ( userPrv ) ;
102+ if ( userPrivateKey . toBase58 ( ) === userPrivateKey . neutered ( ) . toBase58 ( ) ) {
103+ throw new Error ( 'user private key is only public' ) ;
104+ }
105+ if ( userPrivateKey . neutered ( ) . toBase58 ( ) !== userPub ) {
106+ throw new Error ( 'user private key does not match public key' ) ;
107+ }
108+
109+ return true ;
110+ }
111+
84112/**
85- * Decrypt the wallet's user private key and verify that the claimed public key matches
113+ * TODO: Deprecate in favor of verifyUserPublicKeyAsync once v2 encryption is default.
114+ * Decrypt the wallet's user private key and verify that the claimed public key matches (sync, v1 only).
86115 */
87116export function verifyUserPublicKey ( bitgo : BitGoBase , params : VerifyUserPublicKeyOptions ) : boolean {
88117 const { userKeychain, txParams, disableNetworking } = params ;
89118 if ( ! userKeychain ) {
90119 throw new Error ( 'user keychain is required' ) ;
91120 }
92121
93- const userPub = userKeychain . pub ;
94-
95122 let userPrv = userKeychain . prv ;
96123 if ( ! userPrv && txParams . walletPassphrase ) {
97124 userPrv = decryptKeychainPrivateKey ( bitgo , userKeychain , txParams . walletPassphrase ) ;
98125 }
99126
100- if ( ! userPrv ) {
101- const errorMessage = 'user private key unavailable for verification' ;
102- if ( disableNetworking ) {
103- console . log ( errorMessage ) ;
104- return false ;
105- } else {
106- throw new Error ( errorMessage ) ;
107- }
108- } else {
109- const userPrivateKey = BIP32 . fromBase58 ( userPrv ) ;
110- if ( userPrivateKey . toBase58 ( ) === userPrivateKey . neutered ( ) . toBase58 ( ) ) {
111- throw new Error ( 'user private key is only public' ) ;
112- }
113- if ( userPrivateKey . neutered ( ) . toBase58 ( ) !== userPub ) {
114- throw new Error ( 'user private key does not match public key' ) ;
115- }
127+ return verifyUserPublicKeyWithPrv ( userKeychain , userPrv , disableNetworking ) ;
128+ }
129+
130+ /**
131+ * Async version of verifyUserPublicKey with v2 encrypt/decrypt support.
132+ */
133+ export async function verifyUserPublicKeyAsync ( bitgo : BitGoBase , params : VerifyUserPublicKeyOptions ) : Promise < boolean > {
134+ const { userKeychain, txParams, disableNetworking } = params ;
135+ if ( ! userKeychain ) {
136+ throw new Error ( 'user keychain is required' ) ;
116137 }
117138
118- return true ;
139+ let userPrv = userKeychain . prv ;
140+ if ( ! userPrv && txParams . walletPassphrase ) {
141+ userPrv = await decryptKeychainPrivateKeyAsync ( bitgo , userKeychain , txParams . walletPassphrase ) ;
142+ }
143+
144+ return verifyUserPublicKeyWithPrv ( userKeychain , userPrv , disableNetworking ) ;
119145}
0 commit comments