7
7
WalletRepositoryApi
8
8
} from './types' ;
9
9
import { AnyWallet , ScriptWallet , WalletId , WalletType } from '../types' ;
10
+ import { KeyPurpose } from '@cardano-sdk/key-management' ;
10
11
import { Logger } from 'ts-log' ;
11
12
import { Observable , defer , firstValueFrom , map , shareReplay , switchMap , take } from 'rxjs' ;
12
13
import { WalletConflictError } from '../errors' ;
@@ -28,16 +29,24 @@ const cloneSplice = <T>(array: T[], start: number, deleteCount: number, ...items
28
29
const findAccount = < WalletMetadata extends { } , AccountMetadata extends { } > (
29
30
wallets : AnyWallet < WalletMetadata , AccountMetadata > [ ] ,
30
31
walletId : WalletId ,
31
- accountIndex : number
32
+ accountIndex : number ,
33
+ purpose : KeyPurpose
32
34
) => {
33
35
const walletIdx = wallets . findIndex ( ( w ) => w . walletId === walletId ) ;
34
36
const wallet = wallets [ walletIdx ] ;
37
+
35
38
if ( ! wallet || wallet . type === WalletType . Script ) return ;
36
- const accountIdx = wallet . accounts . findIndex ( ( acc ) => acc . accountIndex === accountIndex ) ;
39
+
40
+ const accountIdx = wallet . accounts . findIndex ( ( acc ) => {
41
+ const accountPurpose = acc . purpose || KeyPurpose . STANDARD ;
42
+ return acc . accountIndex === accountIndex && accountPurpose === purpose ;
43
+ } ) ;
44
+
37
45
if ( accountIdx < 0 ) return ;
38
46
return {
39
47
account : wallet . accounts [ accountIdx ] ,
40
48
accountIdx,
49
+ purpose,
41
50
wallet,
42
51
walletIdx
43
52
} ;
@@ -96,6 +105,8 @@ export class WalletRepository<WalletMetadata extends {}, AccountMetadata extends
96
105
addAccount ( props : AddAccountProps < AccountMetadata > ) : Promise < AddAccountProps < AccountMetadata > > {
97
106
const { walletId, accountIndex, metadata, extendedAccountPublicKey } = props ;
98
107
this . #logger. debug ( 'addAccount' , walletId , accountIndex , metadata ) ;
108
+ const purpose = props . purpose || KeyPurpose . STANDARD ;
109
+
99
110
return firstValueFrom (
100
111
this . #getWallets( ) . pipe (
101
112
switchMap ( ( wallets ) => {
@@ -107,8 +118,16 @@ export class WalletRepository<WalletMetadata extends {}, AccountMetadata extends
107
118
if ( wallet . type === WalletType . Script ) {
108
119
throw new WalletConflictError ( 'addAccount for script wallets is not supported' ) ;
109
120
}
110
- if ( wallet . accounts . some ( ( acc ) => acc . accountIndex === accountIndex ) ) {
111
- throw new WalletConflictError ( `Account #${ accountIndex } for wallet '${ walletId } ' already exists` ) ;
121
+
122
+ if (
123
+ wallet . accounts . some ( ( acc ) => {
124
+ const accountPurpose = acc . purpose || KeyPurpose . STANDARD ;
125
+ return acc . accountIndex === accountIndex && accountPurpose === purpose ;
126
+ } )
127
+ ) {
128
+ throw new WalletConflictError (
129
+ `Account #${ accountIndex } with purpose ${ purpose } for wallet '${ walletId } ' already exists`
130
+ ) ;
112
131
}
113
132
114
133
return this . #store
@@ -120,7 +139,8 @@ export class WalletRepository<WalletMetadata extends {}, AccountMetadata extends
120
139
{
121
140
accountIndex,
122
141
extendedAccountPublicKey,
123
- metadata
142
+ metadata,
143
+ purpose : props . purpose
124
144
}
125
145
]
126
146
} )
@@ -136,6 +156,7 @@ export class WalletRepository<WalletMetadata extends {}, AccountMetadata extends
136
156
) : Promise < UpdateWalletMetadataProps < WalletMetadata > > {
137
157
const { walletId, metadata } = props ;
138
158
this . #logger. debug ( 'updateWalletMetadata' , walletId , metadata ) ;
159
+
139
160
return firstValueFrom (
140
161
this . #getWallets( ) . pipe (
141
162
switchMap ( ( wallets ) => {
@@ -160,14 +181,17 @@ export class WalletRepository<WalletMetadata extends {}, AccountMetadata extends
160
181
props : UpdateAccountMetadataProps < AccountMetadata >
161
182
) : Promise < UpdateAccountMetadataProps < AccountMetadata > > {
162
183
const { walletId, accountIndex, metadata } = props ;
163
- this . #logger. debug ( 'updateAccountMetadata' , walletId , accountIndex , metadata ) ;
184
+ const purpose = props . purpose || KeyPurpose . STANDARD ;
185
+
186
+ this . #logger. debug ( 'updateAccountMetadata' , walletId , accountIndex , metadata , purpose ) ;
187
+
164
188
return firstValueFrom (
165
189
this . #getWallets( ) . pipe (
166
190
switchMap ( ( wallets ) => {
167
191
// update account
168
- const bip32Account = findAccount ( wallets , walletId , accountIndex ) ;
192
+ const bip32Account = findAccount ( wallets , walletId , accountIndex , purpose ) ;
169
193
if ( ! bip32Account ) {
170
- throw new WalletConflictError ( `Account not found: ${ walletId } /${ accountIndex } ` ) ;
194
+ throw new WalletConflictError ( `Account not found: ${ walletId } /${ purpose } / ${ accountIndex } ` ) ;
171
195
}
172
196
return this . #store. setAll (
173
197
cloneSplice ( wallets , bip32Account . walletIdx , 1 , {
@@ -185,23 +209,29 @@ export class WalletRepository<WalletMetadata extends {}, AccountMetadata extends
185
209
}
186
210
187
211
removeAccount ( props : RemoveAccountProps ) : Promise < RemoveAccountProps > {
188
- const { walletId, accountIndex } = props ;
189
- this . #logger. debug ( 'removeAccount' , walletId , accountIndex ) ;
212
+ const { walletId, accountIndex, purpose : maybePurpose } = props ;
213
+
214
+ const purpose = maybePurpose || KeyPurpose . STANDARD ;
215
+
216
+ this . #logger. debug ( 'removeAccount' , walletId , accountIndex , purpose ) ;
190
217
return firstValueFrom (
191
218
this . #getWallets( ) . pipe (
192
219
switchMap ( ( wallets ) => {
193
- const bip32Account = findAccount ( wallets , walletId , accountIndex ) ;
220
+ const bip32Account = findAccount ( wallets , walletId , accountIndex , purpose ) ;
194
221
if ( ! bip32Account ) {
195
- throw new WalletConflictError ( `Account '${ walletId } /${ accountIndex } ' does not exist` ) ;
222
+ throw new WalletConflictError ( `Account '${ walletId } /${ purpose } / ${ accountIndex } ' does not exist` ) ;
196
223
}
197
224
const dependentWallet = wallets . find (
198
225
( wallet ) =>
199
226
wallet . type === WalletType . Script &&
200
- wallet . ownSigners . some ( ( signer ) => signer . walletId === walletId && signer . accountIndex === accountIndex )
227
+ wallet . ownSigners . some (
228
+ ( signer ) =>
229
+ signer . walletId === walletId && signer . accountIndex === accountIndex && signer . purpose === purpose
230
+ )
201
231
) ;
202
232
if ( dependentWallet ) {
203
233
throw new WalletConflictError (
204
- `Wallet '${ dependentWallet . walletId } ' depends on account '${ walletId } /${ accountIndex } '`
234
+ `Wallet '${ dependentWallet . walletId } ' depends on account '${ walletId } /${ purpose } / ${ accountIndex } '`
205
235
) ;
206
236
}
207
237
return this . #store. setAll (
0 commit comments