Package
@celo/celocli 9.0.1
@celo/wallet-ledger 8.0.4
Both packages are up to date.
Environment
- macOS on Apple Silicon
- Ledger Nano X
Command
celocli account:list --useLedger --ledgerAddresses 3 --local --ledgerLiveMode
Describe the bug
--ledgerLiveMode does not discover Ledger Live accounts beyond the first account.
With the default Ethereum base path m/44'/60'/0', the command above derives:
m/44'/60'/0'/0/0
m/44'/60'/0'/1/0
m/44'/60'/0'/2/0
Ledger Live's standard BIP-44 account paths are instead:
m/44'/60'/0'/0/0
m/44'/60'/1'/0/0
m/44'/60'/2'/0/0
I confirmed this directly against a Ledger Nano X. The expected third Ledger Live account was returned for m/44'/60'/2'/0/0, but not by celocli --ledgerLiveMode --ledgerAddresses 3.
Expected behavior
--ledgerLiveMode --ledgerAddresses 3 should retrieve hardened account indexes 0, 1, and 2:
m/44'/60'/0'/0/0
m/44'/60'/1'/0/0
m/44'/60'/2'/0/0
Actual behavior
It fixes the account component at 0' and iterates the non-hardened change component. Only the first Ledger Live account is therefore discoverable. Transactions from later accounts fail because the --from address is not loaded into the Ledger wallet.
Likely cause
In packages/cli/src/base.ts, Ledger Live mode maps the requested indexes to changeIndexes:
derivationPathIndexes: isLedgerLiveMode ? [0] : indicesToIterateOver,
changeIndexes: isLedgerLiveMode ? indicesToIterateOver : [0],
In packages/sdk/wallets/wallet-ledger/src/ledger-wallet.ts, the account component is fixed by baseDerivationPath:
const [purpose, coinType, account] = this.baseDerivationPath.split('/')
for (const changeIndex of this.changeIndexes) {
for (const addressIndex of this.derivationPathIndexes) {
const derivationPath =
`${purpose}/${coinType}/${account}/${changeIndex}/${addressIndex}`
}
}
This prevents --ledgerLiveMode from iterating the hardened account component.
Ledger Live's default scheme is 44'/<coin_type>'/<account>'/<node>/<address>:
Suggested fix
Support iterating accountIndexes, producing:
`${purpose}/${coinType}/${accountIndex}'/${changeIndex}/${addressIndex}`
Ledger Live mode should effectively use:
accountIndexes: indicesToIterateOver
changeIndexes: [0]
derivationPathIndexes: [0]
Tests should include account index 1 or 2; index 0 cannot distinguish the incorrect path from the Ledger Live path.
Workaround
Set the desired account as the base path and do not use --ledgerLiveMode:
celocli config:set --derivationPath "m/44'/60'/2'"
celocli account:list --useLedger --ledgerAddresses 1 --local
This derives m/44'/60'/2'/0/0. Restore the default afterward with:
celocli config:set --derivationPath eth
Package
@celo/celocli9.0.1@celo/wallet-ledger8.0.4Both packages are up to date.
Environment
Command
Describe the bug
--ledgerLiveModedoes not discover Ledger Live accounts beyond the first account.With the default Ethereum base path
m/44'/60'/0', the command above derives:Ledger Live's standard BIP-44 account paths are instead:
I confirmed this directly against a Ledger Nano X. The expected third Ledger Live account was returned for
m/44'/60'/2'/0/0, but not bycelocli --ledgerLiveMode --ledgerAddresses 3.Expected behavior
--ledgerLiveMode --ledgerAddresses 3should retrieve hardened account indexes 0, 1, and 2:Actual behavior
It fixes the account component at
0'and iterates the non-hardened change component. Only the first Ledger Live account is therefore discoverable. Transactions from later accounts fail because the--fromaddress is not loaded into the Ledger wallet.Likely cause
In
packages/cli/src/base.ts, Ledger Live mode maps the requested indexes tochangeIndexes:In
packages/sdk/wallets/wallet-ledger/src/ledger-wallet.ts, the account component is fixed bybaseDerivationPath:This prevents
--ledgerLiveModefrom iterating the hardened account component.Ledger Live's default scheme is
44'/<coin_type>'/<account>'/<node>/<address>:--ledgerLiveModeintroduction: PR #488Suggested fix
Support iterating
accountIndexes, producing:`${purpose}/${coinType}/${accountIndex}'/${changeIndex}/${addressIndex}`Ledger Live mode should effectively use:
Tests should include account index 1 or 2; index 0 cannot distinguish the incorrect path from the Ledger Live path.
Workaround
Set the desired account as the base path and do not use
--ledgerLiveMode:celocli config:set --derivationPath "m/44'/60'/2'" celocli account:list --useLedger --ledgerAddresses 1 --localThis derives
m/44'/60'/2'/0/0. Restore the default afterward with: