@@ -6,31 +6,53 @@ import {
66 GroupedAddress ,
77 KeyRole
88} from './types' ;
9+ import {
10+ BIP32_PUBLIC_KEY_HASH_LENGTH ,
11+ Bip32Ed25519 ,
12+ Blake2b ,
13+ Ed25519PublicKeyHex ,
14+ SodiumBip32Ed25519 ,
15+ blake2b
16+ } from '@cardano-sdk/crypto' ;
917import { Cardano } from '@cardano-sdk/core' ;
10- import { Hash28ByteBase16 } from '@cardano-sdk/crypto' ;
1118
1219type Bip32AccountProps = {
1320 extendedAccountPublicKey : Crypto . Bip32PublicKeyHex ;
1421 accountIndex : number ;
1522 chainId : Cardano . ChainId ;
1623} ;
1724
25+ type Bip32AccountDependencies = {
26+ bip32Ed25519 : Pick < Bip32Ed25519 , 'derivePublicKey' > ;
27+ blake2b : Blake2b ;
28+ } ;
29+
1830/** Derives public keys and addresses from a BIP32-ED25519 public key */
1931export class Bip32Account {
20- readonly extendedAccountPublicKey : Crypto . Bip32PublicKey ;
32+ readonly extendedAccountPublicKeyHex : Crypto . Bip32PublicKeyHex ;
2133 readonly chainId : Cardano . ChainId ;
2234 readonly accountIndex : number ;
35+ readonly #bip32Ed25519: Bip32AccountDependencies [ 'bip32Ed25519' ] ;
36+ readonly #blake2b: Blake2b ;
2337
2438 /** Initializes a new instance of the Bip32Ed25519AddressManager class. */
25- constructor ( { extendedAccountPublicKey, chainId, accountIndex } : Bip32AccountProps ) {
26- this . extendedAccountPublicKey = Crypto . Bip32PublicKey . fromHex ( extendedAccountPublicKey ) ;
39+ constructor (
40+ { extendedAccountPublicKey, chainId, accountIndex } : Bip32AccountProps ,
41+ dependencies : Bip32AccountDependencies
42+ ) {
43+ this . extendedAccountPublicKeyHex = extendedAccountPublicKey ;
44+ this . #bip32Ed25519 = dependencies . bip32Ed25519 ;
45+ this . #blake2b = dependencies . blake2b ;
2746 this . chainId = chainId ;
2847 this . accountIndex = accountIndex ;
2948 }
3049
3150 async derivePublicKey ( derivationPath : AccountKeyDerivationPath ) {
32- const key = await this . extendedAccountPublicKey . derive ( [ derivationPath . role , derivationPath . index ] ) ;
33- return key . toRawKey ( ) ;
51+ const extendedKey = this . #bip32Ed25519. derivePublicKey ( this . extendedAccountPublicKeyHex , [
52+ derivationPath . role ,
53+ derivationPath . index
54+ ] ) ;
55+ return Ed25519PublicKeyHex . fromBip32PublicKey ( extendedKey ) ;
3456 }
3557
3658 async deriveAddress (
@@ -47,16 +69,16 @@ export class Bip32Account {
4769 role : Number ( paymentKeyDerivationPath . type )
4870 } ) ;
4971
50- const derivedPublicPaymentKeyHash = await derivedPublicPaymentKey . hash ( ) ;
72+ const derivedPublicPaymentKeyHash = this . #blake2b . hash ( derivedPublicPaymentKey , BIP32_PUBLIC_KEY_HASH_LENGTH ) ;
5173
5274 const publicStakeKey = await this . derivePublicKey ( stakeKeyDerivationPath ) ;
53- const publicStakeKeyHash = await publicStakeKey . hash ( ) ;
75+ const publicStakeKeyHash = this . #blake2b . hash ( publicStakeKey , BIP32_PUBLIC_KEY_HASH_LENGTH ) ;
5476
55- const stakeCredential = { hash : Hash28ByteBase16 ( publicStakeKeyHash . hex ( ) ) , type : Cardano . CredentialType . KeyHash } ;
77+ const stakeCredential = { hash : publicStakeKeyHash , type : Cardano . CredentialType . KeyHash } ;
5678
5779 const address = Cardano . BaseAddress . fromCredentials (
5880 this . chainId . networkId ,
59- { hash : Hash28ByteBase16 ( derivedPublicPaymentKeyHash . hex ( ) ) , type : Cardano . CredentialType . KeyHash } ,
81+ { hash : derivedPublicPaymentKeyHash , type : Cardano . CredentialType . KeyHash } ,
6082 stakeCredential
6183 ) . toAddress ( ) ;
6284
@@ -72,16 +94,30 @@ export class Bip32Account {
7294 } ;
7395 }
7496
97+ static async createDefaultDependencies ( ) : Promise < Bip32AccountDependencies > {
98+ return {
99+ bip32Ed25519 : await SodiumBip32Ed25519 . create ( ) ,
100+ blake2b
101+ } ;
102+ }
103+
75104 /**
76105 * Creates a new instance of the Bip32Ed25519AddressManager class.
77106 *
78107 * @param keyAgent The key agent that will be used to derive addresses.
79108 */
80- static async fromAsyncKeyAgent ( keyAgent : AsyncKeyAgent ) : Promise < Bip32Account > {
81- return new Bip32Account ( {
82- accountIndex : await keyAgent . getAccountIndex ( ) ,
83- chainId : await keyAgent . getChainId ( ) ,
84- extendedAccountPublicKey : await keyAgent . getExtendedAccountPublicKey ( )
85- } ) ;
109+ static async fromAsyncKeyAgent (
110+ keyAgent : AsyncKeyAgent ,
111+ dependencies ?: Bip32AccountDependencies
112+ ) : Promise < Bip32Account > {
113+ dependencies ||= await Bip32Account . createDefaultDependencies ( ) ;
114+ return new Bip32Account (
115+ {
116+ accountIndex : await keyAgent . getAccountIndex ( ) ,
117+ chainId : await keyAgent . getChainId ( ) ,
118+ extendedAccountPublicKey : await keyAgent . getExtendedAccountPublicKey ( )
119+ } ,
120+ dependencies
121+ ) ;
86122 }
87123}
0 commit comments