329 lines
8.8 KiB
TypeScript
329 lines
8.8 KiB
TypeScript
import { ZeroEx } from '0x.js';
|
|
import { BigNumber } from '@0xproject/utils';
|
|
import * as _ from 'lodash';
|
|
import * as moment from 'moment';
|
|
import {
|
|
Action,
|
|
ActionTypes,
|
|
BlockchainErrs,
|
|
Order,
|
|
ProviderType,
|
|
ScreenWidths,
|
|
Side,
|
|
SideToAssetToken,
|
|
SignatureData,
|
|
TokenByAddress,
|
|
} from 'ts/types';
|
|
import { utils } from 'ts/utils/utils';
|
|
|
|
// Instead of defaulting the docs version to an empty string, we pre-populate it with
|
|
// a valid version value. This does not need to be updated however, since onLoad, it
|
|
// is always replaced with a value retrieved from our S3 bucket.
|
|
const DEFAULT_DOCS_VERSION = '0.0.0';
|
|
|
|
export interface State {
|
|
// Portal
|
|
blockchainErr: BlockchainErrs;
|
|
blockchainIsLoaded: boolean;
|
|
networkId: number;
|
|
orderExpiryTimestamp: BigNumber;
|
|
orderFillAmount: BigNumber;
|
|
orderTakerAddress: string;
|
|
orderSignatureData: SignatureData;
|
|
orderSalt: BigNumber;
|
|
nodeVersion: string;
|
|
screenWidth: ScreenWidths;
|
|
shouldBlockchainErrDialogBeOpen: boolean;
|
|
sideToAssetToken: SideToAssetToken;
|
|
tokenByAddress: TokenByAddress;
|
|
lastForceTokenStateRefetch: number;
|
|
userAddress: string;
|
|
userEtherBalance: BigNumber;
|
|
// Note: cache of supplied orderJSON in fill order step. Do not use for anything else.
|
|
userSuppliedOrderCache: Order;
|
|
|
|
// Docs
|
|
docsVersion: string;
|
|
availableDocVersions: string[];
|
|
|
|
// Shared
|
|
flashMessage: string | React.ReactNode;
|
|
providerType: ProviderType;
|
|
injectedProviderName: string;
|
|
}
|
|
|
|
const INITIAL_STATE: State = {
|
|
// Portal
|
|
blockchainErr: BlockchainErrs.NoError,
|
|
blockchainIsLoaded: false,
|
|
networkId: undefined,
|
|
orderExpiryTimestamp: utils.initialOrderExpiryUnixTimestampSec(),
|
|
orderFillAmount: undefined,
|
|
orderSignatureData: {
|
|
hash: '',
|
|
r: '',
|
|
s: '',
|
|
v: 27,
|
|
},
|
|
orderTakerAddress: '',
|
|
orderSalt: ZeroEx.generatePseudoRandomSalt(),
|
|
nodeVersion: undefined,
|
|
screenWidth: utils.getScreenWidth(),
|
|
shouldBlockchainErrDialogBeOpen: false,
|
|
sideToAssetToken: {
|
|
[Side.Deposit]: {},
|
|
[Side.Receive]: {},
|
|
},
|
|
tokenByAddress: {},
|
|
lastForceTokenStateRefetch: moment().unix(),
|
|
userAddress: '',
|
|
userEtherBalance: new BigNumber(0),
|
|
userSuppliedOrderCache: undefined,
|
|
|
|
// Docs
|
|
docsVersion: DEFAULT_DOCS_VERSION,
|
|
availableDocVersions: [DEFAULT_DOCS_VERSION],
|
|
|
|
// Shared
|
|
flashMessage: undefined,
|
|
providerType: ProviderType.Injected,
|
|
injectedProviderName: '',
|
|
};
|
|
|
|
export function reducer(state: State = INITIAL_STATE, action: Action) {
|
|
switch (action.type) {
|
|
// Portal
|
|
case ActionTypes.ResetState:
|
|
return INITIAL_STATE;
|
|
|
|
case ActionTypes.UpdateOrderSalt: {
|
|
return {
|
|
...state,
|
|
orderSalt: action.data,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateNodeVersion: {
|
|
return {
|
|
...state,
|
|
nodeVersion: action.data,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateOrderFillAmount: {
|
|
return {
|
|
...state,
|
|
orderFillAmount: action.data,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateShouldBlockchainErrDialogBeOpen: {
|
|
return {
|
|
...state,
|
|
shouldBlockchainErrDialogBeOpen: action.data,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateUserEtherBalance: {
|
|
return {
|
|
...state,
|
|
userEtherBalance: action.data,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateUserSuppliedOrderCache: {
|
|
return {
|
|
...state,
|
|
userSuppliedOrderCache: action.data,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.AddTokenToTokenByAddress: {
|
|
const newTokenByAddress = state.tokenByAddress;
|
|
newTokenByAddress[action.data.address] = action.data;
|
|
return {
|
|
...state,
|
|
tokenByAddress: newTokenByAddress,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.RemoveTokenFromTokenByAddress: {
|
|
const newTokenByAddress = state.tokenByAddress;
|
|
delete newTokenByAddress[action.data.address];
|
|
return {
|
|
...state,
|
|
tokenByAddress: newTokenByAddress,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateTokenByAddress: {
|
|
const tokenByAddress = state.tokenByAddress;
|
|
const tokens = action.data;
|
|
_.each(tokens, token => {
|
|
const updatedToken = {
|
|
...tokenByAddress[token.address],
|
|
...token,
|
|
};
|
|
tokenByAddress[token.address] = updatedToken;
|
|
});
|
|
return {
|
|
...state,
|
|
tokenByAddress,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.BatchDispatch: {
|
|
return {
|
|
...state,
|
|
networkId: action.data.networkId,
|
|
userAddress: action.data.userAddress,
|
|
sideToAssetToken: action.data.sideToAssetToken,
|
|
tokenByAddress: action.data.tokenByAddress,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.ForceTokenStateRefetch:
|
|
return {
|
|
...state,
|
|
lastForceTokenStateRefetch: moment().unix(),
|
|
};
|
|
|
|
case ActionTypes.UpdateOrderSignatureData: {
|
|
return {
|
|
...state,
|
|
orderSignatureData: action.data,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateScreenWidth: {
|
|
return {
|
|
...state,
|
|
screenWidth: action.data,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateBlockchainIsLoaded: {
|
|
return {
|
|
...state,
|
|
blockchainIsLoaded: action.data,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.BlockchainErrEncountered: {
|
|
return {
|
|
...state,
|
|
blockchainErr: action.data,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateNetworkId: {
|
|
return {
|
|
...state,
|
|
networkId: action.data,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateChosenAssetToken: {
|
|
const newSideToAssetToken = {
|
|
...state.sideToAssetToken,
|
|
[action.data.side]: action.data.token,
|
|
};
|
|
return {
|
|
...state,
|
|
sideToAssetToken: newSideToAssetToken,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateChosenAssetTokenAddress: {
|
|
const newAssetToken = state.sideToAssetToken[action.data.side];
|
|
newAssetToken.address = action.data.address;
|
|
const newSideToAssetToken = {
|
|
...state.sideToAssetToken,
|
|
[action.data.side]: newAssetToken,
|
|
};
|
|
return {
|
|
...state,
|
|
sideToAssetToken: newSideToAssetToken,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.SwapAssetTokens: {
|
|
const newSideToAssetToken = {
|
|
[Side.Deposit]: state.sideToAssetToken[Side.Receive],
|
|
[Side.Receive]: state.sideToAssetToken[Side.Deposit],
|
|
};
|
|
return {
|
|
...state,
|
|
sideToAssetToken: newSideToAssetToken,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateOrderExpiry: {
|
|
return {
|
|
...state,
|
|
orderExpiryTimestamp: action.data,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateOrderTakerAddress: {
|
|
return {
|
|
...state,
|
|
orderTakerAddress: action.data,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateUserAddress: {
|
|
return {
|
|
...state,
|
|
userAddress: action.data,
|
|
};
|
|
}
|
|
|
|
// Docs
|
|
case ActionTypes.UpdateLibraryVersion: {
|
|
return {
|
|
...state,
|
|
docsVersion: action.data,
|
|
};
|
|
}
|
|
case ActionTypes.UpdateAvailableLibraryVersions: {
|
|
return {
|
|
...state,
|
|
availableDocVersions: action.data,
|
|
};
|
|
}
|
|
|
|
// Shared
|
|
case ActionTypes.ShowFlashMessage: {
|
|
return {
|
|
...state,
|
|
flashMessage: action.data,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.HideFlashMessage: {
|
|
return {
|
|
...state,
|
|
flashMessage: undefined,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateProviderType: {
|
|
return {
|
|
...state,
|
|
providerType: action.data,
|
|
};
|
|
}
|
|
|
|
case ActionTypes.UpdateInjectedProviderName: {
|
|
return {
|
|
...state,
|
|
injectedProviderName: action.data,
|
|
};
|
|
}
|
|
|
|
default:
|
|
return state;
|
|
}
|
|
}
|