@@ -13,7 +13,10 @@ import {
1313 NoAmountSpecifiedError ,
1414 PendingFundsError
1515} from 'edge-core-js/types'
16- import type { TransactionDirection } from 'react-native-monero-lwsf'
16+ import type {
17+ TransactionDirection ,
18+ WalletBackend
19+ } from 'react-native-monero-lwsf'
1720import { base64 , base64url } from 'rfc4648'
1821
1922import { CurrencyEngine } from '../common/CurrencyEngine'
@@ -36,13 +39,15 @@ import {
3639 asMoneroPrivateKeys ,
3740 asMoneroUserSettings ,
3841 asMoneroWalletOtherData ,
42+ asMoneroWalletSettings ,
3943 asSafeMoneroWalletInfo ,
4044 LoginResponse ,
4145 MoneroInitOptions ,
4246 MoneroNetworkInfo ,
4347 MoneroPrivateKeys ,
4448 MoneroUserSettings ,
4549 MoneroWalletOtherData ,
50+ MoneroWalletSettings ,
4651 SafeMoneroWalletInfo ,
4752 translateFee
4853} from './moneroTypes'
@@ -54,6 +59,7 @@ export class MoneroEngine extends CurrencyEngine<
5459> {
5560 networkInfo : MoneroNetworkInfo
5661 currentSettings : MoneroUserSettings
62+ currentWalletSettings : MoneroWalletSettings
5763 otherData ! : MoneroWalletOtherData
5864 initOptions : MoneroInitOptions
5965 unlockedBalance : string
@@ -63,6 +69,7 @@ export class MoneroEngine extends CurrencyEngine<
6369 private txSortOrder : 'asc' | 'desc' = 'asc'
6470 private unsubscribeWalletEvent ?: ( ) => void
6571 private abortKeysWait ?: ( ) => void
72+ private settingsChangeQueue : Promise < void > = Promise . resolve ( )
6673
6774 constructor (
6875 env : PluginEnvironment < MoneroNetworkInfo > ,
@@ -77,7 +84,12 @@ export class MoneroEngine extends CurrencyEngine<
7784
7885 this . unlockedBalance = '0'
7986
87+ // Shared across all wallets using this engine:
8088 this . currentSettings = asMoneroUserSettings ( opts . userSettings )
89+ // Unique to this particular wallet instance:
90+ this . currentWalletSettings = asMoneroWalletSettings (
91+ opts . walletSettings ?? { }
92+ )
8193
8294 // Singleton promise resolved once by the first syncNetwork call.
8395 // Stays resolved across restarts so onStart gets keys immediately.
@@ -98,36 +110,47 @@ export class MoneroEngine extends CurrencyEngine<
98110 base64 . parse ( this . walletId )
99111 )
100112
113+ const { backend } = this . currentWalletSettings
114+ this . log . warn ( 'Using backend:' , backend )
101115 const defaults = asMoneroUserSettings ( { } )
102- const daemonAddress = this . currentSettings . enableCustomServers
103- ? this . currentSettings . moneroLightwalletServer
104- : defaults . moneroLightwalletServer
116+ const daemonAddress =
117+ backend === 'lws'
118+ ? this . currentSettings . enableCustomServers
119+ ? this . currentSettings . moneroLightwalletServer
120+ : defaults . moneroLightwalletServer
121+ : this . currentSettings . enableCustomMonerod
122+ ? this . currentSettings . monerodServer
123+ : defaults . monerodServer
105124
106125 try {
107- // LWS setup: API key and login
108- const isEdgeLws = daemonAddress === this . networkInfo . edgeLwsServer
126+ // LWS-specific setup: API key and login
109127 let loginResult : LoginResponse | undefined
110- await this . tools . cppBridge . setLwsApiKey (
111- isEdgeLws ? this . initOptions . edgeApiKey : ''
112- )
113- if ( isEdgeLws ) {
114- loginResult = await this . loginToLwsServer (
115- daemonAddress ,
116- this . walletInfo . keys . moneroAddress ,
117- this . walletInfo . keys . moneroViewKeyPrivate
128+ if ( backend === 'lws' ) {
129+ const isEdgeLws = daemonAddress === this . networkInfo . edgeLwsServer
130+ await this . tools . cppBridge . setLwsApiKey (
131+ isEdgeLws ? this . initOptions . edgeApiKey : ''
118132 )
133+ if ( isEdgeLws ) {
134+ loginResult = await this . loginToLwsServer (
135+ daemonAddress ,
136+ this . walletInfo . keys . moneroAddress ,
137+ this . walletInfo . keys . moneroViewKeyPrivate
138+ )
139+ }
119140 }
120141
121142 // Resolve birthday height (never open a wallet with height 0)
122143 const birthdayHeight = await this . resolveBirthdayHeight (
123144 keys . birthdayHeight ,
145+ backend ,
124146 daemonAddress ,
147+ defaults . moneroLightwalletServer ,
125148 loginResult
126149 )
127150
128151 await this . tools . cppBridge . openWallet (
129152 base64UrlWalletId ,
130- 'lws' ,
153+ backend ,
131154 keys . moneroKey ,
132155 base64url . stringify ( base64 . parse ( keys . dataKey ) ) ,
133156 this . networkInfo . networkType ,
@@ -188,7 +211,9 @@ export class MoneroEngine extends CurrencyEngine<
188211 */
189212 private async resolveBirthdayHeight (
190213 height : number | undefined ,
214+ backend : WalletBackend ,
191215 daemonAddress : string ,
216+ edgeLwsServer : string ,
192217 loginResult ?: LoginResponse
193218 ) : Promise < number > {
194219 if ( height != null ) return height
@@ -198,12 +223,20 @@ export class MoneroEngine extends CurrencyEngine<
198223 return loginResult . start_height
199224 }
200225
201- // Fall back to getAddressInfo
226+ // For monerod wallets, fall back to the Edge LWS server
227+ const serverUrl = backend === 'lws' ? daemonAddress : edgeLwsServer
202228 const addressInfo = await this . getAddressInfo (
203- daemonAddress ,
229+ serverUrl ,
204230 this . walletInfo . keys . moneroAddress ,
205231 this . walletInfo . keys . moneroViewKeyPrivate
206232 )
233+
234+ if ( addressInfo . start_height === 0 ) {
235+ throw new Error (
236+ 'Cannot open wallet: birthdayHeight is 0. ' +
237+ 'The wallet creation height could not be determined.'
238+ )
239+ }
207240 return addressInfo . start_height
208241 }
209242
@@ -531,7 +564,7 @@ export class MoneroEngine extends CurrencyEngine<
531564 await this . clearBlockchainCache ( )
532565 await this . tools . cppBridge . deleteWallet (
533566 base64url . stringify ( base64 . parse ( this . walletId ) ) ,
534- 'lws'
567+ this . currentWalletSettings . backend
535568 )
536569 await this . startEngine ( )
537570 }
@@ -542,9 +575,30 @@ export class MoneroEngine extends CurrencyEngine<
542575 return
543576 }
544577
545- this . currentSettings = newSettings
546- await this . killEngine ( )
547- await this . startEngine ( )
578+ this . settingsChangeQueue = this . settingsChangeQueue . then ( async ( ) => {
579+ this . currentSettings = newSettings
580+ await this . killEngine ( )
581+ await this . startEngine ( )
582+ } )
583+ await this . settingsChangeQueue
584+ }
585+
586+ async changeWalletSettings ( walletSettings : JsonObject ) : Promise < void > {
587+ const newSettings = asMaybe ( asMoneroWalletSettings ) ( walletSettings )
588+ if (
589+ newSettings == null ||
590+ matchJson ( this . currentWalletSettings , newSettings )
591+ ) {
592+ return
593+ }
594+
595+ this . settingsChangeQueue = this . settingsChangeQueue . then ( async ( ) => {
596+ this . currentWalletSettings = newSettings
597+ await this . killEngine ( )
598+ await this . clearBlockchainCache ( )
599+ await this . startEngine ( )
600+ } )
601+ await this . settingsChangeQueue
548602 }
549603
550604 async getMaxSpendable ( edgeSpendInfo : EdgeSpendInfo ) : Promise < string > {
0 commit comments