Skip to content
This repository has been archived by the owner on Oct 10, 2023. It is now read-only.

Commit

Permalink
WIP: thorchain-ledger + hid-singleton
Browse files Browse the repository at this point in the history
  • Loading branch information
veado committed Jul 20, 2021
1 parent 79ffafc commit 2082d28
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 91 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,13 @@
"@devexperts/remote-data-ts": "^2.0.5",
"@devexperts/rx-utils": "^1.0.0-alpha.14",
"@devexperts/utils": "^1.0.0-alpha.14",
"@ledgerhq/hw-transport-webusb": "^6.1.0",
"@ledgerhq/hw-transport-node-hid-singleton": "^6.2.0",
"@openapitools/openapi-generator-cli": "^2.3.5",
"@psf/bitcoincashjs-lib": "^4.0.2",
"@thorchain/asgardex-midgard": "^1.1.0",
"@thorchain/asgardex-theme": "^0.1.1",
"@thorchain/asgardex-util": "^0.9.1",
"@thorchain/ledger-thorchain": "^0.0.3",
"@types/electron-devtools-installer": "^2.2.0",
"@xchainjs/xchain-binance": "^5.2.4",
"@xchainjs/xchain-bitcoin": "0.15.11",
Expand Down
6 changes: 2 additions & 4 deletions src/main/api/ledger/address.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import TransportWebUSB from '@ledgerhq/hw-transport-webusb'
import TransportNodeHidSingleton from '@ledgerhq/hw-transport-node-hid-singleton'
import { Chain, THORChain } from '@xchainjs/xchain-util'
import * as E from 'fp-ts/Either'

import { LedgerErrorId, Network } from '../../../shared/api/types'
// import { getAddress as getBNBAddress } from './binance'
// import { getAddress as getBTCAddress } from './bitcoin'
import { getAddress as getTHORAddress } from './thorchain'
import { getErrorId } from './utils'

