Browse Source

bridge.scanAccountsOnDevice needs to return Observable for safety

master
Gaëtan Renaudeau 7 years ago
parent
commit
21c9ca8677
  1. 13
      src/bridge/EthereumJSBridge.js
  2. 3
      src/bridge/LibcoreBridge.js
  3. 15
      src/bridge/RippleJSBridge.js
  4. 8
      src/bridge/UnsupportedBridge.js
  5. 11
      src/bridge/makeMockBridge.js
  6. 6
      src/bridge/types.js
  7. 2
      src/components/modals/AddAccounts/steps/03-step-import.js

13
src/bridge/EthereumJSBridge.js

@ -156,7 +156,8 @@ const fetchCurrentBlock = (perCurrencyId => currency => {
})({}) })({})
const EthereumBridge: WalletBridge<Transaction> = { const EthereumBridge: WalletBridge<Transaction> = {
scanAccountsOnDevice(currency, deviceId, { next, complete, error }) { scanAccountsOnDevice: (currency, deviceId) =>
Observable.create(o => {
let finished = false let finished = false
const unsubscribe = () => { const unsubscribe = () => {
finished = true finished = true
@ -251,22 +252,22 @@ const EthereumBridge: WalletBridge<Transaction> = {
.send({ currencyId: currency.id, devicePath: deviceId, path: freshAddressPath }) .send({ currencyId: currency.id, devicePath: deviceId, path: freshAddressPath })
.toPromise() .toPromise()
const r = await stepAddress(index, res, isStandard) const r = await stepAddress(index, res, isStandard)
if (r.account) next(r.account) if (r.account) o.next(r.account)
if (r.complete) { if (r.complete) {
break break
} }
} }
} }
complete() o.complete()
} catch (e) { } catch (e) {
error(e) o.error(e)
} }
} }
main() main()
return { unsubscribe } return unsubscribe
}, }),
synchronize: ({ freshAddress, blockHeight, currency, operations }) => synchronize: ({ freshAddress, blockHeight, currency, operations }) =>
Observable.create(o => { Observable.create(o => {

3
src/bridge/LibcoreBridge.js

@ -79,14 +79,13 @@ const getFees = async (a, transaction) => {
} }
const LibcoreBridge: WalletBridge<Transaction> = { const LibcoreBridge: WalletBridge<Transaction> = {
scanAccountsOnDevice(currency, devicePath, observer) { scanAccountsOnDevice(currency, devicePath) {
return libcoreScanAccounts return libcoreScanAccounts
.send({ .send({
devicePath, devicePath,
currencyId: currency.id, currencyId: currency.id,
}) })
.pipe(map(decodeAccount)) .pipe(map(decodeAccount))
.subscribe(observer)
}, },
synchronize: account => synchronize: account =>

15
src/bridge/RippleJSBridge.js

@ -239,7 +239,8 @@ const getServerInfo = (map => endpointConfig => {
})({}) })({})
const RippleJSBridge: WalletBridge<Transaction> = { const RippleJSBridge: WalletBridge<Transaction> = {
scanAccountsOnDevice(currency, deviceId, { next, complete, error }) { scanAccountsOnDevice: (currency, deviceId) =>
Observable.create(o => {
let finished = false let finished = false
const unsubscribe = () => { const unsubscribe = () => {
finished = true finished = true
@ -282,7 +283,7 @@ const RippleJSBridge: WalletBridge<Transaction> = {
// account does not exist in Ripple server // account does not exist in Ripple server
// we are generating a new account locally // we are generating a new account locally
if (!legacy) { if (!legacy) {
next({ o.next({
id: accountId, id: accountId,
xpub: '', xpub: '',
name: getNewAccountPlaceholderName(currency, index), name: getNewAccountPlaceholderName(currency, index),
@ -331,12 +332,12 @@ const RippleJSBridge: WalletBridge<Transaction> = {
lastSyncDate: new Date(), lastSyncDate: new Date(),
} }
account.operations = transactions.map(txToOperation(account)) account.operations = transactions.map(txToOperation(account))
next(account) o.next(account)
} }
} }
complete() o.complete()
} catch (e) { } catch (e) {
error(e) o.error(e)
} finally { } finally {
api.disconnect() api.disconnect()
} }
@ -344,8 +345,8 @@ const RippleJSBridge: WalletBridge<Transaction> = {
main() main()
return { unsubscribe } return unsubscribe
}, }),
synchronize: ({ endpointConfig, freshAddress, blockHeight }) => synchronize: ({ endpointConfig, freshAddress, blockHeight }) =>
Observable.create(o => { Observable.create(o => {

8
src/bridge/UnsupportedBridge.js

@ -10,10 +10,10 @@ const UnsupportedBridge: WalletBridge<*> = {
o.error(genericError) o.error(genericError)
}), }),
scanAccountsOnDevice(currency, deviceId, { error }) { scanAccountsOnDevice: () =>
Promise.resolve(genericError).then(error) Observable.create(o => {
return { unsubscribe() {} } o.error(genericError)
}, }),
pullMoreOperations: () => Promise.reject(genericError), pullMoreOperations: () => Promise.reject(genericError),

11
src/bridge/makeMockBridge.js

@ -75,13 +75,14 @@ function makeMockBridge(opts?: Opts): WalletBridge<*> {
} }
}), }),
scanAccountsOnDevice(currency, deviceId, { next, complete, error }) { scanAccountsOnDevice: (currency, deviceId) =>
Observable.create(o => {
let unsubscribed = false let unsubscribed = false
async function job() { async function job() {
if (Math.random() > scanAccountDeviceSuccessRate) { if (Math.random() > scanAccountDeviceSuccessRate) {
await delay(1000) await delay(1000)
if (!unsubscribed) error(new Error('scan failed')) if (!unsubscribed) o.error(new Error('scan failed'))
return return
} }
const nbAccountToGen = 3 const nbAccountToGen = 3
@ -92,9 +93,9 @@ function makeMockBridge(opts?: Opts): WalletBridge<*> {
currency, currency,
}) })
account.unit = currency.units[0] account.unit = currency.units[0]
if (!unsubscribed) next(account) if (!unsubscribed) o.next(account)
} }
if (!unsubscribed) complete() if (!unsubscribed) o.complete()
} }
job() job()
@ -104,7 +105,7 @@ function makeMockBridge(opts?: Opts): WalletBridge<*> {
unsubscribed = true unsubscribed = true
}, },
} }
}, }),
pullMoreOperations: async (_accountId, _desiredCount) => { pullMoreOperations: async (_accountId, _desiredCount) => {
await delay(1000) await delay(1000)

6
src/bridge/types.js

@ -33,11 +33,7 @@ export interface WalletBridge<Transaction> {
// the scan can stop once all accounts are discovered. // the scan can stop once all accounts are discovered.
// the function returns a Subscription and you MUST stop everything if it is unsubscribed. // the function returns a Subscription and you MUST stop everything if it is unsubscribed.
// TODO return Observable // TODO return Observable
scanAccountsOnDevice( scanAccountsOnDevice(currency: Currency, deviceId: DeviceId): Observable<Account>;
currency: Currency,
deviceId: DeviceId,
observer: Observer<Account>,
): Subscription;
// synchronize an account. meaning updating the account object with latest state. // synchronize an account. meaning updating the account object with latest state.
// function receives the initialAccount object so you can actually know what the user side currently have // function receives the initialAccount object so you can actually know what the user side currently have

2
src/components/modals/AddAccounts/steps/03-step-import.js

@ -72,7 +72,7 @@ class StepImport extends PureComponent<StepProps> {
// TODO: use the real device // TODO: use the real device
const devicePath = currentDevice.path const devicePath = currentDevice.path
this.scanSubscription = bridge.scanAccountsOnDevice(currency, devicePath, { this.scanSubscription = bridge.scanAccountsOnDevice(currency, devicePath).subscribe({
next: account => { next: account => {
const { scannedAccounts, checkedAccountsIds, existingAccounts } = this.props const { scannedAccounts, checkedAccountsIds, existingAccounts } = this.props
const hasAlreadyBeenScanned = !!scannedAccounts.find(a => account.id === a.id) const hasAlreadyBeenScanned = !!scannedAccounts.find(a => account.id === a.id)

Loading…
Cancel
Save