diff --git a/packages/instant/public/index.html b/packages/instant/public/index.html index 2c4314fc27..f91809471f 100644 --- a/packages/instant/public/index.html +++ b/packages/instant/public/index.html @@ -203,6 +203,9 @@ onClose: () => { console.log('0x Instant Closed'); }, + onSuccess: (txHash) => { + console.log(`Success! Transaction hash is: ${txHash}`) + } }; const renderOptions = Object.assign({}, renderOptionsDefaults, removeUndefined(renderOptionsOverrides)); zeroExInstant.render(renderOptions); diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx index aadd7c3a2e..0d9cfdcb08 100644 --- a/packages/instant/src/components/zero_ex_instant_provider.tsx +++ b/packages/instant/src/components/zero_ex_instant_provider.tsx @@ -10,7 +10,7 @@ import { asyncData } from '../redux/async_data'; import { DEFAULT_STATE, DefaultState, State } from '../redux/reducer'; import { store, Store } from '../redux/store'; import { fonts } from '../style/fonts'; -import { AccountState, Network, QuoteFetchOrigin, ZeroExInstantBaseConfig } from '../types'; +import { AccountState, Network, QuoteFetchOrigin, ZeroExInstantBaseConfig, OrderProcessState } from '../types'; import { analytics, disableAnalytics } from '../util/analytics'; import { assetUtils } from '../util/asset'; import { errorFlasher } from '../util/error_flasher'; @@ -19,6 +19,7 @@ import { gasPriceEstimator } from '../util/gas_price_estimator'; import { Heartbeater } from '../util/heartbeater'; import { generateAccountHeartbeater, generateBuyQuoteHeartbeater } from '../util/heartbeater_factory'; import { providerStateFactory } from '../util/provider_state_factory'; +import { ActionTypes, actions } from '../redux/actions'; export type ZeroExInstantProviderProps = ZeroExInstantBaseConfig; @@ -97,6 +98,18 @@ export class ZeroExInstantProvider extends React.PureComponent { + const currentState = this._store.getState(); + if ( + (currentState.buyOrderState.processState === OrderProcessState.Success) && + (currentState.buyOrderState.performedCallback === false) && + (this.props.onSuccess !== undefined) + ) { + const txHash = currentState.buyOrderState.txHash + this.props.onSuccess(txHash) + this._store.dispatch(actions.setBuyOrderStateSuccess(txHash, true)) + } + }) const dispatch = this._store.dispatch; // tslint:disable-next-line:no-floating-promises asyncData.fetchEthPriceAndDispatchToStore(dispatch); diff --git a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts index 4da99cf047..deb482bd14 100644 --- a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts +++ b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts @@ -83,7 +83,7 @@ const mapDispatchToProps = ( onBuyProcessing: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => { dispatch(actions.setBuyOrderStateProcessing(txHash, startTimeUnix, expectedEndTimeUnix)); }, - onBuySuccess: (buyQuote: BuyQuote, txHash: string) => dispatch(actions.setBuyOrderStateSuccess(txHash)), + onBuySuccess: (buyQuote: BuyQuote, txHash: string) => dispatch(actions.setBuyOrderStateSuccess(txHash, false)), onBuyFailure: (buyQuote: BuyQuote, txHash: string) => dispatch(actions.setBuyOrderStateFailure(txHash)), onSignatureDenied: () => { dispatch(actions.resetAmount()); diff --git a/packages/instant/src/redux/actions.ts b/packages/instant/src/redux/actions.ts index 013527f752..86aacd3628 100644 --- a/packages/instant/src/redux/actions.ts +++ b/packages/instant/src/redux/actions.ts @@ -58,7 +58,7 @@ export const actions = { setBuyOrderStateProcessing: (txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => createAction(ActionTypes.SetBuyOrderStateProcessing, { txHash, startTimeUnix, expectedEndTimeUnix }), setBuyOrderStateFailure: (txHash: string) => createAction(ActionTypes.SetBuyOrderStateFailure, txHash), - setBuyOrderStateSuccess: (txHash: string) => createAction(ActionTypes.SetBuyOrderStateSuccess, txHash), + setBuyOrderStateSuccess: (txHash: string, performedCallback: boolean) => createAction(ActionTypes.SetBuyOrderStateSuccess, {txHash, performedCallback}), updateLatestBuyQuote: (buyQuote?: BuyQuote) => createAction(ActionTypes.UpdateLatestBuyQuote, buyQuote), updateSelectedAsset: (asset: Asset) => createAction(ActionTypes.UpdateSelectedAsset, asset), setAvailableAssets: (availableAssets: Asset[]) => createAction(ActionTypes.SetAvailableAssets, availableAssets), diff --git a/packages/instant/src/redux/reducer.ts b/packages/instant/src/redux/reducer.ts index 86963c7917..19890d2158 100644 --- a/packages/instant/src/redux/reducer.ts +++ b/packages/instant/src/redux/reducer.ts @@ -157,6 +157,7 @@ export const createReducer = (initialState: State) => { buyOrderState: { processState: OrderProcessState.Processing, txHash: processingData.txHash, + performedCallback: false, progress: { startTimeUnix, expectedEndTimeUnix, @@ -171,6 +172,7 @@ export const createReducer = (initialState: State) => { return { ...state, buyOrderState: { + performedCallback: false, processState: OrderProcessState.Failure, txHash, progress, @@ -180,13 +182,14 @@ export const createReducer = (initialState: State) => { } return state; case ActionTypes.SetBuyOrderStateSuccess: - const successTxHash = action.data; + const successTxHash = action.data.txHash; if ('txHash' in state.buyOrderState) { if (state.buyOrderState.txHash === successTxHash) { const { txHash, progress } = state.buyOrderState; return { ...state, buyOrderState: { + performedCallback: action.data.performedCallback, processState: OrderProcessState.Success, txHash, progress, diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index 109ee44a5b..e058e22a06 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -43,6 +43,7 @@ interface OrderStatePostTx { processState: OrderProcessState.Processing | OrderProcessState.Success | OrderProcessState.Failure; txHash: string; progress: SimulatedProgress; + performedCallback: boolean } export type OrderState = OrderStatePreTx | OrderStatePostTx; @@ -201,6 +202,7 @@ export interface ZeroExInstantOptionalBaseConfig { networkId: Network; affiliateInfo: AffiliateInfo; shouldDisableAnalyticsTracking: boolean; + onSuccess?: (txHash: string) => void; } export type ZeroExInstantBaseConfig = ZeroExInstantRequiredBaseConfig & Partial;