From e2045b46aff7857128e672db7ed3ee5f36683424 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Thu, 16 Jan 2020 17:27:48 +0100 Subject: [PATCH 01/21] update README and deprecate individual connectors --- README.md | 314 +++++++++++++++++---------------------------------- src/index.ts | 2 - 2 files changed, 104 insertions(+), 212 deletions(-) diff --git a/README.md b/README.md index 3938edb658..5146e08b55 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,6 @@ yarn add @walletconnect/web3-provider @portis/web3 fortmatic squarelink @torusla - [React Button](#React-Button) - [Core Module](#Core-Module) -- [Individual Connectors](#Individual-Connectors) ### React Button @@ -48,64 +47,12 @@ Add Web3Connect Button to your React App as follows ```js import Web3Connect from "web3connect"; -import WalletConnectProvider from "@walletconnect/web3-provider"; -import Portis from "@portis/web3"; -import Fortmatic from "fortmatic"; -import Squarelink from "squarelink"; -import Torus from "@toruslabs/torus-embed"; -import Arkane from "@arkane-network/web3-arkane-provider"; -import Authereum from "authereum"; + +const providerOptions = { /* See Provider Options Section */ } { const web3 = new Web3(provider); // add provider to web3 }} @@ -129,56 +76,13 @@ import Torus from "@toruslabs/torus-embed"; import Arkane from "@arkane-network/web3-arkane-provider"; import Authereum from "authereum"; +const providerOptions = { + /* See Provider Options Section */ +}; + const web3Connect = new Web3Connect.Core({ network: "mainnet", // optional - providerOptions: { - walletconnect: { - package: WalletConnectProvider, // required - options: { - infuraId: "INFURA_ID" // required - } - }, - portis: { - package: Portis, // required - options: { - id: "PORTIS_ID" // required - } - }, - fortmatic: { - package: Fortmatic, // required - options: { - key: "FORTMATIC_KEY" // required - } - }, - squarelink: { - package: Squarelink, // required - options: { - id: "SQUARELINK_ID" // required - } - }, - torus: { - package: Torus, // required - options: { - enableLogging: false, // optional - buttonPosition: "bottom-left", // optional - buildEnv: "production", // optional - showTorusButton: true, // optional - enabledVerifiers: { // optional - google: false // optional - } - } - }, - arkane: { - package: Arkane, // required - options: { - clientId: "ARKANE_CLIENT_ID" // required, replace - } - }, - authereum: { - package: Authereum, // required - options: {} - } - } + providerOptions: providerOptions }); // subscribe to connect @@ -194,68 +98,6 @@ web3Connect.on("close", () => { web3Connect.toggleModal(); // open modal on button click ``` -### Individual Connectors - -Add individual connectors for each provider to your own UI (no modal provided) - -```js -import Web3Connect from "web3connect"; -import WalletConnectProvider from "@walletconnect/web3-provider"; -import Portis from "@portis/web3"; -import Fortmatic from "fortmatic"; -import Squarelink from "squarelink"; -import Torus from "@toruslabs/torus-embed"; -import Authereum from "authereum"; - -// For inject providers in dapp browsers -const provider = await Web3Connect.ConnectToInjected(); - -// For WalletConnect -const provider = await Web3Connect.ConnectToWalletConnect( - WalletConnectProvider, - { - infuraId: "INFURA_ID", // required - bridge: "https://bridge.walletconnect.org" // optional - } -); - -// For Portis -const provider = await Web3Connect.ConnectToPortis(Portis, { - id: "PORTIS_ID", // required - network: "mainnet" // optional -}); - -// For Fortmatic -const provider = await Web3Connect.ConnectToFortmatic(Fortmatic, { - key: "FORTMATIC_KEY", // required - network: "mainnet" // optional -}); - -// For Squarelink -const provider = await Web3Connect.ConnectToSquarelink(Squarelink, { - id: "SQUARELINK_ID", // required - network: "mainnet" // optional -}); - -// For Torus -const provider = await Web3Connect.ConnectToTorus(Torus, { - enableLogging: false, // optional - buttonPosition: "bottom-left", // optional - buildEnv: "production", // optional - showTorusButton: true // optional -}); - -// For Arkane -const provider = await Web3Connect.ConnectToArkane(Arkane, { - key: "ARKANE_CLIENT_ID", // required - environment: "staging" // optional - -// For Authereum -const provider = await Web3Connect.ConnectToAuthereum(Authereum, { - network: "mainnet" // optional -}); -``` - ## Utils ```typescript @@ -298,67 +140,119 @@ interface IProviderCallback { } ``` -## Options +## Provider Options -- providerOptions (optional): An object mapping arbitrary string that adds the required configuration to multiple web3 providers. +These are all the providers available with Web3Connect and how to configure their provider options - - walletconnect: +### WalletConnect - - package: dependency injection to enable provider - - options: - - infuraId: the infura app ID registered (required) - - bridge: bridge url (optional) +```typescript +import WalletConnectProvider from "@walletconnect/web3-provider"; - - portis: +const providerOptions = { + walletconnect: { + package: WalletConnectProvider, // required + options: { + infuraId: "INFURA_ID" // required + } + } +}; +``` - - package: dependency injection to enable provider - - options: - - id: the app id registered (required) - - network: choose initial network name (optional) - - config: additional configuration, like support of Gas Station Network (optional) +### Portis - - fortmatic: +```typescript +import Portis from "@portis/web3"; - - package: dependency injection to enable provider - - options: - - key: the secret key (required) - - network: choose initial network name (optional) +const providerOptions = { + portis: { + package: Portis, // required + options: { + id: "PORTIS_ID" // required + } + } +}; +``` - - arkane: +### Fortmatic - - package: dependency injection to enable provider - - options: - - clientId: the client id used by the application (required) - - nodeUrl: choose initial network name (optional) - - environment: the environment to connect to (optional). Production by default, use 'staging' for testing +```typescript +import Fortmatic from "fortmatic"; - - squarelink: +const providerOptions = { + fortmatic: { + package: Fortmatic, // required + options: { + key: "FORTMATIC_KEY" // required + } + } +}; +``` - - package: dependency injection to enable provider - - options: - - id: the client ID registered (required) - - network: choose initial network name (optional) - - config: additional configuration, like `scope` to use supplemental methods (optional) +### Squarelink -- torus: +```typescript +import Squarelink from "squarelink"; - - package: dependency injection to enable provider - - options: - - enableLogging: enable logging for debugging (optional), - - buttonPosition: set button position (optional), - - buildEnv: set build environment (optional), - - showTorusButton: enable displaying torus button - - enabledVerifiers: disable certain verifiers by passing false against them +const providerOptions = { + squarelink: { + package: Squarelink, // required + options: { + id: "SQUARELINK_ID" // required + } + } +}; +``` + +### Torus + +```typescript +import Torus from "@toruslabs/torus-embed"; + +const providerOptions = { + torus: { + package: Torus, // required + options: { + enableLogging: false, // optional + buttonPosition: "bottom-left", // optional + buildEnv: "production", // optional + showTorusButton: true, // optional + enabledVerifiers: { + // optional + google: false // optional + } + } + } +}; +``` -- authereum: +### Arkane - - package: dependency injection to enable provider - - options: - - network: choose initial network name (optional) +```typescript +import Arkane from "@arkane-network/web3-arkane-provider"; + +const providerOptions = { + arkane: { + package: Arkane, // required + options: { + clientId: "ARKANE_CLIENT_ID" // required, replace + } + } +}; +``` -You can disable the injected provider by adding the following flag: +### Authereum -- disableInjectedProvider: true (optional) +```typescript +import Authereum from "authereum"; + +const providerOptions = { + authereum: { + package: Authereum, // required + options: {} + } +}; +``` ## Collaboration diff --git a/src/index.ts b/src/index.ts index 513250fd35..678ef157d2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,13 +1,11 @@ import ConnectButton from "./components/ConnectButton"; import Core from "./core"; -import connectors from "./core/connectors"; import * as utils from "./helpers/utils"; import * as types from "./helpers/types"; export default { Button: ConnectButton, Core, - ...connectors, ...utils, ...types }; From 5a0b4cbfa392746d0a3178b6648875d9d1b53c37 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Thu, 16 Jan 2020 17:29:15 +0100 Subject: [PATCH 02/21] update README --- README.md | 84 +++++++++++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 5146e08b55..f370b323ac 100644 --- a/README.md +++ b/README.md @@ -98,48 +98,6 @@ web3Connect.on("close", () => { web3Connect.toggleModal(); // open modal on button click ``` -## Utils - -```typescript -function checkInjectedProviders(): IInjectedProvidersMap; -function getInjectedProviderName(): string | null; -function getProviderInfoByName(name: string | null): IProviderInfo; -function getProviderInfo(provider: any): IProviderInfo; -function isMobile(): boolean; -function formatProviderDescription(providerInfo: IProviderInfo); -``` - -## Types - -```typescript -interface IProviderInfo { - name: string; - type: string; - logo: string; - check: string; - styled: { - [prop: string]: any; - }; -} - -interface IProviderOptions { - [providerName: string]: { - package: any; - options: any; - }; -} - -interface IInjectedProvidersMap { - injectedAvailable: boolean; - [isProviderName: string]: boolean; -} - -interface IProviderCallback { - name: string | null; - onClick: () => Promise; -} -``` - ## Provider Options These are all the providers available with Web3Connect and how to configure their provider options @@ -254,6 +212,48 @@ const providerOptions = { }; ``` +## Utils + +```typescript +function checkInjectedProviders(): IInjectedProvidersMap; +function getInjectedProviderName(): string | null; +function getProviderInfoByName(name: string | null): IProviderInfo; +function getProviderInfo(provider: any): IProviderInfo; +function isMobile(): boolean; +function formatProviderDescription(providerInfo: IProviderInfo); +``` + +## Types + +```typescript +interface IProviderInfo { + name: string; + type: string; + logo: string; + check: string; + styled: { + [prop: string]: any; + }; +} + +interface IProviderOptions { + [providerName: string]: { + package: any; + options: any; + }; +} + +interface IInjectedProvidersMap { + injectedAvailable: boolean; + [isProviderName: string]: boolean; +} + +interface IProviderCallback { + name: string | null; + onClick: () => Promise; +} +``` + ## Collaboration ### Code contributions are welcome ❤️❤️❤️! From 6e0a535eb8f5d4585fd2dda44eff59f4b99caf41 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Thu, 16 Jan 2020 17:29:46 +0100 Subject: [PATCH 03/21] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 35bc132dac..a794a6da4b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "web3connect", - "version": "1.0.0-beta.25", + "version": "1.0.0-beta.26", "description": "A single Web3 / Ethereum provider solution for all Wallets", "keywords": [ "web3", From 1ee50ebe34a69295af02f7d436c15613992dfb4f Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Thu, 16 Jan 2020 17:32:51 +0100 Subject: [PATCH 04/21] expose libraries inside providers --- src/core/connectors/authereum.ts | 1 + src/core/connectors/fortmatic.ts | 1 + src/core/connectors/squarelink.ts | 1 + src/core/connectors/torus.ts | 4 +++- 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/connectors/authereum.ts b/src/core/connectors/authereum.ts index ace08b2113..11fd4779ce 100644 --- a/src/core/connectors/authereum.ts +++ b/src/core/connectors/authereum.ts @@ -7,6 +7,7 @@ const ConnectToAuthereum = (Authereum: any, opts: IAuthereumConnectorOptions) => try { const authereum = new Authereum(opts.network); const provider = authereum.getProvider(); + provider.authereum = authereum await provider.enable(); resolve(provider); } catch (error) { diff --git a/src/core/connectors/fortmatic.ts b/src/core/connectors/fortmatic.ts index 8cbe10d81e..f967fd75ee 100644 --- a/src/core/connectors/fortmatic.ts +++ b/src/core/connectors/fortmatic.ts @@ -12,6 +12,7 @@ const ConnectToFortmatic = async ( const key = opts.key; const fm = new Fortmatic(key, opts.network); const provider = await fm.getProvider(); + provider.fm = fm await fm.user.login(); const isLoggedIn = await fm.user.isLoggedIn(); if (isLoggedIn) { diff --git a/src/core/connectors/squarelink.ts b/src/core/connectors/squarelink.ts index 041a479ce4..0c661e3764 100644 --- a/src/core/connectors/squarelink.ts +++ b/src/core/connectors/squarelink.ts @@ -25,6 +25,7 @@ const ConnectToSquarelink = ( const config = opts.config; const sqlk = new Squarelink(id, network, config); const provider = await sqlk.getProvider(); + provider.sqlk = sqlk await provider.enable(); return resolve(provider); } catch (error) { diff --git a/src/core/connectors/torus.ts b/src/core/connectors/torus.ts index 92f556fa6d..c19d6a56f5 100644 --- a/src/core/connectors/torus.ts +++ b/src/core/connectors/torus.ts @@ -82,7 +82,9 @@ const ConnectToTorus = async (Torus: any, opts: ITorusConnectorOptions) => { enabledVerifiers: enabledVerifiers }); await torus.login(); // await torus.ethereum.enable() - resolve(torus.provider); + const provider = torus.provider; + provider.torus = torus + resolve(provider); } catch (err) { reject(err) } From d273264bed44e290eb2a3a383dcff03beaeb4126 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Thu, 16 Jan 2020 17:36:01 +0100 Subject: [PATCH 05/21] updated authereum and arkana in example --- example/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/package.json b/example/package.json index 16158328b4..053c452986 100644 --- a/example/package.json +++ b/example/package.json @@ -3,11 +3,11 @@ "version": "0.1.0", "private": true, "dependencies": { - "@arkane-network/web3-arkane-provider": "0.2.5", + "@arkane-network/web3-arkane-provider": "^0.2.5", "@portis/web3": "^2.0.0-beta.40", "@toruslabs/torus-embed": "^0.2.6", "@walletconnect/web3-provider": "^1.0.0-beta.42", - "authereum": "0.0.4-beta.33", + "authereum": "^0.0.4-beta.68", "axios": "^0.18.0", "bignumber.js": "^8.1.1", "ethereumjs-util": "^6.1.0", From c857dee16c2484d5a0f049e566665afc92c57132 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Thu, 16 Jan 2020 18:20:13 +0100 Subject: [PATCH 06/21] localStorage helpers --- src/helpers/local.ts | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/helpers/local.ts diff --git a/src/helpers/local.ts b/src/helpers/local.ts new file mode 100644 index 0000000000..52e45855b0 --- /dev/null +++ b/src/helpers/local.ts @@ -0,0 +1,44 @@ +export let local: Storage; + +if ( + typeof window !== "undefined" && + typeof window.localStorage !== "undefined" +) { + local = window.localStorage; +} + +export const setLocal = (key: string, data: any) => { + const jsonData = JSON.stringify(data); + if (local) { + local.setItem(key, jsonData); + } +}; + +export const getLocal = (key: string) => { + let data = null; + let raw = null; + if (local) { + raw = local.getItem(key); + } + if (raw && typeof raw === "string") { + try { + data = JSON.parse(raw); + } catch (error) { + return null; + } + } + return data; +}; + +export const removeLocal = (key: string) => { + if (local) { + local.removeItem(key); + } +}; + +export const updateLocal = (key: string, data: any) => { + const localData = getLocal(key) || {}; + const mergedData = { ...localData, ...data }; + setLocal(key, mergedData); +}; + From f93f9481a629bb7a42e3785d97d830ef072c37bb Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Thu, 16 Jan 2020 18:43:01 +0100 Subject: [PATCH 07/21] cache preferred provider --- README.md | 7 ++ src/components/ConnectButton.tsx | 1 + src/core/index.tsx | 109 +++++++++++++++++++++---------- src/helpers/constants.ts | 6 ++ 4 files changed, 88 insertions(+), 35 deletions(-) create mode 100644 src/helpers/constants.ts diff --git a/README.md b/README.md index f370b323ac..3c6c7b707e 100644 --- a/README.md +++ b/README.md @@ -254,6 +254,13 @@ interface IProviderCallback { } ``` +## Optional Flags + +You can enable the following optional flags: + +- disableInjectedProvider: disable displaying injected provider as an option +- disablePreferredProvider: disable caching preffered provider in localStorage + ## Collaboration ### Code contributions are welcome ❤️❤️❤️! diff --git a/src/components/ConnectButton.tsx b/src/components/ConnectButton.tsx index 733440ffb1..6730981ea5 100644 --- a/src/components/ConnectButton.tsx +++ b/src/components/ConnectButton.tsx @@ -8,6 +8,7 @@ class ConnectButton extends React.Component { constructor(props: any) { super(props); this.core = new Core({ + disablePreferredProvider: props.disablePreferredProvider, network: props.network, lightboxOpacity: props.lightboxOpacity, providerOptions: props.providerOptions diff --git a/src/core/index.tsx b/src/core/index.tsx index f05b1da117..92e401f7b0 100644 --- a/src/core/index.tsx +++ b/src/core/index.tsx @@ -6,11 +6,17 @@ import { isMobile, getInjectedProviderName } from "../helpers/utils"; import connectors from "./connectors"; import EventManager from "./events"; import { providerPackages } from "../providers"; - -const WEB3_CONNECT_MODAL_ID = "WEB3_CONNECT_MODAL_ID"; +import { setLocal, removeLocal, getLocal } from "../helpers/local"; +import { + WEB3_CONNECT_MODAL_ID, + PREFERRED_PROVIDER_KEY, + CONNECT_EVENT, + DISCONNECT_EVENT, + CLOSE_EVENT +} from "../helpers/constants"; interface ICoreOptions { - modal?: boolean; + disablePreferredProvider?: boolean; network?: string; lightboxOpacity?: number; providerOptions?: IProviderOptions; @@ -22,48 +28,65 @@ class Core { private show: boolean = INITIAL_STATE.show; private eventManager: EventManager = new EventManager(); private injectedProvider: string | null = null; + private disablePreferredProvider: boolean = false; private network: string = ""; private lightboxOpacity: number = 0.4; private providerOptions: IProviderOptions = {}; private providers: IProviderCallback[]; + private preferredProvider: string | undefined; constructor(opts?: ICoreOptions) { this.injectedProvider = getInjectedProviderName(); if (opts) { + this.disablePreferredProvider = opts.disablePreferredProvider || false; this.network = opts.network || ""; this.lightboxOpacity = opts.lightboxOpacity || 0.4; this.providerOptions = opts.providerOptions || {}; } + this.preferredProvider = getLocal(PREFERRED_PROVIDER_KEY) || undefined; this.providers = this.getProviders(); this.renderModal(); } + // --------------- PUBLIC METHODS --------------- // + public on(event: string, callback: (result: any) => void): () => void { this.eventManager.on({ event, callback }); - return () => this.eventManager.off({ - event, - callback - }) + return () => + this.eventManager.off({ + event, + callback + }); } public off(event: string, callback?: (result: any) => void): void { this.eventManager.off({ event, callback - }) + }); + } + + public setPreferredProvider(name: string) { + this.preferredProvider = name; + setLocal(PREFERRED_PROVIDER_KEY, name); + } + + public clearPreferredProvider() { + this.preferredProvider = undefined; + removeLocal(PREFERRED_PROVIDER_KEY); } public connectToInjected = async () => { try { const provider = await connectors.ConnectToInjected(); - await this.onConnect(provider); + await this.onConnect(provider, "injected"); } catch (error) { await this.onError(error); } @@ -92,17 +115,22 @@ class Core { const provider = await connector(providerPackage, opts); if (provider.isWalletConnect) { // Listen for Disconnect event - provider.wc.on("disconnect", async () => { - return this.onDisconnect() + provider.wc.on(DISCONNECT_EVENT, async () => { + return this.onDisconnect(); }); } - await this.onConnect(provider); + await this.onConnect(provider, name); } catch (error) { await this.onError(error); } }; public toggleModal = async () => { + if (this.preferredProvider) { + const provider = this.getProvider(this.preferredProvider); + await provider.onClick(); + return; + } if ( this.providers && this.providers.length === 1 && @@ -124,11 +152,25 @@ class Core { await this.updateState({ show: !this.show }); }; - private onDisconnect = async () => { - this.eventManager.trigger("disconnect") + public renderModal() { + const el = document.createElement("div"); + el.id = WEB3_CONNECT_MODAL_ID; + document.body.appendChild(el); + + ReactDOM.render( + , + document.getElementById(WEB3_CONNECT_MODAL_ID) + ); } - public shouldDisplayProvider(name: string) { + // --------------- PRIVATE METHODS --------------- // + + private shouldDisplayProvider(name: string) { const { providerOptions } = this; const providerPackage = providerPackages[name]; @@ -158,7 +200,7 @@ class Core { return false; } - public getProviders = () => { + private getProviders = () => { const mobile = isMobile(); let providers = [ @@ -275,6 +317,12 @@ class Core { return providersMap; }; + private getProvider = (name: string) => { + const providers = this.getProviders(); + const provider = providers.filter(x => x.name === name)[0]; + return provider; + }; + private onError = async (error: any) => { if (this.show) { await this.toggleModal(); @@ -282,18 +330,25 @@ class Core { this.eventManager.trigger("error", error); }; - private onConnect = async (provider: any) => { + private onConnect = async (provider: any, name: string) => { if (this.show) { await this.toggleModal(); } - this.eventManager.trigger("connect", provider); + if (this.disablePreferredProvider) { + this.setPreferredProvider(name); + } + this.eventManager.trigger(CONNECT_EVENT, provider); + }; + + private onDisconnect = async () => { + this.eventManager.trigger(DISCONNECT_EVENT); }; private onClose = async () => { if (this.show) { await this.toggleModal(); } - this.eventManager.trigger("close"); + this.eventManager.trigger(CLOSE_EVENT); }; private updateState = async (state: any) => { @@ -304,22 +359,6 @@ class Core { }; private resetState = () => this.updateState({ ...INITIAL_STATE }); - - public renderModal() { - const el = document.createElement("div"); - el.id = WEB3_CONNECT_MODAL_ID; - document.body.appendChild(el); - - ReactDOM.render( - , - document.getElementById(WEB3_CONNECT_MODAL_ID) - ); - } } export default Core; diff --git a/src/helpers/constants.ts b/src/helpers/constants.ts new file mode 100644 index 0000000000..6315f52adc --- /dev/null +++ b/src/helpers/constants.ts @@ -0,0 +1,6 @@ +export const WEB3_CONNECT_MODAL_ID = "WEB3_CONNECT_MODAL_ID"; +export const PREFERRED_PROVIDER_KEY = "WEB3_CONNECT_PREFERRED_PROVIDER"; + +export const CONNECT_EVENT = "connect"; +export const DISCONNECT_EVENT = "disconnect"; +export const CLOSE_EVENT = "close"; From b3c71375e8021094fe6b84ea801f9130c08d052c Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Sat, 18 Jan 2020 14:10:02 +0100 Subject: [PATCH 08/21] export providers --- src/index.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 678ef157d2..21e11a69ab 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,13 @@ -import ConnectButton from "./components/ConnectButton"; +import Button from "./components/ConnectButton"; import Core from "./core"; +import providers from "./providers"; import * as utils from "./helpers/utils"; import * as types from "./helpers/types"; export default { - Button: ConnectButton, + Button, Core, + providers, ...utils, ...types }; From 1fa54bd1d7060645cfceea04884a8a449901024c Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Mon, 20 Jan 2020 18:03:46 +0100 Subject: [PATCH 09/21] change disablePreferredProvider to cachePrefferedProvider --- README.md | 4 ++-- src/core/index.tsx | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3c6c7b707e..04c126ba55 100644 --- a/README.md +++ b/README.md @@ -258,8 +258,8 @@ interface IProviderCallback { You can enable the following optional flags: -- disableInjectedProvider: disable displaying injected provider as an option -- disablePreferredProvider: disable caching preffered provider in localStorage +- disableInjectedProvider: disable displaying injected provider as an option (default: false) +- cachePreferredProvider: enable caching preffered provider in localStorage (default: false) ## Collaboration diff --git a/src/core/index.tsx b/src/core/index.tsx index 92e401f7b0..3de93ecf22 100644 --- a/src/core/index.tsx +++ b/src/core/index.tsx @@ -16,7 +16,7 @@ import { } from "../helpers/constants"; interface ICoreOptions { - disablePreferredProvider?: boolean; + cachePreferredProvider?: boolean; network?: string; lightboxOpacity?: number; providerOptions?: IProviderOptions; @@ -28,7 +28,7 @@ class Core { private show: boolean = INITIAL_STATE.show; private eventManager: EventManager = new EventManager(); private injectedProvider: string | null = null; - private disablePreferredProvider: boolean = false; + private cachePreferredProvider: boolean = false; private network: string = ""; private lightboxOpacity: number = 0.4; private providerOptions: IProviderOptions = {}; @@ -39,7 +39,7 @@ class Core { this.injectedProvider = getInjectedProviderName(); if (opts) { - this.disablePreferredProvider = opts.disablePreferredProvider || false; + this.cachePreferredProvider = typeof opts.cachePreferredProvider !== "undefined" ? opts.cachePreferredProvider : false this.network = opts.network || ""; this.lightboxOpacity = opts.lightboxOpacity || 0.4; this.providerOptions = opts.providerOptions || {}; @@ -334,7 +334,7 @@ class Core { if (this.show) { await this.toggleModal(); } - if (this.disablePreferredProvider) { + if (this.cachePreferredProvider) { this.setPreferredProvider(name); } this.eventManager.trigger(CONNECT_EVENT, provider); From 4d0feba01c3ced0cb195850ab87d21c3729e0cde Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Mon, 20 Jan 2020 18:05:20 +0100 Subject: [PATCH 10/21] revert preferred provider changes --- README.md | 1 - src/core/index.tsx | 25 ------------------------- 2 files changed, 26 deletions(-) diff --git a/README.md b/README.md index 04c126ba55..f4fe7839d9 100644 --- a/README.md +++ b/README.md @@ -259,7 +259,6 @@ interface IProviderCallback { You can enable the following optional flags: - disableInjectedProvider: disable displaying injected provider as an option (default: false) -- cachePreferredProvider: enable caching preffered provider in localStorage (default: false) ## Collaboration diff --git a/src/core/index.tsx b/src/core/index.tsx index 3de93ecf22..80d2f66308 100644 --- a/src/core/index.tsx +++ b/src/core/index.tsx @@ -6,17 +6,14 @@ import { isMobile, getInjectedProviderName } from "../helpers/utils"; import connectors from "./connectors"; import EventManager from "./events"; import { providerPackages } from "../providers"; -import { setLocal, removeLocal, getLocal } from "../helpers/local"; import { WEB3_CONNECT_MODAL_ID, - PREFERRED_PROVIDER_KEY, CONNECT_EVENT, DISCONNECT_EVENT, CLOSE_EVENT } from "../helpers/constants"; interface ICoreOptions { - cachePreferredProvider?: boolean; network?: string; lightboxOpacity?: number; providerOptions?: IProviderOptions; @@ -28,24 +25,20 @@ class Core { private show: boolean = INITIAL_STATE.show; private eventManager: EventManager = new EventManager(); private injectedProvider: string | null = null; - private cachePreferredProvider: boolean = false; private network: string = ""; private lightboxOpacity: number = 0.4; private providerOptions: IProviderOptions = {}; private providers: IProviderCallback[]; - private preferredProvider: string | undefined; constructor(opts?: ICoreOptions) { this.injectedProvider = getInjectedProviderName(); if (opts) { - this.cachePreferredProvider = typeof opts.cachePreferredProvider !== "undefined" ? opts.cachePreferredProvider : false this.network = opts.network || ""; this.lightboxOpacity = opts.lightboxOpacity || 0.4; this.providerOptions = opts.providerOptions || {}; } - this.preferredProvider = getLocal(PREFERRED_PROVIDER_KEY) || undefined; this.providers = this.getProviders(); this.renderModal(); @@ -73,16 +66,6 @@ class Core { }); } - public setPreferredProvider(name: string) { - this.preferredProvider = name; - setLocal(PREFERRED_PROVIDER_KEY, name); - } - - public clearPreferredProvider() { - this.preferredProvider = undefined; - removeLocal(PREFERRED_PROVIDER_KEY); - } - public connectToInjected = async () => { try { const provider = await connectors.ConnectToInjected(); @@ -126,11 +109,6 @@ class Core { }; public toggleModal = async () => { - if (this.preferredProvider) { - const provider = this.getProvider(this.preferredProvider); - await provider.onClick(); - return; - } if ( this.providers && this.providers.length === 1 && @@ -334,9 +312,6 @@ class Core { if (this.show) { await this.toggleModal(); } - if (this.cachePreferredProvider) { - this.setPreferredProvider(name); - } this.eventManager.trigger(CONNECT_EVENT, provider); }; From a48689adf451e42852b55055cd12f1b091e6db9f Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Mon, 20 Jan 2020 18:14:02 +0100 Subject: [PATCH 11/21] fixes --- example/package-lock.json | 388 ++++++++++++++++++++++++------- package-lock.json | 2 +- src/components/ConnectButton.tsx | 1 - src/core/index.tsx | 6 - src/helpers/local.ts | 1 - 5 files changed, 309 insertions(+), 89 deletions(-) diff --git a/example/package-lock.json b/example/package-lock.json index f558ae59e9..7b4dd069ba 100644 --- a/example/package-lock.json +++ b/example/package-lock.json @@ -2618,6 +2618,11 @@ "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=" }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" + }, "array-flatten": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", @@ -2769,29 +2774,48 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "authereum": { - "version": "0.0.4-beta.33", - "resolved": "https://registry.npmjs.org/authereum/-/authereum-0.0.4-beta.33.tgz", - "integrity": "sha512-ll7oQtIFyApsPMNc+mjmgSWCjtKBdpClnUoQPfb+uYYEd62tFZ3q4jiHKpE61wShMBIvP5sY26lyUJ3Rj4Xv0A==", + "version": "0.0.4-beta.71", + "resolved": "https://registry.npmjs.org/authereum/-/authereum-0.0.4-beta.71.tgz", + "integrity": "sha512-gYz14mjUcGrVE+tEqM9n1ZaXn+SNWEK4zZvV5kdMnxwWdRq/wlZ0VNL0HErLsNDkVrcDYCbDcYnMHdq69Pk3LA==", "requires": { "bnc-notify": "^0.2.1", + "ethereum-private-key-to-address": "0.0.3", "ethers": "^4.0.36", "eventemitter3": "^4.0.0", + "moment": "^2.24.0", "penpal": "^4.1.1", + "pify": "^4.0.1", "rollup-plugin-commonjs": "^10.1.0", "store": "^2.0.12", - "web3-provider-engine": "^15.0.3", + "web3-provider-engine": "^15.0.4", "web3-utils": "^1.2.1" }, "dependencies": { "elliptic": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz", - "integrity": "sha1-VILZZG1UvLif19mU/J4ulWiHbj8=", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", + "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", "hash.js": "^1.0.0", - "inherits": "^2.0.1" + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "eth-json-rpc-filters": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/eth-json-rpc-filters/-/eth-json-rpc-filters-4.1.1.tgz", + "integrity": "sha512-GkXb2h6STznD+AmMzblwXgm1JMvjdK9PTIXG7BvIkTlXQ9g0QOxuU1iQRYHoslF9S30BYBSoLSisAYPdLggW+A==", + "requires": { + "await-semaphore": "^0.1.3", + "eth-json-rpc-middleware": "^4.1.4", + "eth-query": "^2.1.2", + "json-rpc-engine": "^5.1.3", + "lodash.flatmap": "^4.5.0", + "safe-event-emitter": "^1.0.1" } }, "eth-json-rpc-infura": { @@ -2806,9 +2830,9 @@ } }, "eth-json-rpc-middleware": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-4.3.0.tgz", - "integrity": "sha512-Acr+FaIHB0oIV0nWrCvepQghgA3FzYFvnMDXdTUeHQvAX/G6ioMbw1exGJs+6HirRjJ+MmkZqaArphx+PTrRNQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-4.4.0.tgz", + "integrity": "sha512-IeOsil/XiHsybJO9nFf86+1+YIqGQWPPfiTEp3WLkpLZhJm97kw6tFM7GttIZXIcwtaO3zEXgY6PWAH1jkB3ag==", "requires": { "btoa": "^1.2.1", "clone": "^2.1.1", @@ -2824,6 +2848,13 @@ "json-stable-stringify": "^1.0.1", "pify": "^3.0.0", "safe-event-emitter": "^1.0.1" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } } }, "ethereumjs-util": { @@ -2841,14 +2872,13 @@ } }, "ethers": { - "version": "4.0.38", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.38.tgz", - "integrity": "sha512-l7l7RIfk2/rIFgRRVLFY3H06S9dhXXPUdMlYm6SCelB6oG+ABmoRig7xSVOLcHLayBfSwssjAAYLKxf1jWhbuQ==", + "version": "4.0.43", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.43.tgz", + "integrity": "sha512-VjQRVgPrlU12jSMvypdE1yEqYQccdVbH8bbiz67dLF7raHlRV4+zW70GlxHcZYqgsnz0XYWrn6C06gqTQRb5tw==", "requires": { - "@types/node": "^10.3.2", "aes-js": "3.0.0", "bn.js": "^4.4.0", - "elliptic": "6.3.3", + "elliptic": "6.5.2", "hash.js": "1.1.3", "js-sha3": "0.5.7", "scrypt-js": "2.0.4", @@ -2882,9 +2912,9 @@ "integrity": "sha512-6d1f8khVLyBz3DnhLztbfjJ7+ANxdXRM2l6awpnCdEtbrmse4AGTsELOvGuNY0SU7xZw7heGbP6IikVvaVTOWw==" }, "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" }, "scrypt-js": { "version": "2.0.4", @@ -2902,9 +2932,9 @@ "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=" }, "web3-provider-engine": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-15.0.3.tgz", - "integrity": "sha512-E2/j0iEA1JJVijV84bPpiFKZPA6jFkcCKJtzDCl/CUn8CeqtkGykpjP55pnQtzxszzmpGgSZlThMEFUzBU7X2g==", + "version": "15.0.4", + "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-15.0.4.tgz", + "integrity": "sha512-Ob9oK0TUZfVC7NXkB7CQSWAiCdCD/Xnlh2zTnV8NdJR8LCrMAy2i6JedU70JHaxw59y7mM4GnsYOTTGkquFnNQ==", "requires": { "async": "^2.5.0", "backoff": "^2.5.0", @@ -2912,7 +2942,7 @@ "cross-fetch": "^2.1.0", "eth-block-tracker": "^4.4.2", "eth-json-rpc-errors": "^1.0.1", - "eth-json-rpc-filters": "^4.1.0", + "eth-json-rpc-filters": "^4.1.1", "eth-json-rpc-infura": "^4.0.1", "eth-json-rpc-middleware": "^4.1.5", "eth-sig-util": "^1.4.2", @@ -4276,15 +4306,13 @@ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" }, "bnc-notify": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/bnc-notify/-/bnc-notify-0.2.1.tgz", - "integrity": "sha512-M08A6pZXYaq22nfPRP92h4Oxv986srY2jVVeiYvSuqhuJLR0uFRZrTVduKrSym6O0ix10VV5kCBQui4uoQL9QA==", + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/bnc-notify/-/bnc-notify-0.2.8.tgz", + "integrity": "sha512-9EFz/SYmuGBbh2d6K7pliLY6gnie8SqwSWc7PoWBFrF3Kf75U0k6f4Rw1WvDrwjMpkgZ5dG9Wal2+cGPBTUStQ==", "requires": { "bignumber.js": "^9.0.0", - "bnc-sdk": "0.2.1", + "bnc-sdk": "0.2.3", "lodash.debounce": "^4.0.8", - "regenerator-runtime": "^0.13.3", - "svelte-i18n": "^1.1.2-beta", "uuid": "^3.3.3" }, "dependencies": { @@ -4292,18 +4320,13 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==" - }, - "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" } } }, "bnc-sdk": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/bnc-sdk/-/bnc-sdk-0.2.1.tgz", - "integrity": "sha512-icdtTUUNYqRYGEb7Q0FL5gLVQWTcZN/+/GhN4P4CxYzjc0589vqKP9ItKHASDP3+ibuJ18qbP01iHXLhAAlxwg==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/bnc-sdk/-/bnc-sdk-0.2.3.tgz", + "integrity": "sha512-SL7hocmgt982eP09RW3vBKa1OzBXzexHW84QvnJ0LqttuPk83OxRk5qFLn7pX5hC/AE9moPwh41RN53eFHXZ/g==", "requires": { "sturdy-websocket": "^0.1.12" } @@ -4717,6 +4740,23 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, + "camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "requires": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + } + } + }, "camelize": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", @@ -6364,6 +6404,14 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.6.tgz", "integrity": "sha512-RpFbQGUE74iyPgvr46U9t1xoQBM8T4BL8SxrN66Le2xYAPSaDJJKeztV3awugusb3g3G9iL8StmkBBXhcbbXhg==" }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "requires": { + "array-find-index": "^1.0.1" + } + }, "cyclist": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", @@ -6419,6 +6467,22 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + } + } + }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", @@ -7912,11 +7976,50 @@ } } }, + "ethereum-checksum-address": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/ethereum-checksum-address/-/ethereum-checksum-address-0.0.2.tgz", + "integrity": "sha512-GAb7mPvGgcfi1j+Bsnwm9af9Z7dLUKp+5cFm88+kMrKACfh9gLatGLVVK5pSGEG2pOGfrmqCRcuh3RtMjIg8GQ==", + "requires": { + "keccak256": "^1.0.0", + "meow": "^5.0.0" + } + }, "ethereum-common": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==" }, + "ethereum-private-key-to-address": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/ethereum-private-key-to-address/-/ethereum-private-key-to-address-0.0.3.tgz", + "integrity": "sha512-P+z9eFlgOezxogEpY1sQR155U4xFmQUWVxKzIJa5BL05Gs7zL0sYuyQuSAme8LBYGQ6p6AwconiMDauf4LbqyA==", + "requires": { + "ethereum-private-key-to-public-key": "0.0.2", + "ethereum-public-key-to-address": "0.0.1", + "meow": "^5.0.0" + } + }, + "ethereum-private-key-to-public-key": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/ethereum-private-key-to-public-key/-/ethereum-private-key-to-public-key-0.0.2.tgz", + "integrity": "sha512-WKwFspLS5IdpV1rBUmWSG2xtIDV7YMpAG/uSjtV9kDzBU6hpSzoqg6R/e1iEfHkOr/eae+NtDTpwzXRtSMDvhw==", + "requires": { + "meow": "^5.0.0", + "secp256k1": "^3.7.1" + } + }, + "ethereum-public-key-to-address": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/ethereum-public-key-to-address/-/ethereum-public-key-to-address-0.0.1.tgz", + "integrity": "sha512-X78x/VBluHUdrYpZunoXJ48luXTaUiUK4ImPjTjI+XiS24+jUR5WFCpm9wCNbLYP6/ZCJ+lwuYormXSjt8rrbw==", + "requires": { + "ethereum-checksum-address": "0.0.2", + "keccak256": "^1.0.0", + "meow": "^5.0.0", + "secp256k1": "^3.7.1" + } + }, "ethereum-types": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/ethereum-types/-/ethereum-types-2.1.6.tgz", @@ -15350,6 +15453,17 @@ "glogg": "^1.0.0" } }, + "handlebars": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", + "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", + "requires": { + "neo-async": "^2.6.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + } + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -20957,6 +21071,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", + "optional": true, "requires": { "commander": "~2.20.0", "source-map": "~0.6.1" @@ -20965,7 +21080,8 @@ "commander": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "optional": true } } }, @@ -23586,6 +23702,11 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=" + }, "indexes-of": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", @@ -23664,19 +23785,6 @@ "ipaddr.js": "^1.5.2" } }, - "intl-messageformat": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-4.4.0.tgz", - "integrity": "sha512-z+Bj2rS3LZSYU4+sNitdHrwnBhr0wO80ZJSW8EzKDBowwUe3Q/UsvgCGjrwa+HPzoGCLEb9HAjfJgo4j2Sac8w==", - "requires": { - "intl-messageformat-parser": "^1.8.1" - } - }, - "intl-messageformat-parser": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-1.8.1.tgz", - "integrity": "sha512-IMSCKVf0USrM/959vj3xac7s8f87sc+80Y/ipBzdKy4ifBv5Gsj2tZ41EAaURVg01QU71fYr77uA8Meh6kELbg==" - }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -24892,6 +25000,15 @@ "safe-buffer": "^5.1.0" } }, + "keccak256": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.0.tgz", + "integrity": "sha512-8qv2vJdQk+Aa2tFXo8zYodm+6DgXqUOqvNJhj1p1V2pxQJT1oNKxNF+zWfhtKXNLZdLvyxjB/dvd9GwcvTHSQQ==", + "requires": { + "bn.js": "^4.11.8", + "keccak": "^1.4.0" + } + }, "keccakjs": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.3.tgz", @@ -25305,6 +25422,15 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, "lower-case": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", @@ -25330,9 +25456,9 @@ "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" }, "magic-string": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.4.tgz", - "integrity": "sha512-oycWO9nEVAP2RVPbIoDoA4Y7LFIJ3xRYov93gAyJhZkET1tNuB0u7uWkZS2LpBWTJUWnmau/To8ECWRC+jKNfw==", + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.6.tgz", + "integrity": "sha512-3a5LOMSGoCTH5rbqobC2HuDNRtE2glHZ8J7pK+QZYppyWA36yuNpsX994rIY2nCuyP7CZYy7lQq/X2jygiZ89g==", "requires": { "sourcemap-codec": "^1.4.4" } @@ -25378,6 +25504,11 @@ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" }, + "map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=" + }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", @@ -25461,6 +25592,85 @@ "readable-stream": "^2.0.1" } }, + "meow": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", + "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", + "requires": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0", + "yargs-parser": "^10.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, "merge": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", @@ -25535,11 +25745,6 @@ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, - "micro-memoize": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micro-memoize/-/micro-memoize-4.0.8.tgz", - "integrity": "sha512-Mzlo15iWNrP5EwokGjx0Wlh2b3aMjTPdpsD+ryQtkYJBD67IxBddWU2fO3MIXRtXDH8NsuhaotTrtDbfb+k6jw==" - }, "micromatch": { "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", @@ -25638,6 +25843,15 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, + "minimist-options": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0" + } + }, "minipass": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.4.0.tgz", @@ -25735,6 +25949,11 @@ "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.10.1.tgz", "integrity": "sha512-w22rOL5ZYu6HbUehB5deurghGM0hS/xBVyHMGKOuQctkk93J9z9VEOhDsiWrXOprVNQpP9uzGKdl8v9mFspKuw==" }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -26107,11 +26326,6 @@ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, - "object-resolve-path": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-resolve-path/-/object-resolve-path-1.1.1.tgz", - "integrity": "sha1-p/j5Poogr4DkQhe6fbVDFtnRIjI=" - }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -30199,6 +30413,11 @@ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==" }, + "quick-lru": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", + "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=" + }, "raf": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.0.tgz", @@ -30884,6 +31103,15 @@ "minimatch": "3.0.4" } }, + "redent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "requires": { + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" + } + }, "regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", @@ -31262,9 +31490,9 @@ }, "dependencies": { "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.2.tgz", + "integrity": "sha512-EjlOBLBO1kxsUxsKjLt7TAECyKW6fOh1VRkykQkKGzcBbjjPIxBqGh0jf7GJ3k/f5mxMqW3htMD3WdTUVtW8HQ==", "requires": { "path-parse": "^1.0.6" } @@ -32272,9 +32500,9 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "sourcemap-codec": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz", - "integrity": "sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg==" + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" }, "spdx-correct": { "version": "3.1.0", @@ -32701,6 +32929,11 @@ "is-hex-prefixed": "1.0.0" } }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=" + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -32850,16 +33083,6 @@ "has-flag": "^3.0.0" } }, - "svelte-i18n": { - "version": "1.1.2-beta", - "resolved": "https://registry.npmjs.org/svelte-i18n/-/svelte-i18n-1.1.2-beta.tgz", - "integrity": "sha512-OgjRHgLmx30q1xrXRb63a94xogvrXTUu/D2pwcSPXsg9NqFy/VX9sWoy8c3VgH72hDWpSAoBTCE7npSMC7acUA==", - "requires": { - "intl-messageformat": "^4.0.1", - "micro-memoize": "^4.0.7", - "object-resolve-path": "^1.1.1" - } - }, "svgo": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.0.tgz", @@ -33398,6 +33621,11 @@ "punycode": "^2.1.0" } }, + "trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=" + }, "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", diff --git a/package-lock.json b/package-lock.json index cb8f07edc4..e87906d6b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "web3connect", - "version": "1.0.0-beta.25", + "version": "1.0.0-beta.26", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/components/ConnectButton.tsx b/src/components/ConnectButton.tsx index 6730981ea5..733440ffb1 100644 --- a/src/components/ConnectButton.tsx +++ b/src/components/ConnectButton.tsx @@ -8,7 +8,6 @@ class ConnectButton extends React.Component { constructor(props: any) { super(props); this.core = new Core({ - disablePreferredProvider: props.disablePreferredProvider, network: props.network, lightboxOpacity: props.lightboxOpacity, providerOptions: props.providerOptions diff --git a/src/core/index.tsx b/src/core/index.tsx index 80d2f66308..c1e8744cca 100644 --- a/src/core/index.tsx +++ b/src/core/index.tsx @@ -295,12 +295,6 @@ class Core { return providersMap; }; - private getProvider = (name: string) => { - const providers = this.getProviders(); - const provider = providers.filter(x => x.name === name)[0]; - return provider; - }; - private onError = async (error: any) => { if (this.show) { await this.toggleModal(); diff --git a/src/helpers/local.ts b/src/helpers/local.ts index 52e45855b0..56bc83055d 100644 --- a/src/helpers/local.ts +++ b/src/helpers/local.ts @@ -41,4 +41,3 @@ export const updateLocal = (key: string, data: any) => { const mergedData = { ...localData, ...data }; setLocal(key, mergedData); }; - From 56fcfc44c516a8fcc14dd71d07437de5dd91f32a Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Mon, 20 Jan 2020 20:10:41 +0100 Subject: [PATCH 12/21] WARNING: major refactor --- src/components/ConnectButton.tsx | 1 - src/core/connectors/index.ts | 32 +-- src/core/index.tsx | 242 +++------------------- src/helpers/constants.ts | 4 +- src/helpers/types.ts | 23 ++- src/helpers/utils.ts | 6 +- src/index.ts | 2 +- src/providers/index.ts | 336 ++++++++++++------------------- 8 files changed, 201 insertions(+), 445 deletions(-) diff --git a/src/components/ConnectButton.tsx b/src/components/ConnectButton.tsx index 733440ffb1..d94cd5e29f 100644 --- a/src/components/ConnectButton.tsx +++ b/src/components/ConnectButton.tsx @@ -13,7 +13,6 @@ class ConnectButton extends React.Component { providerOptions: props.providerOptions }); this.core.on("connect", props.onConnect); - this.core.on("disconnect", props.onDisconnect); this.core.on("close", props.onClose); this.core.on("error", props.onError); } diff --git a/src/core/connectors/index.ts b/src/core/connectors/index.ts index fe98217001..403b26d13e 100644 --- a/src/core/connectors/index.ts +++ b/src/core/connectors/index.ts @@ -1,19 +1,19 @@ -import ConnectToInjected from "./injected"; -import ConnectToWalletConnect from "./walletconnect"; -import ConnectToPortis from "./portis"; -import ConnectToFortmatic from "./fortmatic"; -import ConnectToTorus from "./torus"; -import ConnectToSquarelink from "./squarelink"; -import ConnectToArkane from "./arkane"; -import ConnectToAuthereum from "./authereum"; +import injected from "./injected"; +import walletconnect from "./walletconnect"; +import portis from "./portis"; +import fortmatic from "./fortmatic"; +import torus from "./torus"; +import squarelink from "./squarelink"; +import arkane from "./arkane"; +import authereum from "./authereum"; export default { - ConnectToInjected, - ConnectToWalletConnect, - ConnectToPortis, - ConnectToTorus, - ConnectToFortmatic, - ConnectToSquarelink, - ConnectToArkane, - ConnectToAuthereum + injected, + walletconnect, + portis, + torus, + fortmatic, + squarelink, + arkane, + authereum }; diff --git a/src/core/index.tsx b/src/core/index.tsx index c1e8744cca..254fd9265a 100644 --- a/src/core/index.tsx +++ b/src/core/index.tsx @@ -2,21 +2,20 @@ import * as React from "react"; import * as ReactDOM from "react-dom"; import Modal from "../components/Modal"; import { IProviderOptions, IProviderCallback } from "../helpers/types"; -import { isMobile, getInjectedProviderName } from "../helpers/utils"; -import connectors from "./connectors"; + import EventManager from "./events"; -import { providerPackages } from "../providers"; +import ProviderManager from "./providerManager"; import { WEB3_CONNECT_MODAL_ID, CONNECT_EVENT, - DISCONNECT_EVENT, + ERROR_EVENT, CLOSE_EVENT } from "../helpers/constants"; interface ICoreOptions { - network?: string; - lightboxOpacity?: number; - providerOptions?: IProviderOptions; + network: string; + lightboxOpacity: number; + providerOptions: IProviderOptions; } const INITIAL_STATE = { show: false }; @@ -24,23 +23,31 @@ const INITIAL_STATE = { show: false }; class Core { private show: boolean = INITIAL_STATE.show; private eventManager: EventManager = new EventManager(); - private injectedProvider: string | null = null; - private network: string = ""; - private lightboxOpacity: number = 0.4; - private providerOptions: IProviderOptions = {}; + private lightboxOpacity: number; + private providerManager: ProviderManager; private providers: IProviderCallback[]; - constructor(opts?: ICoreOptions) { - this.injectedProvider = getInjectedProviderName(); + constructor(opts?: Partial) { + const options: ICoreOptions = { + lightboxOpacity: 0.4, + providerOptions: {}, + network: "", + ...opts + }; - if (opts) { - this.network = opts.network || ""; - this.lightboxOpacity = opts.lightboxOpacity || 0.4; - this.providerOptions = opts.providerOptions || {}; - } + this.lightboxOpacity = options.lightboxOpacity; + + this.providerManager = new ProviderManager({ + providerOptions: options.providerOptions, + network: options.network + }); - this.providers = this.getProviders(); + this.providerManager.on(CONNECT_EVENT, provider => + this.onConnect(provider) + ); + this.providerManager.on(ERROR_EVENT, error => this.onError(error)); + this.providers = this.providerManager.getProviders(); this.renderModal(); } @@ -66,48 +73,6 @@ class Core { }); } - public connectToInjected = async () => { - try { - const provider = await connectors.ConnectToInjected(); - await this.onConnect(provider, "injected"); - } catch (error) { - await this.onError(error); - } - }; - - public connectTo = async ( - name: string, - connector: (providerPackage: any, opts: any) => Promise - ) => { - try { - const providerPackage = - this.providerOptions && - this.providerOptions[name] && - this.providerOptions[name].package - ? this.providerOptions[name].package - : {}; - const providerOptions = - this.providerOptions && - this.providerOptions[name] && - this.providerOptions[name].options - ? this.providerOptions[name].options - : {}; - const opts = this.network - ? { network: this.network, ...providerOptions } - : providerOptions; - const provider = await connector(providerPackage, opts); - if (provider.isWalletConnect) { - // Listen for Disconnect event - provider.wc.on(DISCONNECT_EVENT, async () => { - return this.onDisconnect(); - }); - } - await this.onConnect(provider, name); - } catch (error) { - await this.onError(error); - } - }; - public toggleModal = async () => { if ( this.providers && @@ -148,171 +113,20 @@ class Core { // --------------- PRIVATE METHODS --------------- // - private shouldDisplayProvider(name: string) { - const { providerOptions } = this; - const providerPackage = providerPackages[name]; - - if (providerOptions) { - const providerPackageOptions = providerOptions[providerPackage.option]; - - if (providerPackageOptions) { - const isProvided = providerPackageOptions.package; - if (isProvided) { - const required = providerPackage.required; - if (required.length) { - const providedOptions = providerPackageOptions.options; - if (providedOptions && Object.keys(providedOptions).length) { - const matches = required.filter( - (key: string) => key in providedOptions - ); - if (required.length === matches.length) { - return true; - } - } - } else { - return true; - } - } - } - } - return false; - } - - private getProviders = () => { - const mobile = isMobile(); - - let providers = [ - "injected", - "walletconnect", - "portis", - "fortmatic", - "squarelink", - "torus", - "arkane", - "authereum" - ]; - - const { injectedProvider, providerOptions } = this; - - const displayInjected = - injectedProvider && !providerOptions.disableInjectedProvider; - - const onlyInjected = displayInjected && mobile; - - if (onlyInjected) { - providers = ["injected"]; - } else { - if (!displayInjected) { - providers = providers.filter(provider => provider !== "injected"); - } - - if (!this.shouldDisplayProvider("walletconnect")) { - providers = providers.filter(provider => provider !== "walletconnect"); - } - - if (!this.shouldDisplayProvider("portis")) { - providers = providers.filter(provider => provider !== "portis"); - } - - if (!this.shouldDisplayProvider("fortmatic")) { - providers = providers.filter(provider => provider !== "fortmatic"); - } - - if (!this.shouldDisplayProvider("squarelink")) { - providers = providers.filter(provider => provider !== "squarelink"); - } - - if (!this.shouldDisplayProvider("torus")) { - providers = providers.filter(provider => provider !== "torus"); - } - - if (!this.shouldDisplayProvider("arkane")) { - providers = providers.filter(provider => provider !== "arkane"); - } - - if (!this.shouldDisplayProvider("authereum")) { - providers = providers.filter(provider => provider !== "authereum"); - } - } - - const providersMap = providers.map(provider => { - switch (provider) { - case "injected": - return { - name: injectedProvider, - onClick: this.connectToInjected - }; - case "walletconnect": - return { - name: "WalletConnect", - onClick: () => - this.connectTo("walletconnect", connectors.ConnectToWalletConnect) - }; - case "portis": - return { - name: "Portis", - onClick: () => this.connectTo("portis", connectors.ConnectToPortis) - }; - case "fortmatic": - return { - name: "Fortmatic", - onClick: () => - this.connectTo("fortmatic", connectors.ConnectToFortmatic) - }; - case "squarelink": - return { - name: "Squarelink", - onClick: () => - this.connectTo("squarelink", connectors.ConnectToSquarelink) - }; - case "arkane": - return { - name: "Arkane", - onClick: () => this.connectTo("arkane", connectors.ConnectToArkane) - }; - case "torus": - return { - name: "Google", - onClick: () => this.connectTo("torus", connectors.ConnectToTorus) - }; - case "authereum": - return { - name: "Authereum", - onClick: () => - this.connectTo("authereum", connectors.ConnectToAuthereum) - }; - - default: - return { - name: "", - onClick: async () => { - // empty - } - }; - } - }); - - return providersMap; - }; - private onError = async (error: any) => { if (this.show) { await this.toggleModal(); } - this.eventManager.trigger("error", error); + this.eventManager.trigger(ERROR_EVENT, error); }; - private onConnect = async (provider: any, name: string) => { + private onConnect = async (provider: any) => { if (this.show) { await this.toggleModal(); } this.eventManager.trigger(CONNECT_EVENT, provider); }; - private onDisconnect = async () => { - this.eventManager.trigger(DISCONNECT_EVENT); - }; - private onClose = async () => { if (this.show) { await this.toggleModal(); diff --git a/src/helpers/constants.ts b/src/helpers/constants.ts index 6315f52adc..f6fa227139 100644 --- a/src/helpers/constants.ts +++ b/src/helpers/constants.ts @@ -1,6 +1,8 @@ export const WEB3_CONNECT_MODAL_ID = "WEB3_CONNECT_MODAL_ID"; export const PREFERRED_PROVIDER_KEY = "WEB3_CONNECT_PREFERRED_PROVIDER"; +export const INJECTED_PROVIDER_ID = "injected"; + export const CONNECT_EVENT = "connect"; -export const DISCONNECT_EVENT = "disconnect"; +export const ERROR_EVENT = "error"; export const CLOSE_EVENT = "close"; diff --git a/src/helpers/types.ts b/src/helpers/types.ts index f2c709214c..d2a3e8ddfb 100644 --- a/src/helpers/types.ts +++ b/src/helpers/types.ts @@ -1,15 +1,19 @@ export interface IProviderInfo { + id: string; name: string; type: string; logo: string; check: string; - styled: { - [prop: string]: any; - }; + package: IProviderPackageOptions; + styled: IProviderStyledOptions; +} + +export interface IProviderStyledOptions { + [prop: string]: any; } export interface IProviderOptions { - [providerName: string]: { + [id: string]: { package: any; options: any; }; @@ -31,3 +35,14 @@ export interface IProviderCallback { name: string | null; onClick: () => Promise; } + +export interface IProviderMappingEntry { + id: string; + name: string; + connector: any; + package: IProviderPackageOptions; +} + +export interface IProviderPackageOptions { + required: string[]; +} diff --git a/src/helpers/utils.ts b/src/helpers/utils.ts index 5754875bb5..6fbe1e754f 100644 --- a/src/helpers/utils.ts +++ b/src/helpers/utils.ts @@ -1,4 +1,4 @@ -import providers, { fallbackProvider } from "../providers"; +import { providers, FALLBACK } from "../providers"; import { IProviderInfo, IInjectedProvidersMap } from "./types"; export function checkInjectedProviders(): IInjectedProvidersMap { @@ -52,7 +52,7 @@ export function getInjectedProviderName(): string | null { } export function getProviderInfoByName(name: string | null): IProviderInfo { - let result = fallbackProvider; + let result = FALLBACK; if (name) { const matches = providers.filter(provider => provider.name === name); @@ -66,7 +66,7 @@ export function getProviderInfoByName(name: string | null): IProviderInfo { } export function getProviderInfo(provider: any): IProviderInfo { - let result = fallbackProvider; + let result = FALLBACK; if (provider) { const matches = providers.filter(_provider => provider[_provider.check]); diff --git a/src/index.ts b/src/index.ts index 21e11a69ab..4f7daa1eb5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ import Button from "./components/ConnectButton"; import Core from "./core"; -import providers from "./providers"; +import { providers } from "./providers"; import * as utils from "./helpers/utils"; import * as types from "./helpers/types"; diff --git a/src/providers/index.ts b/src/providers/index.ts index 266011e1f1..160d8c0cdf 100644 --- a/src/providers/index.ts +++ b/src/providers/index.ts @@ -1,15 +1,11 @@ -import { IProviderInfo } from "../helpers/types"; -// @ts-ignore -import Web3DefaultLogo from "../assets/web3-default.svg"; +import { IProviderInfo, IProviderMappingEntry } from "../helpers/types"; +import connectors from "../core/connectors"; +import { INJECTED_PROVIDER_ID } from "../helpers/constants"; +import { FALLBACK_INJECTED, injected } from "./injected"; + // @ts-ignore import WalletConnectLogo from "../assets/walletconnect-circle.svg"; // @ts-ignore -import MetaMaskLogo from "../assets/metamask.svg"; -// @ts-ignore -import SafeLogo from "../assets/safe.svg"; -// @ts-ignore -import NiftyWalletLogo from "../assets/niftyWallet.png"; -// @ts-ignore import PortisLogo from "../assets/portis.svg"; // @ts-ignore import SquarelinkLogo from "../assets/squarelink.svg"; @@ -18,238 +14,168 @@ import FortmaticLogo from "../assets/fortmatic.svg"; // @ts-ignore import ArkaneLogo from "../assets/arkane.svg"; // @ts-ignore -import TrustLogo from "../assets/trust.svg"; -// @ts-ignore -import DapperLogo from "../assets/dapper.png"; -// @ts-ignore -import CoinbaseLogo from "../assets/coinbase.svg"; -// @ts-ignore -import CipherLogo from "../assets/cipher.svg"; -// @ts-ignore -import imTokenLogo from "../assets/imtoken.svg"; -// @ts-ignore -import StatusLogo from "../assets/status.svg"; -// @ts-ignore -import TokenaryLogo from "../assets/tokenary.png"; -// @ts-ignore -import OperaLogo from "../assets/opera.svg"; -// @ts-ignore import TorusLogo from "../assets/torus.png"; // @ts-ignore import AuthereumLogo from "../assets/authereum.svg"; -export const providerPackages = { - walletconnect: { - name: "@walletconnect/web3-provider", - option: "walletconnect", +export const FALLBACK = FALLBACK_INJECTED; + +export const WALLETCONNECT_PROVIDER: IProviderInfo = { + id: "walletconnect", + name: "WalletConnect", + logo: WalletConnectLogo, + type: "qrcode", + check: "isWalletConnect", + styled: { + noShadow: false + }, + package: { required: ["infuraId"] + } +}; + +export const PORTIS_PROVIDER: IProviderInfo = { + id: "portis", + name: "Portis", + logo: PortisLogo, + type: "web", + check: "isPortis", + styled: { + noShadow: true }, - portis: { - name: "@portis/web3", - option: "portis", + package: { required: ["id"] + } +}; + +export const FORTMATIC_PROVIDER: IProviderInfo = { + id: "fortmatic", + name: "Fortmatic", + logo: FortmaticLogo, + type: "web", + check: "isFortmatic", + styled: { + noShadow: true }, - fortmatic: { - name: "fortmatic", - option: "fortmatic", + package: { required: ["key"] + } +}; + +export const SQUARELINK_PROVIDER: IProviderInfo = { + id: "squarelink", + name: "Squarelink", + logo: SquarelinkLogo, + type: "web", + check: "isSquarelink", + styled: { + noShadow: true }, - squarelink: { - name: "squarelink", - option: "squarelink", + package: { required: ["id"] + } +}; + +export const TORUS_PROVIDER: IProviderInfo = { + id: "torus", + name: "Google", + logo: TorusLogo, + type: "web", + check: "isTorus", + styled: { + noShadow: false }, - torus: { - name: "@toruslabs/torus-embed", - option: "torus", + package: { required: [] + } +}; + +export const ARKANE_PROVIDER: IProviderInfo = { + id: "arkane", + name: "Arkane", + logo: ArkaneLogo, + type: "web", + check: "isArkane", + styled: { + noShadow: true }, - arkane: { - name: "@arkane-network/web3-arkane-provider", - option: "arkane", + package: { required: ["clientId"] - }, - authereum: { - name: "authereum", - option: "authereum", - required: [] } }; -export const fallbackProvider: IProviderInfo = { - name: "Web3", - logo: Web3DefaultLogo, - type: "injected", - check: "isWeb3", +export const AUTHEREUM_PROVIDER: IProviderInfo = { + id: "authereum", + name: "Authereum", + logo: AuthereumLogo, + type: "web", + check: "isAuthereum", styled: { - noShadow: false + noShadow: true + }, + package: { + required: [] } }; -const providers: IProviderInfo[] = [ - fallbackProvider, - { - name: "WalletConnect", - logo: WalletConnectLogo, - type: "qrcode", - check: "isWalletConnect", - styled: { - noShadow: false - } - }, - { - name: "MetaMask", - logo: MetaMaskLogo, - type: "injected", - check: "isMetaMask", - styled: { - noShadow: true - } - }, - { - name: "Safe", - logo: SafeLogo, - type: "injected", - check: "isSafe", - styled: { - noShadow: true - } - }, - { - name: "Nifty", - logo: NiftyWalletLogo, - type: "injected", - check: "isNiftyWallet", - styled: { - noShadow: true - } - }, - { - name: "Squarelink", - logo: SquarelinkLogo, - type: "web", - check: "isSquarelink", - styled: { - noShadow: true - } - }, - { - name: "Portis", - logo: PortisLogo, - type: "web", - check: "isPortis", - styled: { - noShadow: true - } - }, - { - name: "Fortmatic", - logo: FortmaticLogo, - type: "web", - check: "isFortmatic", - styled: { - noShadow: true - } - }, - { - name: "Arkane", - logo: ArkaneLogo, - type: "web", - check: "isArkane", - styled: { - noShadow: true - } - }, - { - name: "Dapper", - logo: DapperLogo, - type: "injected", - check: "isDapper", - styled: { - noShadow: true - } - }, - { - name: "Opera", - logo: OperaLogo, - type: "injected", - check: "isOpera", - styled: { - noShadow: false - } - }, +export const providers: IProviderInfo[] = [ + ...injected, + WALLETCONNECT_PROVIDER, + SQUARELINK_PROVIDER, + PORTIS_PROVIDER, + FORTMATIC_PROVIDER, + ARKANE_PROVIDER, + TORUS_PROVIDER, + AUTHEREUM_PROVIDER +]; + +export const providerMapping: IProviderMappingEntry[] = [ { - name: "Trust", - logo: TrustLogo, - type: "injected", - check: "isTrust", - styled: { - noShadow: false - } + id: INJECTED_PROVIDER_ID, + name: "", + connector: connectors.injected, + package: WALLETCONNECT_PROVIDER.package }, { - name: "Coinbase", - logo: CoinbaseLogo, - type: "injected", - check: "isToshi", - styled: { - noShadow: false - } + id: WALLETCONNECT_PROVIDER.id, + name: WALLETCONNECT_PROVIDER.name, + connector: connectors.walletconnect, + package: WALLETCONNECT_PROVIDER.package }, { - name: "Cipher", - logo: CipherLogo, - type: "injected", - check: "isCipher", - styled: { - noShadow: false - } + id: PORTIS_PROVIDER.id, + name: PORTIS_PROVIDER.name, + connector: connectors.portis, + package: WALLETCONNECT_PROVIDER.package }, { - name: "imToken", - logo: imTokenLogo, - type: "injected", - check: "isImToken", - styled: { - noShadow: false - } + id: FORTMATIC_PROVIDER.id, + name: FORTMATIC_PROVIDER.name, + connector: connectors.fortmatic, + package: WALLETCONNECT_PROVIDER.package }, { - name: "Status", - logo: StatusLogo, - type: "injected", - check: "isStatus", - styled: { - noShadow: false - } + id: SQUARELINK_PROVIDER.id, + name: SQUARELINK_PROVIDER.name, + connector: connectors.squarelink, + package: WALLETCONNECT_PROVIDER.package }, { - name: "Tokenary", - logo: TokenaryLogo, - type: "injected", - check: "isTokenary", - styled: { - noShadow: false - } + id: TORUS_PROVIDER.id, + name: TORUS_PROVIDER.name, + connector: connectors.torus, + package: WALLETCONNECT_PROVIDER.package }, { - name: "Google", - logo: TorusLogo, - type: "web", - check: "isTorus", - styled: { - noShadow: false - } + id: ARKANE_PROVIDER.id, + name: ARKANE_PROVIDER.name, + connector: connectors.arkane, + package: WALLETCONNECT_PROVIDER.package }, { - name: "Authereum", - logo: AuthereumLogo, - type: "web", - check: "isAuthereum", - styled: { - noShadow: true - } + id: AUTHEREUM_PROVIDER.id, + name: AUTHEREUM_PROVIDER.name, + connector: connectors.authereum, + package: WALLETCONNECT_PROVIDER.package } ]; - -export default providers; From 42976b4c0529fc76d94678be43bf5c78e8b36222 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Mon, 20 Jan 2020 20:10:50 +0100 Subject: [PATCH 13/21] add providerManager --- src/core/providerManager.ts | 171 +++++++++++++++++++++++++++++ src/providers/injected.ts | 209 ++++++++++++++++++++++++++++++++++++ 2 files changed, 380 insertions(+) create mode 100644 src/core/providerManager.ts create mode 100644 src/providers/injected.ts diff --git a/src/core/providerManager.ts b/src/core/providerManager.ts new file mode 100644 index 0000000000..328dbf4131 --- /dev/null +++ b/src/core/providerManager.ts @@ -0,0 +1,171 @@ +import { IProviderOptions, IProviderMappingEntry } from "../helpers/types"; +import { isMobile, getInjectedProviderName } from "../helpers/utils"; +import { providerMapping } from "../providers"; +import EventManager from "./events"; +import { + CONNECT_EVENT, + ERROR_EVENT, + INJECTED_PROVIDER_ID +} from "../helpers/constants"; + +interface IProviderManagerOptions { + providerOptions: IProviderOptions; + network: string; +} + +class ProviderManager { + private eventManager: EventManager = new EventManager(); + private injectedProvider: string | null = null; + private providerMapping: IProviderMappingEntry[] = []; + private providerOptions: IProviderOptions; + private network: string = ""; + + constructor(opts: IProviderManagerOptions) { + this.providerOptions = opts.providerOptions; + this.network = opts.network; + + this.generateProviderMapping(); + } + + public generateProviderMapping() { + this.injectedProvider = getInjectedProviderName(); + this.providerMapping = providerMapping.map(entry => { + if (entry.id === INJECTED_PROVIDER_ID) { + entry.name = this.injectedProvider || ""; + } + return entry; + }); + } + + public shouldDisplayProvider(id: string) { + const { providerOptions } = this; + const provider = this.getProviderMappingEntry(id); + if (provider) { + if (providerOptions) { + const providerPackageOptions = providerOptions[id]; + + if (providerPackageOptions) { + const isProvided = providerPackageOptions.package; + if (isProvided) { + const required = provider.package.required; + if (required.length) { + const providedOptions = providerPackageOptions.options; + if (providedOptions && Object.keys(providedOptions).length) { + const matches = required.filter( + (key: string) => key in providedOptions + ); + if (required.length === matches.length) { + return true; + } + } + } else { + return true; + } + } + } + } + } + return false; + } + + public getProviders = () => { + const mobile = isMobile(); + + const defaultProviderList = this.providerMapping.map(({ id }) => id); + + const displayInjected = + this.injectedProvider && !this.providerOptions.disableInjectedProvider; + + const onlyInjected = displayInjected && mobile; + + const providerList = []; + + if (onlyInjected) { + providerList.push(INJECTED_PROVIDER_ID); + } else { + if (displayInjected) { + providerList.push(INJECTED_PROVIDER_ID); + } + + defaultProviderList.forEach((id: string) => { + if (this.shouldDisplayProvider(id)) { + providerList.push(id); + } + }); + } + + const providersMap = providerList.map((id: string) => { + let provider = this.getProviderMappingEntry(id); + if (typeof provider !== "undefined") { + const { id, name, connector } = provider; + return { + name: name, + onClick: () => this.connectTo(id, connector) + }; + } + return { + name: "", + onClick: async () => { + // empty + } + }; + }); + + return providersMap; + }; + + public getProviderMappingEntry(id: string) { + const matches = this.providerMapping + .filter(entry => (entry.id === id ? entry : undefined)) + .filter(x => !!x); + if (matches && matches.length) { + return matches[0]; + } + return undefined; + } + + public getProviderOption(id: string, field: string) { + return this.providerOptions && + this.providerOptions[id] && + this.providerOptions[id][field] + ? this.providerOptions[id][field] + : {}; + } + + public connectTo = async ( + id: string, + connector: (providerPackage: any, opts: any) => Promise + ) => { + try { + const providerPackage = this.getProviderOption(id, "package"); + const providerOptions = this.getProviderOption(id, "field"); + const opts = { network: this.network || undefined, ...providerOptions }; + const provider = await connector(providerPackage, opts); + this.eventManager.trigger(CONNECT_EVENT, { provider, id }); + } catch (error) { + this.eventManager.trigger(ERROR_EVENT); + } + }; + + public on(event: string, callback: (result: any) => void): () => void { + this.eventManager.on({ + event, + callback + }); + + return () => + this.eventManager.off({ + event, + callback + }); + } + + public off(event: string, callback?: (result: any) => void): void { + this.eventManager.off({ + event, + callback + }); + } +} + +export default ProviderManager; diff --git a/src/providers/injected.ts b/src/providers/injected.ts new file mode 100644 index 0000000000..45e39b355f --- /dev/null +++ b/src/providers/injected.ts @@ -0,0 +1,209 @@ +import { IProviderInfo } from "../helpers/types"; + +// @ts-ignore +import Web3DefaultLogo from "../assets/web3-default.svg"; +// @ts-ignore +import MetaMaskLogo from "../assets/metamask.svg"; +// @ts-ignore +import SafeLogo from "../assets/safe.svg"; +// @ts-ignore +import NiftyWalletLogo from "../assets/niftyWallet.png"; +// @ts-ignore +import TrustLogo from "../assets/trust.svg"; +// @ts-ignore +import DapperLogo from "../assets/dapper.png"; +// @ts-ignore +import CoinbaseLogo from "../assets/coinbase.svg"; +// @ts-ignore +import CipherLogo from "../assets/cipher.svg"; +// @ts-ignore +import imTokenLogo from "../assets/imtoken.svg"; +// @ts-ignore +import StatusLogo from "../assets/status.svg"; +// @ts-ignore +import TokenaryLogo from "../assets/tokenary.png"; +// @ts-ignore +import OperaLogo from "../assets/opera.svg"; + +export const FALLBACK_INJECTED: IProviderInfo = { + id: "injected", + name: "Web3", + logo: Web3DefaultLogo, + type: "injected", + check: "isWeb3", + styled: { + noShadow: false + }, + package: { + required: [] + } +}; + +export const METAMASK_INJECTED: IProviderInfo = { + id: "injected", + name: "MetaMask", + logo: MetaMaskLogo, + type: "injected", + check: "isMetaMask", + styled: { + noShadow: true + }, + package: { + required: [] + } +}; + +export const SAFE_INJECTED: IProviderInfo = { + id: "injected", + name: "Safe", + logo: SafeLogo, + type: "injected", + check: "isSafe", + styled: { + noShadow: true + }, + package: { + required: [] + } +}; + +export const NIFTY_INJECTED: IProviderInfo = { + id: "injected", + name: "Nifty", + logo: NiftyWalletLogo, + type: "injected", + check: "isNiftyWallet", + styled: { + noShadow: true + }, + package: { + required: [] + } +}; + +export const DAPPER_INJECTED: IProviderInfo = { + id: "injected", + name: "Dapper", + logo: DapperLogo, + type: "injected", + check: "isDapper", + styled: { + noShadow: true + }, + package: { + required: [] + } +}; + +export const OPERA_INJECTED: IProviderInfo = { + id: "injected", + name: "Opera", + logo: OperaLogo, + type: "injected", + check: "isOpera", + styled: { + noShadow: false + }, + package: { + required: [] + } +}; + +export const TRUST_INJECTED: IProviderInfo = { + id: "injected", + name: "Trust", + logo: TrustLogo, + type: "injected", + check: "isTrust", + styled: { + noShadow: false + }, + package: { + required: [] + } +}; + +export const COINBASE_INJECTED: IProviderInfo = { + id: "injected", + name: "Coinbase", + logo: CoinbaseLogo, + type: "injected", + check: "isToshi", + styled: { + noShadow: false + }, + package: { + required: [] + } +}; + +export const CIPHER_INJECTED: IProviderInfo = { + id: "injected", + name: "Cipher", + logo: CipherLogo, + type: "injected", + check: "isCipher", + styled: { + noShadow: false + }, + package: { + required: [] + } +}; + +export const IMTOKEN_INJECTED: IProviderInfo = { + id: "injected", + name: "imToken", + logo: imTokenLogo, + type: "injected", + check: "isImToken", + styled: { + noShadow: false + }, + package: { + required: [] + } +}; + +export const STATUS_INJECTED: IProviderInfo = { + id: "injected", + name: "Status", + logo: StatusLogo, + type: "injected", + check: "isStatus", + styled: { + noShadow: false + }, + package: { + required: [] + } +}; + +export const TOKENARY_INJECTED: IProviderInfo = { + id: "injected", + name: "Tokenary", + logo: TokenaryLogo, + type: "injected", + check: "isTokenary", + styled: { + noShadow: false + }, + package: { + required: [] + } +}; + +export const injected: IProviderInfo[] = [ + FALLBACK_INJECTED, + METAMASK_INJECTED, + SAFE_INJECTED, + NIFTY_INJECTED, + DAPPER_INJECTED, + OPERA_INJECTED, + TRUST_INJECTED, + COINBASE_INJECTED, + CIPHER_INJECTED, + IMTOKEN_INJECTED, + STATUS_INJECTED, + TOKENARY_INJECTED +]; From 2e57f0aabb60e2ea7f9aab6ee6c76980ca6cf1e2 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Mon, 20 Jan 2020 20:41:44 +0100 Subject: [PATCH 14/21] refactor fixes --- example/src/App.tsx | 398 +++++++++++++++++++----------------- src/core/providerManager.ts | 45 ++-- src/providers/index.ts | 14 +- 3 files changed, 244 insertions(+), 213 deletions(-) diff --git a/example/src/App.tsx b/example/src/App.tsx index fd42c81daf..33d84bc6ea 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -1,47 +1,91 @@ -import * as React from "react"; -import styled from "styled-components"; -import Web3 from "web3"; -import Web3Connect from "web3connect"; +import * as React from 'react' +import styled from 'styled-components' +import Web3 from 'web3' + +import Web3Connect from 'web3connect' // @ts-ignore -import WalletConnectProvider from "@walletconnect/web3-provider"; -import Portis from "@portis/web3"; +import WalletConnectProvider from '@walletconnect/web3-provider' +import Portis from '@portis/web3' // @ts-ignore -// import Squarelink from 'squarelink' -import Torus from '@toruslabs/torus-embed' +import Fortmatic from 'fortmatic' + // @ts-ignore -import Fortmatic from "fortmatic"; -import Arkane from "@arkane-network/web3-arkane-provider"; -import Authereum from "authereum"; -import { convertUtf8ToHex } from "@walletconnect/utils"; -import Button from "./components/Button"; -import Column from "./components/Column"; -import Wrapper from "./components/Wrapper"; -import Modal from "./components/Modal"; -import Header from "./components/Header"; -import Loader from "./components/Loader"; -import AccountAssets from "./components/AccountAssets"; -import { apiGetAccountAssets } from "./helpers/api"; +// import Squarelink from 'squarelink' +// import Torus from '@toruslabs/torus-embed' +// import Arkane from "@arkane-network/web3-arkane-provider"; +// import Authereum from "authereum"; + +import { convertUtf8ToHex } from '@walletconnect/utils' +import Button from './components/Button' +import Column from './components/Column' +import Wrapper from './components/Wrapper' +import Modal from './components/Modal' +import Header from './components/Header' +import Loader from './components/Loader' +import AccountAssets from './components/AccountAssets' +import { apiGetAccountAssets } from './helpers/api' import { hashPersonalMessage, recoverPublicKey, recoverPersonalSignature, formatTestTransaction -} from "./helpers/utilities"; -import { IAssetData } from "./helpers/types"; -import { fonts } from "./styles"; +} from './helpers/utilities' +import { IAssetData } from './helpers/types' +import { fonts } from './styles' + +const providerOptions = { + walletconnect: { + package: WalletConnectProvider, + options: { + infuraId: process.env.REACT_APP_INFURA_ID + } + }, + portis: { + package: Portis, + options: { + id: process.env.REACT_APP_PORTIS_ID + } + }, + fortmatic: { + package: Fortmatic, + options: { + key: process.env.REACT_APP_FORTMATIC_KEY + } + } + // arkane: { + // package: Arkane, + // options: { + // clientId: process.env.REACT_APP_ARKANE_CLIENT_ID, + // environment: "staging" + // } + // }, + // authereum: { + // package: Authereum, + // options: {} + // }, + // squarelink: { + // package: Squarelink, + // options: { + // id: process.env.REACT_APP_SQUARELINK_ID + // } + // }, + // torus: { + // package: Torus + // } +} const SLayout = styled.div` position: relative; width: 100%; min-height: 100vh; text-align: center; -`; +` const SContent = styled(Wrapper)` width: 100%; height: 100%; padding: 0 16px; -`; +` const SContainer = styled.div` height: 100%; @@ -51,55 +95,55 @@ const SContainer = styled.div` justify-content: center; align-items: center; word-break: break-word; -`; +` const SLanding = styled(Column)` height: 600px; -`; +` const SModalContainer = styled.div` width: 100%; position: relative; word-wrap: break-word; -`; +` const SModalTitle = styled.div` margin: 1em 0; font-size: 20px; font-weight: 700; -`; +` const SModalParagraph = styled.p` margin-top: 30px; -`; +` const SBalances = styled(SLanding)` height: 100%; & h3 { padding-top: 30px; } -`; +` const STable = styled(SContainer)` flex-direction: column; text-align: left; -`; +` const SRow = styled.div` width: 100%; display: flex; margin: 6px 0; -`; +` const SKey = styled.div` width: 30%; font-weight: 700; -`; +` const SValue = styled.div` width: 70%; font-family: monospace; -`; +` const STestButtonContainer = styled.div` width: 100%; @@ -107,7 +151,7 @@ const STestButtonContainer = styled.div` justify-content: center; align-items: center; flex-wrap: wrap; -`; +` const STestButton = styled(Button)` border-radius: 8px; @@ -116,24 +160,24 @@ const STestButton = styled(Button)` width: 100%; max-width: 175px; margin: 12px; -`; +` interface IAppState { - fetching: boolean; - address: string; - web3: any; - connected: boolean; - chainId: number; - networkId: number; - assets: IAssetData[]; - showModal: boolean; - pendingRequest: boolean; - result: any | null; + fetching: boolean + address: string + web3: any + connected: boolean + chainId: number + networkId: number + assets: IAssetData[] + showModal: boolean + pendingRequest: boolean + result: any | null } const INITIAL_STATE: IAppState = { fetching: false, - address: "", + address: '', web3: null, connected: false, chainId: 1, @@ -142,33 +186,41 @@ const INITIAL_STATE: IAppState = { showModal: false, pendingRequest: false, result: null -}; +} + +function initWeb3(provider: any) { + const web3: any = new Web3(provider) + + web3.eth.extend({ + methods: [ + { + name: 'chainId', + call: 'eth_chainId', + outputFormatter: web3.utils.hexToNumber + } + ] + }) + + return web3 +} class App extends React.Component { public state: IAppState = { ...INITIAL_STATE - }; + } public onConnect = async (provider: any) => { - const web3: any = new Web3(provider); + await this.subscribeProvider(provider) - const accounts = await web3.eth.getAccounts(); + const web3: any = initWeb3(provider) - const address = accounts[0]; + const accounts = await web3.eth.getAccounts() - const networkId = await web3.eth.net.getId(); + const address = accounts[0] - web3.eth.extend({ - methods: [ - { - name: "chainId", - call: "eth_chainId", - outputFormatter: web3.utils.hexToNumber - } - ] - }); + const networkId = await web3.eth.net.getId() - const chainId = await web3.eth.chainId(); + const chainId = await web3.eth.chainId() await this.setState({ web3, @@ -176,181 +228,201 @@ class App extends React.Component { address, chainId, networkId - }); - await this.getAccountAssets(); - }; + }) + await this.getAccountAssets() + } + + public subscribeProvider = async (provider: any) => { + provider.on('close', () => this.resetApp()) + provider.on('accountsChanged', async (accounts: string[]) => { + await this.setState({ address: accounts[0] }) + await this.getAccountAssets() + }) + provider.on('chainChanged', async (chainId: number) => { + const { web3 } = this.state + const networkId = await web3.eth.net.getId() + await this.setState({ chainId, networkId }) + await this.getAccountAssets() + }) + + provider.on('networkChanged', async (networkId: number) => { + const { web3 } = this.state + const chainId = await web3.eth.chainId() + await this.setState({ chainId, networkId }) + await this.getAccountAssets() + }) + } public getAccountAssets = async () => { - const { address, chainId } = this.state; - this.setState({ fetching: true }); + const { address, chainId } = this.state + this.setState({ fetching: true }) try { // get account balances - const assets = await apiGetAccountAssets(address, chainId); + const assets = await apiGetAccountAssets(address, chainId) - await this.setState({ fetching: false, assets }); + await this.setState({ fetching: false, assets }) } catch (error) { - console.error(error); // tslint:disable-line - await this.setState({ fetching: false }); + console.error(error) // tslint:disable-line + await this.setState({ fetching: false }) } - }; + } - public toggleModal = () => - this.setState({ showModal: !this.state.showModal }); + public toggleModal = () => this.setState({ showModal: !this.state.showModal }) public testSendTransaction = async () => { - const { web3, address, chainId } = this.state; + const { web3, address, chainId } = this.state if (!web3) { - return; + return } - const tx = await formatTestTransaction(address, chainId); + const tx = await formatTestTransaction(address, chainId) try { // open modal - this.toggleModal(); + this.toggleModal() // toggle pending request indicator - this.setState({ pendingRequest: true }); + this.setState({ pendingRequest: true }) // @ts-ignore function sendTransaction(_tx: any) { return new Promise((resolve, reject) => { web3.eth .sendTransaction(_tx) - .once("transactionHash", (txHash: string) => resolve(txHash)) - .catch((err: any) => reject(err)); - }); + .once('transactionHash', (txHash: string) => resolve(txHash)) + .catch((err: any) => reject(err)) + }) } // send transaction - const result = await sendTransaction(tx); + const result = await sendTransaction(tx) // format displayed result const formattedResult = { - method: "eth_sendTransaction", + method: 'eth_sendTransaction', txHash: result, from: address, to: address, - value: "0 ETH" - }; + value: '0 ETH' + } // display result this.setState({ web3, pendingRequest: false, result: formattedResult || null - }); + }) } catch (error) { - console.error(error); // tslint:disable-line - this.setState({ web3, pendingRequest: false, result: null }); + console.error(error) // tslint:disable-line + this.setState({ web3, pendingRequest: false, result: null }) } - }; + } public testSignMessage = async () => { - const { web3, address } = this.state; + const { web3, address } = this.state if (!web3) { - return; + return } // test message - const message = "My email is john@doe.com - 1537836206101"; + const message = 'My email is john@doe.com - 1537836206101' // hash message - const hash = hashPersonalMessage(message); + const hash = hashPersonalMessage(message) try { // open modal - this.toggleModal(); + this.toggleModal() // toggle pending request indicator - this.setState({ pendingRequest: true }); + this.setState({ pendingRequest: true }) // send message - const result = await web3.eth.sign(hash, address); + const result = await web3.eth.sign(hash, address) // verify signature - const signer = recoverPublicKey(result, hash); - const verified = signer.toLowerCase() === address.toLowerCase(); + const signer = recoverPublicKey(result, hash) + const verified = signer.toLowerCase() === address.toLowerCase() // format displayed result const formattedResult = { - method: "eth_sign", + method: 'eth_sign', address, signer, verified, result - }; + } // display result this.setState({ web3, pendingRequest: false, result: formattedResult || null - }); + }) } catch (error) { - console.error(error); // tslint:disable-line - this.setState({ web3, pendingRequest: false, result: null }); + console.error(error) // tslint:disable-line + this.setState({ web3, pendingRequest: false, result: null }) } - }; + } public testSignPersonalMessage = async () => { - const { web3, address } = this.state; + const { web3, address } = this.state if (!web3) { - return; + return } // test message - const message = "My email is john@doe.com - 1537836206101"; + const message = 'My email is john@doe.com - 1537836206101' // encode message (hex) - const hexMsg = convertUtf8ToHex(message); + const hexMsg = convertUtf8ToHex(message) try { // open modal - this.toggleModal(); + this.toggleModal() // toggle pending request indicator - this.setState({ pendingRequest: true }); + this.setState({ pendingRequest: true }) // send message - const result = await web3.eth.personal.sign(hexMsg, address); + const result = await web3.eth.personal.sign(hexMsg, address) // verify signature - const signer = recoverPersonalSignature(result, message); - const verified = signer.toLowerCase() === address.toLowerCase(); + const signer = recoverPersonalSignature(result, message) + const verified = signer.toLowerCase() === address.toLowerCase() // format displayed result const formattedResult = { - method: "personal_sign", + method: 'personal_sign', address, signer, verified, result - }; + } // display result this.setState({ web3, pendingRequest: false, result: formattedResult || null - }); + }) } catch (error) { - console.error(error); // tslint:disable-line - this.setState({ web3, pendingRequest: false, result: null }); + console.error(error) // tslint:disable-line + this.setState({ web3, pendingRequest: false, result: null }) } - }; + } public resetApp = async () => { - const { web3 } = this.state; + const { web3 } = this.state if (web3 && web3.currentProvider && web3.currentProvider.close) { - console.log("web3.currentProvider", web3.currentProvider); // tslint:disable-line - await web3.currentProvider.close(); + console.log('web3.currentProvider', web3.currentProvider) // tslint:disable-line + await web3.currentProvider.close() } - this.setState({ ...INITIAL_STATE }); - }; + this.setState({ ...INITIAL_STATE }) + } public render = () => { const { @@ -362,8 +434,8 @@ class App extends React.Component { showModal, pendingRequest, result - } = this.state; - + } = this.state + return ( @@ -386,75 +458,35 @@ class App extends React.Component { - {"eth_sendTransaction"} + {'eth_sendTransaction'} - {"eth_sign"} + {'eth_sign'} - {"personal_sign"} + {'personal_sign'}

Balances

- {" "} + {' '} ) : (

{`Test Web3Connect`}

{ - this.onConnect(provider); + this.onConnect(provider) }} onClose={() => { // empty }} - onDisconnect={() => this.resetApp()} onError={(error: Error) => { - console.error(error); // tslint:disable-line + console.error(error) // tslint:disable-line }} />
@@ -464,17 +496,17 @@ class App extends React.Component { {pendingRequest ? ( - {"Pending Call Request"} + {'Pending Call Request'} - {"Approve or reject request using your wallet"} + {'Approve or reject request using your wallet'} ) : result ? ( - {"Call Request Approved"} + {'Call Request Approved'} {Object.keys(result).map(key => ( @@ -486,13 +518,13 @@ class App extends React.Component { ) : ( - {"Call Request Rejected"} + {'Call Request Rejected'} )}
- ); - }; + ) + } } -export default App; +export default App diff --git a/src/core/providerManager.ts b/src/core/providerManager.ts index 328dbf4131..ea591acc52 100644 --- a/src/core/providerManager.ts +++ b/src/core/providerManager.ts @@ -38,29 +38,25 @@ class ProviderManager { } public shouldDisplayProvider(id: string) { - const { providerOptions } = this; const provider = this.getProviderMappingEntry(id); if (provider) { - if (providerOptions) { - const providerPackageOptions = providerOptions[id]; - - if (providerPackageOptions) { - const isProvided = providerPackageOptions.package; - if (isProvided) { - const required = provider.package.required; - if (required.length) { - const providedOptions = providerPackageOptions.options; - if (providedOptions && Object.keys(providedOptions).length) { - const matches = required.filter( - (key: string) => key in providedOptions - ); - if (required.length === matches.length) { - return true; - } + const providerPackageOptions = this.providerOptions[id]; + if (providerPackageOptions) { + const isProvided = !!providerPackageOptions.package; + if (isProvided) { + const required = provider.package.required; + if (required.length) { + const providedOptions = providerPackageOptions.options; + if (providedOptions && Object.keys(providedOptions).length) { + const matches = required.filter( + (key: string) => key in providedOptions + ); + if (required.length === matches.length) { + return true; } - } else { - return true; } + } else { + return true; } } } @@ -88,8 +84,11 @@ class ProviderManager { } defaultProviderList.forEach((id: string) => { - if (this.shouldDisplayProvider(id)) { - providerList.push(id); + if (id !== INJECTED_PROVIDER_ID) { + const result = this.shouldDisplayProvider(id); + if (result) { + providerList.push(id); + } } }); } @@ -138,10 +137,10 @@ class ProviderManager { ) => { try { const providerPackage = this.getProviderOption(id, "package"); - const providerOptions = this.getProviderOption(id, "field"); + const providerOptions = this.getProviderOption(id, "options"); const opts = { network: this.network || undefined, ...providerOptions }; const provider = await connector(providerPackage, opts); - this.eventManager.trigger(CONNECT_EVENT, { provider, id }); + this.eventManager.trigger(CONNECT_EVENT, provider); } catch (error) { this.eventManager.trigger(ERROR_EVENT); } diff --git a/src/providers/index.ts b/src/providers/index.ts index 160d8c0cdf..1c60d79e59 100644 --- a/src/providers/index.ts +++ b/src/providers/index.ts @@ -134,7 +134,7 @@ export const providerMapping: IProviderMappingEntry[] = [ id: INJECTED_PROVIDER_ID, name: "", connector: connectors.injected, - package: WALLETCONNECT_PROVIDER.package + package: FALLBACK_INJECTED.package }, { id: WALLETCONNECT_PROVIDER.id, @@ -146,36 +146,36 @@ export const providerMapping: IProviderMappingEntry[] = [ id: PORTIS_PROVIDER.id, name: PORTIS_PROVIDER.name, connector: connectors.portis, - package: WALLETCONNECT_PROVIDER.package + package: PORTIS_PROVIDER.package }, { id: FORTMATIC_PROVIDER.id, name: FORTMATIC_PROVIDER.name, connector: connectors.fortmatic, - package: WALLETCONNECT_PROVIDER.package + package: FORTMATIC_PROVIDER.package }, { id: SQUARELINK_PROVIDER.id, name: SQUARELINK_PROVIDER.name, connector: connectors.squarelink, - package: WALLETCONNECT_PROVIDER.package + package: SQUARELINK_PROVIDER.package }, { id: TORUS_PROVIDER.id, name: TORUS_PROVIDER.name, connector: connectors.torus, - package: WALLETCONNECT_PROVIDER.package + package: TORUS_PROVIDER.package }, { id: ARKANE_PROVIDER.id, name: ARKANE_PROVIDER.name, connector: connectors.arkane, - package: WALLETCONNECT_PROVIDER.package + package: ARKANE_PROVIDER.package }, { id: AUTHEREUM_PROVIDER.id, name: AUTHEREUM_PROVIDER.name, connector: connectors.authereum, - package: WALLETCONNECT_PROVIDER.package + package: AUTHEREUM_PROVIDER.package } ]; From edf56f0f31176a2fd2e1454b1a3efcfc1be934c9 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Mon, 20 Jan 2020 20:58:00 +0100 Subject: [PATCH 15/21] move connectors inside providers directory --- src/core/connectors/arkane.ts | 30 --------- src/core/connectors/authereum.ts | 19 ------ src/core/connectors/fortmatic.ts | 31 --------- src/core/connectors/index.ts | 19 ------ src/core/connectors/injected.ts | 18 ------ src/core/connectors/portis.ts | 42 ------------- src/core/connectors/squarelink.ts | 40 ------------ src/core/connectors/torus.ts | 94 ---------------------------- src/core/connectors/walletconnect.ts | 53 ---------------- 9 files changed, 346 deletions(-) delete mode 100644 src/core/connectors/arkane.ts delete mode 100644 src/core/connectors/authereum.ts delete mode 100644 src/core/connectors/fortmatic.ts delete mode 100644 src/core/connectors/index.ts delete mode 100644 src/core/connectors/injected.ts delete mode 100644 src/core/connectors/portis.ts delete mode 100644 src/core/connectors/squarelink.ts delete mode 100644 src/core/connectors/torus.ts delete mode 100644 src/core/connectors/walletconnect.ts diff --git a/src/core/connectors/arkane.ts b/src/core/connectors/arkane.ts deleted file mode 100644 index 0fafce4c40..0000000000 --- a/src/core/connectors/arkane.ts +++ /dev/null @@ -1,30 +0,0 @@ -export interface IArkaneConnectorOptions { - clientId: string; - nodeUrl?: string; - environment?: string -} - -const ConnectToArkane = (Arkane: any, opts: IArkaneConnectorOptions) => { - return new Promise(async (resolve, reject) => { - if (opts && opts.clientId) { - try { - const options = { - clientId: opts.clientId, - rpcUrl: opts.nodeUrl, - environment: opts.environment, - signMethod: 'POPUP', - }; - console.log(Arkane); - const provider = await (window as any).Arkane.createArkaneProviderEngine(options); - return resolve(provider); - } catch (error) { - console.error(error); - return reject(new Error("Failed to login to Arkane 2")); - } - } else { - return reject(new Error("Please provide an Arkane client id")); - } - }); -}; - -export default ConnectToArkane; diff --git a/src/core/connectors/authereum.ts b/src/core/connectors/authereum.ts deleted file mode 100644 index 11fd4779ce..0000000000 --- a/src/core/connectors/authereum.ts +++ /dev/null @@ -1,19 +0,0 @@ -export interface IAuthereumConnectorOptions { - network?: string; -} - -const ConnectToAuthereum = (Authereum: any, opts: IAuthereumConnectorOptions) => { - return new Promise(async (resolve, reject) => { - try { - const authereum = new Authereum(opts.network); - const provider = authereum.getProvider(); - provider.authereum = authereum - await provider.enable(); - resolve(provider); - } catch (error) { - return reject(error); - } - }); -}; - -export default ConnectToAuthereum; diff --git a/src/core/connectors/fortmatic.ts b/src/core/connectors/fortmatic.ts deleted file mode 100644 index f967fd75ee..0000000000 --- a/src/core/connectors/fortmatic.ts +++ /dev/null @@ -1,31 +0,0 @@ -export interface IFortmaticConnectorOptions { - key: string; - network?: string; -} - -const ConnectToFortmatic = async ( - Fortmatic: any, - opts: IFortmaticConnectorOptions -) => { - if (opts && opts.key) { - try { - const key = opts.key; - const fm = new Fortmatic(key, opts.network); - const provider = await fm.getProvider(); - provider.fm = fm - await fm.user.login(); - const isLoggedIn = await fm.user.isLoggedIn(); - if (isLoggedIn) { - return provider; - } else { - throw new Error("Failed to login to Fortmatic"); - } - } catch (error) { - throw error; - } - } else { - throw new Error("Missing Fortmatic key"); - } -}; - -export default ConnectToFortmatic; diff --git a/src/core/connectors/index.ts b/src/core/connectors/index.ts deleted file mode 100644 index 403b26d13e..0000000000 --- a/src/core/connectors/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import injected from "./injected"; -import walletconnect from "./walletconnect"; -import portis from "./portis"; -import fortmatic from "./fortmatic"; -import torus from "./torus"; -import squarelink from "./squarelink"; -import arkane from "./arkane"; -import authereum from "./authereum"; - -export default { - injected, - walletconnect, - portis, - torus, - fortmatic, - squarelink, - arkane, - authereum -}; diff --git a/src/core/connectors/injected.ts b/src/core/connectors/injected.ts deleted file mode 100644 index 6766471a5b..0000000000 --- a/src/core/connectors/injected.ts +++ /dev/null @@ -1,18 +0,0 @@ -const ConnectToInjected = async () => { - let provider = null; - if (window.ethereum) { - provider = window.ethereum; - try { - await window.ethereum.enable(); - } catch (error) { - throw new Error("User Rejected"); - } - } else if (window.web3) { - provider = window.web3.currentProvider; - } else { - throw new Error("No Web3 Provider found"); - } - return provider; -}; - -export default ConnectToInjected; diff --git a/src/core/connectors/portis.ts b/src/core/connectors/portis.ts deleted file mode 100644 index 8f8a0e3171..0000000000 --- a/src/core/connectors/portis.ts +++ /dev/null @@ -1,42 +0,0 @@ -export interface INetwork { - nodeUrl: string; - chainId?: string; - gasRelayHubAddress?: string; -} - -export type Scope = "email"; - -export interface IOptions { - scope?: Scope[]; - gasRelay?: boolean; - registerPageByDefault?: boolean; - pocketDevId?: string; -} - -export interface IPortisConnectorOptions { - id: string; - network?: string | INetwork; - config?: IOptions; -} - -const ConnectToPortis = (Portis: any, opts: IPortisConnectorOptions) => { - return new Promise(async (resolve, reject) => { - if (opts && opts.id) { - try { - const id = opts.id; - const network = opts.network || "mainnet"; - const config = opts.config; - const pt = new Portis(id, network, config); - await pt.provider.enable(); - pt.provider._portis = pt; - resolve(pt.provider); - } catch (error) { - return reject(error); - } - } else { - return reject(new Error("Missing Portis Id")); - } - }); -}; - -export default ConnectToPortis; diff --git a/src/core/connectors/squarelink.ts b/src/core/connectors/squarelink.ts deleted file mode 100644 index 0c661e3764..0000000000 --- a/src/core/connectors/squarelink.ts +++ /dev/null @@ -1,40 +0,0 @@ -export interface INetwork { - nodeUrl: string; - chainId?: string; -} - -export interface IOptions { - scope?: string[]; -} - -export interface ISquarelinkConnectorOptions { - id: string; - network?: string | INetwork; - config?: IOptions; -} - -const ConnectToSquarelink = ( - Squarelink: any, - opts: ISquarelinkConnectorOptions -) => { - return new Promise(async (resolve, reject) => { - if (opts && opts.id) { - try { - const id = opts.id; - const network = opts.network || "mainnet"; - const config = opts.config; - const sqlk = new Squarelink(id, network, config); - const provider = await sqlk.getProvider(); - provider.sqlk = sqlk - await provider.enable(); - return resolve(provider); - } catch (error) { - return reject(new Error("Failed to login to Squarelink")); - } - } else { - return reject(new Error("Missing Squarelink Id")); - } - }); -}; - -export default ConnectToSquarelink; diff --git a/src/core/connectors/torus.ts b/src/core/connectors/torus.ts deleted file mode 100644 index c19d6a56f5..0000000000 --- a/src/core/connectors/torus.ts +++ /dev/null @@ -1,94 +0,0 @@ - - -export interface INetwork { - nodeUrl: string; - chainId?: string; - networkName?: string; -} - -interface NetworkInterface { - host: 'mainnet' | 'rinkeby' | 'ropsten' | 'kovan' | 'goerli' | 'localhost' | 'matic' | string, - chainId?: number; - networkName?: string; -} - -interface VerifierStatus { - google?: boolean; - facebook?: boolean; - reddit?: boolean; - twitch?: boolean; - discord?: boolean; -} - - -export interface IOptions { - enableLogging?: boolean; - buttonPosition?: string; - buildEnv?: string; - showTorusButton?: boolean; - enabledVerifiers?: VerifierStatus -} - -export interface ITorusConnectorOptions { - network?: string | INetwork; - config?: IOptions; -} - -// Supports Torus package versions 0.1.* -const ConnectToTorus = async (Torus: any, opts: ITorusConnectorOptions) => { - return new Promise(async (resolve, reject) => { - try { - - // defaults - let buttonPosition = 'bottom-left' - let buildEnv = 'production' - let enableLogging = true - let showTorusButton = false - let enabledVerifiers = {} - let network : NetworkInterface = {host: 'mainnet'} - - // parsing to Torus interfaces - if (opts.network) { - if (typeof(opts.network) == 'string') { - network.host = opts.network - } else { - network.host = opts.network.nodeUrl - let chainId: string = opts.network.chainId || '' - network.chainId = parseInt(chainId, 10) - network.networkName = opts.network.networkName - } - } - if (opts.config) { - buttonPosition = opts.config.buttonPosition || buttonPosition - buildEnv = opts.config.buildEnv || buildEnv - enableLogging = opts.config.enableLogging || enableLogging - showTorusButton = opts.config.showTorusButton || showTorusButton - enabledVerifiers = opts.config.enabledVerifiers || enabledVerifiers - } - - const torus = new Torus({ - buttonPosition: buttonPosition - }); - await torus.init({ - buildEnv: buildEnv, - enableLogging: enableLogging, - // network: { - // host: 'kovan', // mandatory - // // chainId: 1, // optional - // networkName: 'kovan' // optional - // }, - network: network, - showTorusButton: showTorusButton, - enabledVerifiers: enabledVerifiers - }); - await torus.login(); // await torus.ethereum.enable() - const provider = torus.provider; - provider.torus = torus - resolve(provider); - } catch (err) { - reject(err) - } - }); -}; - -export default ConnectToTorus; \ No newline at end of file diff --git a/src/core/connectors/walletconnect.ts b/src/core/connectors/walletconnect.ts deleted file mode 100644 index c7220a50f1..0000000000 --- a/src/core/connectors/walletconnect.ts +++ /dev/null @@ -1,53 +0,0 @@ -export interface IWalletConnectConnectorOptions { - infuraId: string; - bridge?: string; - qrcode?: boolean; - network?: string; -} - -function getChainId(network: string) { - const infuraChainIds = { - mainnet: 1, - ropsten: 3, - rinkeby: 4, - goerli: 5, - kovan: 42 - }; - const chainId = infuraChainIds[network]; - if (!chainId) { - throw new Error(`Invalid or unknown chainId for network=${network}`); - } - return chainId; -} - -const ConnectToWalletConnect = ( - WalletConnectProvider: any, - opts: IWalletConnectConnectorOptions -) => { - return new Promise(async (resolve, reject) => { - let bridge = "https://bridge.walletconnect.org"; - let qrcode = true; - let infuraId = ""; - let chainId = 1; - - if (opts) { - bridge = opts.bridge || bridge; - qrcode = typeof opts.qrcode !== "undefined" ? opts.qrcode : qrcode; - infuraId = opts.infuraId || ""; - chainId = opts.network ? getChainId(opts.network) : 1; - } - - const provider = new WalletConnectProvider({ - bridge, - qrcode, - infuraId, - chainId - }); - - await provider.enable(); - - resolve(provider); - }); -}; - -export default ConnectToWalletConnect; From 86c7f9f89900a54d62009dc0d3a02fe8ae12b212 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Mon, 20 Jan 2020 20:58:46 +0100 Subject: [PATCH 16/21] move connectors inside providers directory --- src/providers/connectors/arkane.ts | 30 ++++++++ src/providers/connectors/authereum.ts | 19 +++++ src/providers/connectors/fortmatic.ts | 31 ++++++++ src/providers/connectors/index.ts | 19 +++++ src/providers/connectors/injected.ts | 18 +++++ src/providers/connectors/portis.ts | 42 ++++++++++ src/providers/connectors/squarelink.ts | 40 ++++++++++ src/providers/connectors/torus.ts | 94 +++++++++++++++++++++++ src/providers/connectors/walletconnect.ts | 53 +++++++++++++ 9 files changed, 346 insertions(+) create mode 100644 src/providers/connectors/arkane.ts create mode 100644 src/providers/connectors/authereum.ts create mode 100644 src/providers/connectors/fortmatic.ts create mode 100644 src/providers/connectors/index.ts create mode 100644 src/providers/connectors/injected.ts create mode 100644 src/providers/connectors/portis.ts create mode 100644 src/providers/connectors/squarelink.ts create mode 100644 src/providers/connectors/torus.ts create mode 100644 src/providers/connectors/walletconnect.ts diff --git a/src/providers/connectors/arkane.ts b/src/providers/connectors/arkane.ts new file mode 100644 index 0000000000..0fafce4c40 --- /dev/null +++ b/src/providers/connectors/arkane.ts @@ -0,0 +1,30 @@ +export interface IArkaneConnectorOptions { + clientId: string; + nodeUrl?: string; + environment?: string +} + +const ConnectToArkane = (Arkane: any, opts: IArkaneConnectorOptions) => { + return new Promise(async (resolve, reject) => { + if (opts && opts.clientId) { + try { + const options = { + clientId: opts.clientId, + rpcUrl: opts.nodeUrl, + environment: opts.environment, + signMethod: 'POPUP', + }; + console.log(Arkane); + const provider = await (window as any).Arkane.createArkaneProviderEngine(options); + return resolve(provider); + } catch (error) { + console.error(error); + return reject(new Error("Failed to login to Arkane 2")); + } + } else { + return reject(new Error("Please provide an Arkane client id")); + } + }); +}; + +export default ConnectToArkane; diff --git a/src/providers/connectors/authereum.ts b/src/providers/connectors/authereum.ts new file mode 100644 index 0000000000..11fd4779ce --- /dev/null +++ b/src/providers/connectors/authereum.ts @@ -0,0 +1,19 @@ +export interface IAuthereumConnectorOptions { + network?: string; +} + +const ConnectToAuthereum = (Authereum: any, opts: IAuthereumConnectorOptions) => { + return new Promise(async (resolve, reject) => { + try { + const authereum = new Authereum(opts.network); + const provider = authereum.getProvider(); + provider.authereum = authereum + await provider.enable(); + resolve(provider); + } catch (error) { + return reject(error); + } + }); +}; + +export default ConnectToAuthereum; diff --git a/src/providers/connectors/fortmatic.ts b/src/providers/connectors/fortmatic.ts new file mode 100644 index 0000000000..f967fd75ee --- /dev/null +++ b/src/providers/connectors/fortmatic.ts @@ -0,0 +1,31 @@ +export interface IFortmaticConnectorOptions { + key: string; + network?: string; +} + +const ConnectToFortmatic = async ( + Fortmatic: any, + opts: IFortmaticConnectorOptions +) => { + if (opts && opts.key) { + try { + const key = opts.key; + const fm = new Fortmatic(key, opts.network); + const provider = await fm.getProvider(); + provider.fm = fm + await fm.user.login(); + const isLoggedIn = await fm.user.isLoggedIn(); + if (isLoggedIn) { + return provider; + } else { + throw new Error("Failed to login to Fortmatic"); + } + } catch (error) { + throw error; + } + } else { + throw new Error("Missing Fortmatic key"); + } +}; + +export default ConnectToFortmatic; diff --git a/src/providers/connectors/index.ts b/src/providers/connectors/index.ts new file mode 100644 index 0000000000..403b26d13e --- /dev/null +++ b/src/providers/connectors/index.ts @@ -0,0 +1,19 @@ +import injected from "./injected"; +import walletconnect from "./walletconnect"; +import portis from "./portis"; +import fortmatic from "./fortmatic"; +import torus from "./torus"; +import squarelink from "./squarelink"; +import arkane from "./arkane"; +import authereum from "./authereum"; + +export default { + injected, + walletconnect, + portis, + torus, + fortmatic, + squarelink, + arkane, + authereum +}; diff --git a/src/providers/connectors/injected.ts b/src/providers/connectors/injected.ts new file mode 100644 index 0000000000..6766471a5b --- /dev/null +++ b/src/providers/connectors/injected.ts @@ -0,0 +1,18 @@ +const ConnectToInjected = async () => { + let provider = null; + if (window.ethereum) { + provider = window.ethereum; + try { + await window.ethereum.enable(); + } catch (error) { + throw new Error("User Rejected"); + } + } else if (window.web3) { + provider = window.web3.currentProvider; + } else { + throw new Error("No Web3 Provider found"); + } + return provider; +}; + +export default ConnectToInjected; diff --git a/src/providers/connectors/portis.ts b/src/providers/connectors/portis.ts new file mode 100644 index 0000000000..8f8a0e3171 --- /dev/null +++ b/src/providers/connectors/portis.ts @@ -0,0 +1,42 @@ +export interface INetwork { + nodeUrl: string; + chainId?: string; + gasRelayHubAddress?: string; +} + +export type Scope = "email"; + +export interface IOptions { + scope?: Scope[]; + gasRelay?: boolean; + registerPageByDefault?: boolean; + pocketDevId?: string; +} + +export interface IPortisConnectorOptions { + id: string; + network?: string | INetwork; + config?: IOptions; +} + +const ConnectToPortis = (Portis: any, opts: IPortisConnectorOptions) => { + return new Promise(async (resolve, reject) => { + if (opts && opts.id) { + try { + const id = opts.id; + const network = opts.network || "mainnet"; + const config = opts.config; + const pt = new Portis(id, network, config); + await pt.provider.enable(); + pt.provider._portis = pt; + resolve(pt.provider); + } catch (error) { + return reject(error); + } + } else { + return reject(new Error("Missing Portis Id")); + } + }); +}; + +export default ConnectToPortis; diff --git a/src/providers/connectors/squarelink.ts b/src/providers/connectors/squarelink.ts new file mode 100644 index 0000000000..0c661e3764 --- /dev/null +++ b/src/providers/connectors/squarelink.ts @@ -0,0 +1,40 @@ +export interface INetwork { + nodeUrl: string; + chainId?: string; +} + +export interface IOptions { + scope?: string[]; +} + +export interface ISquarelinkConnectorOptions { + id: string; + network?: string | INetwork; + config?: IOptions; +} + +const ConnectToSquarelink = ( + Squarelink: any, + opts: ISquarelinkConnectorOptions +) => { + return new Promise(async (resolve, reject) => { + if (opts && opts.id) { + try { + const id = opts.id; + const network = opts.network || "mainnet"; + const config = opts.config; + const sqlk = new Squarelink(id, network, config); + const provider = await sqlk.getProvider(); + provider.sqlk = sqlk + await provider.enable(); + return resolve(provider); + } catch (error) { + return reject(new Error("Failed to login to Squarelink")); + } + } else { + return reject(new Error("Missing Squarelink Id")); + } + }); +}; + +export default ConnectToSquarelink; diff --git a/src/providers/connectors/torus.ts b/src/providers/connectors/torus.ts new file mode 100644 index 0000000000..c19d6a56f5 --- /dev/null +++ b/src/providers/connectors/torus.ts @@ -0,0 +1,94 @@ + + +export interface INetwork { + nodeUrl: string; + chainId?: string; + networkName?: string; +} + +interface NetworkInterface { + host: 'mainnet' | 'rinkeby' | 'ropsten' | 'kovan' | 'goerli' | 'localhost' | 'matic' | string, + chainId?: number; + networkName?: string; +} + +interface VerifierStatus { + google?: boolean; + facebook?: boolean; + reddit?: boolean; + twitch?: boolean; + discord?: boolean; +} + + +export interface IOptions { + enableLogging?: boolean; + buttonPosition?: string; + buildEnv?: string; + showTorusButton?: boolean; + enabledVerifiers?: VerifierStatus +} + +export interface ITorusConnectorOptions { + network?: string | INetwork; + config?: IOptions; +} + +// Supports Torus package versions 0.1.* +const ConnectToTorus = async (Torus: any, opts: ITorusConnectorOptions) => { + return new Promise(async (resolve, reject) => { + try { + + // defaults + let buttonPosition = 'bottom-left' + let buildEnv = 'production' + let enableLogging = true + let showTorusButton = false + let enabledVerifiers = {} + let network : NetworkInterface = {host: 'mainnet'} + + // parsing to Torus interfaces + if (opts.network) { + if (typeof(opts.network) == 'string') { + network.host = opts.network + } else { + network.host = opts.network.nodeUrl + let chainId: string = opts.network.chainId || '' + network.chainId = parseInt(chainId, 10) + network.networkName = opts.network.networkName + } + } + if (opts.config) { + buttonPosition = opts.config.buttonPosition || buttonPosition + buildEnv = opts.config.buildEnv || buildEnv + enableLogging = opts.config.enableLogging || enableLogging + showTorusButton = opts.config.showTorusButton || showTorusButton + enabledVerifiers = opts.config.enabledVerifiers || enabledVerifiers + } + + const torus = new Torus({ + buttonPosition: buttonPosition + }); + await torus.init({ + buildEnv: buildEnv, + enableLogging: enableLogging, + // network: { + // host: 'kovan', // mandatory + // // chainId: 1, // optional + // networkName: 'kovan' // optional + // }, + network: network, + showTorusButton: showTorusButton, + enabledVerifiers: enabledVerifiers + }); + await torus.login(); // await torus.ethereum.enable() + const provider = torus.provider; + provider.torus = torus + resolve(provider); + } catch (err) { + reject(err) + } + }); +}; + +export default ConnectToTorus; \ No newline at end of file diff --git a/src/providers/connectors/walletconnect.ts b/src/providers/connectors/walletconnect.ts new file mode 100644 index 0000000000..c7220a50f1 --- /dev/null +++ b/src/providers/connectors/walletconnect.ts @@ -0,0 +1,53 @@ +export interface IWalletConnectConnectorOptions { + infuraId: string; + bridge?: string; + qrcode?: boolean; + network?: string; +} + +function getChainId(network: string) { + const infuraChainIds = { + mainnet: 1, + ropsten: 3, + rinkeby: 4, + goerli: 5, + kovan: 42 + }; + const chainId = infuraChainIds[network]; + if (!chainId) { + throw new Error(`Invalid or unknown chainId for network=${network}`); + } + return chainId; +} + +const ConnectToWalletConnect = ( + WalletConnectProvider: any, + opts: IWalletConnectConnectorOptions +) => { + return new Promise(async (resolve, reject) => { + let bridge = "https://bridge.walletconnect.org"; + let qrcode = true; + let infuraId = ""; + let chainId = 1; + + if (opts) { + bridge = opts.bridge || bridge; + qrcode = typeof opts.qrcode !== "undefined" ? opts.qrcode : qrcode; + infuraId = opts.infuraId || ""; + chainId = opts.network ? getChainId(opts.network) : 1; + } + + const provider = new WalletConnectProvider({ + bridge, + qrcode, + infuraId, + chainId + }); + + await provider.enable(); + + resolve(provider); + }); +}; + +export default ConnectToWalletConnect; From d24253ae155e7e5ad5f39145f806d4c61563cc5e Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Mon, 20 Jan 2020 21:17:02 +0100 Subject: [PATCH 17/21] move src/assets directory to src/providers/logos --- src/assets/.DS_Store | Bin 6148 -> 0 bytes src/providers/index.ts | 2 +- src/{assets => providers/logos}/arkane.svg | 0 src/{assets => providers/logos}/authereum.svg | 0 src/{assets => providers/logos}/cipher.svg | 0 src/{assets => providers/logos}/coinbase.svg | 0 src/{assets => providers/logos}/dapper.png | Bin src/{assets => providers/logos}/fortmatic.svg | 0 src/{assets => providers/logos}/imtoken.svg | 0 src/{assets => providers/logos}/metamask.png | Bin src/{assets => providers/logos}/metamask.svg | 0 src/{assets => providers/logos}/niftyWallet.png | Bin src/{assets => providers/logos}/niftyWallet.svg | 0 src/{assets => providers/logos}/opera.svg | 0 src/{assets => providers/logos}/portis.svg | 0 src/{assets => providers/logos}/safe.svg | 0 src/{assets => providers/logos}/squarelink.svg | 0 src/{assets => providers/logos}/status.svg | 0 src/{assets => providers/logos}/tokenary.png | Bin src/{assets => providers/logos}/torus.png | Bin src/{assets => providers/logos}/torus.svg | 0 src/{assets => providers/logos}/trust.svg | 0 .../logos}/walletconnect-circle.svg | 0 .../logos}/walletconnect.svg | 0 src/{assets => providers/logos}/web3-default.svg | 0 25 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 src/assets/.DS_Store rename src/{assets => providers/logos}/arkane.svg (100%) rename src/{assets => providers/logos}/authereum.svg (100%) rename src/{assets => providers/logos}/cipher.svg (100%) rename src/{assets => providers/logos}/coinbase.svg (100%) rename src/{assets => providers/logos}/dapper.png (100%) rename src/{assets => providers/logos}/fortmatic.svg (100%) rename src/{assets => providers/logos}/imtoken.svg (100%) rename src/{assets => providers/logos}/metamask.png (100%) rename src/{assets => providers/logos}/metamask.svg (100%) rename src/{assets => providers/logos}/niftyWallet.png (100%) rename src/{assets => providers/logos}/niftyWallet.svg (100%) rename src/{assets => providers/logos}/opera.svg (100%) rename src/{assets => providers/logos}/portis.svg (100%) rename src/{assets => providers/logos}/safe.svg (100%) rename src/{assets => providers/logos}/squarelink.svg (100%) rename src/{assets => providers/logos}/status.svg (100%) rename src/{assets => providers/logos}/tokenary.png (100%) rename src/{assets => providers/logos}/torus.png (100%) rename src/{assets => providers/logos}/torus.svg (100%) rename src/{assets => providers/logos}/trust.svg (100%) rename src/{assets => providers/logos}/walletconnect-circle.svg (100%) rename src/{assets => providers/logos}/walletconnect.svg (100%) rename src/{assets => providers/logos}/web3-default.svg (100%) diff --git a/src/assets/.DS_Store b/src/assets/.DS_Store deleted file mode 100644 index dcf2ab33a82cc724261c52de2f77c2959417db71..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKO-}+b6r3Ulf}nVkS{#^AxT2d^%$5F!Hdq4BmCe~gL$#h;|}UaQ%K zVmKM2eVcZ=?VG-KmbMgtIbU>-fd+sIlVG{Z%wy6nX~jyercN~4M~W$qFu@4@74J|H z6bK6ZHU(tuR?$VmRXag${ay~oo%V3tW;-_rvrjyFSJNrf(ZiUleU3YF=NO>Fl|RD+ z`b*5`C1#C`l#E1~Gu(de7)4$w*?{MXS9)9G?Q%C7aI|wg;hIs0d?dcxr;1Ux&NgOy zV&jzT*PKdKYHC#)P#eEKqHLa1p=ZMJrfd8~&%FN*{qM0LXG+eHa~-Lsp7F_7GzYoy z)u_Xm-YGf4fAXuM-y$EgiN~Ch9riKelkzt($073p`|7C9-Z`tv`Tq94>CfAPC|#II zgFU2Zzq?^XY0!3G6J diff --git a/src/providers/index.ts b/src/providers/index.ts index 1c60d79e59..38de3481c7 100644 --- a/src/providers/index.ts +++ b/src/providers/index.ts @@ -1,5 +1,5 @@ import { IProviderInfo, IProviderMappingEntry } from "../helpers/types"; -import connectors from "../core/connectors"; +import connectors from "./connectors"; import { INJECTED_PROVIDER_ID } from "../helpers/constants"; import { FALLBACK_INJECTED, injected } from "./injected"; diff --git a/src/assets/arkane.svg b/src/providers/logos/arkane.svg similarity index 100% rename from src/assets/arkane.svg rename to src/providers/logos/arkane.svg diff --git a/src/assets/authereum.svg b/src/providers/logos/authereum.svg similarity index 100% rename from src/assets/authereum.svg rename to src/providers/logos/authereum.svg diff --git a/src/assets/cipher.svg b/src/providers/logos/cipher.svg similarity index 100% rename from src/assets/cipher.svg rename to src/providers/logos/cipher.svg diff --git a/src/assets/coinbase.svg b/src/providers/logos/coinbase.svg similarity index 100% rename from src/assets/coinbase.svg rename to src/providers/logos/coinbase.svg diff --git a/src/assets/dapper.png b/src/providers/logos/dapper.png similarity index 100% rename from src/assets/dapper.png rename to src/providers/logos/dapper.png diff --git a/src/assets/fortmatic.svg b/src/providers/logos/fortmatic.svg similarity index 100% rename from src/assets/fortmatic.svg rename to src/providers/logos/fortmatic.svg diff --git a/src/assets/imtoken.svg b/src/providers/logos/imtoken.svg similarity index 100% rename from src/assets/imtoken.svg rename to src/providers/logos/imtoken.svg diff --git a/src/assets/metamask.png b/src/providers/logos/metamask.png similarity index 100% rename from src/assets/metamask.png rename to src/providers/logos/metamask.png diff --git a/src/assets/metamask.svg b/src/providers/logos/metamask.svg similarity index 100% rename from src/assets/metamask.svg rename to src/providers/logos/metamask.svg diff --git a/src/assets/niftyWallet.png b/src/providers/logos/niftyWallet.png similarity index 100% rename from src/assets/niftyWallet.png rename to src/providers/logos/niftyWallet.png diff --git a/src/assets/niftyWallet.svg b/src/providers/logos/niftyWallet.svg similarity index 100% rename from src/assets/niftyWallet.svg rename to src/providers/logos/niftyWallet.svg diff --git a/src/assets/opera.svg b/src/providers/logos/opera.svg similarity index 100% rename from src/assets/opera.svg rename to src/providers/logos/opera.svg diff --git a/src/assets/portis.svg b/src/providers/logos/portis.svg similarity index 100% rename from src/assets/portis.svg rename to src/providers/logos/portis.svg diff --git a/src/assets/safe.svg b/src/providers/logos/safe.svg similarity index 100% rename from src/assets/safe.svg rename to src/providers/logos/safe.svg diff --git a/src/assets/squarelink.svg b/src/providers/logos/squarelink.svg similarity index 100% rename from src/assets/squarelink.svg rename to src/providers/logos/squarelink.svg diff --git a/src/assets/status.svg b/src/providers/logos/status.svg similarity index 100% rename from src/assets/status.svg rename to src/providers/logos/status.svg diff --git a/src/assets/tokenary.png b/src/providers/logos/tokenary.png similarity index 100% rename from src/assets/tokenary.png rename to src/providers/logos/tokenary.png diff --git a/src/assets/torus.png b/src/providers/logos/torus.png similarity index 100% rename from src/assets/torus.png rename to src/providers/logos/torus.png diff --git a/src/assets/torus.svg b/src/providers/logos/torus.svg similarity index 100% rename from src/assets/torus.svg rename to src/providers/logos/torus.svg diff --git a/src/assets/trust.svg b/src/providers/logos/trust.svg similarity index 100% rename from src/assets/trust.svg rename to src/providers/logos/trust.svg diff --git a/src/assets/walletconnect-circle.svg b/src/providers/logos/walletconnect-circle.svg similarity index 100% rename from src/assets/walletconnect-circle.svg rename to src/providers/logos/walletconnect-circle.svg diff --git a/src/assets/walletconnect.svg b/src/providers/logos/walletconnect.svg similarity index 100% rename from src/assets/walletconnect.svg rename to src/providers/logos/walletconnect.svg diff --git a/src/assets/web3-default.svg b/src/providers/logos/web3-default.svg similarity index 100% rename from src/assets/web3-default.svg rename to src/providers/logos/web3-default.svg From bd34b8af4276712b034a47d17e162780d8b1e7aa Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Mon, 20 Jan 2020 21:17:17 +0100 Subject: [PATCH 18/21] update assets imports --- src/providers/index.ts | 14 +++++++------- src/providers/injected.ts | 24 ++++++++++++------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/providers/index.ts b/src/providers/index.ts index 38de3481c7..66c73682d6 100644 --- a/src/providers/index.ts +++ b/src/providers/index.ts @@ -4,19 +4,19 @@ import { INJECTED_PROVIDER_ID } from "../helpers/constants"; import { FALLBACK_INJECTED, injected } from "./injected"; // @ts-ignore -import WalletConnectLogo from "../assets/walletconnect-circle.svg"; +import WalletConnectLogo from "./logos/walletconnect-circle.svg"; // @ts-ignore -import PortisLogo from "../assets/portis.svg"; +import PortisLogo from "./logos/portis.svg"; // @ts-ignore -import SquarelinkLogo from "../assets/squarelink.svg"; +import SquarelinkLogo from "./logos/squarelink.svg"; // @ts-ignore -import FortmaticLogo from "../assets/fortmatic.svg"; +import FortmaticLogo from "./logos/fortmatic.svg"; // @ts-ignore -import ArkaneLogo from "../assets/arkane.svg"; +import ArkaneLogo from "./logos/arkane.svg"; // @ts-ignore -import TorusLogo from "../assets/torus.png"; +import TorusLogo from "./logos/torus.png"; // @ts-ignore -import AuthereumLogo from "../assets/authereum.svg"; +import AuthereumLogo from "./logos/authereum.svg"; export const FALLBACK = FALLBACK_INJECTED; diff --git a/src/providers/injected.ts b/src/providers/injected.ts index 45e39b355f..30c559785b 100644 --- a/src/providers/injected.ts +++ b/src/providers/injected.ts @@ -1,29 +1,29 @@ import { IProviderInfo } from "../helpers/types"; // @ts-ignore -import Web3DefaultLogo from "../assets/web3-default.svg"; +import Web3DefaultLogo from "./logos/web3-default.svg"; // @ts-ignore -import MetaMaskLogo from "../assets/metamask.svg"; +import MetaMaskLogo from "./logos/metamask.svg"; // @ts-ignore -import SafeLogo from "../assets/safe.svg"; +import SafeLogo from "./logos/safe.svg"; // @ts-ignore -import NiftyWalletLogo from "../assets/niftyWallet.png"; +import NiftyWalletLogo from "./logos/niftyWallet.png"; // @ts-ignore -import TrustLogo from "../assets/trust.svg"; +import TrustLogo from "./logos/trust.svg"; // @ts-ignore -import DapperLogo from "../assets/dapper.png"; +import DapperLogo from "./logos/dapper.png"; // @ts-ignore -import CoinbaseLogo from "../assets/coinbase.svg"; +import CoinbaseLogo from "./logos/coinbase.svg"; // @ts-ignore -import CipherLogo from "../assets/cipher.svg"; +import CipherLogo from "./logos/cipher.svg"; // @ts-ignore -import imTokenLogo from "../assets/imtoken.svg"; +import imTokenLogo from "./logos/imtoken.svg"; // @ts-ignore -import StatusLogo from "../assets/status.svg"; +import StatusLogo from "./logos/status.svg"; // @ts-ignore -import TokenaryLogo from "../assets/tokenary.png"; +import TokenaryLogo from "./logos/tokenary.png"; // @ts-ignore -import OperaLogo from "../assets/opera.svg"; +import OperaLogo from "./logos/opera.svg"; export const FALLBACK_INJECTED: IProviderInfo = { id: "injected", From ad1a091489a54e0401846452fa4ec7ed1137075b Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Mon, 20 Jan 2020 21:29:20 +0100 Subject: [PATCH 19/21] add instructions to adding a new provider --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index f4fe7839d9..98384dd13d 100644 --- a/README.md +++ b/README.md @@ -260,6 +260,10 @@ You can enable the following optional flags: - disableInjectedProvider: disable displaying injected provider as an option (default: false) +## Adding a new provider + +Do you want to add your provider to Web3Connect? All logic for supported providers lives inside the `src/providers` directory. To add a new follow the following steps [here](ADDING_PROVIDERS.md) + ## Collaboration ### Code contributions are welcome ❤️❤️❤️! From c6f97b8845c4c636da9a3048b1a8546fe7e097a3 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Mon, 20 Jan 2020 21:29:36 +0100 Subject: [PATCH 20/21] add ADDING_PROVIDERS.md --- ADDING_PROVIDERS.md | 114 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 ADDING_PROVIDERS.md diff --git a/ADDING_PROVIDERS.md b/ADDING_PROVIDERS.md new file mode 100644 index 0000000000..e59be32f6e --- /dev/null +++ b/ADDING_PROVIDERS.md @@ -0,0 +1,114 @@ +# Adding a new provider + +Do you want to add your provider to Web3Connect? All logic for supported providers lives inside the `src/providers` directory. To add a new follow the following steps: + +Let's call this example provider Firebox + +## 1) Create a new connector + +Create a new connector file inside `src/providers/connectors` directory. The file should be named after your provider name's in lowercase (eg. firebox.ts) + +This file should export as a default a callback function which must have two parameters: your provider package and a options object. It should + +```typescript +// src/providers/connectors/firebox.ts + +interface IFireboxOptions { + apiKey: string; +} + +const ConnectToFirebox = async ( + FireboxProvider: any, + opts: IFireboxOptions +) => { + const provider = new FireboxProvider(opts.apiKey); + + await provider.enable(); + + return provider; +}; +``` + +Make sure your return your provider only after enabling it. Any provider-specific UI/UX should also be handled inside enable. + +## 2) Add your connector to the index.ts + +On the same directory (`src/providers/connectors`) there is an `index.ts` file where we expose all connectors, you should add yours as follows: + +```typescript +// src/providers/connectors/firebox.ts + +import firebox from "./firebox"; + +export default { + // other connectors + firebox +}; +``` + +## 3) Add your logo to the assets directory + +The logo can be either svg, png or jpg but you should try to keep it small around 200x200px size. The directory is located at `src/providers/logos` and you should also name your file as provider's name (eg. firebox.png) + +## 4) Add your Provider info to providers index + +On the providers directory (`src/providers/`) there is an index file where you can list your provider information. Your provider information should a constant variable with capitalized name and it should match the `IProviderInfo` interface as follows: + +```typescript +// src/providers/index.ts + +import FireboxLogo from "./logos/firebox.png"; + +export const FIREBOX_PROVIDER: IProviderInfo = { + id: "firebox", + name: "Firebox", + logo: FireboxLogo, + type: "web", + check: "isFirebox", + styled: { + noShadow: false + }, + package: { + required: ["apiKey"] + } +}; +``` + +More detail on how the IProviderInfo interface works is still undocumentated but the most important parts to pay attention are the required array for your provider options, the id should be lowercase and the logo should be imported as demonstrated. + +## 5) List your provider in the mapping + +On the bottom of the same file as the step before (`src/providers/index.ts`), you should also add your provider to the mapping using references to your provider info and add your connector as well as follows: + +```typescript +// src/providers/index.ts + +export const providerMapping: IProviderMappingEntry[] = [ + // other providers + { + id: FIREBOX_PROVIDER.id, + name: FIREBOX_PROVIDER.name, + connector: connectors.firebox, + package: FIREBOX_PROVIDER.package + } +]; +``` + +## 6) Update the Web3Connect README file + +Finally you should update the main README file so other developers can use your provider with Web3Connect easily. Inside the section of **Provider Options** you should add an example of how to configure Web3Connect to display your provider using the provider-specific options. + +```typescript +### Firebox + +import FireboxProvider from "firebox-web3-provider"; + +const providerOptions = { + firebox: { + package: FireboxProvider, // required + options: { + apiKey: "FIREBOX_API_KEY" // required + } + } +}; +``` From 0d000cabcc572c83e0f0371d0411e65b27d25889 Mon Sep 17 00:00:00 2001 From: Cristian Espinoza Garner Date: Mon, 20 Jan 2020 21:04:40 -0600 Subject: [PATCH 21/21] Small fixes --- ADDING_PROVIDERS.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ADDING_PROVIDERS.md b/ADDING_PROVIDERS.md index e59be32f6e..304a7de4a6 100644 --- a/ADDING_PROVIDERS.md +++ b/ADDING_PROVIDERS.md @@ -1,6 +1,6 @@ # Adding a new provider -Do you want to add your provider to Web3Connect? All logic for supported providers lives inside the `src/providers` directory. To add a new follow the following steps: +Do you want to add your provider to Web3Connect? All logic for supported providers lives inside the `src/providers` directory. To add a new follow the next steps: Let's call this example provider Firebox @@ -8,7 +8,7 @@ Let's call this example provider Firebox Create a new connector file inside `src/providers/connectors` directory. The file should be named after your provider name's in lowercase (eg. firebox.ts) -This file should export as a default a callback function which must have two parameters: your provider package and a options object. It should +This file should export as a default a callback function which must have two parameters: your provider package and a options object. ```typescript // src/providers/connectors/firebox.ts @@ -29,14 +29,14 @@ const ConnectToFirebox = async ( }; ``` -Make sure your return your provider only after enabling it. Any provider-specific UI/UX should also be handled inside enable. +Make sure you return your provider only after enabling it. Any provider-specific UI/UX should also be handled inside enable. ## 2) Add your connector to the index.ts On the same directory (`src/providers/connectors`) there is an `index.ts` file where we expose all connectors, you should add yours as follows: ```typescript -// src/providers/connectors/firebox.ts +// src/providers/connectors/index.ts import firebox from "./firebox";