Skip to content

Commit

Permalink
feat: scan devices
Browse files Browse the repository at this point in the history
  • Loading branch information
vivalaakam committed Jan 11, 2023
1 parent 9369d07 commit dc6c6ab
Show file tree
Hide file tree
Showing 7 changed files with 3,432 additions and 95 deletions.
21 changes: 16 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"name": "@haqq/provider-ledger-react-native",
"version": "0.0.1",
"description": "Provider for react-native ledger",
"main": "index.js",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"repository": "https://github.com/haqq-network/haqq-wallet-provider-ledger-react-native",
"author": "vivalaakam",
"license": "MIT",
Expand All @@ -15,18 +16,28 @@
},
"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",
"@ledgerhq/hw-app-eth": "6.30.0",
"@ledgerhq/hw-transport": "^6.27.8",
"@ledgerhq/react-native-hw-transport-ble": "6.27.9",
"ethers": "^5.7.2",
"react-native-ble-plx": "^2.0.3"
"events": "^3.3.0",
"rxjs": "^7.8.0"
},
"peerDependencies": {
"react": "*",
"react-native": "*",
"react-native-ble-plx": "*"
},
"devDependencies": {
"@types/react-native": "^0.70.6",
"@haqq/provider-base": "^0.0.7",
"@types/jest": "^29.2.5",
"@types/node": "^18.11.18",
"jest": "^29.3.1",
"prettier": "^2.8.1",
"react": "18.2.0",
"react-native": "0.70.6",
"react-native-ble-plx": "^2.0.3",
"ts-jest": "^29.0.3",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0",
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export * from './provider';
export * from './types';
export * from './scan-devices';
export * from './try-to-init-bt';
24 changes: 24 additions & 0 deletions src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,30 @@ export class ProviderLedgerReactNative extends Provider<ProviderLedgerReactNativ
this.stop = true;
}

async confirmAddress(hdPath: 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 response = await eth.getAddress(hdPath, true);

resp = response.address
this.emit('confirmAddress', true);
} catch (e) {
if (e instanceof Error) {
this.emit('confirmAddress', false, e.message);
throw new Error(e.message);
}
}
return resp
}

async awaitForTransport(deviceId: string) {
if (!this._bleManager) {
this._bleManager = new BleManager();
Expand Down
63 changes: 63 additions & 0 deletions src/scan-devices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {Observable, Subscription} from 'rxjs';
import TransportBLE from '@ledgerhq/react-native-hw-transport-ble';
import EventEmitter from 'events';

export function scanDevices() {
let sub: null | Subscription = null
let transport: null | Subscription = null

const emitter = new EventEmitter();

const listen = () => {
try {
if (transport) {
transport.unsubscribe();
}

transport = new Observable(TransportBLE.listen).subscribe({
complete: () => {
emitter.emit('complete', true);
},
next: e => {
if (e.type === 'add') {
emitter.emit('device', e.descriptor)
}
},
error: e => {
emitter.emit('error', e);
emitter.emit('complete', true);
},
});
} catch (e) {
emitter.emit('error', e);
}
}

return {
start() {
let previousAvailable: boolean = false;
sub = new Observable<{available: boolean}>(
TransportBLE.observeState,
).subscribe(e => {
if (e.available !== previousAvailable) {
previousAvailable = e.available;
if (e.available) {
listen();
}
}
});

listen();
},
stop() {
if(sub) {
sub.unsubscribe();
}
if (transport) {
transport.unsubscribe();
}
},
on: emitter.on.bind(emitter),
off: emitter.off.bind(emitter)
}
}
28 changes: 28 additions & 0 deletions src/try-to-init-bt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {BleManager, State, Subscription as BleSub} from 'react-native-ble-plx';
import {PermissionsAndroid, Platform} from 'react-native';
import {Observable} from 'rxjs';

export async function tryToInitBt(): Promise<Observable<State>> {
if (Platform.OS === 'android') {
await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
PermissionsAndroid.PERMISSIONS.BLUETOOTH_ADVERTISE,
]);
}
const manager = new BleManager();
let sub: BleSub;
let previousState = State.Unknown;
return new Observable(observer => {
const subs = (state: State) => {
if (state !== previousState) {
previousState = state;
observer.next(state);
}
}

manager.state().then(subs);
sub = manager.onStateChange(subs, true);
})
}
36 changes: 36 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
export type Device = {
id: string

/**
* Device name if present
*/
name: string | null
}

export enum State {
/**
* The current state of the manager is unknown; an update is imminent.
*/
Unknown = 'Unknown',
/**
* The connection with the system service was momentarily lost; an update is imminent.
*/
Resetting = 'Resetting',
/**
* The platform does not support Bluetooth low energy.
*/
Unsupported = 'Unsupported',
/**
* The app is not authorized to use Bluetooth low energy.
*/
Unauthorized = 'Unauthorized',
/**
* Bluetooth is currently powered off.
*/
PoweredOff = 'PoweredOff',
/**
* Bluetooth is currently powered on and available to use.
*/
PoweredOn = 'PoweredOn'
}

export type ProviderLedgerReactNativeOptions = {
deviceId: string;
hdPath: string;
Expand Down
Loading

0 comments on commit dc6c6ab

Please sign in to comment.