Skip to content

Commit 5d6a96d

Browse files
committed
Add backend switching with walletSettings
1 parent 1c3e619 commit 5d6a96d

File tree

3 files changed

+84
-21
lines changed

3 files changed

+84
-21
lines changed

src/monero/MoneroEngine.ts

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
NoAmountSpecifiedError,
1414
PendingFundsError
1515
} from 'edge-core-js/types'
16+
import type { WalletBackend } from 'react-native-monero-lwsf'
1617
import { TransactionDirection } from 'react-native-monero-lwsf'
1718
import { base64, base64url } from 'rfc4648'
1819

@@ -36,13 +37,15 @@ import {
3637
asMoneroPrivateKeys,
3738
asMoneroUserSettings,
3839
asMoneroWalletOtherData,
40+
asMoneroWalletSettings,
3941
asSafeMoneroWalletInfo,
4042
LoginResponse,
4143
MoneroInitOptions,
4244
MoneroNetworkInfo,
4345
MoneroPrivateKeys,
4446
MoneroUserSettings,
4547
MoneroWalletOtherData,
48+
MoneroWalletSettings,
4649
SafeMoneroWalletInfo,
4750
translateFee
4851
} from './moneroTypes'
@@ -54,6 +57,7 @@ export class MoneroEngine extends CurrencyEngine<
5457
> {
5558
networkInfo: MoneroNetworkInfo
5659
currentSettings: MoneroUserSettings
60+
currentWalletSettings: MoneroWalletSettings
5761
otherData!: MoneroWalletOtherData
5862
initOptions: MoneroInitOptions
5963
unlockedBalance: string
@@ -63,6 +67,7 @@ export class MoneroEngine extends CurrencyEngine<
6367
private txSortOrder: 'asc' | 'desc' = 'asc'
6468
private unsubscribeWalletEvent?: () => void
6569
private abortKeysWait?: () => void
70+
private settingsChangeQueue: Promise<void> = Promise.resolve()
6671

6772
constructor(
6873
env: PluginEnvironment<MoneroNetworkInfo>,
@@ -77,7 +82,12 @@ export class MoneroEngine extends CurrencyEngine<
7782

7883
this.unlockedBalance = '0'
7984

85+
// Shared across all wallets using this engine:
8086
this.currentSettings = asMoneroUserSettings(opts.userSettings)
87+
// Unique to this particular wallet instance:
88+
this.currentWalletSettings = asMoneroWalletSettings(
89+
opts.walletSettings ?? {}
90+
)
8191

8292
// Singleton promise resolved once by the first syncNetwork call.
8393
// Stays resolved across restarts so onStart gets keys immediately.
@@ -98,36 +108,47 @@ export class MoneroEngine extends CurrencyEngine<
98108
base64.parse(this.walletId)
99109
)
100110

111+
const { backend } = this.currentWalletSettings
112+
this.log.warn('Using backend:', backend)
101113
const defaults = asMoneroUserSettings({})
102-
const daemonAddress = this.currentSettings.enableCustomServers
103-
? this.currentSettings.moneroLightwalletServer
104-
: defaults.moneroLightwalletServer
114+
const daemonAddress =
115+
backend === 'lws'
116+
? this.currentSettings.enableCustomServers
117+
? this.currentSettings.moneroLightwalletServer
118+
: defaults.moneroLightwalletServer
119+
: this.currentSettings.enableCustomMonerod
120+
? this.currentSettings.monerodServer
121+
: defaults.monerodServer
105122

106123
try {
107-
// LWS setup: API key and login
108-
const isEdgeLws = daemonAddress === this.networkInfo.edgeLwsServer
124+
// LWS-specific setup: API key and login
109125
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
126+
if (backend === 'lws') {
127+
const isEdgeLws = daemonAddress === this.networkInfo.edgeLwsServer
128+
await this.tools.cppBridge.setLwsApiKey(
129+
isEdgeLws ? this.initOptions.edgeApiKey : ''
118130
)
131+
if (isEdgeLws) {
132+
loginResult = await this.loginToLwsServer(
133+
daemonAddress,
134+
this.walletInfo.keys.moneroAddress,
135+
this.walletInfo.keys.moneroViewKeyPrivate
136+
)
137+
}
119138
}
120139

121140
// Resolve birthday height (never open a wallet with height 0)
122141
const birthdayHeight = await this.resolveBirthdayHeight(
123142
keys.birthdayHeight,
143+
backend,
124144
daemonAddress,
145+
defaults.moneroLightwalletServer,
125146
loginResult
126147
)
127148

128149
await this.tools.cppBridge.openWallet(
129150
base64UrlWalletId,
130-
'lws',
151+
backend,
131152
keys.moneroKey,
132153
base64url.stringify(base64.parse(keys.dataKey)),
133154
this.networkInfo.networkType,
@@ -188,7 +209,9 @@ export class MoneroEngine extends CurrencyEngine<
188209
*/
189210
private async resolveBirthdayHeight(
190211
height: number | undefined,
212+
backend: WalletBackend,
191213
daemonAddress: string,
214+
edgeLwsServer: string,
192215
loginResult?: LoginResponse
193216
): Promise<number> {
194217
if (height != null) return height
@@ -198,12 +221,20 @@ export class MoneroEngine extends CurrencyEngine<
198221
return loginResult.start_height
199222
}
200223

201-
// Fall back to getAddressInfo
224+
// For monerod wallets, fall back to the Edge LWS server
225+
const serverUrl = backend === 'lws' ? daemonAddress : edgeLwsServer
202226
const addressInfo = await this.getAddressInfo(
203-
daemonAddress,
227+
serverUrl,
204228
this.walletInfo.keys.moneroAddress,
205229
this.walletInfo.keys.moneroViewKeyPrivate
206230
)
231+
232+
if (addressInfo.start_height === 0) {
233+
throw new Error(
234+
'Cannot open wallet: birthdayHeight is 0. ' +
235+
'The wallet creation height could not be determined.'
236+
)
237+
}
207238
return addressInfo.start_height
208239
}
209240

@@ -531,7 +562,7 @@ export class MoneroEngine extends CurrencyEngine<
531562
await this.clearBlockchainCache()
532563
await this.tools.cppBridge.deleteWallet(
533564
base64url.stringify(base64.parse(this.walletId)),
534-
'lws'
565+
this.currentWalletSettings.backend
535566
)
536567
await this.startEngine()
537568
}
@@ -542,9 +573,30 @@ export class MoneroEngine extends CurrencyEngine<
542573
return
543574
}
544575

