Skip to content

Commit 48a2b84

Browse files
[refactor]: Alternative method of address generation for Ledger (#901)
* [fix] Fixes the ledger live paths * [refactor] Alternative way of generating addresses * Removes unused deps
1 parent 3075629 commit 48a2b84

File tree

3 files changed

+21
-50
lines changed

3 files changed

+21
-50
lines changed

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
"name": "web3-onboard-monorepo",
33
"private": true,
44
"workspaces": [
5-
"./packages/*"
5+
"./packages/common",
6+
"./packages/core",
7+
"./packages/!(demo|core|common)/**",
8+
"./packages/demo"
69
],
710
"scripts": {
811
"install-m1-mac": "yarn install --ignore-optional",

packages/ledger/package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
"@ledgerhq/hw-transport-webusb": "^6.19.0",
3131
"@metamask/eth-sig-util": "^4.0.0",
3232
"buffer": "^6.0.3",
33-
"eth-crypto": "^2.1.0",
34-
"ethereumjs-util": "^7.1.3",
35-
"hdkey": "^2.0.1"
33+
"ethereumjs-util": "^7.1.3"
3634
}
3735
}

packages/ledger/src/index.ts

Lines changed: 16 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { Buffer } from 'buffer'
1414

1515
import type Transport from '@ledgerhq/hw-transport'
1616
import type { providers } from 'ethers'
17+
import type Eth from '@ledgerhq/hw-app-eth'
1718

1819
const LEDGER_LIVE_PATH = `m/44'/60'`
1920
const LEDGER_DEFAULT_PATH = `m/44'/60'/0'`
@@ -54,38 +55,20 @@ const getTransport = async () =>
5455
: (await import('@ledgerhq/hw-transport-u2f')).default
5556
).create()
5657

57-
interface LedgerAccount {
58-
publicKey: string
59-
derivationPath: string
60-
chainCode: string
61-
}
62-
6358
const getAccount = async (
64-
{ publicKey, chainCode, derivationPath }: LedgerAccount,
59+
derivationPath: string,
6560
asset: Asset,
6661
index: number,
67-
provider: providers.StaticJsonRpcProvider
62+
provider: providers.StaticJsonRpcProvider,
63+
eth: Eth
6864
): Promise<Account> => {
69-
//@ts-ignore
70-
const { default: HDKey } = await import('hdkey')
71-
const ethUtil = await import('ethereumjs-util')
72-
73-
// @ts-ignore - Commonjs importing weirdness
74-
const { publicToAddress, toChecksumAddress } = ethUtil.default || ethUtil
75-
76-
const hdk = new HDKey()
77-
78-
hdk.publicKey = Buffer.from(publicKey, 'hex')
79-
hdk.chainCode = Buffer.from(chainCode, 'hex')
80-
81-
const dkey = hdk.deriveChild(index)
82-
83-
const address = toChecksumAddress(
84-
`0x${publicToAddress(dkey.publicKey, true).toString('hex')}`
85-
)
86-
65+
const dPath =
66+
derivationPath === LEDGER_LIVE_PATH
67+
? `${derivationPath}/${index}'/0/0`
68+
: `${derivationPath}/${index}`
69+
const { address } = await eth.getAddress(dPath)
8770
return {
88-
derivationPath: `${derivationPath}/${index}`,
71+
derivationPath: dPath,
8972
address,
9073
balance: {
9174
asset: asset.label,
@@ -95,9 +78,10 @@ const getAccount = async (
9578
}
9679

9780
const getAddresses = async (
98-
account: LedgerAccount,
81+
derivationPath: string,
9982
asset: Asset,
100-
provider: providers.StaticJsonRpcProvider
83+
provider: providers.StaticJsonRpcProvider,
84+
eth: Eth
10185
): Promise<Account[]> => {
10286
const accounts = []
10387
let index = 0
@@ -106,7 +90,7 @@ const getAddresses = async (
10690
// Iterates until a 0 balance account is found
10791
// Then adds 4 more 0 balance accounts to the array
10892
while (zeroBalanceAccounts < 5) {
109-
const acc = await getAccount(account, asset, index, provider)
93+
const acc = await getAccount(derivationPath, asset, index, provider, eth)
11094
if (acc.balance.value.isZero()) {
11195
zeroBalanceAccounts++
11296
accounts.push(acc)
@@ -135,7 +119,6 @@ function ledger({
135119
getInterface: async ({ EventEmitter, chains }: GetInterfaceHelpers) => {
136120
const Eth = (await import('@ledgerhq/hw-app-eth')).default
137121
const { default: Common, Hardfork } = await import('@ethereumjs/common')
138-
const { compress } = (await import('eth-crypto')).publicKey
139122
const ethUtil = await import('ethereumjs-util')
140123

141124
const { SignTypedDataVersion } = await import('@metamask/eth-sig-util')
@@ -165,18 +148,13 @@ function ledger({
165148
chains.find(({ id }: Chain) => id === chainId) || currentChain
166149
const provider = new StaticJsonRpcProvider(currentChain.rpcUrl)
167150

168-
const { publicKey, chainCode, address } = await eth.getAddress(
169-
derivationPath,
170-
false,
171-
true // set to true to return chainCode
172-
)
173-
174151
// Checks to see if this is a custom derivation path
175152
// If it is then just return the single account
176153
if (
177154
derivationPath !== LEDGER_LIVE_PATH &&
178155
derivationPath !== LEDGER_DEFAULT_PATH
179156
) {
157+
const { address } = await eth.getAddress(derivationPath)
180158
return [
181159
{
182160
derivationPath,
@@ -189,15 +167,7 @@ function ledger({
189167
]
190168
}
191169

192-
return getAddresses(
193-
{
194-
publicKey: compress(publicKey),
195-
chainCode: chainCode || '',
196-
derivationPath
197-
},
198-
asset,
199-
provider
200-
)
170+
return getAddresses(derivationPath, asset, provider, eth)
201171
} catch (error) {
202172
const { statusText } = error as { statusText: string }
203173
throw new Error(

0 commit comments

Comments
 (0)