-
Notifications
You must be signed in to change notification settings - Fork 202
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d9ac8c9
commit 9807132
Showing
14 changed files
with
8,502 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# 🌟 Injective Protocol - Ledger Wallet Strategy | ||
|
||
<!-- TODO --> | ||
|
||
[](https://www.npmjs.com/package/@injectivelabs/wallet-ts) | ||
[](https://www.npmjs.com/package/@injectivelabs/wallet-ts) | ||
[]() | ||
|
||
_Package to use Ledger Wallets on Injective via the wallet strategy._ | ||
|
||
--- | ||
|
||
## 📚 Installation | ||
|
||
```bash | ||
yarn add @injectivelabs/wallet-ledger | ||
``` | ||
|
||
--- | ||
|
||
## 📖 Documentation | ||
|
||
<!-- TODO --> | ||
|
||
Read more and find example usages on our [WalletStrategy Docs](https://docs.ts.injective.network/wallet/wallet-wallet-strategy) | ||
|
||
--- | ||
|
||
## 📜 Contribution | ||
|
||
**Contribution guides and practices will be available once there is a stable foundation of the whole package set within the `injective-ts` repo.** | ||
|
||
--- | ||
|
||
## ⛑ Support | ||
|
||
Reach out to us at one of the following places! | ||
|
||
- Website at <a href="https://injective.com" target="_blank">`injective.com`</a> | ||
- Twitter at <a href="https://twitter.com/Injective_" target="_blank">`@Injective`</a> | ||
- Discord at <a href="https://discord.com/invite/NK4qdbv" target="_blank">`Discord`</a> | ||
- Telegram at <a href="https://t.me/joininjective" target="_blank">`Telegram`</a> | ||
|
||
--- | ||
|
||
## 🔓 License | ||
|
||
Copyright © 2021 - 2022 Injective Labs Inc. (https://injectivelabs.org/) | ||
|
||
<a href="https://iili.io/mNneZN.md.png"><img src="https://iili.io/mNneZN.md.png" style="width: 300px; max-width: 100%; height: auto" /> | ||
|
||
Originally released by Injective Labs Inc. under: <br /> | ||
Apache License <br /> | ||
Version 2.0, January 2004 <br /> | ||
http://www.apache.org/licenses/ | ||
|
||
<p> </p> | ||
<div align="center"> | ||
<sub><em>Powering the future of decentralized finance.</em></sub> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
{ | ||
"name": "@injectivelabs/wallet-trezor", | ||
"description": "Trezor wallet strategy for use with @injectivelabs/wallet-core.", | ||
"version": "0.0.1", | ||
"sideEffects": false, | ||
"author": { | ||
"name": "InjectiveLabs", | ||
"email": "admin@injectivelabs.org" | ||
}, | ||
"license": "Apache-2.0", | ||
"types": "dist/cjs/index.d.ts", | ||
"main": "dist/cjs/index.js", | ||
"module": "dist/esm/index.js", | ||
"files": [ | ||
"dist" | ||
], | ||
"_moduleAliases": { | ||
"~wallet-trezor": "dist" | ||
}, | ||
"scripts": { | ||
"postinstall": "link-module-alias", | ||
"build:cjs": "BUILD_MODE=cjs tsc --build tsconfig.build.json", | ||
"build:esm": "BUILD_MODE=esm tsc --build tsconfig.build.esm.json", | ||
"build": "yarn build:esm && yarn build:cjs && yarn build:post && link-module-alias", | ||
"build:watch": "tsc --build -w tsconfig.build.json && tsc -w --build tsconfig.build.esm.json && yarn build:post && link-module-alias", | ||
"build:post": "shx cp ../../../etc/stub/package.json.stub dist/cjs/package.json && shx cp ../../../etc/stub/package.esm.json.stub dist/esm/package.json", | ||
"clean": "tsc --build tsconfig.build.json --clean && tsc --build tsconfig.build.esm.json --clean && shx rm -rf coverage *.log junit.xml dist && jest --clearCache && shx mkdir -p dist", | ||
"test": "jest", | ||
"test:watch": "jest --watch", | ||
"test:ci": "jest --coverage --ci --reporters='jest-junit'", | ||
"coverage": "jest --coverage", | ||
"coverage:show": "live-server coverage", | ||
"dev": "ts-node -r tsconfig-paths/register src/index.ts", | ||
"start": "node dist/index.js" | ||
}, | ||
"dependencies": { | ||
"@ethereumjs/common": "^3.1.1", | ||
"@ethereumjs/tx": "^4.1.1", | ||
"@injectivelabs/exceptions": "^1.14.14", | ||
"@injectivelabs/networks": "^1.14.15-beta.0", | ||
"@injectivelabs/sdk-ts": "^1.14.15-beta.9", | ||
"@injectivelabs/ts-types": "^1.14.14", | ||
"@injectivelabs/utils": "^1.14.14", | ||
"@injectivelabs/wallet-base": "^0.0.1", | ||
"alchemy-sdk": "^2.6.3", | ||
"eip1193-provider": "^1.0.1", | ||
"eth-sig-util": "^3.0.1", | ||
"ethereumjs-util": "^7.1.0", | ||
"ethers": "^6.5.1", | ||
"hdkey": "^2.0.1", | ||
"@trezor/connect-web": "9.2.1", | ||
"link-module-alias": "^1.2.0", | ||
"long": "^5.2.1", | ||
"shx": "^0.3.3" | ||
}, | ||
"devDependencies": { | ||
"@types/eth-sig-util": "^2.1.1", | ||
"@types/ethereumjs-util": "^6.1.0", | ||
"@types/hdkey": "^2.0.1" | ||
}, | ||
"resolutions": { | ||
"**/libsodium": "npm:@bangjelkoski/noop", | ||
"**/libsodium-wrappers": "npm:@bangjelkoski/noop" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export { TrezorWallet as TrezorWalletStrategy } from './strategy/strategy' | ||
|
||
export * from './types' |
108 changes: 108 additions & 0 deletions
108
packages/wallets/wallet-trezor/src/strategy/hw/AccountManager.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* eslint-disable class-methods-use-this */ | ||
import { AccountAddress } from '@injectivelabs/ts-types' | ||
import HDNode from 'hdkey' | ||
import { addHexPrefix, publicToAddress } from 'ethereumjs-util' | ||
import { TrezorWalletInfo } from '../../types' | ||
import { | ||
DEFAULT_NUM_ADDRESSES_TO_FETCH, | ||
DEFAULT_BASE_DERIVATION_PATH, | ||
} from '@injectivelabs/wallet-base' | ||
|
||
const addressOfHDKey = (hdKey: HDNode): string => { | ||
const shouldSanitizePublicKey = true | ||
const derivedPublicKey = hdKey.publicKey | ||
const ethereumAddressWithoutPrefix = publicToAddress( | ||
derivedPublicKey, | ||
shouldSanitizePublicKey, | ||
).toString('hex') | ||
const address = addHexPrefix(ethereumAddressWithoutPrefix) | ||
|
||
return address | ||
} | ||
|
||
export default class AccountManager { | ||
private wallets: TrezorWalletInfo[] = [] | ||
|
||
private hdKey: HDNode | ||
|
||
constructor(hdKey: HDNode) { | ||
this.wallets = [] | ||
this.hdKey = hdKey | ||
} | ||
|
||
async getWallets(): Promise<TrezorWalletInfo[]> { | ||
const { start, end } = this.getOffset() | ||
|
||
/** | ||
* 1. Wallets are not yet fetched at all, | ||
* 2. Wallets are not yet fetched for that offset | ||
*/ | ||
if (!this.hasWallets() || !this.hasWalletsInOffset(start)) { | ||
await this.getWalletsBasedOnIndex({ | ||
start, | ||
end, | ||
}) | ||
} | ||
|
||
return this.wallets.slice(start, end) | ||
} | ||
|
||
private async getWalletsBasedOnIndex({ | ||
start, | ||
end, | ||
}: { | ||
start: number | ||
end: number | ||
}) { | ||
for (let index = start; index < end; index += 1) { | ||
const path = `m/${index}` | ||
const hdKey = this.hdKey.derive(path) | ||
const address = addressOfHDKey(hdKey) | ||
|
||
this.wallets.push({ | ||
hdKey, | ||
address: address.toLowerCase(), | ||
derivationPath: `${DEFAULT_BASE_DERIVATION_PATH}/0'/0/${index}`, | ||
}) | ||
} | ||
} | ||
|
||
private hasWallets(): boolean { | ||
return this.wallets.length > 0 | ||
} | ||
|
||
private hasWalletsInOffset(offset: number): boolean { | ||
return this.wallets.length > offset | ||
} | ||
|
||
private getOffset(): { start: number; end: number } { | ||
const totalWallets = this.wallets.length | ||
const nextBatchStart = totalWallets | ||
const nextBatchEnd = totalWallets + DEFAULT_NUM_ADDRESSES_TO_FETCH | ||
|
||
return { | ||
start: nextBatchStart, | ||
end: nextBatchEnd, | ||
} | ||
} | ||
|
||
hasWalletForAddress(address: AccountAddress): boolean { | ||
return ( | ||
this.wallets.find( | ||
(wallet) => wallet.address.toLowerCase() === address.toLowerCase(), | ||
) !== undefined | ||
) | ||
} | ||
|
||
async getWalletForAddress( | ||
address: AccountAddress, | ||
): Promise<TrezorWalletInfo | undefined> { | ||
return this.wallets.find( | ||
(wallet) => wallet.address.toLowerCase() === address.toLowerCase(), | ||
) | ||
} | ||
|
||
reset() { | ||
this.wallets = [] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import TrezorConnect from '@trezor/connect-web' | ||
import HDNode from 'hdkey' | ||
import { DEFAULT_BASE_DERIVATION_PATH } from '@injectivelabs/wallet-base' | ||
import AccountManager from './AccountManager' | ||
|
||
// @ts-ignore | ||
const trezorConnect = TrezorConnect.default || TrezorConnect | ||
|
||
const TREZOR_CONNECT_MANIFEST = { | ||
email: 'contact@injectivelabs.org', | ||
appUrl: 'https://injectivelabs.org', | ||
} | ||
|
||
export default class TrezorTransport { | ||
private accountManager: AccountManager | null = null | ||
|
||
private hdKey: HDNode = new HDNode() | ||
|
||
constructor() { | ||
trezorConnect.init({ lazyLoad: true, manifest: TREZOR_CONNECT_MANIFEST }) | ||
} | ||
|
||
async connect() { | ||
await this.init() | ||
} | ||
|
||
async getAccountManager(): Promise<AccountManager> { | ||
if (!this.accountManager) { | ||
this.accountManager = new AccountManager(this.hdKey) | ||
} | ||
|
||
return this.accountManager | ||
} | ||
|
||
private isUnlocked() { | ||
return Boolean(this.hdKey && this.hdKey.publicKey) | ||
} | ||
|
||
private async init() { | ||
if (this.isUnlocked()) { | ||
return Promise.resolve() | ||
} | ||
|
||
return new Promise((resolve, reject) => { | ||
TrezorConnect.getPublicKey({ | ||
path: `${DEFAULT_BASE_DERIVATION_PATH}/0'/0`, | ||
coin: 'ETH', | ||
}) | ||
.then((response: any) => { | ||
if (!response.success) { | ||
return reject( | ||
new Error( | ||
(response.payload && response.payload.error) || | ||
'Please make sure your Trezor is connected and unlocked', | ||
), | ||
) | ||
} | ||
|
||
this.hdKey.publicKey = Buffer.from(response.payload.publicKey, 'hex') | ||
this.hdKey.chainCode = Buffer.from(response.payload.chainCode, 'hex') | ||
|
||
return resolve(TrezorConnect) | ||
}) | ||
.catch((e: any) => { | ||
reject( | ||
new Error( | ||
(e && e.toString()) || | ||
'Please make sure your Trezor is connected and unlocked', | ||
), | ||
) | ||
}) | ||
}) | ||
} | ||
} |
Oops, something went wrong.