feat(instant): fallback to an empty wallet provider when none is injected
This commit is contained in:
parent
c30dca6961
commit
dfbf10c94b
@ -49,6 +49,7 @@
|
||||
"@0x/asset-buyer": "^2.1.0",
|
||||
"@0x/json-schemas": "^2.0.0",
|
||||
"@0x/order-utils": "^2.0.0",
|
||||
"@0x/subproviders": "^2.1.0",
|
||||
"@0x/types": "^1.2.0",
|
||||
"@0x/typescript-typings": "^3.0.3",
|
||||
"@0x/utils": "^2.0.3",
|
||||
|
@ -17,7 +17,7 @@ import { Text } from './ui/text';
|
||||
|
||||
export interface BuyButtonProps {
|
||||
buyQuote?: BuyQuote;
|
||||
assetBuyer?: AssetBuyer;
|
||||
assetBuyer: AssetBuyer;
|
||||
affiliateInfo?: AffiliateInfo;
|
||||
onValidationPending: (buyQuote: BuyQuote) => void;
|
||||
onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void;
|
||||
@ -34,7 +34,7 @@ export class BuyButton extends React.Component<BuyButtonProps> {
|
||||
onBuyFailure: util.boundNoop,
|
||||
};
|
||||
public render(): React.ReactNode {
|
||||
const shouldDisableButton = _.isUndefined(this.props.buyQuote) || _.isUndefined(this.props.assetBuyer);
|
||||
const shouldDisableButton = _.isUndefined(this.props.buyQuote);
|
||||
return (
|
||||
<Button width="100%" onClick={this._handleClick} isDisabled={shouldDisableButton}>
|
||||
<Text fontColor={ColorOption.white} fontWeight={600} fontSize="20px">
|
||||
@ -46,11 +46,13 @@ export class BuyButton extends React.Component<BuyButtonProps> {
|
||||
private readonly _handleClick = async () => {
|
||||
// The button is disabled when there is no buy quote anyway.
|
||||
const { buyQuote, assetBuyer, affiliateInfo } = this.props;
|
||||
if (_.isUndefined(buyQuote) || _.isUndefined(assetBuyer)) {
|
||||
if (_.isUndefined(buyQuote)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.onValidationPending(buyQuote);
|
||||
|
||||
// TODO(bmillman): move address and balance fetching to the async state
|
||||
const web3Wrapper = new Web3Wrapper(assetBuyer.provider);
|
||||
const takerAddress = await getBestAddress(web3Wrapper);
|
||||
|
||||
|
@ -15,7 +15,7 @@ import { Text } from './ui/text';
|
||||
export interface BuyOrderStateButtonProps {
|
||||
buyQuote?: BuyQuote;
|
||||
buyOrderProcessingState: OrderProcessState;
|
||||
assetBuyer?: AssetBuyer;
|
||||
assetBuyer: AssetBuyer;
|
||||
affiliateInfo?: AffiliateInfo;
|
||||
onViewTransaction: () => void;
|
||||
onValidationPending: (buyQuote: BuyQuote) => void;
|
||||
|
@ -1,23 +1,22 @@
|
||||
import { AssetBuyer } from '@0x/asset-buyer';
|
||||
import { ObjectMap, SignedOrder } from '@0x/types';
|
||||
import { ObjectMap } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { Provider } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import { Provider as ReduxProvider } from 'react-redux';
|
||||
import { oc } from 'ts-optchain';
|
||||
|
||||
import { SelectedAssetThemeProvider } from '../containers/selected_asset_theme_provider';
|
||||
import { asyncData } from '../redux/async_data';
|
||||
import { INITIAL_STATE, State } from '../redux/reducer';
|
||||
import { DEFAULT_STATE, DefaultState, State } from '../redux/reducer';
|
||||
import { store, Store } from '../redux/store';
|
||||
import { fonts } from '../style/fonts';
|
||||
import { AffiliateInfo, AssetMetaData, Network } from '../types';
|
||||
import { AffiliateInfo, AssetMetaData, Network, OrderSource, ProviderState, ProviderType } from '../types';
|
||||
import { assetUtils } from '../util/asset';
|
||||
import { assetBuyerFactory } from '../util/asset_buyer_factory';
|
||||
import { errorFlasher } from '../util/error_flasher';
|
||||
import { gasPriceEstimator } from '../util/gas_price_estimator';
|
||||
import { getInjectedProvider } from '../util/injected_provider';
|
||||
import { providerFactory } from '../util/provider_factory';
|
||||
|
||||
fonts.include();
|
||||
|
||||
@ -25,7 +24,7 @@ export type ZeroExInstantProviderProps = ZeroExInstantProviderRequiredProps &
|
||||
Partial<ZeroExInstantProviderOptionalProps>;
|
||||
|
||||
export interface ZeroExInstantProviderRequiredProps {
|
||||
orderSource: string | SignedOrder[];
|
||||
orderSource: OrderSource;
|
||||
}
|
||||
|
||||
export interface ZeroExInstantProviderOptionalProps {
|
||||
@ -41,30 +40,43 @@ export interface ZeroExInstantProviderOptionalProps {
|
||||
export class ZeroExInstantProvider extends React.Component<ZeroExInstantProviderProps> {
|
||||
private readonly _store: Store;
|
||||
// TODO(fragosti): Write tests for this beast once we inject a provider.
|
||||
private static _mergeInitialStateWithProps(props: ZeroExInstantProviderProps, state: State = INITIAL_STATE): State {
|
||||
const networkId = props.networkId || state.network;
|
||||
// TODO: Proper wallet connect flow
|
||||
const provider = props.provider || getInjectedProvider();
|
||||
const assetBuyerOptions = {
|
||||
networkId,
|
||||
};
|
||||
let assetBuyer;
|
||||
if (_.isString(props.orderSource)) {
|
||||
assetBuyer = AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl(
|
||||
provider,
|
||||
props.orderSource,
|
||||
assetBuyerOptions,
|
||||
);
|
||||
private static _mergeDefaultStateWithProps(
|
||||
props: ZeroExInstantProviderProps,
|
||||
defaultState: DefaultState = DEFAULT_STATE,
|
||||
): State {
|
||||
// use the networkId passed in with the props, otherwise default to that of the default state (1, mainnet)
|
||||
const networkId = props.networkId || defaultState.network;
|
||||
// construct the ProviderState
|
||||
let provider: Provider;
|
||||
let providerType: ProviderType;
|
||||
if (!_.isUndefined(props.provider)) {
|
||||
provider = props.provider;
|
||||
providerType = ProviderType.Props;
|
||||
} else {
|
||||
assetBuyer = AssetBuyer.getAssetBuyerForProvidedOrders(provider, props.orderSource, assetBuyerOptions);
|
||||
const injectedProviderIfExists = providerFactory.getInjectedProviderIfExists();
|
||||
if (!_.isUndefined(injectedProviderIfExists)) {
|
||||
provider = injectedProviderIfExists;
|
||||
providerType = ProviderType.Injected;
|
||||
} else {
|
||||
provider = providerFactory.getFallbackNoSigningProvider(networkId);
|
||||
providerType = ProviderType.FallbackEmptyWallet;
|
||||
}
|
||||
}
|
||||
const providerState: ProviderState = {
|
||||
provider,
|
||||
type: providerType,
|
||||
web3Wrapper: new Web3Wrapper(provider),
|
||||
assetBuyer: assetBuyerFactory.getAssetBuyer(provider, props.orderSource, networkId),
|
||||
};
|
||||
// merge the additional additionalAssetMetaDataMap with our default map
|
||||
const completeAssetMetaDataMap = {
|
||||
...props.additionalAssetMetaDataMap,
|
||||
...state.assetMetaDataMap,
|
||||
...defaultState.assetMetaDataMap,
|
||||
};
|
||||
// construct the final state
|
||||
const storeStateFromProps: State = {
|
||||
...state,
|
||||
assetBuyer,
|
||||
...defaultState,
|
||||
providerState,
|
||||
network: networkId,
|
||||
selectedAsset: _.isUndefined(props.defaultSelectedAssetData)
|
||||
? undefined
|
||||
@ -74,7 +86,7 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider
|
||||
networkId,
|
||||
),
|
||||
selectedAssetAmount: _.isUndefined(props.defaultAssetBuyAmount)
|
||||
? state.selectedAssetAmount
|
||||
? undefined
|
||||
: new BigNumber(props.defaultAssetBuyAmount),
|
||||
availableAssets: _.isUndefined(props.availableAssetDatas)
|
||||
? undefined
|
||||
@ -86,10 +98,9 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider
|
||||
}
|
||||
constructor(props: ZeroExInstantProviderProps) {
|
||||
super(props);
|
||||
const initialAppState = ZeroExInstantProvider._mergeInitialStateWithProps(this.props, INITIAL_STATE);
|
||||
const initialAppState = ZeroExInstantProvider._mergeDefaultStateWithProps(this.props);
|
||||
this._store = store.create(initialAppState);
|
||||
}
|
||||
|
||||
public componentDidMount(): void {
|
||||
const state = this._store.getState();
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
@ -108,7 +119,6 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
this._flashErrorIfWrongNetwork();
|
||||
}
|
||||
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<ReduxProvider store={this._store}>
|
||||
@ -116,19 +126,15 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider
|
||||
</ReduxProvider>
|
||||
);
|
||||
}
|
||||
|
||||
private readonly _flashErrorIfWrongNetwork = async (): Promise<void> => {
|
||||
const msToShowError = 30000; // 30 seconds
|
||||
const network = this._store.getState().network;
|
||||
const assetBuyerIfExists = this._store.getState().assetBuyer;
|
||||
const providerIfExists = oc(assetBuyerIfExists).provider();
|
||||
if (!_.isUndefined(providerIfExists)) {
|
||||
const web3Wrapper = new Web3Wrapper(providerIfExists);
|
||||
const state = this._store.getState();
|
||||
const network = state.network;
|
||||
const web3Wrapper = state.providerState.web3Wrapper;
|
||||
const networkOfProvider = await web3Wrapper.getNetworkIdAsync();
|
||||
if (network !== networkOfProvider) {
|
||||
const errorMessage = `Wrong network detected. Try switching to ${Network[network]}.`;
|
||||
errorFlasher.flashNewErrorMessage(this._store.dispatch, errorMessage, msToShowError);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import { Network } from './types';
|
||||
|
||||
export const BIG_NUMBER_ZERO = new BigNumber(0);
|
||||
export const ETH_DECIMALS = 18;
|
||||
export const DEFAULT_ZERO_EX_CONTAINER_SELECTOR = '#zeroExInstantContainer';
|
||||
@ -13,3 +16,8 @@ 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 ETHEREUM_NODE_URL_BY_NETWORK = {
|
||||
[Network.Mainnet]: 'https://mainnet.infura.io/',
|
||||
[Network.Kovan]: 'https://kovan.infura.io/',
|
||||
};
|
||||
export const BLOCK_POLLING_INTERVAL_MS = 10000; // 10s
|
||||
|
@ -14,7 +14,7 @@ import { etherscanUtil } from '../util/etherscan';
|
||||
interface ConnectedState {
|
||||
buyQuote?: BuyQuote;
|
||||
buyOrderProcessingState: OrderProcessState;
|
||||
assetBuyer?: AssetBuyer;
|
||||
assetBuyer: AssetBuyer;
|
||||
affiliateInfo?: AffiliateInfo;
|
||||
onViewTransaction: () => void;
|
||||
}
|
||||
@ -29,21 +29,22 @@ interface ConnectedDispatch {
|
||||
onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void;
|
||||
}
|
||||
export interface SelectedAssetBuyOrderStateButtons {}
|
||||
const mapStateToProps = (state: State, _ownProps: SelectedAssetBuyOrderStateButtons): ConnectedState => ({
|
||||
const mapStateToProps = (state: State, _ownProps: SelectedAssetBuyOrderStateButtons): ConnectedState => {
|
||||
const assetBuyer = state.providerState.assetBuyer;
|
||||
return {
|
||||
buyOrderProcessingState: state.buyOrderState.processState,
|
||||
assetBuyer: state.assetBuyer,
|
||||
assetBuyer,
|
||||
buyQuote: state.latestBuyQuote,
|
||||
affiliateInfo: state.affiliateInfo,
|
||||
onViewTransaction: () => {
|
||||
if (
|
||||
state.assetBuyer &&
|
||||
(state.buyOrderState.processState === OrderProcessState.Processing ||
|
||||
state.buyOrderState.processState === OrderProcessState.Processing ||
|
||||
state.buyOrderState.processState === OrderProcessState.Success ||
|
||||
state.buyOrderState.processState === OrderProcessState.Failure)
|
||||
state.buyOrderState.processState === OrderProcessState.Failure
|
||||
) {
|
||||
const etherscanUrl = etherscanUtil.getEtherScanTxnAddressIfExists(
|
||||
state.buyOrderState.txHash,
|
||||
state.assetBuyer.networkId,
|
||||
assetBuyer.networkId,
|
||||
);
|
||||
if (etherscanUrl) {
|
||||
window.open(etherscanUrl, '_blank');
|
||||
@ -51,7 +52,8 @@ const mapStateToProps = (state: State, _ownProps: SelectedAssetBuyOrderStateButt
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (
|
||||
dispatch: Dispatch<Action>,
|
||||
|
@ -23,7 +23,7 @@ export interface SelectedERC20AssetAmountInputProps {
|
||||
}
|
||||
|
||||
interface ConnectedState {
|
||||
assetBuyer?: AssetBuyer;
|
||||
assetBuyer: AssetBuyer;
|
||||
value?: BigNumber;
|
||||
asset?: ERC20Asset;
|
||||
isDisabled: boolean;
|
||||
@ -33,7 +33,7 @@ interface ConnectedState {
|
||||
|
||||
interface ConnectedDispatch {
|
||||
updateBuyQuote: (
|
||||
assetBuyer?: AssetBuyer,
|
||||
assetBuyer: AssetBuyer,
|
||||
value?: BigNumber,
|
||||
asset?: ERC20Asset,
|
||||
affiliateInfo?: AffiliateInfo,
|
||||
@ -59,8 +59,9 @@ const mapStateToProps = (state: State, _ownProps: SelectedERC20AssetAmountInputP
|
||||
? (state.selectedAsset as ERC20Asset)
|
||||
: undefined;
|
||||
const numberOfAssetsAvailable = _.isUndefined(state.availableAssets) ? undefined : state.availableAssets.length;
|
||||
const assetBuyer = state.providerState.assetBuyer;
|
||||
return {
|
||||
assetBuyer: state.assetBuyer,
|
||||
assetBuyer,
|
||||
value: state.selectedAssetAmount,
|
||||
asset: selectedAsset,
|
||||
isDisabled,
|
||||
@ -128,7 +129,7 @@ const mapDispatchToProps = (
|
||||
// reset our buy state
|
||||
dispatch(actions.setBuyOrderStateNone());
|
||||
|
||||
if (!_.isUndefined(value) && value.greaterThan(0) && !_.isUndefined(asset) && !_.isUndefined(assetBuyer)) {
|
||||
if (!_.isUndefined(value) && value.greaterThan(0) && !_.isUndefined(asset)) {
|
||||
// even if it's debounced, give them the illusion it's loading
|
||||
dispatch(actions.setQuoteRequestStatePending());
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
|
@ -20,8 +20,8 @@ export const asyncData = {
|
||||
}
|
||||
},
|
||||
fetchAvailableAssetDatasAndDispatchToStore: async (store: Store) => {
|
||||
const { assetBuyer, assetMetaDataMap, network } = store.getState();
|
||||
if (!_.isUndefined(assetBuyer)) {
|
||||
const { providerState, assetMetaDataMap, network } = store.getState();
|
||||
const assetBuyer = providerState.assetBuyer;
|
||||
try {
|
||||
const assetDatas = await assetBuyer.getAvailableAssetDatasAsync();
|
||||
const assets = assetUtils.createAssetsFromAssetDatas(assetDatas, assetMetaDataMap, network);
|
||||
@ -32,6 +32,5 @@ export const asyncData = {
|
||||
// On error, just specify that none are available
|
||||
store.dispatch(actions.setAvailableAssets([]));
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AssetBuyer, BuyQuote } from '@0x/asset-buyer';
|
||||
import { BuyQuote } from '@0x/asset-buyer';
|
||||
import { AssetProxyId, ObjectMap } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
@ -14,41 +14,48 @@ import {
|
||||
Network,
|
||||
OrderProcessState,
|
||||
OrderState,
|
||||
ProviderState,
|
||||
} from '../types';
|
||||
|
||||
import { Action, ActionTypes } from './actions';
|
||||
|
||||
export interface State {
|
||||
// State that is required and we have defaults for, before props are passed in
|
||||
export interface DefaultState {
|
||||
network: Network;
|
||||
assetBuyer?: AssetBuyer;
|
||||
assetMetaDataMap: ObjectMap<AssetMetaData>;
|
||||
selectedAsset?: Asset;
|
||||
availableAssets?: Asset[];
|
||||
selectedAssetAmount?: BigNumber;
|
||||
buyOrderState: OrderState;
|
||||
ethUsdPrice?: BigNumber;
|
||||
latestBuyQuote?: BuyQuote;
|
||||
quoteRequestState: AsyncProcessState;
|
||||
latestErrorMessage?: string;
|
||||
latestErrorDisplayStatus: DisplayStatus;
|
||||
affiliateInfo?: AffiliateInfo;
|
||||
quoteRequestState: AsyncProcessState;
|
||||
}
|
||||
|
||||
export const INITIAL_STATE: State = {
|
||||
// State that is required but needs to be derived from the props
|
||||
interface PropsDerivedState {
|
||||
providerState: ProviderState;
|
||||
}
|
||||
|
||||
// State that is optional
|
||||
interface OptionalState {
|
||||
selectedAsset: Asset;
|
||||
availableAssets: Asset[];
|
||||
selectedAssetAmount: BigNumber;
|
||||
ethUsdPrice: BigNumber;
|
||||
latestBuyQuote: BuyQuote;
|
||||
latestErrorMessage: string;
|
||||
affiliateInfo: AffiliateInfo;
|
||||
}
|
||||
|
||||
export type State = DefaultState & PropsDerivedState & Partial<OptionalState>;
|
||||
|
||||
export const DEFAULT_STATE: DefaultState = {
|
||||
network: Network.Mainnet,
|
||||
selectedAssetAmount: undefined,
|
||||
availableAssets: undefined,
|
||||
assetMetaDataMap,
|
||||
buyOrderState: { processState: OrderProcessState.None },
|
||||
ethUsdPrice: undefined,
|
||||
latestBuyQuote: undefined,
|
||||
latestErrorMessage: undefined,
|
||||
latestErrorDisplayStatus: DisplayStatus.Hidden,
|
||||
quoteRequestState: AsyncProcessState.None,
|
||||
affiliateInfo: undefined,
|
||||
};
|
||||
|
||||
export const reducer = (state: State = INITIAL_STATE, action: Action): State => {
|
||||
export const createReducer = (initialState: State) => {
|
||||
const reducer = (state: State = initialState, action: Action): State => {
|
||||
switch (action.type) {
|
||||
case ActionTypes.UPDATE_ETH_USD_PRICE:
|
||||
return {
|
||||
@ -180,6 +187,8 @@ export const reducer = (state: State = INITIAL_STATE, action: Action): State =>
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
return reducer;
|
||||
};
|
||||
|
||||
const doesBuyQuoteMatchState = (buyQuote: BuyQuote, state: State): boolean => {
|
||||
|
@ -2,12 +2,13 @@ import * as _ from 'lodash';
|
||||
import { createStore, Store as ReduxStore } from 'redux';
|
||||
import { devToolsEnhancer } from 'redux-devtools-extension/developmentOnly';
|
||||
|
||||
import { reducer, State } from './reducer';
|
||||
import { createReducer, State } from './reducer';
|
||||
|
||||
export type Store = ReduxStore<State>;
|
||||
|
||||
export const store = {
|
||||
create: (state: State): Store => {
|
||||
return createStore(reducer, state, devToolsEnhancer({}));
|
||||
create: (initialState: State): Store => {
|
||||
const reducer = createReducer(initialState);
|
||||
return createStore(reducer, initialState, devToolsEnhancer({}));
|
||||
},
|
||||
};
|
||||
|
@ -1,4 +1,7 @@
|
||||
import { AssetProxyId, ObjectMap } from '@0x/types';
|
||||
import { AssetBuyer } from '@0x/asset-buyer';
|
||||
import { AssetProxyId, ObjectMap, SignedOrder } from '@0x/types';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { Provider } from 'ethereum-types';
|
||||
|
||||
// Reusable
|
||||
export type Maybe<T> = T | undefined;
|
||||
@ -89,3 +92,24 @@ export interface AffiliateInfo {
|
||||
feeRecipient: string;
|
||||
feePercentage: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Our provider may be of 3 different types:
|
||||
* Props: the provider was passed in a prop to the component
|
||||
* Injected: the provider was injected into `window`
|
||||
* FallbackEmptyWallet: the provider has no wallet but responds to data requests using infura
|
||||
*/
|
||||
export enum ProviderType {
|
||||
Props = 'PROPS',
|
||||
Injected = 'INJECTED',
|
||||
FallbackEmptyWallet = 'FALLBACK_EMPTY_WALLET',
|
||||
}
|
||||
|
||||
export interface ProviderState {
|
||||
type: ProviderType;
|
||||
provider: Provider;
|
||||
assetBuyer: AssetBuyer;
|
||||
web3Wrapper: Web3Wrapper;
|
||||
}
|
||||
|
||||
export type OrderSource = string | SignedOrder[];
|
||||
|
17
packages/instant/src/util/asset_buyer_factory.ts
Normal file
17
packages/instant/src/util/asset_buyer_factory.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { AssetBuyer, AssetBuyerOpts } from '@0x/asset-buyer';
|
||||
import { Provider } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { Network, OrderSource } from '../types';
|
||||
|
||||
export const assetBuyerFactory = {
|
||||
getAssetBuyer: (provider: Provider, orderSource: OrderSource, network: Network): AssetBuyer => {
|
||||
const assetBuyerOptions: Partial<AssetBuyerOpts> = {
|
||||
networkId: network,
|
||||
};
|
||||
const assetBuyer = _.isString(orderSource)
|
||||
? AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl(provider, orderSource, assetBuyerOptions)
|
||||
: AssetBuyer.getAssetBuyerForProvidedOrders(provider, orderSource, assetBuyerOptions);
|
||||
return assetBuyer;
|
||||
},
|
||||
};
|
@ -1,16 +0,0 @@
|
||||
import { Provider } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
export const getInjectedProvider = (): Provider => {
|
||||
const injectedProviderIfExists = (window as any).ethereum;
|
||||
if (!_.isUndefined(injectedProviderIfExists)) {
|
||||
// TODO: call enable here when implementing wallet connection flow
|
||||
return injectedProviderIfExists;
|
||||
}
|
||||
const injectedWeb3IfExists = (window as any).web3;
|
||||
if (!_.isUndefined(injectedWeb3IfExists.currentProvider)) {
|
||||
return injectedWeb3IfExists.currentProvider;
|
||||
} else {
|
||||
throw new Error(`No injected web3 found`);
|
||||
}
|
||||
};
|
34
packages/instant/src/util/provider_factory.ts
Normal file
34
packages/instant/src/util/provider_factory.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { EmptyWalletSubprovider, RPCSubprovider, Web3ProviderEngine } from '@0x/subproviders';
|
||||
import { Provider } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { BLOCK_POLLING_INTERVAL_MS, ETHEREUM_NODE_URL_BY_NETWORK } from '../constants';
|
||||
import { Maybe, Network } from '../types';
|
||||
|
||||
export const providerFactory = {
|
||||
getInjectedProviderIfExists: (): Maybe<Provider> => {
|
||||
const injectedProviderIfExists = (window as any).ethereum;
|
||||
if (!_.isUndefined(injectedProviderIfExists)) {
|
||||
return injectedProviderIfExists;
|
||||
}
|
||||
const injectedWeb3IfExists = (window as any).web3;
|
||||
if (!_.isUndefined(injectedWeb3IfExists) && !_.isUndefined(injectedWeb3IfExists.currentProvider)) {
|
||||
return injectedWeb3IfExists.currentProvider;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
getFallbackNoSigningProvider: (network: Network): Provider => {
|
||||
const providerEngine = new Web3ProviderEngine({
|
||||
pollingInterval: BLOCK_POLLING_INTERVAL_MS,
|
||||
});
|
||||
// Intercept calls to `eth_accounts` and always return empty
|
||||
providerEngine.addProvider(new EmptyWalletSubprovider());
|
||||
// Construct an RPC subprovider, all data based requests will be sent via the RPCSubprovider
|
||||
// TODO(bmillman): make this more resilient to infura failures
|
||||
const rpcUrl = ETHEREUM_NODE_URL_BY_NETWORK[network];
|
||||
providerEngine.addProvider(new RPCSubprovider(rpcUrl));
|
||||
// // Start the Provider Engine
|
||||
providerEngine.start();
|
||||
return providerEngine;
|
||||
},
|
||||
};
|
41
yarn.lock
41
yarn.lock
@ -1900,10 +1900,6 @@ aes-js@^0.2.3:
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-0.2.4.tgz#94b881ab717286d015fa219e08fb66709dda5a3d"
|
||||
|
||||
aes-js@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.npmjs.org/aes-js/-/aes-js-3.1.1.tgz#89fd1f94ae51b4c72d62466adc1a7323ff52f072"
|
||||
|
||||
agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9"
|
||||
@ -3341,7 +3337,7 @@ bs-logger@0.x:
|
||||
dependencies:
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
|
||||
bs58@=4.0.1, bs58@^4.0.0:
|
||||
bs58@=4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a"
|
||||
dependencies:
|
||||
@ -3364,14 +3360,6 @@ bs58check@^1.0.8:
|
||||
bs58 "^3.1.0"
|
||||
create-hash "^1.1.0"
|
||||
|
||||
bs58check@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc"
|
||||
dependencies:
|
||||
bs58 "^4.0.0"
|
||||
create-hash "^1.1.0"
|
||||
safe-buffer "^5.1.2"
|
||||
|
||||
bser@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719"
|
||||
@ -5959,19 +5947,6 @@ ethereumjs-wallet@0.6.0:
|
||||
utf8 "^2.1.1"
|
||||
uuid "^2.0.1"
|
||||
|
||||
ethereumjs-wallet@~0.6.0:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.2.tgz#67244b6af3e8113b53d709124b25477b64aeccda"
|
||||
dependencies:
|
||||
aes-js "^3.1.1"
|
||||
bs58check "^2.1.2"
|
||||
ethereumjs-util "^5.2.0"
|
||||
hdkey "^1.0.0"
|
||||
safe-buffer "^5.1.2"
|
||||
scrypt.js "^0.2.0"
|
||||
utf8 "^3.0.0"
|
||||
uuid "^3.3.2"
|
||||
|
||||
ethers@~4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.4.tgz#d3f85e8b27f4b59537e06526439b0fb15b44dc65"
|
||||
@ -6776,7 +6751,7 @@ ganache-core@0xProject/ganache-core#monorepo-dep:
|
||||
ethereumjs-tx "0xProject/ethereumjs-tx#fake-tx-include-signature-by-default"
|
||||
ethereumjs-util "^5.2.0"
|
||||
ethereumjs-vm "2.3.5"
|
||||
ethereumjs-wallet "~0.6.0"
|
||||
ethereumjs-wallet "0.6.0"
|
||||
fake-merkle-patricia-tree "~1.0.1"
|
||||
heap "~0.2.6"
|
||||
js-scrypt "^0.2.0"
|
||||
@ -7501,14 +7476,6 @@ hdkey@^0.7.0, hdkey@^0.7.1:
|
||||
coinstring "^2.0.0"
|
||||
secp256k1 "^3.0.1"
|
||||
|
||||
hdkey@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/hdkey/-/hdkey-1.1.0.tgz#e74e7b01d2c47f797fa65d1d839adb7a44639f29"
|
||||
dependencies:
|
||||
coinstring "^2.0.0"
|
||||
safe-buffer "^5.1.1"
|
||||
secp256k1 "^3.0.1"
|
||||
|
||||
he@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
|
||||
@ -15595,10 +15562,6 @@ utf8@^2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.2.tgz#1fa0d9270e9be850d9b05027f63519bf46457d96"
|
||||
|
||||
utf8@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1"
|
||||
|
||||
util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
|
Loading…
x
Reference in New Issue
Block a user