From 00654f27ad8ebf3e2a7b8faf63980b8099fd0a0d Mon Sep 17 00:00:00 2001 From: Leila Wang Date: Tue, 18 Feb 2020 17:40:30 +0000 Subject: [PATCH] fix(sdk): expose apis to get account or network even when not enabled --- .../extension/src/client/Aztec/ApiManager.js | 15 ++++--- .../client/Aztec/__tests__/ApiManager.spec.js | 28 +++++++++++++ packages/extension/src/client/Aztec/index.js | 6 ++- .../utils/generateApis.js | 39 +++++++++++++++---- packages/extension/src/index.js | 7 +++- 5 files changed, 77 insertions(+), 18 deletions(-) diff --git a/packages/extension/src/client/Aztec/ApiManager.js b/packages/extension/src/client/Aztec/ApiManager.js index fb53c2622..cfd45df9a 100644 --- a/packages/extension/src/client/Aztec/ApiManager.js +++ b/packages/extension/src/client/Aztec/ApiManager.js @@ -45,13 +45,16 @@ export default class ApiManager { default: } } + if (!this.aztecAccount && !this.sessionPromise) { + this.generateDefaultApis(); + } this.eventListeners.notify('profileChanged', changedType, objValue); }); } - generateDefaultApis() { - const apis = ApiPermissionService.generateApis(); + async generateDefaultApis() { + const apis = await ApiPermissionService.generateApis(); this.setApis(apis); } @@ -154,14 +157,14 @@ export default class ApiManager { this.aztecAccount = null; this.error = null; this.unbindOneTimeProfileChangeListener(); - this.generateDefaultApis(); + await this.generateDefaultApis(); await ConnectionService.disconnect(); } async refreshSession(options) { this.aztecAccount = null; this.error = null; - this.generateDefaultApis(); + await this.generateDefaultApis(); await ConnectionService.disconnect(); let networkSwitchedDuringStart = false; @@ -208,8 +211,8 @@ export default class ApiManager { } = await ApiPermissionService.ensurePermission() || {}; return aztecAccount; }, - (aztecAccount) => { - const apis = ApiPermissionService.generateApis(true); + async (aztecAccount) => { + const apis = await ApiPermissionService.generateApis(true); this.setApis(apis); if (this.autoRefreshOnProfileChange) { diff --git a/packages/extension/src/client/Aztec/__tests__/ApiManager.spec.js b/packages/extension/src/client/Aztec/__tests__/ApiManager.spec.js index f31c2e6d3..2eb78d5de 100644 --- a/packages/extension/src/client/Aztec/__tests__/ApiManager.spec.js +++ b/packages/extension/src/client/Aztec/__tests__/ApiManager.spec.js @@ -44,6 +44,34 @@ describe('ApiManager listeners', () => { name: 'Rinkeby', }); }); + + it('generate default apis again if not enabled', () => { + const generateDefaultApisSpy = jest.spyOn(manager, 'generateDefaultApis') + .mockImplementation(jest.fn()); + + expect(generateDefaultApisSpy).toHaveBeenCalledTimes(0); + + Web3Service.eventListeners.notify('profile', 'networkChanged', '12345'); + expect(generateDefaultApisSpy).toHaveBeenCalledTimes(1); + + manager.aztecAccount = { + address: 'aztec_address', + }; + + Web3Service.eventListeners.notify('profile', 'networkChanged', '12345'); + expect(generateDefaultApisSpy).toHaveBeenCalledTimes(1); + + manager.aztecAccount = null; + manager.sessionPromise = {}; + + Web3Service.eventListeners.notify('profile', 'accountChanged', 'address_123'); + expect(generateDefaultApisSpy).toHaveBeenCalledTimes(1); + + manager.sessionPromise = null; + + Web3Service.eventListeners.notify('profile', 'networkChanged', '12345'); + expect(generateDefaultApisSpy).toHaveBeenCalledTimes(2); + }); }); describe('ApiManager.handleResolveSession', () => { diff --git a/packages/extension/src/client/Aztec/index.js b/packages/extension/src/client/Aztec/index.js index 48fed189c..ab54d79cf 100644 --- a/packages/extension/src/client/Aztec/index.js +++ b/packages/extension/src/client/Aztec/index.js @@ -16,8 +16,6 @@ class Aztec { }); }; - manager.generateDefaultApis(); - Object.keys(aztec).forEach((name) => { if (this[name]) { warnLog(`Api '${name}' is already in Aztec.`); @@ -27,6 +25,10 @@ class Aztec { }); } + async generateInitialApis() { // eslint-disable-line class-methods-use-this + await manager.generateDefaultApis(); + } + get enabled() { // eslint-disable-line class-methods-use-this return !!manager.aztecAccount; } diff --git a/packages/extension/src/client/services/ApiPermissionService/utils/generateApis.js b/packages/extension/src/client/services/ApiPermissionService/utils/generateApis.js index 60e8606e7..02d780f99 100644 --- a/packages/extension/src/client/services/ApiPermissionService/utils/generateApis.js +++ b/packages/extension/src/client/services/ApiPermissionService/utils/generateApis.js @@ -1,3 +1,4 @@ +import Web3 from 'web3'; import { getNetworkName, } from '~/utils/network'; @@ -11,20 +12,42 @@ const availableWeb3Apis = [ 'deploy', ]; -export default function generateApis(hasPermission = false) { - const web3 = { - getNetwork: () => ({ - id: Web3Service.networkId, - name: getNetworkName(Web3Service.networkId), - }), - getAccount: () => ({ ...Web3Service.account }), - }; +export default async function generateApis(hasPermission = false) { + const web3 = {}; + + let networkId; + let account; if (hasPermission) { + ({ + networkId, + account, + } = Web3Service); availableWeb3Apis.forEach((name) => { web3[name] = (...args) => Web3Service[name](...args); }); + } else { + const web3Instance = new Web3(window.ethereum); + networkId = await web3Instance.eth.net.getId(); + const [address] = await web3Instance.eth.getAccounts(); + if (address) { + account = { + address, + }; + } } + web3.network = !networkId + ? null + : { + id: networkId, + name: getNetworkName(networkId), + }; + web3.account = !account + ? null + : { ...account }; + web3.getNetwork = () => web3.network; + web3.getAccount = () => web3.account; + // TODO - assign mock modules that show warnings when calling apis before enabled return { diff --git a/packages/extension/src/index.js b/packages/extension/src/index.js index ee00a2c0a..95676a714 100644 --- a/packages/extension/src/index.js +++ b/packages/extension/src/index.js @@ -1,7 +1,10 @@ import Aztec from '~/client/Aztec'; -document.addEventListener('DOMContentLoaded', () => { - window.aztec = new Aztec(); +document.addEventListener('DOMContentLoaded', async () => { + const aztec = new Aztec(); + await aztec.generateInitialApis(); + delete aztec.generateInitialApis; + window.aztec = aztec; // TODO - callback's name should be configurable through url: // /sdk/aztec/?key=API_KEY&callback=aztecCallback