-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create provider-ledger-react-native package
- Loading branch information
0 parents
commit 7794551
Showing
16 changed files
with
3,321 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
root = true | ||
|
||
[*] | ||
indent_style = space | ||
indent_size = 2 | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true | ||
|
||
[*.md] | ||
trim_trailing_whitespace = false |
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,34 @@ | ||
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created | ||
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages | ||
|
||
name: Node.js Package | ||
|
||
on: | ||
release: | ||
types: [created] | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/setup-node@v3 | ||
with: | ||
node-version: 16 | ||
- run: yarn install --frozen-lockfile | ||
- run: yarn test | ||
|
||
publish-npm: | ||
needs: build | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/setup-node@v3 | ||
with: | ||
node-version: 16 | ||
registry-url: https://registry.npmjs.org/ | ||
- run: yarn install --frozen-lockfile | ||
- run: yarn build | ||
- run: yarn publish --access public | ||
env: | ||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} |
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,78 @@ | ||
# OSX | ||
# | ||
.DS_Store | ||
|
||
# IntelliJ | ||
# | ||
build/ | ||
.idea | ||
.gradle | ||
local.properties | ||
*.iml | ||
*.hprof | ||
|
||
|
||
# VSCode | ||
.vscode/ | ||
jsconfig.json | ||
|
||
# Xcode | ||
# | ||
build/ | ||
*.pbxuser | ||
!default.pbxuser | ||
*.mode1v3 | ||
!default.mode1v3 | ||
*.mode2v3 | ||
!default.mode2v3 | ||
*.perspectivev3 | ||
!default.perspectivev3 | ||
xcuserdata | ||
*.xccheckout | ||
*.moved-aside | ||
DerivedData | ||
*.hmap | ||
*.ipa | ||
*.xcuserstate | ||
project.xcworkspace | ||
|
||
# Android/IJ | ||
# | ||
.classpath | ||
.cxx | ||
.gradle | ||
.idea | ||
.project | ||
.settings | ||
local.properties | ||
android.iml | ||
|
||
# Cocoapods | ||
# | ||
example/ios/Pods | ||
|
||
# Ruby | ||
example/vendor/ | ||
|
||
# node.js | ||
# | ||
node_modules/ | ||
npm-debug.log | ||
yarn-debug.log | ||
yarn-error.log | ||
|
||
# BUCK | ||
buck-out/ | ||
\.buckd/ | ||
android/app/libs | ||
android/keystores/debug.keystore | ||
|
||
# node.js | ||
# | ||
node_modules/ | ||
npm-debug.log | ||
yarn-error.log | ||
|
||
dist/ | ||
.npmrc | ||
.vscode/ |
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,15 @@ | ||
.DS_Store | ||
|
||
build/ | ||
.idea | ||
.gradle | ||
local.properties | ||
*.iml | ||
*.hprof | ||
|
||
node_modules/ | ||
npm-debug.log | ||
yarn-error.log | ||
.npmrc | ||
|
||
.github |
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 @@ | ||
v16.16.0 |
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,7 @@ | ||
module.exports = { | ||
arrowParens: 'avoid', | ||
bracketSameLine: true, | ||
bracketSpacing: false, | ||
singleQuote: true, | ||
trailingComma: 'all', | ||
}; |
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,7 @@ | ||
{ | ||
"transform": { | ||
"^.+\\.(t|j)sx?$": "ts-jest" | ||
}, | ||
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", | ||
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"] | ||
} |
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,35 @@ | ||
{ | ||
"name": "@haqq/provider-ledger-react-native", | ||
"version": "0.0.1", | ||
"description": "Provider for react-native ledger", | ||
"main": "index.js", | ||
"repository": "https://github.com/haqq-network/haqq-wallet-provider-ledger-react-native", | ||
"author": "vivalaakam", | ||
"license": "MIT", | ||
"private": false, | ||
"scripts": { | ||
"test": "jest --config jestconfig.json", | ||
"build": "tsc", | ||
"format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"", | ||
"lint": "tslint -p tsconfig.json" | ||
}, | ||
"dependencies": { | ||
"@ethersproject/abstract-provider": "^5.7.0", | ||
"@ledgerhq/hw-app-eth": "^6.30.3", | ||
"@ledgerhq/hw-transport": "^6.27.9", | ||
"@ledgerhq/react-native-hw-transport-ble": "^6.27.12", | ||
"ethers": "^5.7.2", | ||
"react-native-ble-plx": "^2.0.3" | ||
}, | ||
"devDependencies": { | ||
"@haqq/provider-base": "^0.0.7", | ||
"@types/jest": "^29.2.5", | ||
"@types/node": "^18.11.18", | ||
"jest": "^29.3.1", | ||
"prettier": "^2.8.1", | ||
"ts-jest": "^29.0.3", | ||
"tslint": "^6.1.3", | ||
"tslint-config-prettier": "^1.18.0", | ||
"typescript": "^4.9.4" | ||
} | ||
} |
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 @@ | ||
# Provider for ledger react-native |
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,2 @@ | ||
export * from './provider'; | ||
export * from './types'; |
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,168 @@ | ||
import {ProviderLedgerReactNativeOptions,} from './types'; | ||
import { | ||
compressPublicKey, | ||
Provider, | ||
ProviderInterface | ||
} from '@haqq/provider-base'; | ||
import {TransactionRequest} from '@ethersproject/abstract-provider'; | ||
import {UnsignedTransaction, utils} from 'ethers'; | ||
import AppEth, {ledgerService} from '@ledgerhq/hw-app-eth'; | ||
import TransportBLE from '@ledgerhq/react-native-hw-transport-ble'; | ||
import {BleManager, State} from 'react-native-ble-plx'; | ||
import {sleep} from './sleep'; | ||
|
||
const connectOptions = { | ||
requestMTU: 156, | ||
connectionPriority: 1, | ||
}; | ||
|
||
export class ProviderLedgerReactNative extends Provider<ProviderLedgerReactNativeOptions> implements ProviderInterface { | ||
public stop: boolean = false; | ||
private _transport: TransportBLE | null = null | ||
private _bleManager: BleManager | null = null | ||
|
||
async getBase64PublicKey() { | ||
let resp = '' | ||
try { | ||
if (!this._wallet.publicKey) { | ||
this.stop = false; | ||
|
||
const transport = await this.awaitForTransport(this._options.deviceId); | ||
if (!transport) { | ||
throw new Error('can_not_connected'); | ||
} | ||
const eth = new AppEth(transport); | ||
|
||
const response = await eth.getAddress(this._options.hdPath); | ||
|
||
this._wallet.publicKey = compressPublicKey(response.publicKey); | ||
} | ||
|
||
resp = Buffer.from(this._wallet.publicKey, 'hex').toString('base64'); | ||
} catch (e) { | ||
if (e instanceof Error) { | ||
this.emit('getBase64PublicKey', false, e.message); | ||
throw new Error(e.message); | ||
} | ||
} | ||
return resp | ||
} | ||
|
||
async getSignedTx(transaction: TransactionRequest) { | ||
let resp = '' | ||
try { | ||
this.stop = false; | ||
const unsignedTx = utils | ||
.serializeTransaction(transaction as UnsignedTransaction) | ||
.substring(2); | ||
const resolution = await ledgerService.resolveTransaction( | ||
unsignedTx, | ||
{}, | ||
{}, | ||
); | ||
|
||
const transport = await this.awaitForTransport(this._options.deviceId); | ||
|
||
if (!transport) { | ||
throw new Error('can_not_connected'); | ||
} | ||
|
||
const eth = new AppEth(transport); | ||
|
||
const signature = await eth.signTransaction(this._options.hdPath, unsignedTx, resolution); | ||
|
||
resp = utils.serializeTransaction(transaction as UnsignedTransaction, { | ||
...signature, | ||
r: '0x' + signature.r, | ||
s: '0x' + signature.s, | ||
v: parseInt(signature.v, 10), | ||
}); | ||
|
||
this.emit('getSignedTx', true); | ||
} catch (e) { | ||
if (e instanceof Error) { | ||
this.emit('getSignedTx', false, e.message); | ||
throw new Error(e.message); | ||
} | ||
} | ||
|
||
return resp | ||
} | ||
|
||
async signTypedData(domainHash: string, valuesHash: string) { | ||
let resp = '' | ||
try { | ||
this.stop = false; | ||
|
||
const transport = await this.awaitForTransport(this._options.deviceId); | ||
|
||
if (!transport) { | ||
throw new Error('can_not_connected') | ||
} | ||
|
||
const eth = new AppEth(transport); | ||
|
||
const signature = await eth.signEIP712HashedMessage(this._options.hdPath, domainHash, valuesHash); | ||
|
||
const v = (signature.v - 27).toString(16).padStart(2, '0'); | ||
resp = '0x' + signature.r + signature.s + v; | ||
|
||
this.emit('signTypedData', true); | ||
} catch (e) { | ||
if (e instanceof Error) { | ||
this.emit('signTypedData', false, e.message); | ||
throw new Error(e.message); | ||
} | ||
return ''; | ||
} | ||
|
||
return resp | ||
} | ||
|
||
abort() { | ||
this.emit('abortCall'); | ||
this.stop = true; | ||
} | ||
|
||
async awaitForTransport(deviceId: string) { | ||
if (!this._bleManager) { | ||
this._bleManager = new BleManager(); | ||
} | ||
while (!this._transport && !this.stop) { | ||
try { | ||
const state = await this._bleManager.state(); | ||
|
||
if (state !== State.PoweredOn) { | ||
throw new Error(`not_connected ${state}`); | ||
} | ||
|
||
const device = await this._bleManager.connectToDevice( | ||
deviceId, | ||
connectOptions, | ||
); | ||
|
||
const isConnected = await device.isConnected(); | ||
|
||
if (!isConnected) { | ||
await device.connect(); | ||
} | ||
|
||
this._transport = await TransportBLE.open(device); | ||
if (this._transport) { | ||
this._transport.on('disconnect', this.onDisconnectTransport) | ||
} | ||
} catch (e) { | ||
this.emit('awaitForTransport', new Date(), e) | ||
await sleep(500); | ||
} | ||
} | ||
|
||
return this._transport | ||
} | ||
|
||
onDisconnectTransport = () => { | ||
if (this._transport) { | ||
this._transport.off('disconnect', this.onDisconnectTransport) | ||
} | ||
} | ||
} |
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,5 @@ | ||
export function sleep(duration: number) { | ||
return new Promise(resolve => { | ||
setTimeout(resolve, duration); | ||
}); | ||
} |
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,4 @@ | ||
export type ProviderLedgerReactNativeOptions = { | ||
deviceId: string; | ||
hdPath: string; | ||
} |
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,14 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es5", | ||
"module": "commonjs", | ||
"esModuleInterop": true, | ||
"skipLibCheck": true, | ||
"declaration": true, | ||
"outDir": "./dist", | ||
"strict": true | ||
}, | ||
"include": ["src"], | ||
"exclude": ["node_modules", "**/__tests__/*"] | ||
} | ||
|
Oops, something went wrong.