Better recovery keyset selection

This commit is contained in:
minibits-cash
2024-08-11 21:54:32 +02:00
parent c1e31afc13
commit bb0c91e4de
3 changed files with 41 additions and 36 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "minibits_wallet",
"version": "0.1.8-beta.47",
"version": "0.1.8-beta.48",
"private": true,
"scripts": {
"android:clean": "cd android && ./gradlew clean",
+34 -28
View File
@@ -20,6 +20,7 @@ import { MintUnit } from '../services/wallet/currency'
import { CashuUtils, ProofV3, TokenV3 } from '../services/cashu/cashuUtils'
import { Proof } from './Proof'
import { isObj } from '@cashu/cashu-ts/src/utils'
import { Mint } from './Mint'
/*
Not persisted, in-memory only model of the cashu-ts wallet instances and seed.
@@ -68,8 +69,33 @@ export const WalletStoreModel = types
}),
getMintModelInstance(mintUrl: string) {
const mintsStore = getRoot(self).mintsStore
return mintsStore.findByUrl(mintUrl)
}
return mintsStore.findByUrl(mintUrl) as Mint
},
getOptimalKeyset(mintInstance: Mint, unit: MintUnit) {
const optimalKeyset: MintKeyset =mintInstance.keysets!
.filter((k: MintKeyset) => k.unit === unit && k.active)
.sort((a: MintKeyset, b: MintKeyset) => {
// Prioritize keysets that start with '00'
const aStartsWith00 = a.id.startsWith('00') ? 1 : 0;
const bStartsWith00 = b.id.startsWith('00') ? 1 : 0;
if (aStartsWith00 !== bStartsWith00) {
return bStartsWith00 - aStartsWith00;
}
// If both start with '00' or neither do, sort by input_fee_ppk
return (a.input_fee_ppk ?? 0) - (b.input_fee_ppk ?? 0);
})[0]
if(!optimalKeyset) {
throw new AppError(Err.VALIDATION_ERROR, 'Wallet has not any active keyset for the selected unit.', {
mintUrl: mintInstance.mintUrl,
unit
})
}
return optimalKeyset
},
}))
.actions(self => ({
getOrCreateMnemonic: flow(function* getOrCreateMnemonic() {
@@ -111,17 +137,17 @@ export const WalletStoreModel = types
// skip checks if this is new mint being added
if(mintInstance) {
const newKeysets = keysets.filter((freshKeyset: MintKeyset) => {
return !mintInstance.keysets.some((keyset: MintKeyset) => keyset.id === freshKeyset.id)
return !mintInstance.keysets!.some((keyset: MintKeyset) => keyset.id === freshKeyset.id)
})
if(newKeysets.length > 0) {
// if we heve new keysets, get and sync new keys
const {keysets} = yield newMint.getKeys()
mintInstance.refreshKeys(keysets)
mintInstance.refreshKeys!(keysets)
}
// sync wallet state with fresh keysets, active statuses and keys
mintInstance.refreshKeysets(keysets)
mintInstance.refreshKeysets!(keysets)
}
// store cashu-ts mint instance in memory
@@ -156,7 +182,7 @@ export const WalletStoreModel = types
let walletKeys: MintKeys
if(options && options.keysetId) {
const requestedKeys = mintInstance.keys.find((k: MintKeys) => k.id === options.keysetId)
const requestedKeys = mintInstance.keys!.find((k: MintKeys) => k.id === options.keysetId)
if(!requestedKeys) {
throw new AppError(Err.NOTFOUND_ERROR, 'Wallet has not keys with provided keyset id.', {
@@ -176,31 +202,11 @@ export const WalletStoreModel = types
walletKeys = requestedKeys
} else {
// if not we find active keyset with lowest fees and related keys
const activeKeyset: MintKeyset =mintInstance.keysets
.filter((k: MintKeyset) => k.unit === unit && k.active)
.sort((a: MintKeyset, b: MintKeyset) => {
// Prioritize keysets that start with '00'
const aStartsWith00 = a.id.startsWith('00') ? 1 : 0;
const bStartsWith00 = b.id.startsWith('00') ? 1 : 0;
if (aStartsWith00 !== bStartsWith00) {
return bStartsWith00 - aStartsWith00;
}
// If both start with '00' or neither do, sort by input_fee_ppk
return (a.input_fee_ppk ?? 0) - (b.input_fee_ppk ?? 0);
})[0]
const activeKeyset: MintKeyset = self.getOptimalKeyset(mintInstance, unit) // throws
log.trace('[WalletStore.getWallet]', {activeKeyset, mintUrl})
if(!activeKeyset) {
throw new AppError(Err.VALIDATION_ERROR, 'Wallet has not any active keyset for the selected unit.', {
mintUrl,
unit
})
}
const activeKeys = mintInstance.keys.find((k: MintKeys) => k.id === activeKeyset.id)
const activeKeys = mintInstance.keys!.find((k: MintKeys) => k.id === activeKeyset.id)
if(!activeKeys) {
throw new AppError(Err.VALIDATION_ERROR, 'Wallet has not any keys for the selected unit.', {
+6 -7
View File
@@ -34,7 +34,7 @@ import { ResultModalInfo } from './Wallet/ResultModalInfo'
import { deriveSeedFromMnemonic } from '@cashu/cashu-ts'
import { MINIBITS_NIP05_DOMAIN } from '@env'
import { delay } from '../utils/utils'
import { isStateTreeNode } from 'mobx-state-tree'
import { getSnapshot, isStateTreeNode } from 'mobx-state-tree'
import { scale } from '@gocodingnow/rn-size-matters'
import { WalletUtils } from '../services/wallet/utils'
import { WalletScreen } from './WalletScreen'
@@ -182,12 +182,11 @@ export const RemoteRecoveryScreen: FC<AppStackScreenProps<'RemoteRecovery'>> = o
const onMintSelect = async function (mint: Mint) {
try {
setSelectedMintUrl(mint.mintUrl)
const allActiveKeysets = await walletStore.getMintKeysets(mint.mintUrl) // mint api call
// Default is the last one as it seems to be the newest one
const lastKeyset = allActiveKeysets.slice(-1)[0]
setSelectedKeyset(lastKeyset)
setSelectedMintKeysets(allActiveKeysets)
const allKeysets = getSnapshot(mint.keysets!)
const defaultKeyset = walletStore.getOptimalKeyset(mint, 'sat')
setSelectedKeyset(defaultKeyset)
setSelectedMintKeysets(allKeysets)
setStartIndex(0)
setEndIndex(RESTORE_INDEX_INTERVAL)
} catch (e: any) {