Skip to content

Commit cd039f0

Browse files
committed
Derive primaryFormat with a dedicated getPrimaryFormat utility
This implements a single algorithm responsible for getting a wallet's primaryFormat. This function uses the existing algorithm for publicKeys and is now also used in `createPrivateKey`. This change should be an idempotent, but guarantees our future changes (about how we select the primary key) is couple to the appropriate routines. The goal is to future-proof our existing implementation for when we enable new wallet formats. We do not introduce any side-effects to existing wallets (wallets already persisted prior to any change).
1 parent 8a046c7 commit cd039f0

File tree

2 files changed

+34
-11
lines changed

2 files changed

+34
-11
lines changed

src/common/plugin/makeCurrencyTools.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { parsePathname } from '../utxobased/engine/utils'
1616
import {
1717
asNumbWalletInfo,
1818
asPrivateKey,
19+
getPrimaryFormat,
1920
PrivateKey
2021
} from '../utxobased/keymanager/cleaners'
2122
import { EncodeUriMetadata, ExtendedParseUri, PluginInfo } from './types'
@@ -42,10 +43,11 @@ export function makeCurrencyTools(
4243
opts?: JsonObject
4344
): Promise<JsonObject> {
4445
const mnemonic = bip39.entropyToMnemonic(Buffer.from(io.random(32)))
46+
const currencyFormats = engineInfo.formats ?? (['bip44'] as ['bip44'])
4547

4648
const privateKey: PrivateKey = {
4749
seed: mnemonic,
48-
format: opts?.format ?? engineInfo.formats?.[0] ?? 'bip44',
50+
format: getPrimaryFormat(currencyFormats, currencyFormats),
4951
coinType: opts?.coinType ?? coinInfo.coinType ?? 0
5052
}
5153

src/common/utxobased/keymanager/cleaners.ts

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,31 @@ export const getSupportedFormats = (
9999
}
100100
}
101101

102+
/**
103+
* An algorithm that defines the primary format for a wallet given all of the
104+
* wallet's formats and the currency formats (from plugin info).
105+
*
106+
* The purpose for this algorithm is to deterministically return a single
107+
* primary format regardless of the order of the wallet formats given.
108+
* The algorithm effectively takes the first format in the formats from plugin
109+
* info that matches one of the formats in the given wallet formats.
110+
*
111+
* If no wallet format matches any of the formats in the plugin info, then
112+
* the primary format is the first format in the wallet format after sorting
113+
* in ascending order lexicographically.
114+
*/
115+
export const getPrimaryFormat = (
116+
currencyFormats: CurrencyFormat[],
117+
walletFormats: CurrencyFormat[]
118+
): CurrencyFormat => {
119+
return (
120+
(currencyFormats.length > 0
121+
? currencyFormats.find(format => walletFormats.includes(format))
122+
: undefined) ??
123+
walletFormats.sort((a, b) => (a === b ? 0 : a > b ? 1 : -1))[0]
124+
)
125+
}
126+
102127
/**
103128
* A cleaner that desensitizes the walletInfo object, excluding sensitive
104129
* keys (seed/mnemonic, sync key, data key, etc). By using this object type
@@ -147,16 +172,10 @@ export const asNumbWalletInfo = (
147172
if (walletFormats.length === 0) {
148173
throw new Error('Missing wallet public keys')
149174
}
150-
151-
// Search the engineInfo's formats array for the first format that exists
152-
// in the publicKey data.
153-
// If there are no defined formats in the engineInfo, then fallback to the
154-
// first format in the publicKey after sorting alphabetically.
155-
const primaryFormat =
156-
(engineInfo.formats != null && engineInfo.formats.length > 0
157-
? engineInfo.formats.find(format => walletFormats.includes(format))
158-
: undefined) ??
159-
walletFormats.sort((a, b) => (a === b ? 0 : a > b ? 1 : -1))[0]
175+
const primaryFormat = getPrimaryFormat(
176+
engineInfo.formats ?? [],
177+
walletFormats
178+
)
160179

161180
return {
162181
id,
@@ -181,6 +200,8 @@ export const asNumbWalletInfo = (
181200
id,
182201
type,
183202
keys: {
203+
// Private key format is the primary format because it was determined
204+
// during `createPrivateKey` phase.
184205
primaryFormat: privateKey.format,
185206
walletFormats,
186207
publicKey: { publicKeys: publicKey }

0 commit comments

Comments
 (0)