@@ -32,7 +32,7 @@ import { Cardano } from '@cardano-sdk/core';
32
32
import { CommunicationType , emip3encrypt , util } from '@cardano-sdk/key-management' ;
33
33
import { HexBlob } from '@cardano-sdk/util' ;
34
34
import { SodiumBip32Ed25519 } from '@cardano-sdk/crypto' ;
35
- import { combineLatest , firstValueFrom , of } from 'rxjs' ;
35
+ import { combineLatest , firstValueFrom , merge , of } from 'rxjs' ;
36
36
import { runtime } from 'webextension-polyfill' ;
37
37
38
38
const delegationConfig = {
@@ -222,6 +222,18 @@ const signerManager = new SignerManager(
222
222
}
223
223
) ;
224
224
225
+ const passphraseByteArray = Uint8Array . from (
226
+ env . KEY_MANAGEMENT_PARAMS . passphrase . split ( '' ) . map ( ( letter ) => letter . charCodeAt ( 0 ) )
227
+ ) ;
228
+ merge ( signerManager . signDataRequest$ , signerManager . transactionWitnessRequest$ ) . subscribe ( ( req ) => {
229
+ if ( req . walletType === WalletType . InMemory ) {
230
+ req . sign ( passphraseByteArray ) ;
231
+ } else {
232
+ req . sign ( ) ;
233
+ }
234
+ logger . info ( 'Signed' , req ) ;
235
+ } ) ;
236
+
225
237
// Expose signer manager.
226
238
exposeSignerManagerApi (
227
239
{
@@ -230,7 +242,9 @@ exposeSignerManagerApi(
230
242
{ logger, runtime }
231
243
) ;
232
244
233
- const walletManager = new WalletManagerUi ( { walletName } , { logger, runtime } ) ;
245
+ type Metadata = { name : string } ;
246
+ // TODO: toSerializableObj does not support serializing empty obj {}
247
+ const walletManager = new WalletManagerUi < Metadata > ( { walletName } , { logger, runtime } ) ;
234
248
235
249
// Wallet object does not change when wallets are activated/deactivated.
236
250
// Instead, it's observable properties emit from the currently active wallet.
@@ -253,40 +267,50 @@ wallet.delegation.distribution$.subscribe((delegationDistrib) => {
253
267
}
254
268
} ) ;
255
269
256
- const createWallet = async ( accountIndex : number ) => {
257
- logger . log ( 'creating wallet' ) ;
258
- clearWalletValues ( ) ;
259
- const bip32Ed25519 = new SodiumBip32Ed25519 ( ) ;
260
- const passphraseByteArray = Uint8Array . from (
261
- env . KEY_MANAGEMENT_PARAMS . passphrase . split ( '' ) . map ( ( letter ) => letter . charCodeAt ( 0 ) )
262
- ) ;
263
- const entropy = Buffer . from ( util . mnemonicWordsToEntropy ( env . KEY_MANAGEMENT_PARAMS . mnemonic . split ( ' ' ) ) , 'hex' ) ;
264
- const rootPrivateKey = await bip32Ed25519 . fromBip39Entropy ( entropy , env . KEY_MANAGEMENT_PARAMS . passphrase ) ;
265
- const encryptedRootPrivateKey = await emip3encrypt ( Buffer . from ( rootPrivateKey , 'hex' ) , passphraseByteArray ) ;
266
- const encryptedEntropy = await emip3encrypt ( entropy , passphraseByteArray ) ;
267
-
268
- const accountPrivateKey = await util . deriveAccountPrivateKey ( {
269
- accountIndex,
270
- bip32Ed25519,
271
- rootPrivateKey
272
- } ) ;
270
+ const createWalletIfNotExistsAndActivate = async ( accountIndex : number ) => {
271
+ const wallets = await firstValueFrom ( walletManager . repository . wallets$ ) ;
272
+ let walletId = wallets . find (
273
+ ( w ) => w . type !== WalletType . Script && w . accounts . some ( ( a ) => a . accountIndex === accountIndex )
274
+ ) ?. walletId ;
275
+ if ( ! walletId ) {
276
+ logger . log ( 'creating wallet' ) ;
277
+ clearWalletValues ( ) ;
278
+ const bip32Ed25519 = new SodiumBip32Ed25519 ( ) ;
279
+ const entropy = Buffer . from ( util . mnemonicWordsToEntropy ( env . KEY_MANAGEMENT_PARAMS . mnemonic . split ( ' ' ) ) , 'hex' ) ;
280
+ const rootPrivateKey = await bip32Ed25519 . fromBip39Entropy ( entropy , env . KEY_MANAGEMENT_PARAMS . passphrase ) ;
281
+ const encryptedRootPrivateKey = await emip3encrypt ( Buffer . from ( rootPrivateKey , 'hex' ) , passphraseByteArray ) ;
282
+ const encryptedEntropy = await emip3encrypt ( entropy , passphraseByteArray ) ;
283
+
284
+ const accountPrivateKey = await util . deriveAccountPrivateKey ( {
285
+ accountIndex,
286
+ bip32Ed25519,
287
+ rootPrivateKey
288
+ } ) ;
273
289
274
- const extendedAccountPublicKey = await bip32Ed25519 . getBip32PublicKey ( accountPrivateKey ) ;
275
-
276
- logger . log ( 'adding to repository wallet' ) ;
277
- // Add wallet to the repository.
278
- const walletId = await walletManager . repository . addWallet ( {
279
- encryptedSecrets : {
280
- entropy : HexBlob . fromBytes ( encryptedEntropy ) ,
281
- rootPrivateKeyBytes : HexBlob . fromBytes ( encryptedRootPrivateKey )
282
- } ,
283
- extendedAccountPublicKey,
284
- type : WalletType . InMemory
285
- } ) ;
290
+ const extendedAccountPublicKey = await bip32Ed25519 . getBip32PublicKey ( accountPrivateKey ) ;
291
+
292
+ logger . log ( 'adding to repository wallet' ) ;
293
+ // Add wallet to the repository.
294
+ walletId = await walletManager . repository . addWallet ( {
295
+ encryptedSecrets : {
296
+ entropy : HexBlob . fromBytes ( encryptedEntropy ) ,
297
+ rootPrivateKeyBytes : HexBlob . fromBytes ( encryptedRootPrivateKey )
298
+ } ,
299
+ extendedAccountPublicKey,
300
+ type : WalletType . InMemory
301
+ } ) ;
302
+ await walletManager . repository . addAccount ( {
303
+ accountIndex,
304
+ metadata : { name : `Wallet #${ accountIndex + 1 } ` } ,
305
+ walletId
306
+ } ) ;
286
307
287
- logger . log ( `Wallet added: ${ walletId } ` ) ;
308
+ logger . log ( `Wallet added: ${ walletId } ` ) ;
309
+ } else {
310
+ logger . info ( `Wallet with accountIndex ${ accountIndex } already exists` ) ;
311
+ }
288
312
289
- await walletManager . destroy ( ) ;
313
+ // await walletManager.destroy();
290
314
await walletManager . activate ( {
291
315
accountIndex,
292
316
chainId : env . KEY_MANAGEMENT_PARAMS . chainId ,
@@ -299,8 +323,12 @@ const createWallet = async (accountIndex: number) => {
299
323
setName ( await wallet . getName ( ) ) ;
300
324
} ;
301
325
302
- document . querySelector ( selectors . btnActivateWallet1 ) ! . addEventListener ( 'click' , async ( ) => await createWallet ( 0 ) ) ;
303
- document . querySelector ( selectors . btnActivateWallet2 ) ! . addEventListener ( 'click' , async ( ) => await createWallet ( 1 ) ) ;
326
+ document
327
+ . querySelector ( selectors . btnActivateWallet1 ) !
328
+ . addEventListener ( 'click' , async ( ) => await createWalletIfNotExistsAndActivate ( 0 ) ) ;
329
+ document
330
+ . querySelector ( selectors . btnActivateWallet2 ) !
331
+ . addEventListener ( 'click' , async ( ) => await createWalletIfNotExistsAndActivate ( 1 ) ) ;
304
332
document . querySelector ( selectors . deactivateWallet ) ! . addEventListener ( 'click' , async ( ) => await deactivateWallet ( ) ) ;
305
333
document . querySelector ( selectors . destroyWallet ) ! . addEventListener ( 'click' , async ( ) => await destroyWallet ( ) ) ;
306
334
document . querySelector ( selectors . btnDelegate ) ! . addEventListener ( 'click' , async ( ) => {
0 commit comments