aboutsummaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/instant/package.json1
-rw-r--r--packages/instant/src/components/coinbase_wallet_logo.tsx32
-rw-r--r--packages/instant/src/components/install_wallet_panel_content.tsx124
-rw-r--r--packages/instant/src/components/meta_mask_logo.tsx2
-rw-r--r--packages/instant/src/components/payment_method.tsx43
-rw-r--r--packages/instant/src/components/standard_panel_content.tsx14
-rw-r--r--packages/instant/src/components/wallet_prompt.tsx32
-rw-r--r--packages/instant/src/constants.ts5
-rw-r--r--packages/instant/src/containers/connected_account_payment_method.ts1
-rw-r--r--packages/instant/src/style/theme.ts2
-rw-r--r--packages/instant/src/types.ts28
-rw-r--r--packages/instant/src/util/env.ts67
-rw-r--r--packages/instant/src/util/provider_state_factory.ts4
13 files changed, 295 insertions, 60 deletions
diff --git a/packages/instant/package.json b/packages/instant/package.json
index f71fe45ef..aa9157bcc 100644
--- a/packages/instant/package.json
+++ b/packages/instant/package.json
@@ -54,6 +54,7 @@
"@0x/typescript-typings": "^3.0.4",
"@0x/utils": "^2.0.4",
"@0x/web3-wrapper": "^3.1.3",
+ "bowser": "^2.0.0-beta.3",
"copy-to-clipboard": "^3.0.8",
"ethereum-types": "^1.1.2",
"lodash": "^4.17.10",
diff --git a/packages/instant/src/components/coinbase_wallet_logo.tsx b/packages/instant/src/components/coinbase_wallet_logo.tsx
new file mode 100644
index 000000000..f5a7be81c
--- /dev/null
+++ b/packages/instant/src/components/coinbase_wallet_logo.tsx
@@ -0,0 +1,32 @@
+import * as React from 'react';
+
+export interface CoinbaseWalletLogoProps {
+ width?: number;
+}
+
+export const CoinbaseWalletLogo: React.StatelessComponent<CoinbaseWalletLogoProps> = ({ width }) => (
+ <svg width={width} viewBox="0 0 164 28" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path
+ fillRule="evenodd"
+ clipRule="evenodd"
+ d="M49.576172.545441h-2.9453v19.595c1.3398.4742 3.0058.8594 4.9101.8594 4.8809 0 7.7071-2.8458 7.7071-7.0846 0-4.20983-2.8555-6.64028-6.666-6.64028-1.1602 0-2.3809.32621-3.0059.65241V.545441zm-21.0176 1.18585c-.9824 0-1.8457.80039-1.8457 1.80802 0 1.03784.8633 1.8684 1.8457 1.8684.9824 0 1.8457-.83056 1.8457-1.8684 0-1.00763-.8633-1.80802-1.8457-1.80802zm-18.2324 16.30675c-.64258.251-1.32031.3832-2.05273.3832-2.56055 0-4.34766-1.6602-4.34766-4.2689 0-2.7568 1.8457-4.26886 4.22656-4.26886.70117 0 1.38086.11985 2.04102.38318.31836-.77942.74023-1.48746 1.25001-2.11145-1.09376-.58255-2.1797-.88037-3.55665-.88037-3.8711 0-6.93555 2.6377-6.93555 6.8775 0 4.2099 2.91602 6.8476 6.93555 6.8476 1.35156 0 2.58984-.2827 3.77345-.9166-.5371-.6008-.98634-1.2863-1.334-2.0453zm8.084-10.76317c3.957 0 6.8144 2.78684 6.8144 6.87757 0 4.0616-2.8574 6.8475-6.8144 6.8475-3.9278 0-6.7852-2.7859-6.7852-6.8475 0-4.09073 2.8574-6.87757 6.7852-6.87757zm-3.8125 6.87757c0-2.6677 1.6074-4.35792 3.8086-4.35792 2.2637 0 3.8398 1.69022 3.8398 4.35792 0 2.6388-1.5761 4.3279-3.8398 4.3279-2.2012 0-3.8086-1.6891-3.8086-4.3279zm12.5 6.5512h2.9453V7.571011h-2.9453v13.13263zm5.5176-12.302c1.8457-.71139 4.1074-1.1268 6.041-1.1268 3.3633 0 5.5058 1.27481 5.5058 4.9803v8.4486h-2.916v-8.1814c0-1.8973-1.1894-2.57984-2.8281-2.57984-1.041 0-2.082.14823-2.8555.38544v10.3758h-2.9472v-12.3021zm16.9609 9.8125c.5664.1771 1.3105.2661 2.0527.2661 2.709 0 4.6446-1.4819 4.6446-4.5059 0-2.5498-1.8164-4.06165-4.0489-4.06165-1.1601 0-2.0527.29712-2.6484.62332v7.67813zm15.6523-8.38946c1.459 0 2.5293.65127 2.5293 2.07426v1.0978h-1.457c-3.8105 0-6.1016 1.3039-6.1016 3.9715 0 2.965 2.5 4.0026 5.9239 4.0026 1.4863 0 3.2715-.2081 4.5215-.5343v-8.6858c0-3.29008-2.0528-4.4759-4.9395-4.4759-1.6367 0-3.125.41541-4.2851 1.06665v2.54985c1.1015-.62242 2.291-1.06666 3.8085-1.06666zm2.5313 5.12836h-1.25c-2.0527 0-3.3926.5922-3.3926 1.9263 0 1.3638 1.25 1.8972 3.0352 1.8972.4472 0 1.0722-.059 1.6074-.1482v-3.6753zm9.0449 3.6754c-1.3379 0-2.7949-.5634-4.0156-1.482v2.7868c.9824.6524 2.5293 1.0667 4.0762 1.0667 2.8574 0 4.9707-1.2449 4.9707-4.0015 0-2.3717-1.3086-3.4985-4.3164-4.1509-1.5176-.4143-2.0821-.8596-2.0821-1.719 0-.85965.6836-1.48209 1.9649-1.48209 1.3965 0 2.5293.5044 3.6894 1.33379v-2.69759c-1.1015-.68142-2.2929-1.00763-3.7793-1.00763-2.6797 0-4.7031 1.30365-4.7031 3.97242 0 2.2827 1.1621 3.3793 3.8984 4.0017 1.6973.4443 2.4707.8295 2.4707 1.8973 0 1.0376-.8632 1.482-2.1738 1.482zm9.0625-3.8236v.0591c.1778 2.3414 2.2012 3.6163 4.2559 3.6163 1.8144 0 3.125-.4152 4.4336-1.2749v2.5798c-1.1914.8295-2.9473 1.2147-4.6426 1.2147-4.1074 0-6.9043-2.6086-6.9043-6.7584 0-4.17964 2.7383-6.96648 6.3691-6.96648 3.8379 0 5.6543 2.46064 5.6543 6.04698v1.4829h-9.166zm3.4238-5.06921c1.9043 0 2.9161 1.12571 2.9747 3.17201h-6.3086c.3867-1.9862 1.6367-3.17201 3.3339-3.17201z"
+ fill="#1452F5"
+ />
+ <path
+ fillRule="evenodd"
+ clipRule="evenodd"
+ d="M105.543.479151c0-.264628.214523-.479151.479151-.479151s.479151.214523.479151.479151V27.0663c0 .2646-.214523.4792-.479151.4792s-.479151-.2146-.479151-.4792V.479151z"
+ fill="#AAB4C0"
+ />
+ <path
+ d="M123.76075 7.60523l-2.94965 11.86278-3.08272-11.86278H116.309l3.57063 13.12198h1.81859l2.83876-11.55353 2.83872 11.55353h1.8186l3.5707-13.12198h-1.3529l-3.1049 11.86278-2.92746-11.86278h-1.61899zM138.3712 15.16032h-1.0867c-2.9496 0-4.7017.99409-4.7017 2.89389 0 2.0324 1.7521 2.8497 4.3691 2.8497.8205 0 1.8629-.1104 2.75-.3534v-6.64937c0-2.16491-1.2641-3.02646-3.2158-3.02646-1.131 0-2.1734.30928-2.994.75109v1.25919c.8871-.46391 1.7299-.77319 2.8388-.77319 1.2419 0 2.0403.64064 2.0403 1.87773v1.17082zm0 4.50659c-.4657.0883-.9536.1325-1.3528.1325-1.7742 0-3.1049-.4639-3.1049-1.7452s1.4637-1.8114 3.4597-1.8114h.998v3.4241zM143.1294 5.70541h-1.3307v15.0218h1.3307V5.70541zM146.7177 5.70541h-1.3307v15.0218h1.3307V5.70541zM156.8928 15.97771v-.90575c0-2.73928-1.619-4.19728-4.0586-4.19728-2.5948 0-4.5908 2.14282-4.5908 5.03673 0 3.1369 2.1291 5.0367 4.9235 5.0367 1.1976 0 2.4396-.2872 3.3045-.9278v-1.3254c-.9758.729-1.9295 1.0824-3.3045 1.0824-1.8851 0-3.5928-1.3917-3.5928-3.7554v-.0442h7.3187zm-7.23-1.10457c.377-1.81146 1.5968-2.82764 3.1049-2.82764 1.619 0 2.7057.81737 2.7944 2.82764h-5.8993zM157.1456 12.22223h1.4859v6.00868c0 1.9882 1.0423 2.7172 2.4395 2.7172.8428 0 1.5081-.1988 2.0848-.486v-1.1708c-.6654.3314-1.1755.5302-1.7965.5302-.9092 0-1.3972-.486-1.3972-1.7231v-5.87618h2.7279v-1.12664h-2.7279V8.75395h-1.3306v2.34164h-1.4859v1.12664z"
+ fill="#202A36"
+ />
+ </svg>
+);
+
+CoinbaseWalletLogo.displayName = 'CoinbaseWalletLogo';
+
+CoinbaseWalletLogo.defaultProps = {
+ width: 164,
+};
diff --git a/packages/instant/src/components/install_wallet_panel_content.tsx b/packages/instant/src/components/install_wallet_panel_content.tsx
index 546874212..0700e9051 100644
--- a/packages/instant/src/components/install_wallet_panel_content.tsx
+++ b/packages/instant/src/components/install_wallet_panel_content.tsx
@@ -1,32 +1,112 @@
import * as React from 'react';
-import { META_MASK_CHROME_STORE_URL, META_MASK_SITE_URL } from '../constants';
+import {
+ COINBASE_WALLET_ANDROID_APP_STORE_URL,
+ COINBASE_WALLET_IOS_APP_STORE_URL,
+ COINBASE_WALLET_SITE_URL,
+ META_MASK_CHROME_STORE_URL,
+ META_MASK_FIREFOX_STORE_URL,
+ META_MASK_OPERA_STORE_URL,
+ META_MASK_SITE_URL,
+} from '../constants';
import { ColorOption } from '../style/theme';
+import { Browser, OperatingSystem } from '../types';
+import { envUtil } from '../util/env';
+import { CoinbaseWalletLogo } from './coinbase_wallet_logo';
import { MetaMaskLogo } from './meta_mask_logo';
-import { StandardPanelContent } from './standard_panel_content';
+import { StandardPanelContent, StandardPanelContentProps } from './standard_panel_content';
import { Button } from './ui/button';
export interface InstallWalletPanelContentProps {}
-export const InstallWalletPanelContent: React.StatelessComponent<InstallWalletPanelContentProps> = () => (
- <StandardPanelContent
- image={<MetaMaskLogo width={85} height={80} />}
- title="Install MetaMask"
- description="Please install the MetaMask wallet extension from the Chrome Store."
- moreInfoSettings={{
- href: META_MASK_SITE_URL,
- text: 'What is MetaMask?',
- }}
- action={
- <Button
- href={META_MASK_CHROME_STORE_URL}
- width="100%"
- fontColor={ColorOption.white}
- backgroundColor={ColorOption.darkOrange}
- >
- Get Chrome Extension
- </Button>
+export class InstallWalletPanelContent extends React.Component<InstallWalletPanelContentProps> {
+ public render(): React.ReactNode {
+ const panelProps = this._getStandardPanelContentProps();
+ return <StandardPanelContent {...panelProps} />;
+ }
+ private readonly _getStandardPanelContentProps = (): StandardPanelContentProps => {
+ const isMobileOS = envUtil.isMobileOperatingSystem();
+ const browser = envUtil.getBrowser();
+ const operatingSystem = envUtil.getOperatingSystem();
+ if (isMobileOS) {
+ let description = 'Please install the Coinbase Wallet app.';
+ let actionText = 'Learn More';
+ let actionUrl = COINBASE_WALLET_SITE_URL;
+ switch (operatingSystem) {
+ case OperatingSystem.Android:
+ description = 'Please install the Coinbase Wallet app from the Google Play Store.';
+ actionText = 'Get Coinbase Wallet';
+ actionUrl = COINBASE_WALLET_ANDROID_APP_STORE_URL;
+ break;
+ case OperatingSystem.iOS:
+ description = 'Please install the Coinbase Wallet app from the iOS App Store.';
+ actionText = 'Get Coinbase Wallet';
+ actionUrl = COINBASE_WALLET_IOS_APP_STORE_URL;
+ break;
+ default:
+ break;
+ }
+ return {
+ image: <CoinbaseWalletLogo width={246} />,
+ description,
+ moreInfoSettings: {
+ href: COINBASE_WALLET_SITE_URL,
+ text: 'What is Coinbase Wallet?',
+ },
+ action: (
+ <Button
+ href={actionUrl}
+ width="100%"
+ fontColor={ColorOption.white}
+ backgroundColor={ColorOption.blue}
+ >
+ {actionText}
+ </Button>
+ ),
+ };
+ } else {
+ let description = 'Please install the MetaMask wallet browser extension.';
+ let actionText = 'Learn More';
+ let actionUrl = META_MASK_SITE_URL;
+ switch (browser) {
+ case Browser.Chrome:
+ description = 'Please install the MetaMask wallet browser extension from the Chrome Store.';
+ actionText = 'Get Chrome Extension';
+ actionUrl = META_MASK_CHROME_STORE_URL;
+ break;
+ case Browser.Firefox:
+ description = 'Please install the MetaMask wallet browser extension from the Firefox Store.';
+ actionText = 'Get Firefox Extension';
+ actionUrl = META_MASK_FIREFOX_STORE_URL;
+ break;
+ case Browser.Opera:
+ description = 'Please install the MetaMask wallet browser extension from the Opera Store.';
+ actionText = 'Get Opera Add-on';
+ actionUrl = META_MASK_OPERA_STORE_URL;
+ break;
+ default:
+ break;
+ }
+ return {
+ image: <MetaMaskLogo width={85} height={80} />,
+ title: 'Install MetaMask',
+ description,
+ moreInfoSettings: {
+ href: META_MASK_SITE_URL,
+ text: 'What is MetaMask?',
+ },
+ action: (
+ <Button
+ href={actionUrl}
+ width="100%"
+ fontColor={ColorOption.white}
+ backgroundColor={ColorOption.darkOrange}
+ >
+ {actionText}
+ </Button>
+ ),
+ };
}
- />
-);
+ };
+}
diff --git a/packages/instant/src/components/meta_mask_logo.tsx b/packages/instant/src/components/meta_mask_logo.tsx
index d1ad10c23..bfbc67270 100644
--- a/packages/instant/src/components/meta_mask_logo.tsx
+++ b/packages/instant/src/components/meta_mask_logo.tsx
@@ -72,6 +72,8 @@ export const MetaMaskLogo: React.StatelessComponent<MetaMaskLogoProps> = ({ widt
</svg>
);
+MetaMaskLogo.displayName = 'MetaMaskLogo';
+
MetaMaskLogo.defaultProps = {
width: 85,
height: 80,
diff --git a/packages/instant/src/components/payment_method.tsx b/packages/instant/src/components/payment_method.tsx
index 49ec22164..0f9f3ebfa 100644
--- a/packages/instant/src/components/payment_method.tsx
+++ b/packages/instant/src/components/payment_method.tsx
@@ -3,7 +3,9 @@ import * as React from 'react';
import { ColorOption } from '../style/theme';
import { Account, AccountState, Network } from '../types';
+import { envUtil } from '../util/env';
+import { CoinbaseWalletLogo } from './coinbase_wallet_logo';
import { MetaMaskLogo } from './meta_mask_logo';
import { PaymentMethodDropdown } from './payment_method_dropdown';
import { Circle } from './ui/circle';
@@ -11,10 +13,12 @@ import { Container } from './ui/container';
import { Flex } from './ui/flex';
import { Icon } from './ui/icon';
import { Text } from './ui/text';
+import { WalletPrompt } from './wallet_prompt';
export interface PaymentMethodProps {
account: Account;
network: Network;
+ walletName: string;
onInstallWalletClick: () => void;
onUnlockWalletClick: () => void;
}
@@ -62,7 +66,7 @@ export class PaymentMethod extends React.Component<PaymentMethodProps> {
<Circle diameter={8} color={circleColor} />
<Container marginLeft="3px">
<Text fontColor={ColorOption.darkGrey} fontSize="12px">
- MetaMask
+ {this.props.walletName}
</Text>
</Container>
</React.Fragment>
@@ -72,6 +76,9 @@ export class PaymentMethod extends React.Component<PaymentMethodProps> {
};
private readonly _renderMainContent = (): React.ReactNode => {
const { account, network } = this.props;
+ const isMobile = envUtil.isMobileOperatingSystem();
+ // TODO: Use Toshi logo
+ const logo = isMobile ? undefined : <MetaMaskLogo width={19} height={18} />;
switch (account.state) {
case AccountState.Loading:
// Just take up the same amount of space as the other states.
@@ -82,16 +89,13 @@ export class PaymentMethod extends React.Component<PaymentMethodProps> {
onClick={this.props.onUnlockWalletClick}
image={<Icon width={13} icon="lock" color={ColorOption.black} />}
>
- Please Unlock MetaMask
+ Please Unlock {this.props.walletName}
</WalletPrompt>
);
case AccountState.None:
return (
- <WalletPrompt
- onClick={this.props.onInstallWalletClick}
- image={<MetaMaskLogo width={19} height={18} />}
- >
- Install MetaMask
+ <WalletPrompt onClick={this.props.onInstallWalletClick} image={logo}>
+ {isMobile ? 'Install Coinbase Wallet' : 'Install MetaMask'}
</WalletPrompt>
);
case AccountState.Ready:
@@ -105,28 +109,3 @@ export class PaymentMethod extends React.Component<PaymentMethodProps> {
}
};
}
-
-interface WalletPromptProps {
- image: React.ReactNode;
- onClick?: () => void;
-}
-
-const WalletPrompt: React.StatelessComponent<WalletPromptProps> = ({ onClick, image, children }) => (
- <Container
- padding="14.5px"
- border={`1px solid ${ColorOption.darkOrange}`}
- backgroundColor={ColorOption.lightOrange}
- width="100%"
- borderRadius="4px"
- onClick={onClick}
- cursor={onClick ? 'pointer' : undefined}
- boxShadowOnHover={!!onClick}
- >
- <Flex>
- <Container marginRight="10px">{image}</Container>
- <Text fontSize="16px" fontColor={ColorOption.darkOrange}>
- {children}
- </Text>
- </Flex>
- </Container>
-);
diff --git a/packages/instant/src/components/standard_panel_content.tsx b/packages/instant/src/components/standard_panel_content.tsx
index 89e4da70c..582b3318e 100644
--- a/packages/instant/src/components/standard_panel_content.tsx
+++ b/packages/instant/src/components/standard_panel_content.tsx
@@ -13,7 +13,7 @@ export interface MoreInfoSettings {
export interface StandardPanelContentProps {
image: React.ReactNode;
- title: string;
+ title?: string;
description: string;
moreInfoSettings?: MoreInfoSettings;
action: React.ReactNode;
@@ -31,11 +31,13 @@ export const StandardPanelContent: React.StatelessComponent<StandardPanelContent
<Container height="100%">
<Flex direction="column" height="calc(100% - 58px)">
<Container marginBottom={SPACING_BETWEEN_PX}>{image}</Container>
- <Container marginBottom={SPACING_BETWEEN_PX}>
- <Text fontSize="20px" fontWeight={700} fontColor={ColorOption.black}>
- {title}
- </Text>
- </Container>
+ {title && (
+ <Container marginBottom={SPACING_BETWEEN_PX}>
+ <Text fontSize="20px" fontWeight={700} fontColor={ColorOption.black}>
+ {title}
+ </Text>
+ </Container>
+ )}
<Container marginBottom={SPACING_BETWEEN_PX}>
<Text fontSize="14px" fontColor={ColorOption.grey} center={true}>
{description}
diff --git a/packages/instant/src/components/wallet_prompt.tsx b/packages/instant/src/components/wallet_prompt.tsx
new file mode 100644
index 000000000..cd0a7828b
--- /dev/null
+++ b/packages/instant/src/components/wallet_prompt.tsx
@@ -0,0 +1,32 @@
+import * as React from 'react';
+
+import { ColorOption } from '../style/theme';
+
+import { Container } from './ui/container';
+import { Flex } from './ui/flex';
+import { Text } from './ui/text';
+
+export interface WalletPromptProps {
+ image: React.ReactNode;
+ onClick?: () => void;
+}
+
+export const WalletPrompt: React.StatelessComponent<WalletPromptProps> = ({ onClick, image, children }) => (
+ <Container
+ padding="14.5px"
+ border={`1px solid ${ColorOption.darkOrange}`}
+ backgroundColor={ColorOption.lightOrange}
+ width="100%"
+ borderRadius="4px"
+ onClick={onClick}
+ cursor={onClick ? 'pointer' : undefined}
+ boxShadowOnHover={!!onClick}
+ >
+ <Flex>
+ <Container marginRight="10px">{image}</Container>
+ <Text fontSize="16px" fontColor={ColorOption.darkOrange}>
+ {children}
+ </Text>
+ </Flex>
+ </Container>
+);
diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts
index 2bf7849ec..8170ae354 100644
--- a/packages/instant/src/constants.ts
+++ b/packages/instant/src/constants.ts
@@ -19,8 +19,13 @@ export const ETH_GAS_STATION_API_BASE_URL = 'https://ethgasstation.info';
export const COINBASE_API_BASE_URL = 'https://api.coinbase.com/v2';
export const PROGRESS_STALL_AT_WIDTH = '95%';
export const PROGRESS_FINISH_ANIMATION_TIME_MS = 200;
+export const COINBASE_WALLET_IOS_APP_STORE_URL = 'https://itunes.apple.com/us/app/coinbase-wallet/id1278383455?mt=8';
+export const COINBASE_WALLET_ANDROID_APP_STORE_URL = 'https://play.google.com/store/apps/details?id=org.toshi&hl=en';
+export const COINBASE_WALLET_SITE_URL = 'https://wallet.coinbase.com/';
+export const META_MASK_FIREFOX_STORE_URL = 'https://addons.mozilla.org/en-US/firefox/addon/ether-metamask/';
export const META_MASK_CHROME_STORE_URL =
'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en';
+export const META_MASK_OPERA_STORE_URL = 'https://addons.opera.com/en/extensions/details/metamask/';
export const META_MASK_SITE_URL = 'https://metamask.io/';
export const ETHEREUM_NODE_URL_BY_NETWORK = {
[Network.Mainnet]: 'https://mainnet.infura.io/',
diff --git a/packages/instant/src/containers/connected_account_payment_method.ts b/packages/instant/src/containers/connected_account_payment_method.ts
index 65b3710a6..69c2ddf19 100644
--- a/packages/instant/src/containers/connected_account_payment_method.ts
+++ b/packages/instant/src/containers/connected_account_payment_method.ts
@@ -47,6 +47,7 @@ const mergeProps = (
network: connectedState.network,
account: connectedState.providerState.account,
onInstallWalletClick: connectedDispatch.onInstallWalletClick,
+ walletName: connectedState.providerState.name,
onUnlockWalletClick: () => {
connectedDispatch.unlockWalletAndDispatchToStore(connectedState.providerState);
},
diff --git a/packages/instant/src/style/theme.ts b/packages/instant/src/style/theme.ts
index 1e9f55e00..489f11dc3 100644
--- a/packages/instant/src/style/theme.ts
+++ b/packages/instant/src/style/theme.ts
@@ -17,6 +17,7 @@ export enum ColorOption {
darkOrange = 'darkOrange',
green = 'green',
red = 'red',
+ blue = 'blue',
}
export const theme: Theme = {
@@ -32,6 +33,7 @@ export const theme: Theme = {
darkOrange: '#F2994C',
green: '#3CB34F',
red: '#D00000',
+ blue: '#135df6',
};
export const transparentWhite = 'rgba(255,255,255,0.3)';
diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts
index b6f449f38..cbb1e2caf 100644
--- a/packages/instant/src/types.ts
+++ b/packages/instant/src/types.ts
@@ -95,6 +95,7 @@ export interface AffiliateInfo {
}
export interface ProviderState {
+ name: string;
provider: Provider;
assetBuyer: AssetBuyer;
web3Wrapper: Web3Wrapper;
@@ -137,3 +138,30 @@ export interface StandardSlidingPanelSettings {
animationState: SlideAnimationState;
content: StandardSlidingPanelContent;
}
+
+export enum Browser {
+ Chrome = 'Chrome',
+ Firefox = 'Firefox',
+ Opera = 'Opera',
+ Safari = 'Safari',
+ Edge = 'Edge',
+ Other = 'Other',
+}
+
+export enum OperatingSystem {
+ Android = 'Android',
+ iOS = 'iOS',
+ Mac = 'Mac',
+ Windows = 'Windows',
+ WindowsPhone = 'WindowsPhone',
+ Linux = 'Linux',
+ Other = 'Other',
+}
+
+export enum ProviderType {
+ Parity = 'Parity',
+ MetaMask = 'MetaMask',
+ Mist = 'Mist',
+ CoinbaseWallet = 'Coinbase Wallet',
+ Cipher = 'Cipher',
+}
diff --git a/packages/instant/src/util/env.ts b/packages/instant/src/util/env.ts
new file mode 100644
index 000000000..448ad5262
--- /dev/null
+++ b/packages/instant/src/util/env.ts
@@ -0,0 +1,67 @@
+import * as bowser from 'bowser';
+import { Provider } from 'ethereum-types';
+import * as _ from 'lodash';
+
+import { Browser, OperatingSystem, ProviderType } from '../types';
+
+export const envUtil = {
+ getBrowser(): Browser {
+ if (bowser.chrome) {
+ return Browser.Chrome;
+ } else if (bowser.firefox) {
+ return Browser.Firefox;
+ } else if (bowser.opera) {
+ return Browser.Opera;
+ } else if (bowser.msedge) {
+ return Browser.Edge;
+ } else if (bowser.safari) {
+ return Browser.Safari;
+ } else {
+ return Browser.Other;
+ }
+ },
+ isMobileOperatingSystem(): boolean {
+ return bowser.mobile;
+ },
+ getOperatingSystem(): OperatingSystem {
+ if (bowser.android) {
+ return OperatingSystem.Android;
+ } else if (bowser.ios) {
+ return OperatingSystem.iOS;
+ } else if (bowser.mac) {
+ return OperatingSystem.Mac;
+ } else if (bowser.windows) {
+ return OperatingSystem.Windows;
+ } else if (bowser.windowsphone) {
+ return OperatingSystem.WindowsPhone;
+ } else if (bowser.linux) {
+ return OperatingSystem.Linux;
+ } else {
+ return OperatingSystem.Other;
+ }
+ },
+ getProviderName(provider: Provider): ProviderType | string {
+ const constructorName = provider.constructor.name;
+ let parsedProviderName = constructorName;
+ // https://ethereum.stackexchange.com/questions/24266/elegant-way-to-detect-current-provider-int-web3-js
+ switch (constructorName) {
+ case 'EthereumProvider':
+ parsedProviderName = ProviderType.Mist;
+ break;
+
+ default:
+ parsedProviderName = constructorName;
+ break;
+ }
+ if ((provider as any).isParity) {
+ parsedProviderName = ProviderType.Parity;
+ } else if ((provider as any).isMetaMask) {
+ parsedProviderName = ProviderType.MetaMask;
+ } else if (!_.isUndefined(_.get(window, 'SOFA'))) {
+ parsedProviderName = ProviderType.CoinbaseWallet;
+ } else if (!_.isUndefined(_.get(window, '__CIPHER__'))) {
+ parsedProviderName = ProviderType.Cipher;
+ }
+ return parsedProviderName;
+ },
+};
diff --git a/packages/instant/src/util/provider_state_factory.ts b/packages/instant/src/util/provider_state_factory.ts
index 3281f6bfb..452a71460 100644
--- a/packages/instant/src/util/provider_state_factory.ts
+++ b/packages/instant/src/util/provider_state_factory.ts
@@ -4,6 +4,7 @@ import * as _ from 'lodash';
import { LOADING_ACCOUNT, NO_ACCOUNT } from '../constants';
import { Maybe, Network, OrderSource, ProviderState } from '../types';
+import { envUtil } from '../util/env';
import { assetBuyerFactory } from './asset_buyer_factory';
import { providerFactory } from './provider_factory';
@@ -29,6 +30,7 @@ export const providerStateFactory = {
provider: Provider,
): ProviderState => {
const providerState: ProviderState = {
+ name: envUtil.getProviderName(provider),
provider,
web3Wrapper: new Web3Wrapper(provider),
assetBuyer: assetBuyerFactory.getAssetBuyer(provider, orderSource, network),
@@ -40,6 +42,7 @@ export const providerStateFactory = {
const injectedProviderIfExists = providerFactory.getInjectedProviderIfExists();
if (!_.isUndefined(injectedProviderIfExists)) {
const providerState: ProviderState = {
+ name: envUtil.getProviderName(injectedProviderIfExists),
provider: injectedProviderIfExists,
web3Wrapper: new Web3Wrapper(injectedProviderIfExists),
assetBuyer: assetBuyerFactory.getAssetBuyer(injectedProviderIfExists, orderSource, network),
@@ -53,6 +56,7 @@ export const providerStateFactory = {
getInitialProviderStateFallback: (orderSource: OrderSource, network: Network): ProviderState => {
const provider = providerFactory.getFallbackNoSigningProvider(network);
const providerState: ProviderState = {
+ name: envUtil.getProviderName(provider),
provider,
web3Wrapper: new Web3Wrapper(provider),
assetBuyer: assetBuyerFactory.getAssetBuyer(provider, orderSource, network),