545-
this.currentSettings = newSettings
546-
await this.killEngine()
547-
await this.startEngine()
576+
this.settingsChangeQueue = this.settingsChangeQueue.then(async () => {
577+
this.currentSettings = newSettings
578+
await this.killEngine()
579+
await this.startEngine()
580+
})
581+
await this.settingsChangeQueue
582+
}
583+
584+
async changeWalletSettings(walletSettings: JsonObject): Promise<void> {
585+
const newSettings = asMaybe(asMoneroWalletSettings)(walletSettings)
586+
if (
587+
newSettings == null ||
588+
matchJson(this.currentWalletSettings, newSettings)
589+
) {
590+
return
591+
}
592+
593+
this.settingsChangeQueue = this.settingsChangeQueue.then(async () => {
594+
this.currentWalletSettings = newSettings
595+
await this.killEngine()
596+
await this.clearBlockchainCache()
597+
await this.startEngine()
598+
})
599+
await this.settingsChangeQueue
548600
}
549601

550602
async getMaxSpendable(edgeSpendInfo: EdgeSpendInfo): Promise<string> {

src/monero/moneroInfo.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export const currencyInfo: EdgeCurrencyInfo = {
4141
],
4242

4343
defaultSettings,
44+
hasWalletSettings: true,
4445

4546
unsafeSyncNetwork: true,
4647
chainDisplayName: 'Monero',

src/monero/moneroTypes.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@ import {
66
asObject,
77
asOptional,
88
asString,
9+
asValue,
910
Cleaner
1011
} from 'cleaners'
11-
import type { NetworkType, WalletEventData } from 'react-native-monero-lwsf'
12+
import type {
13+
NetworkType,
14+
WalletBackend,
15+
WalletEventData
16+
} from 'react-native-monero-lwsf'
1217
import { TransactionPriority } from 'react-native-monero-lwsf'
1318
import type { Subscriber } from 'yaob'
1419

@@ -33,6 +38,11 @@ export const asMoneroUserSettings = asObject({
3338
})
3439
export type MoneroUserSettings = ReturnType<typeof asMoneroUserSettings>
3540

41+
export const asMoneroWalletSettings = asObject({
42+
backend: asMaybe<WalletBackend>(asValue('lws', 'monerod'), 'lws')
43+
})
44+
export type MoneroWalletSettings = ReturnType<typeof asMoneroWalletSettings>
45+
3646
export const asMoneroKeyOptions = asObject({
3747
birthdayHeight: asNumber
3848
})

0 commit comments

Comments
 (0)