From d285575203127ec0b390114a88fc7aaff5a2282b Mon Sep 17 00:00:00 2001 From: Vladimir Date: Sun, 29 Aug 2021 22:51:43 +0200 Subject: [PATCH] ADD: Mobile onboarding (Android & IOS) MetaMask app will be opened in Play Store / App Store depending on the mobile device. Resolves #55 --- package.json | 2 +- src/index.ts | 89 +++++++++++++++++++++++++++++++++++----------------- yarn.lock | 8 ++--- 3 files changed, 65 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index 7a7a673..073234f 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "build": "rollup --config" }, "dependencies": { - "bowser": "^2.9.0" + "bowser": "^2.11.0" }, "devDependencies": { "@lavamoat/allow-scripts": "^1.0.6", diff --git a/src/index.ts b/src/index.ts index cfd5081..e4f79e2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,17 +1,28 @@ import Bowser from 'bowser'; -const ONBOARDING_STATE = { - INSTALLED: 'INSTALLED' as const, - NOT_INSTALLED: 'NOT_INSTALLED' as const, - REGISTERED: 'REGISTERED' as const, - REGISTERING: 'REGISTERING' as const, - RELOADING: 'RELOADING' as const, +const enum PLATFORM { + DESKTOP, + MOBILE, +} + +const enum ONBOARDING_STATE { + INSTALLED, + NOT_INSTALLED, + REGISTERED, + REGISTERING, + RELOADING, }; -const EXTENSION_DOWNLOAD_URL = { - CHROME: - 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn', - FIREFOX: 'https://addons.mozilla.org/firefox/addon/ether-metamask/', +const METAMASK_DOWNLOAD_URL = { + DESKTOP: { + CHROME: + 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn', + FIREFOX: 'https://addons.mozilla.org/firefox/addon/ether-metamask', + }, + MOBILE: { + IOS: 'https://apps.apple.com/us/app/metamask-blockchain-wallet/id1438144202', + ANDROID: 'market://details?id=io.metamask', + }, DEFAULT: 'https://metamask.io', }; @@ -29,11 +40,13 @@ export default class Onboarding { private readonly forwarderOrigin: string; + private readonly isPlatformDesktop: boolean; + private readonly downloadUrl: string; private readonly forwarderMode: keyof typeof Onboarding.FORWARDER_MODE; - private state: keyof typeof ONBOARDING_STATE; + private state: ONBOARDING_STATE; constructor({ forwarderOrigin = 'https://fwd.metamask.io', @@ -45,12 +58,9 @@ export default class Onboarding { ? ONBOARDING_STATE.INSTALLED : ONBOARDING_STATE.NOT_INSTALLED; - const browser = Onboarding._detectBrowser(); - if (browser) { - this.downloadUrl = EXTENSION_DOWNLOAD_URL[browser]; - } else { - this.downloadUrl = EXTENSION_DOWNLOAD_URL.DEFAULT; - } + const platformType = this._getPlatformType(); + this.isPlatformDesktop = platformType === PLATFORM.DESKTOP; + this.downloadUrl = this._getDownloadUrl(); this._onMessage = this._onMessage.bind(this); this._onMessageFromForwarder = this._onMessageFromForwarder.bind(this); @@ -125,12 +135,17 @@ export default class Onboarding { } /** - * Starts onboarding by opening the MetaMask download page and the Onboarding forwarder + * Starts onboarding by opening the MetaMask download page and the Onboarding forwarder (desktop) + * Starts onboarding by opening the MetaMask app in Play Store / App Store (mobile) */ startOnboarding() { - sessionStorage.setItem(REGISTRATION_IN_PROGRESS, 'true'); - this._openDownloadPage(); - this._openForwarder(); + if (this.isPlatformDesktop) { + sessionStorage.setItem(REGISTRATION_IN_PROGRESS, 'true'); + this._openDownloadPage(); + this._openForwarder(); + } else { + this._openDownloadPage(); + } } /** @@ -191,15 +206,31 @@ export default class Onboarding { document.getElementById(FORWARDER_ID)?.remove(); } - static _detectBrowser() { + _getDownloadUrl() { const browserInfo = Bowser.parse(window.navigator.userAgent); - if (browserInfo.browser.name === 'Firefox') { - return 'FIREFOX'; - } else if ( - ['Chrome', 'Chromium'].includes(browserInfo.browser.name || '') - ) { - return 'CHROME'; + const browserName = browserInfo.browser.name; + const { DESKTOP, MOBILE, DEFAULT } = METAMASK_DOWNLOAD_URL; + + if (this.isPlatformDesktop) { + if (browserName === 'Firefox') { + return DESKTOP.FIREFOX; + } else if (['Chrome', 'Chromium'].includes(browserName || '')) { + return DESKTOP.CHROME; + } + + return DEFAULT; } - return null; + + const isIOS = browserInfo.platform.vendor === 'Apple'; + if (isIOS) return MOBILE.IOS; + return MOBILE.ANDROID; + } + + _getPlatformType() { + const browserInfo = Bowser.parse(window.navigator.userAgent); + const isPlatformDesktop = browserInfo.platform.type === 'desktop'; + + if (isPlatformDesktop) return PLATFORM.DESKTOP; + else return PLATFORM.MOBILE; } } diff --git a/yarn.lock b/yarn.lock index 66a3575..6718fac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -423,10 +423,10 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -bowser@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.9.0.tgz#3bed854233b419b9a7422d9ee3e85504373821c9" - integrity sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA== +bowser@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" + integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== brace-expansion@^1.1.7: version "1.1.11"