export const getAddress = async (chain: Chain, network: Network) => {
try {
const transport = await TransportWebUSB.create()
let res: E.Either<LedgerErrorId, string>
const transport = await TransportNodeHidSingleton.open()
switch (chain) {
case THORChain:
res = await getTHORAddress(transport, network)
Expand Down
4 changes: 2 additions & 2 deletions src/main/api/ledger/common.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import TransportWebUSB from '@ledgerhq/hw-transport-webusb'
import TransportNodeHidSingleton from '@ledgerhq/hw-transport-node-hid-singleton'

export const getTransport = async () => await TransportWebUSB.create()
export const getTransport = async () => await TransportNodeHidSingleton.open()
18 changes: 10 additions & 8 deletions src/main/api/ledger/thorchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as Client from '@xchainjs/xchain-client'
import { getPrefix } from '@xchainjs/xchain-thorchain'
import * as E from 'fp-ts/Either'

import { LedgerErrorId, Network } from '../../../shared/api/types'
import { Network } from '../../../shared/api/types'
import { getErrorId } from './utils'

// TODO(@Veado) Move `toClientNetwork` from `renderer/services/clients` to `main/util` or so
Expand All @@ -17,14 +17,16 @@ export const getAddress = async (transport: Transport, network: Network) => {
try {
const app = new THORChainApp(transport)
const clientNetwork = toClientNetwork(network)
const response = await app.getAddressAndPubKey(PATH, getPrefix(clientNetwork))
if (response.return_code !== 0x9000) {
// TODO(@Veado) get address from pubkey
return E.right('my-address')
} else {
return E.left(LedgerErrorId.UNKNOWN)
const prefix = getPrefix(clientNetwork)
console.log('clientNetwork:', clientNetwork)
console.log('prefix:', prefix)
const res = await app.getAddressAndPubKey(PATH, prefix)
console.log('response:', res)
if (!res.bech32_address || res.return_code !== 0x9000 /* ERROR_CODE.NoError */) {
return E.left(res.return_code.toString())
}
return E.right(res.bech32_address)
} catch (error) {
return E.left(getErrorId(error.toString()))
return E.left(getErrorId(error))
}
}
2 changes: 1 addition & 1 deletion src/main/electron.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ const initIPC = () => {
)
ipcMain.handle(IPCMessages.LOAD_KEYSTORE, () => loadKeystore())
// Ledger
ipcMain.handle(IPCMessages.GET_LEDGER_ADDRESS, (_, chain: Chain, network: Network) =>
ipcMain.handle(IPCMessages.GET_LEDGER_ADDRESS, async (_, chain: Chain, network: Network) =>
getLedgerAddress(chain, network)
)
ipcMain.handle(IPCMessages.SEND_LEDGER_TX, (_, chain: Chain, network: Network, txInfo: LedgerTxInfo) =>
Expand Down
43 changes: 3 additions & 40 deletions src/renderer/hooks/useLedger.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,18 @@
import { useCallback, useMemo } from 'react'

import * as RD from '@devexperts/remote-data-ts'
import Transport from '@ledgerhq/hw-transport'
import THORChainApp from '@thorchain/ledger-thorchain'
import { getPrefix as getTHORPrefix } from '@xchainjs/xchain-thorchain'
import { Chain } from '@xchainjs/xchain-util'
import * as E from 'fp-ts/Either'
import * as FP from 'fp-ts/function'
import { useObservableState } from 'observable-hooks'
import * as Rx from 'rxjs'
import * as RxOp from 'rxjs/operators'

import { LedgerErrorId, Network } from '../../shared/api/types'
import { Network } from '../../shared/api/types'
import { useAppContext } from '../contexts/AppContext'
import { observableState } from '../helpers/stateHelper'
import { toClientNetwork } from '../services/clients'
import { DEFAULT_NETWORK } from '../services/const'
import { LedgerAddressRD } from '../services/wallet/types'

// TODO(@veado) Get path by using `xchain-thorchain`
const PATH = [44, 931, 0, 0, 0]

export const getTHORAddress = async (transport: Transport, network: Network) => {
try {
const app = new THORChainApp(transport)
const clientNetwork = toClientNetwork(network)
const response = await app.getAddressAndPubKey(PATH, getTHORPrefix(clientNetwork))
if (response.return_code !== 0x9000) {
// TODO(@Veado) get address from pubkey
return E.right('my-address')
} else {
return E.left(LedgerErrorId.UNKNOWN)
}
} catch (error) {
return E.left(LedgerErrorId.WRONG_APP)
}
}

export const useLedger = () => {
const { network$ } = useAppContext()
const network = useObservableState<Network>(network$, DEFAULT_NETWORK)
Expand All @@ -46,10 +22,9 @@ export const useLedger = () => {
const addressRD = useObservableState(FP.pipe(address$, RxOp.shareReplay(1)), RD.initial)

const getAddress = useCallback(
(_chain: Chain) => {
(chain: Chain) => {
FP.pipe(
Rx.from(window.apiHDWallet.getTransport()),
RxOp.switchMap((transport) => Rx.from(getTHORAddress(transport, network))),
Rx.from(window.apiHDWallet.getLedgerAddress(chain, network)),
RxOp.map(RD.fromEither),
RxOp.startWith(RD.pending),
RxOp.catchError((error) => Rx.of(RD.failure(error)))
Expand All @@ -58,18 +33,6 @@ export const useLedger = () => {
[network, setAddress]
)

// const getAddress = useCallback(
// (chain: Chain) => {
// FP.pipe(
// Rx.from(window.apiHDWallet.getLedgerAddress(chain, network)),
// RxOp.map(RD.fromEither),
// RxOp.startWith(RD.pending),
// RxOp.catchError((error) => Rx.of(RD.failure(error)))
// ).subscribe(setAddress)
// },
// [network, setAddress]
// )

return {
getAddress,
address: addressRD
Expand Down
3 changes: 1 addition & 2 deletions src/shared/mock/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Transport from '@ledgerhq/hw-transport'
import { Keystore } from '@xchainjs/xchain-crypto'
import * as E from 'fp-ts/Either'

Expand Down Expand Up @@ -79,5 +78,5 @@ export const apiUrl: ApiUrl = {
export const apiHDWallet: ApiHDWallet = {
getLedgerAddress: () => Promise.resolve(E.right('ledger_address')),
sendTxInLedger: () => Promise.resolve(E.right('tx_hash')),
getTransport: () => Promise.resolve({} as Transport)
getTransport: () => Promise.reject(Error('`getTransport` is not implemented'))
}
105 changes: 72 additions & 33 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2251,13 +2251,13 @@
rxjs "6"
semver "^7.3.5"

"@ledgerhq/devices@^6.1.0":
version "6.1.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-6.1.0.tgz#54963409011c0bb83e2cc3d4d55ad9b905e296ff"
integrity sha512-Swl08sVuvx7IL9yx9P0ZzvwjIl4JXl51X34Po3pT2uRRaLnh/fRRSNe9tSC1gFMioviiLJlkmO+yydE4XeV+Jg==
"@ledgerhq/devices@^6.2.0":
version "6.2.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-6.2.0.tgz#2dd38ff81bb72d5d93eb9137574ef53a83f68b78"
integrity sha512-X64YWq29E0Ogqb5HPeNjzLaDxre4yPK9yv3AJ3ttTCNrES4qM/QPkb1E/rAhD75LTXVBDb8NKJRPA9fKKLpdcg==
dependencies:
"@ledgerhq/errors" "^6.0.2"
"@ledgerhq/logs" "^6.0.2"
"@ledgerhq/errors" "^6.2.0"
"@ledgerhq/logs" "^6.2.0"
rxjs "6"
semver "^7.3.5"

Expand All @@ -2266,10 +2266,10 @@
resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-5.50.0.tgz#e3a6834cb8c19346efca214c1af84ed28e69dad9"
integrity sha512-gu6aJ/BHuRlpU7kgVpy2vcYk6atjB4iauP2ymF7Gk0ez0Y/6VSMVSJvubeEQN+IV60+OBK0JgeIZG7OiHaw8ow==

"@ledgerhq/errors@^6.0.2":
version "6.0.2"
resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-6.0.2.tgz#7c88d16620db08c96de6a2636440db1c0e541da1"
integrity sha512-m42ZMzR/EKpOrZfPR3DzusE98DoF3d03cbBkQG6ddm6diwVXFSa7MabaKzgD+41EYQ+hrCGOEZK1K0kosX1itg==
"@ledgerhq/errors@^6.2.0":
version "6.2.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-6.2.0.tgz#7dc2b3bf6bdedccdaa1b97dccacfa912c4fc22f8"
integrity sha512-eO03x8HJmG60WtlrMuahigW/rwywFdcGzCnihta/MjkM8BD9A660cKVkyIuheCcpaB7UV/r+QsRl9abHbjjaag==

"@ledgerhq/hw-transport-node-hid-noevents@^5.51.1":
version "5.51.1"
Expand All @@ -2282,6 +2282,31 @@
"@ledgerhq/logs" "^5.50.0"
node-hid "2.1.1"

"@ledgerhq/hw-transport-node-hid-noevents@^6.2.0":
version "6.2.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-6.2.0.tgz#334232c686c49be28a3c9e78b302d02a4598b85b"
integrity sha512-SZOE/YD6kScWrXkqH9EOclStYrJiyCEIVjXLRQUgiCZ9fgVo4N6XBRcrBoDagT2gyQHLCEBR21RvIe8h2M7DXg==
dependencies:
"@ledgerhq/devices" "^6.2.0"
"@ledgerhq/errors" "^6.2.0"
"@ledgerhq/hw-transport" "^6.2.0"
"@ledgerhq/logs" "^6.2.0"
node-hid "2.1.1"

"@ledgerhq/hw-transport-node-hid-singleton@^6.2.0":
version "6.2.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid-singleton/-/hw-transport-node-hid-singleton-6.2.0.tgz#def123f3ca2defa2d394157112011d79ddd38cd7"
integrity sha512-9I3g40zelqIntXQ+oaMkj4a2IlUr5/9O2JYynoAEc2X1Lre67Un6c3sXU/zSiiMtwrfMgcUceALj1bG0Efh+tw==
dependencies:
"@ledgerhq/devices" "^6.2.0"
"@ledgerhq/errors" "^6.2.0"
"@ledgerhq/hw-transport" "^6.2.0"
"@ledgerhq/hw-transport-node-hid-noevents" "^6.2.0"
"@ledgerhq/logs" "^6.2.0"
lodash "^4.17.21"
node-hid "2.1.1"
usb-detection "^4.10.0"

"@ledgerhq/hw-transport-node-hid@^5.10.0":
version "5.51.1"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-5.51.1.tgz#fe8eb81e18929663540698c80905952cdbe542d5"
Expand Down Expand Up @@ -2317,16 +2342,6 @@
"@ledgerhq/logs" "^5.50.0"
rxjs "6"

"@ledgerhq/hw-transport-webusb@^6.1.0":
version "6.1.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-webusb/-/hw-transport-webusb-6.1.0.tgz#47f779c000de6b1f6d7e3b44805bcc18beea416c"
integrity sha512-UsfB9UcDgAo6ykO40Ai8qimv/VYvGwZVIe65nUGs6JK+2PRnkuk2i00FTK3NTgmvIeX4cOIlkg8+ZmGQuB8Evw==
dependencies:
"@ledgerhq/devices" "^6.1.0"
"@ledgerhq/errors" "^6.0.2"
"@ledgerhq/hw-transport" "^6.1.0"
"@ledgerhq/logs" "^6.0.2"

"@ledgerhq/hw-transport@^5.34.0", "@ledgerhq/hw-transport@^5.51.1":
version "5.51.1"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-5.51.1.tgz#8dd14a8e58cbee4df0c29eaeef983a79f5f22578"
Expand All @@ -2336,24 +2351,24 @@
"@ledgerhq/errors" "^5.50.0"
events "^3.3.0"

"@ledgerhq/hw-transport@^6.1.0":
version "6.1.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-6.1.0.tgz#b50151c6199e9ad6d3ab9e447532a22170c9f3b7"
integrity sha512-j9IyvksI9PjFoFrk/B3p8wCXWRWc8uK24gc20pAaXQiDtqMkWqEge8iZyPKWBVIv69vDQF3LE3Y6EeRwwA7wJA==
"@ledgerhq/hw-transport@^6.1.0", "@ledgerhq/hw-transport@^6.2.0":
version "6.2.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-6.2.0.tgz#b3bf21e6d8a0552bf67b0d0be5139c6b855ba5ca"
integrity sha512-6Yz6Hm5fbjdNhbOFb86H6q4o92DHm9HaPXdavk7PM9VXTcdyz4d7BjIZxlVTmoa4+4nWjfere5o+psAl1WD+Ug==
dependencies:
"@ledgerhq/devices" "^6.1.0"
"@ledgerhq/errors" "^6.0.2"
"@ledgerhq/devices" "^6.2.0"
"@ledgerhq/errors" "^6.2.0"
events "^3.3.0"

"@ledgerhq/logs@^5.30.0", "@ledgerhq/logs@^5.50.0":
version "5.50.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-5.50.0.tgz#29c6419e8379d496ab6d0426eadf3c4d100cd186"
integrity sha512-swKHYCOZUGyVt4ge0u8a7AwNcA//h4nx5wIi0sruGye1IJ5Cva0GyK9L2/WdX+kWVTKp92ZiEo1df31lrWGPgA==

"@ledgerhq/logs@^6.0.2":
version "6.0.2"
resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-6.0.2.tgz#a6063ed99461c0d2c36a48de89ed0283f13cb908"
integrity sha512-4lU3WBwugG+I/dv/qE8HQ2f7MNsKfU58FEzSE1PAELvW96umrlO4ogwuO1tRCPmrtOo9ssam1QVYotwELY8zvw==
"@ledgerhq/logs@^6.2.0":
version "6.2.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-6.2.0.tgz#9fb2d6f1811316697f7b3cc14607f6c608912419"
integrity sha512-SLyFyD7ElMhgKWPYedFGCT/ilcbGPgL5hXXYHxOM79Fs5fWi0zaUpt5oGqGMsOAAFaMa9/rbun0pokzPhEFz8A==

"@malept/cross-spawn-promise@^1.1.0":
version "1.1.1"
Expand Down Expand Up @@ -3487,6 +3502,15 @@
resolved "https://registry.yarnpkg.com/@thorchain/asgardex-util/-/asgardex-util-0.9.1.tgz#06b75eb6642adae7c4924c37b23f1d5ab41bb33d"
integrity sha512-+w5jTojttZo0ku7t3cGsrnhymaeBnrWfhzypW1/TWL8Vup1XfHJmYrb60Iel2cftMJp4hlJF6ZmBwUJGbV0Ugg==

"@thorchain/ledger-thorchain@^0.0.3":
version "0.0.3"
resolved "https://registry.yarnpkg.com/@thorchain/ledger-thorchain/-/ledger-thorchain-0.0.3.tgz#4ddfc755ba26910d57730d83e5e89e86f8d1281d"
integrity sha512-jYv20JLtuRSHSoZOoZgpsuozv2/W3KDSgwvnU3CHITHlt/VNgL9oc+emTv6RU6nJFj30BuOvuA3RAzhsjtjvtg==
dependencies:
"@ledgerhq/hw-transport" "^6.1.0"
bech32 "^2.0.0"
ripemd160 "^2.0.2"

"@tootallnate/once@1":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
Expand Down Expand Up @@ -5651,7 +5675,7 @@ bchaddrjs@^0.5.2:
cashaddrjs "0.4.4"
stream-browserify "^3.0.0"

bech32@*:
bech32@*, bech32@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/bech32/-/bech32-2.0.0.tgz#078d3686535075c8c79709f054b1b226a133b355"
integrity sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==
Expand Down Expand Up @@ -9038,6 +9062,11 @@ [email protected]:
resolved "https://registry.yarnpkg.com/event-pubsub/-/event-pubsub-4.3.0.tgz#f68d816bc29f1ec02c539dc58c8dd40ce72cb36e"
integrity sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==

eventemitter2@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-5.0.1.tgz#6197a095d5fb6b57e8942f6fd7eaad63a09c9452"
integrity sha1-YZegldX7a1folC9v1+qtY6CclFI=

eventemitter3@^4.0.0:
version "4.0.7"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
Expand Down Expand Up @@ -14837,7 +14866,7 @@ postcss@^8.1.0:
nanoid "^3.1.23"
source-map-js "^0.6.2"

prebuild-install@^5.3.3:
prebuild-install@^5.3.3, prebuild-install@^5.3.5:
version "5.3.6"
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.3.6.tgz#7c225568d864c71d89d07f8796042733a3f54291"
integrity sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==
Expand Down Expand Up @@ -16562,7 +16591,7 @@ rimraf@~2.6.2:
dependencies:
glob "^7.1.3"

ripemd160@^2.0.0, ripemd160@^2.0.1:
ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==
Expand Down Expand Up @@ -18927,6 +18956,16 @@ url@^0.11.0:
punycode "1.3.2"
querystring "0.2.0"

usb-detection@^4.10.0:
version "4.10.0"
resolved "https://registry.yarnpkg.com/usb-detection/-/usb-detection-4.10.0.tgz#0f8a3b8965a5e4e7fbee1667971ca97e455ed11f"
integrity sha512-YUzVWXwfSviE2pInXCKYXhR5heY9GUzlWsdZYxb/Br1Xela6P31A0KDHm7XW0Wsku1HwrokZx+/OD8cZSPHR3w==
dependencies:
bindings "^1.3.0"
eventemitter2 "^5.0.1"
nan "^2.13.2"
prebuild-install "^5.3.5"

usb@^1.7.0:
version "1.7.1"
resolved "https://registry.yarnpkg.com/usb/-/usb-1.7.1.tgz#d723223ec517b802c4d2082e31a4649c65c491c5"
Expand Down

0 comments on commit 2082d28

Please sign in to comment.