11import Transport from "@ledgerhq/hw-transport"
22import TransportWebUSB from "@ledgerhq/hw-transport-webusb"
3+ import { toChecksumAddress } from "@tallyho/hd-keyring"
34import Eth from "@ledgerhq/hw-app-eth"
45import { DeviceModelId } from "@ledgerhq/devices"
56import {
@@ -25,7 +26,7 @@ import { ServiceCreatorFunction, ServiceLifecycleEvents } from "../types"
2526import logger from "../../lib/logger"
2627import { getOrCreateDB , LedgerAccount , LedgerDatabase } from "./db"
2728import { ethersTransactionFromTransactionRequest } from "../chain/utils"
28- import { NETWORK_FOR_LEDGER_SIGNING } from "../../constants"
29+ import { NETWORK_SUPPORTED_BY_LEDGER , ROOTSTOCK } from "../../constants"
2930import { normalizeEVMAddress } from "../../lib/utils"
3031import { AddressOnNetwork } from "../../accounts"
3132
@@ -113,15 +114,24 @@ type Events = ServiceLifecycleEvents & {
113114
114115export const idDerivationPath = "44'/60'/0'/0/0"
115116
117+ const ROOTSTOCK_DERIVATION_PATH = "44'/137'/0'/0"
118+
116119async function deriveAddressOnLedger ( path : string , eth : Eth ) {
117120 const derivedIdentifiers = await eth . getAddress ( path )
121+
122+ if ( path . includes ( ROOTSTOCK_DERIVATION_PATH . slice ( 0 , 8 ) ) ) {
123+ // ethersGetAddress rejects Rootstock addresses so using toChecksumAddress
124+ return toChecksumAddress ( derivedIdentifiers . address , + ROOTSTOCK . chainID )
125+ }
126+
118127 const address = ethersGetAddress ( derivedIdentifiers . address )
119128 return address
120129}
121130
122131async function generateLedgerId (
123132 transport : Transport ,
124- eth : Eth
133+ eth : Eth ,
134+ derivationPath : string
125135) : Promise < [ string | undefined , LedgerType ] > {
126136 let extensionDeviceType = LedgerType . UNKNOWN
127137
@@ -147,7 +157,7 @@ async function generateLedgerId(
147157 return [ undefined , extensionDeviceType ]
148158 }
149159
150- const address = await deriveAddressOnLedger ( idDerivationPath , eth )
160+ const address = await deriveAddressOnLedger ( derivationPath , eth )
151161
152162 return [ address , extensionDeviceType ]
153163}
@@ -172,6 +182,8 @@ async function generateLedgerId(
172182export default class LedgerService extends BaseService < Events > {
173183 #currentLedgerId: string | null = null
174184
185+ #derivationPath: string = idDerivationPath
186+
175187 transport : Transport | undefined = undefined
176188
177189 #lastOperationPromise = Promise . resolve ( )
@@ -209,7 +221,11 @@ export default class LedgerService extends BaseService<Events> {
209221
210222 const eth = new Eth ( this . transport )
211223
212- const [ id , type ] = await generateLedgerId ( this . transport , eth )
224+ const [ id , type ] = await generateLedgerId (
225+ this . transport ,
226+ eth ,
227+ this . #derivationPath
228+ )
213229
214230 if ( ! id ) {
215231 throw new Error ( "Can't derive meaningful identification address!" )
@@ -239,7 +255,7 @@ export default class LedgerService extends BaseService<Events> {
239255 this . emitter . emit ( "ledgerAdded" , {
240256 id : this . #currentLedgerId,
241257 type,
242- accountIDs : [ idDerivationPath ] ,
258+ accountIDs : [ this . #derivationPath ] ,
243259 metadata : {
244260 ethereumVersion : appData . version ,
245261 isArbitraryDataSigningEnabled : appData . arbitraryDataEnabled !== 0 ,
@@ -250,6 +266,10 @@ export default class LedgerService extends BaseService<Events> {
250266 } )
251267 }
252268
269+ setDefaultDerivationPath ( path : string ) : void {
270+ this . #derivationPath = path
271+ }
272+
253273 #handleUSBConnect = async ( event : USBConnectionEvent ) : Promise < void > => {
254274 this . emitter . emit (
255275 "usbDeviceCount" ,
@@ -535,7 +555,7 @@ export default class LedgerService extends BaseService<Events> {
535555 hexDataToSign : HexString
536556 ) : Promise < string > {
537557 if (
538- ! NETWORK_FOR_LEDGER_SIGNING . find ( ( supportedNetwork ) =>
558+ ! NETWORK_SUPPORTED_BY_LEDGER . find ( ( supportedNetwork ) =>
539559 sameNetwork ( network , supportedNetwork )
540560 )
541561 ) {
0 commit comments