diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 5ccd6b58..00000000 --- a/.babelrc +++ /dev/null @@ -1,25 +0,0 @@ -{ - "plugins": [ - [ - "transform-runtime", { - "helpers": false, - "polyfill": false, - "regenerator": true, - "moduleName": "babel-runtime" - } - ], - ["module-resolver", { - "root": ["./common"], - "alias": { - "underscore": "lodash" - }, - "cwd": "babelrc" - }], - "react-hot-loader/babel"], - "presets": ["es2015", "react", "stage-0", "flow"], - "env": { - "production": { - "presets": ["react-optimize"] - } - } -} diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index b3ce884c..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "extends": ["eslint:recommended", "plugin:react/recommended"], - "parser": "babel-eslint", - "plugins": ["react"], - "parserOptions": { - "ecmaFeatures": { - "jsx": true, - "modules": true - } - }, - "env": { - "browser": true, - "amd": true, - "es6": true, - "node": true, - "jest": true - }, - "rules": { - "comma-dangle": 1, - "quotes": [1, "single"], - "no-undef": 1, - "global-strict": 0, - "no-extra-semi": 1, - "no-underscore-dangle": 0, - "no-console": 0, - "no-unused-vars": 0, - "no-constant-condition": 0, - "no-trailing-spaces": [1, { "skipBlankLines": true }], - "no-unreachable": 1, - "no-alert": 0, - "react/jsx-uses-react": 1, - "no-unused-vars": [1, { "argsIgnorePattern": "^_" }], - "no-restricted-globals": ["error", "event"] - }, - "globals": { - "SyntheticInputEvent": false, - "SyntheticKeyboardEvent": false, - "Generator": false, - "$Keys": false, - "SyntheticMouseEvent": false - } -} diff --git a/.gitignore b/.gitignore index 7363a552..39bf79fb 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ jspm_packages .vscode/ static/dll.vendor.js dll +.cache-loader # SSL cert stuff webpack_config/server.key diff --git a/.travis.yml b/.travis.yml index 0bf1ba16..ecf3e767 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,4 +15,4 @@ notifications: script: - npm run test -- npm run flow \ No newline at end of file +- npm run tslint diff --git a/common/actions/config.js b/common/actions/config.js deleted file mode 100644 index 3f940abe..00000000 --- a/common/actions/config.js +++ /dev/null @@ -1,47 +0,0 @@ -// @flow - -/*** Change Language ***/ -export type ChangeLanguageAction = { - type: 'CONFIG_LANGUAGE_CHANGE', - value: string -}; - -export function changeLanguage(sign: string): ChangeLanguageAction { - return { - type: 'CONFIG_LANGUAGE_CHANGE', - value: sign - }; -} - -/*** Change Node ***/ -export type ChangeNodeAction = { - type: 'CONFIG_NODE_CHANGE', - // FIXME $keyof? - value: string -}; - -export function changeNode(value: string): ChangeNodeAction { - return { - type: 'CONFIG_NODE_CHANGE', - value - }; -} - -/*** Change gas price ***/ -export type ChangeGasPriceAction = { - type: 'CONFIG_GAS_PRICE', - value: number -}; - -export function changeGasPrice(value: number): ChangeGasPriceAction { - return { - type: 'CONFIG_GAS_PRICE', - value - }; -} - -/*** Union Type ***/ -export type ConfigAction = - | ChangeNodeAction - | ChangeLanguageAction - | ChangeGasPriceAction; diff --git a/common/actions/config/actionCreators.ts b/common/actions/config/actionCreators.ts new file mode 100644 index 00000000..60aa0cd3 --- /dev/null +++ b/common/actions/config/actionCreators.ts @@ -0,0 +1,26 @@ +import * as interfaces from './actionTypes'; +import { TypeKeys } from './constants'; + +export type TChangeLanguage = typeof changeLanguage; +export function changeLanguage(sign: string): interfaces.ChangeLanguageAction { + return { + type: TypeKeys.CONFIG_LANGUAGE_CHANGE, + value: sign + }; +} + +export type TChangeNode = typeof changeNode; +export function changeNode(value: string): interfaces.ChangeNodeAction { + return { + type: TypeKeys.CONFIG_NODE_CHANGE, + value + }; +} + +export type TChangeGasPrice = typeof changeGasPrice; +export function changeGasPrice(value: number): interfaces.ChangeGasPriceAction { + return { + type: TypeKeys.CONFIG_GAS_PRICE, + value + }; +} diff --git a/common/actions/config/actionTypes.ts b/common/actions/config/actionTypes.ts new file mode 100644 index 00000000..571227f8 --- /dev/null +++ b/common/actions/config/actionTypes.ts @@ -0,0 +1,25 @@ +import { TypeKeys } from './constants'; +/*** Change Language ***/ +export interface ChangeLanguageAction { + type: TypeKeys.CONFIG_LANGUAGE_CHANGE; + value: string; +} + +/*** Change Node ***/ +export interface ChangeNodeAction { + type: TypeKeys.CONFIG_NODE_CHANGE; + // FIXME $keyof? + value: string; +} + +/*** Change gas price ***/ +export interface ChangeGasPriceAction { + type: TypeKeys.CONFIG_GAS_PRICE; + value: number; +} + +/*** Union Type ***/ +export type ConfigAction = + | ChangeNodeAction + | ChangeLanguageAction + | ChangeGasPriceAction; diff --git a/common/actions/config/constants.ts b/common/actions/config/constants.ts new file mode 100644 index 00000000..33afe1ba --- /dev/null +++ b/common/actions/config/constants.ts @@ -0,0 +1,5 @@ +export enum TypeKeys { + CONFIG_LANGUAGE_CHANGE = 'CONFIG_LANGUAGE_CHANGE', + CONFIG_NODE_CHANGE = 'CONFIG_NODE_CHANGE', + CONFIG_GAS_PRICE = 'CONFIG_GAS_PRICE' +} diff --git a/common/actions/config/index.ts b/common/actions/config/index.ts new file mode 100644 index 00000000..113dd69a --- /dev/null +++ b/common/actions/config/index.ts @@ -0,0 +1,2 @@ +export * from './actionCreators'; +export * from './actionTypes'; diff --git a/common/actions/contracts.js b/common/actions/contracts.js deleted file mode 100644 index b17987e2..00000000 --- a/common/actions/contracts.js +++ /dev/null @@ -1,47 +0,0 @@ -// @flow - -/***** Access Contract *****/ -export type AccessContractAction = { - type: 'ACCESS_CONTRACT', - address: string, - abiJson: string -}; - -export function accessContract( - address: string, - abiJson: string -): AccessContractAction { - return { - type: 'ACCESS_CONTRACT', - address, - abiJson - }; -} - -/***** Set Interactive Contract *****/ -export type ABIFunctionField = { - name: string, - type: string -}; - -export type ABIFunction = { - name: string, - type: string, - constant: boolean, - inputs: Array, - outputs: Array -}; - -export type SetInteractiveContractAction = { - type: 'SET_INTERACTIVE_CONTRACT', - functions: Array -}; - -export function setInteractiveContract( - functions: Array -): SetInteractiveContractAction { - return { - type: 'SET_INTERACTIVE_CONTRACT', - functions - }; -} diff --git a/common/actions/contracts/actionCreators.ts b/common/actions/contracts/actionCreators.ts new file mode 100644 index 00000000..3ef77e59 --- /dev/null +++ b/common/actions/contracts/actionCreators.ts @@ -0,0 +1,22 @@ +import * as interfaces from './actionTypes'; +import { TypeKeys } from './constants'; + +export function accessContract( + address: string, + abiJson: string +): interfaces.AccessContractAction { + return { + type: TypeKeys.ACCESS_CONTRACT, + address, + abiJson + }; +} + +export function setInteractiveContract( + functions: interfaces.ABIFunction[] +): interfaces.SetInteractiveContractAction { + return { + type: TypeKeys.SET_INTERACTIVE_CONTRACT, + functions + }; +} diff --git a/common/actions/contracts/actionTypes.ts b/common/actions/contracts/actionTypes.ts new file mode 100644 index 00000000..7ae50608 --- /dev/null +++ b/common/actions/contracts/actionTypes.ts @@ -0,0 +1,31 @@ +import { TypeKeys } from './constants'; +/***** Set Interactive Contract *****/ +export interface ABIFunctionField { + name: string; + type: string; +} + +export interface ABIFunction { + name: string; + type: string; + constant: boolean; + inputs: ABIFunctionField[]; + outputs: ABIFunctionField[]; +} + +export interface SetInteractiveContractAction { + type: TypeKeys.SET_INTERACTIVE_CONTRACT; + functions: ABIFunction[]; +} + +/***** Access Contract *****/ +export interface AccessContractAction { + type: TypeKeys.ACCESS_CONTRACT; + address: string; + abiJson: string; +} + +/*** Union Type ***/ +export type ContractsAction = + | SetInteractiveContractAction + | AccessContractAction; diff --git a/common/actions/contracts/constants.ts b/common/actions/contracts/constants.ts new file mode 100644 index 00000000..3a23e1ef --- /dev/null +++ b/common/actions/contracts/constants.ts @@ -0,0 +1,4 @@ +export enum TypeKeys { + ACCESS_CONTRACT = 'ACCESS_CONTRACT', + SET_INTERACTIVE_CONTRACT = 'SET_INTERACTIVE_CONTRACT' +} diff --git a/common/actions/contracts/index.ts b/common/actions/contracts/index.ts new file mode 100644 index 00000000..fee14683 --- /dev/null +++ b/common/actions/contracts/index.ts @@ -0,0 +1,3 @@ +export * from './constants'; +export * from './actionTypes'; +export * from './actionCreators'; diff --git a/common/actions/customTokens.js b/common/actions/customTokens.js deleted file mode 100644 index 4512fe85..00000000 --- a/common/actions/customTokens.js +++ /dev/null @@ -1,31 +0,0 @@ -// @flow -import type { Token } from 'config/data'; - -/*** Add custom token ***/ -export type AddCustomTokenAction = { - type: 'CUSTOM_TOKEN_ADD', - payload: Token -}; - -export function addCustomToken(payload: Token): AddCustomTokenAction { - return { - type: 'CUSTOM_TOKEN_ADD', - payload - }; -} - -/*** Remove Custom Token ***/ -export type RemoveCustomTokenAction = { - type: 'CUSTOM_TOKEN_REMOVE', - payload: string -}; - -export function removeCustomToken(payload: string): RemoveCustomTokenAction { - return { - type: 'CUSTOM_TOKEN_REMOVE', - payload - }; -} - -/*** Union Type ***/ -export type CustomTokenAction = AddCustomTokenAction | RemoveCustomTokenAction; diff --git a/common/actions/customTokens/actionCreators.ts b/common/actions/customTokens/actionCreators.ts new file mode 100644 index 00000000..300bacde --- /dev/null +++ b/common/actions/customTokens/actionCreators.ts @@ -0,0 +1,24 @@ +import { Token } from 'config/data'; +import * as interfaces from './actionTypes'; +import { TypeKeys } from './constants'; + +export type TAddCustomToken = typeof addCustomToken; +export function addCustomToken( + payload: Token +): interfaces.AddCustomTokenAction { + return { + type: TypeKeys.CUSTOM_TOKEN_ADD, + payload + }; +} + +export type TRemoveCustomToken = typeof removeCustomToken; + +export function removeCustomToken( + payload: string +): interfaces.RemoveCustomTokenAction { + return { + type: TypeKeys.CUSTOM_TOKEN_REMOVE, + payload + }; +} diff --git a/common/actions/customTokens/actionTypes.ts b/common/actions/customTokens/actionTypes.ts new file mode 100644 index 00000000..2d214915 --- /dev/null +++ b/common/actions/customTokens/actionTypes.ts @@ -0,0 +1,15 @@ +import { Token } from 'config/data'; +import { TypeKeys } from './constants'; +/*** Add custom token ***/ +export interface AddCustomTokenAction { + type: TypeKeys.CUSTOM_TOKEN_ADD; + payload: Token; +} + +/*** Remove Custom Token ***/ +export interface RemoveCustomTokenAction { + type: TypeKeys.CUSTOM_TOKEN_REMOVE; + payload: string; +} + +export type CustomTokenAction = AddCustomTokenAction | RemoveCustomTokenAction; diff --git a/common/actions/customTokens/constants.ts b/common/actions/customTokens/constants.ts new file mode 100644 index 00000000..7a5dcaa3 --- /dev/null +++ b/common/actions/customTokens/constants.ts @@ -0,0 +1,4 @@ +export enum TypeKeys { + CUSTOM_TOKEN_ADD = 'CUSTOM_TOKEN_ADD', + CUSTOM_TOKEN_REMOVE = 'CUSTOM_TOKEN_REMOVE' +} diff --git a/common/actions/customTokens/index.ts b/common/actions/customTokens/index.ts new file mode 100644 index 00000000..113dd69a --- /dev/null +++ b/common/actions/customTokens/index.ts @@ -0,0 +1,2 @@ +export * from './actionCreators'; +export * from './actionTypes'; diff --git a/common/actions/deterministicWallets.js b/common/actions/deterministicWallets.js deleted file mode 100644 index ee30d31c..00000000 --- a/common/actions/deterministicWallets.js +++ /dev/null @@ -1,105 +0,0 @@ -// @flow -import type Big from 'bignumber.js'; - -export type TokenValues = { [string]: ?Big }; - -export type DeterministicWalletData = { - index: number, - address: string, - value?: Big, - tokenValues: TokenValues -}; - -/*** Get determinstic wallets ***/ -export type GetDeterministicWalletsAction = { - type: 'DW_GET_WALLETS', - payload: { - seed: ?string, - dPath: string, - publicKey: ?string, - chainCode: ?string, - limit: number, - offset: number - } -}; - -export type GetDeterministicWalletsArgs = { - seed: ?string, - dPath: string, - publicKey: ?string, - chainCode: ?string, - limit?: number, - offset?: number -}; - -export function getDeterministicWallets( - args: GetDeterministicWalletsArgs -): GetDeterministicWalletsAction { - const { seed, dPath, publicKey, chainCode, limit, offset } = args; - return { - type: 'DW_GET_WALLETS', - payload: { - seed, - dPath, - publicKey, - chainCode, - limit: limit || 5, - offset: offset || 0 - } - }; -} - -/*** Set deterministic wallets ***/ -export type SetDeterministicWalletsAction = { - type: 'DW_SET_WALLETS', - payload: DeterministicWalletData[] -}; - -export function setDeterministicWallets( - wallets: DeterministicWalletData[] -): SetDeterministicWalletsAction { - return { - type: 'DW_SET_WALLETS', - payload: wallets - }; -} - -/*** Set desired token ***/ -export type SetDesiredTokenAction = { - type: 'DW_SET_DESIRED_TOKEN', - payload: ?string -}; - -export function setDesiredToken(token: ?string): SetDesiredTokenAction { - return { - type: 'DW_SET_DESIRED_TOKEN', - payload: token - }; -} - -/*** Set wallet values ***/ -export type UpdateDeterministicWalletArgs = { - address: string, - value: ?Big, - tokenValues: ?TokenValues -}; - -export type UpdateDeterministicWalletAction = { - type: 'DW_UPDATE_WALLET', - payload: UpdateDeterministicWalletArgs -}; - -export function updateDeterministicWallet( - args: UpdateDeterministicWalletArgs -): UpdateDeterministicWalletAction { - return { - type: 'DW_UPDATE_WALLET', - payload: args - }; -} - -/*** Union Type ***/ -export type DeterministicWalletAction = - | GetDeterministicWalletsAction - | UpdateDeterministicWalletAction - | SetDesiredTokenAction; diff --git a/common/actions/deterministicWallets/actionCreators.ts b/common/actions/deterministicWallets/actionCreators.ts new file mode 100644 index 00000000..fb043d7c --- /dev/null +++ b/common/actions/deterministicWallets/actionCreators.ts @@ -0,0 +1,45 @@ +import * as interfaces from './actionTypes'; +import { TypeKeys } from './constants'; +export function getDeterministicWallets( + args: interfaces.GetDeterministicWalletsArgs +): interfaces.GetDeterministicWalletsAction { + const { seed, dPath, publicKey, chainCode, limit, offset } = args; + return { + type: TypeKeys.DW_GET_WALLETS, + payload: { + seed, + dPath, + publicKey, + chainCode, + limit: limit || 5, + offset: offset || 0 + } + }; +} + +export function setDeterministicWallets( + wallets: interfaces.DeterministicWalletData[] +): interfaces.SetDeterministicWalletsAction { + return { + type: TypeKeys.DW_SET_WALLETS, + payload: wallets + }; +} + +export function setDesiredToken( + token: string | undefined +): interfaces.SetDesiredTokenAction { + return { + type: TypeKeys.DW_SET_DESIRED_TOKEN, + payload: token + }; +} + +export function updateDeterministicWallet( + args: interfaces.UpdateDeterministicWalletArgs +): interfaces.UpdateDeterministicWalletAction { + return { + type: TypeKeys.DW_UPDATE_WALLET, + payload: args + }; +} diff --git a/common/actions/deterministicWallets/actionTypes.ts b/common/actions/deterministicWallets/actionTypes.ts new file mode 100644 index 00000000..bc601b50 --- /dev/null +++ b/common/actions/deterministicWallets/actionTypes.ts @@ -0,0 +1,66 @@ +import { BigNumber } from 'bignumber.js'; + +export interface TokenValues { + [key: string]: BigNumber; +} + +export interface DeterministicWalletData { + index: number; + address: string; + value?: BigNumber; + tokenValues: TokenValues; +} + +/*** Get determinstic wallets ***/ +export interface GetDeterministicWalletsAction { + type: 'DW_GET_WALLETS'; + payload: { + seed?: string; + dPath: string; + publicKey?: string; + chainCode?: string; + limit: number; + offset: number; + }; +} + +/*** Set deterministic wallets ***/ +export interface SetDeterministicWalletsAction { + type: 'DW_SET_WALLETS'; + payload: DeterministicWalletData[]; +} + +/*** Set desired token ***/ +export interface SetDesiredTokenAction { + type: 'DW_SET_DESIRED_TOKEN'; + payload: string | undefined; +} + +/*** Set wallet values ***/ +export interface UpdateDeterministicWalletArgs { + address: string; + value?: BigNumber; + tokenValues?: TokenValues; + index?: any; +} + +export interface UpdateDeterministicWalletAction { + type: 'DW_UPDATE_WALLET'; + payload: UpdateDeterministicWalletArgs; +} + +export interface GetDeterministicWalletsArgs { + seed?: string; + dPath: string; + publicKey?: string; + chainCode?: string; + limit?: number; + offset?: number; +} + +/*** Union Type ***/ +export type DeterministicWalletAction = + | SetDeterministicWalletsAction + | GetDeterministicWalletsAction + | UpdateDeterministicWalletAction + | SetDesiredTokenAction; diff --git a/common/actions/deterministicWallets/constants.ts b/common/actions/deterministicWallets/constants.ts new file mode 100644 index 00000000..b7e566a5 --- /dev/null +++ b/common/actions/deterministicWallets/constants.ts @@ -0,0 +1,6 @@ +export enum TypeKeys { + DW_GET_WALLETS = 'DW_GET_WALLETS', + DW_SET_WALLETS = 'DW_SET_WALLETS', + DW_SET_DESIRED_TOKEN = 'DW_SET_DESIRED_TOKEN', + DW_UPDATE_WALLET = 'DW_UPDATE_WALLET' +} diff --git a/common/actions/deterministicWallets/index.ts b/common/actions/deterministicWallets/index.ts new file mode 100644 index 00000000..2608a18e --- /dev/null +++ b/common/actions/deterministicWallets/index.ts @@ -0,0 +1,2 @@ +export * from './actionTypes'; +export * from './actionCreators'; diff --git a/common/actions/ens.js b/common/actions/ens.js deleted file mode 100644 index 102bfcb3..00000000 --- a/common/actions/ens.js +++ /dev/null @@ -1,39 +0,0 @@ -// @flow - -/*** Resolve ENS name ***/ -export type ResolveEnsNameAction = { - type: 'ENS_RESOLVE', - payload: string -}; - -export function resolveEnsName(name: string): ResolveEnsNameAction { - return { - type: 'ENS_RESOLVE', - payload: name - }; -} - -/*** Cache ENS address ***/ -export type CacheEnsAddressAction = { - type: 'ENS_CACHE', - payload: { - ensName: string, - address: string - } -}; - -export function cacheEnsAddress( - ensName: string, - address: string -): CacheEnsAddressAction { - return { - type: 'ENS_CACHE', - payload: { - ensName, - address - } - }; -} - -/*** Union Type ***/ -export type EnsAction = ResolveEnsNameAction | CacheEnsAddressAction; diff --git a/common/actions/ens/actionCreators.ts b/common/actions/ens/actionCreators.ts new file mode 100644 index 00000000..7bfb11c7 --- /dev/null +++ b/common/actions/ens/actionCreators.ts @@ -0,0 +1,22 @@ +import * as interfaces from './actionTypes'; +import * as constants from './constants'; + +export function resolveEnsName(name: string): interfaces.ResolveEnsNameAction { + return { + type: constants.ENS_RESOLVE, + payload: name + }; +} + +export function cacheEnsAddress( + ensName: string, + address: string +): interfaces.CacheEnsAddressAction { + return { + type: constants.ENS_CACHE, + payload: { + ensName, + address + } + }; +} diff --git a/common/actions/ens/actionTypes.ts b/common/actions/ens/actionTypes.ts new file mode 100644 index 00000000..6489772a --- /dev/null +++ b/common/actions/ens/actionTypes.ts @@ -0,0 +1,19 @@ +import * as constants from './constants'; + +/*** Resolve ENS name ***/ +export interface ResolveEnsNameAction { + type: 'ENS_RESOLVE'; + payload: string; +} + +/*** Cache ENS address ***/ +export interface CacheEnsAddressAction { + type: 'ENS_CACHE'; + payload: { + ensName: string; + address: string; + }; +} + +/*** Union Type ***/ +export type EnsAction = ResolveEnsNameAction | CacheEnsAddressAction; diff --git a/common/actions/ens/constants.ts b/common/actions/ens/constants.ts new file mode 100644 index 00000000..2948a37a --- /dev/null +++ b/common/actions/ens/constants.ts @@ -0,0 +1,2 @@ +export const ENS_RESOLVE = 'ENS_RESOLVE'; +export const ENS_CACHE = 'ENS_CACHE'; diff --git a/common/actions/ens/index.ts b/common/actions/ens/index.ts new file mode 100644 index 00000000..fee14683 --- /dev/null +++ b/common/actions/ens/index.ts @@ -0,0 +1,3 @@ +export * from './constants'; +export * from './actionTypes'; +export * from './actionCreators'; diff --git a/common/actions/generateWallet.js b/common/actions/generateWallet.js deleted file mode 100644 index d441fe16..00000000 --- a/common/actions/generateWallet.js +++ /dev/null @@ -1,38 +0,0 @@ -// @flow -import { PrivKeyWallet } from 'libs/wallet'; - -/*** Generate Wallet File ***/ -export type GenerateNewWalletAction = { - type: 'GENERATE_WALLET_GENERATE_WALLET', - wallet: PrivKeyWallet, - password: string -}; - -export function generateNewWallet(password: string): GenerateNewWalletAction { - return { - type: 'GENERATE_WALLET_GENERATE_WALLET', - wallet: PrivKeyWallet.generate(), - password - }; -} - -/*** Confirm Continue To Paper ***/ -export type ContinueToPaperAction = { - type: 'GENERATE_WALLET_CONTINUE_TO_PAPER' -}; - -export function continueToPaper(): ContinueToPaperAction { - return { type: 'GENERATE_WALLET_CONTINUE_TO_PAPER' }; -} - -/*** Reset Generate Wallet ***/ -export type ResetGenerateWalletAction = { - type: 'GENERATE_WALLET_RESET' -}; - -export function resetGenerateWallet(): ResetGenerateWalletAction { - return { type: 'GENERATE_WALLET_RESET' }; -} - -/*** Action Union ***/ -export type GenerateWalletAction = GenerateWalletAction; diff --git a/common/actions/generateWallet/actionCreators.ts b/common/actions/generateWallet/actionCreators.ts new file mode 100644 index 00000000..896d6ffc --- /dev/null +++ b/common/actions/generateWallet/actionCreators.ts @@ -0,0 +1,24 @@ +import { PrivKeyWallet } from 'libs/wallet'; +import * as interfaces from './actionTypes'; +import { TypeKeys } from './constants'; + +export type TGenerateNewWallet = typeof generateNewWallet; +export function generateNewWallet( + password: string +): interfaces.GenerateNewWalletAction { + return { + type: TypeKeys.GENERATE_WALLET_GENERATE_WALLET, + wallet: PrivKeyWallet.generate(), + password + }; +} + +export type TContinueToPaper = typeof continueToPaper; +export function continueToPaper(): interfaces.ContinueToPaperAction { + return { type: TypeKeys.GENERATE_WALLET_CONTINUE_TO_PAPER }; +} + +export type TResetGenerateWallet = typeof resetGenerateWallet; +export function resetGenerateWallet(): interfaces.ResetGenerateWalletAction { + return { type: TypeKeys.GENERATE_WALLET_RESET }; +} diff --git a/common/actions/generateWallet/actionTypes.ts b/common/actions/generateWallet/actionTypes.ts new file mode 100644 index 00000000..9bbecb70 --- /dev/null +++ b/common/actions/generateWallet/actionTypes.ts @@ -0,0 +1,25 @@ +import { PrivKeyWallet } from 'libs/wallet'; +import { TypeKeys } from './constants'; + +/*** Generate Wallet File ***/ +export interface GenerateNewWalletAction { + type: TypeKeys.GENERATE_WALLET_GENERATE_WALLET; + wallet: PrivKeyWallet; + password: string; +} + +/*** Reset Generate Wallet ***/ +export interface ResetGenerateWalletAction { + type: TypeKeys.GENERATE_WALLET_RESET; +} + +/*** Confirm Continue To Paper ***/ +export interface ContinueToPaperAction { + type: TypeKeys.GENERATE_WALLET_CONTINUE_TO_PAPER; +} + +/*** Action Union ***/ +export type GenerateWalletAction = + | GenerateNewWalletAction + | ContinueToPaperAction + | ResetGenerateWalletAction; diff --git a/common/actions/generateWallet/constants.ts b/common/actions/generateWallet/constants.ts new file mode 100644 index 00000000..d872f337 --- /dev/null +++ b/common/actions/generateWallet/constants.ts @@ -0,0 +1,5 @@ +export enum TypeKeys { + GENERATE_WALLET_GENERATE_WALLET = 'GENERATE_WALLET_GENERATE_WALLET', + GENERATE_WALLET_CONTINUE_TO_PAPER = 'GENERATE_WALLET_CONTINUE_TO_PAPER', + GENERATE_WALLET_RESET = 'GENERATE_WALLET_RESET' +} diff --git a/common/actions/generateWallet/index.ts b/common/actions/generateWallet/index.ts new file mode 100644 index 00000000..fee14683 --- /dev/null +++ b/common/actions/generateWallet/index.ts @@ -0,0 +1,3 @@ +export * from './constants'; +export * from './actionTypes'; +export * from './actionCreators'; diff --git a/common/actions/notifications.js b/common/actions/notifications.js deleted file mode 100644 index 5c0cee61..00000000 --- a/common/actions/notifications.js +++ /dev/null @@ -1,53 +0,0 @@ -// @flow -import type { Element } from 'react'; - -/*** Shared types ***/ -export type NOTIFICATION_LEVEL = 'danger' | 'warning' | 'success' | 'info'; -export type INFINITY = 'infinity'; - -export type Notification = { - level: NOTIFICATION_LEVEL, - msg: Element<*> | string, - duration?: number | INFINITY -}; - -/*** Show Notification ***/ -export type ShowNotificationAction = { - type: 'SHOW_NOTIFICATION', - payload: Notification -}; - -export function showNotification( - level: NOTIFICATION_LEVEL = 'info', - msg: Element<*> | string, - duration?: number | INFINITY -): ShowNotificationAction { - return { - type: 'SHOW_NOTIFICATION', - payload: { - level, - msg, - duration - } - }; -} - -/*** Close notification ***/ -export type CloseNotificationAction = { - type: 'CLOSE_NOTIFICATION', - payload: Notification -}; - -export function closeNotification( - notification: Notification -): CloseNotificationAction { - return { - type: 'CLOSE_NOTIFICATION', - payload: notification - }; -} - -/*** Union Type ***/ -export type NotificationsAction = - | ShowNotificationAction - | CloseNotificationAction; diff --git a/common/actions/notifications/actionCreators.ts b/common/actions/notifications/actionCreators.ts new file mode 100644 index 00000000..c439c65d --- /dev/null +++ b/common/actions/notifications/actionCreators.ts @@ -0,0 +1,29 @@ +import { ReactElement } from 'react'; +import * as types from './actionTypes'; +import { TypeKeys } from './constants'; + +export type TShowNotification = typeof showNotification; +export function showNotification( + level: types.NOTIFICATION_LEVEL = 'info', + msg: ReactElement | string, + duration?: number | types.INFINITY +): types.ShowNotificationAction { + return { + type: TypeKeys.SHOW_NOTIFICATION, + payload: { + level, + msg, + duration + } + }; +} + +export type TCloseNotification = typeof closeNotification; +export function closeNotification( + notification: types.Notification +): types.CloseNotificationAction { + return { + type: TypeKeys.CLOSE_NOTIFICATION, + payload: notification + }; +} diff --git a/common/actions/notifications/actionTypes.ts b/common/actions/notifications/actionTypes.ts new file mode 100644 index 00000000..939cc1af --- /dev/null +++ b/common/actions/notifications/actionTypes.ts @@ -0,0 +1,28 @@ +import { ReactElement } from 'react'; +import { TypeKeys } from './constants'; +/*** Shared types ***/ +export type NOTIFICATION_LEVEL = 'danger' | 'warning' | 'success' | 'info'; +export type INFINITY = 'infinity'; + +export interface Notification { + level: NOTIFICATION_LEVEL; + msg: ReactElement | string; + duration?: number | INFINITY; +} + +/*** Close notification ***/ +export interface CloseNotificationAction { + type: TypeKeys.CLOSE_NOTIFICATION; + payload: Notification; +} + +/*** Show Notification ***/ +export interface ShowNotificationAction { + type: TypeKeys.SHOW_NOTIFICATION; + payload: Notification; +} + +/*** Union Type ***/ +export type NotificationsAction = + | ShowNotificationAction + | CloseNotificationAction; diff --git a/common/actions/notifications/constants.ts b/common/actions/notifications/constants.ts new file mode 100644 index 00000000..8529f18e --- /dev/null +++ b/common/actions/notifications/constants.ts @@ -0,0 +1,4 @@ +export enum TypeKeys { + SHOW_NOTIFICATION = 'SHOW_NOTIFICATION', + CLOSE_NOTIFICATION = 'CLOSE_NOTIFICATION' +} diff --git a/common/actions/notifications/index.ts b/common/actions/notifications/index.ts new file mode 100644 index 00000000..2608a18e --- /dev/null +++ b/common/actions/notifications/index.ts @@ -0,0 +1,2 @@ +export * from './actionTypes'; +export * from './actionCreators'; diff --git a/common/actions/rates.js b/common/actions/rates.js deleted file mode 100644 index 2255c832..00000000 --- a/common/actions/rates.js +++ /dev/null @@ -1,29 +0,0 @@ -// @flow - -export type FiatRequestedRatesAction = { - type: 'RATES_FIAT_REQUESTED' -}; - -export function fiatRequestedRates() { - return { - type: 'RATES_FIAT_REQUESTED' - }; -} - -/*** Set rates ***/ -export type FiatSucceededRatesAction = { - type: 'RATES_FIAT_SUCCEEDED', - payload: { [string]: number } -}; - -export function fiatSucceededRates(payload: { - [string]: number -}): FiatSucceededRatesAction { - return { - type: 'RATES_FIAT_SUCCEEDED', - payload - }; -} - -/*** Union Type ***/ -export type RatesAction = FiatSucceededRatesAction | FiatRequestedRatesAction; diff --git a/common/actions/rates/actionCreators.ts b/common/actions/rates/actionCreators.ts new file mode 100644 index 00000000..00a5401c --- /dev/null +++ b/common/actions/rates/actionCreators.ts @@ -0,0 +1,19 @@ +import * as interfaces from './actionTypes'; +import { TypeKeys } from './constants'; + +export type TFiatRequestedRates = typeof fiatRequestedRates; +export function fiatRequestedRates(): interfaces.FiatRequestedRatesAction { + return { + type: TypeKeys.RATES_FIAT_REQUESTED + }; +} + +export type TFiatSucceededRates = typeof fiatSucceededRates; +export function fiatSucceededRates(payload: { + [key: string]: number; +}): interfaces.FiatSucceededRatesAction { + return { + type: TypeKeys.RATES_FIAT_SUCCEEDED, + payload + }; +} diff --git a/common/actions/rates/actionTypes.ts b/common/actions/rates/actionTypes.ts new file mode 100644 index 00000000..7ab69077 --- /dev/null +++ b/common/actions/rates/actionTypes.ts @@ -0,0 +1,13 @@ +import { TypeKeys } from './constants'; +export interface FiatRequestedRatesAction { + type: TypeKeys.RATES_FIAT_REQUESTED; +} + +/*** Set rates ***/ +export interface FiatSucceededRatesAction { + type: TypeKeys.RATES_FIAT_SUCCEEDED; + payload: { [key: string]: number }; +} + +/*** Union Type ***/ +export type RatesAction = FiatSucceededRatesAction | FiatRequestedRatesAction; diff --git a/common/actions/rates/constants.ts b/common/actions/rates/constants.ts new file mode 100644 index 00000000..a42b4755 --- /dev/null +++ b/common/actions/rates/constants.ts @@ -0,0 +1,4 @@ +export enum TypeKeys { + RATES_FIAT_REQUESTED = 'RATES_FIAT_REQUESTED', + RATES_FIAT_SUCCEEDED = 'RATES_FIAT_SUCCEEDED' +} diff --git a/common/actions/rates/index.ts b/common/actions/rates/index.ts new file mode 100644 index 00000000..113dd69a --- /dev/null +++ b/common/actions/rates/index.ts @@ -0,0 +1,2 @@ +export * from './actionCreators'; +export * from './actionTypes'; diff --git a/common/actions/swap.js b/common/actions/swap.js deleted file mode 100644 index a9027669..00000000 --- a/common/actions/swap.js +++ /dev/null @@ -1,169 +0,0 @@ -// @flow -import type { - OriginKindSwapAction, - DestinationKindSwapAction, - OriginAmountSwapAction, - DestinationAmountSwapAction, - LoadBityRatesSucceededSwapAction, - DestinationAddressSwapAction, - BityOrderCreateSucceededSwapAction, - BityOrderCreateRequestedSwapAction, - OrderStatusSucceededSwapAction, - ChangeStepSwapAction, - Pairs, - RestartSwapAction, - LoadBityRatesRequestedSwapAction, - StopLoadBityRatesSwapAction, - BityOrderResponse, - BityOrderPostResponse, - OrderStatusRequestedSwapAction, - StopOrderTimerSwapAction, - StartOrderTimerSwapAction, - StartPollBityOrderStatusAction, - StopPollBityOrderStatusAction -} from './swapTypes'; - -export function changeStepSwap(value: number): ChangeStepSwapAction { - return { - type: 'SWAP_STEP', - value - }; -} - -export function originKindSwap(value: string): OriginKindSwapAction { - return { - type: 'SWAP_ORIGIN_KIND', - value - }; -} - -export function destinationKindSwap(value: string): DestinationKindSwapAction { - return { - type: 'SWAP_DESTINATION_KIND', - value - }; -} - -export function originAmountSwap(value: ?number): OriginAmountSwapAction { - return { - type: 'SWAP_ORIGIN_AMOUNT', - value - }; -} - -export function destinationAmountSwap( - value: ?number -): DestinationAmountSwapAction { - return { - type: 'SWAP_DESTINATION_AMOUNT', - value - }; -} - -export function loadBityRatesSucceededSwap( - value: Pairs -): LoadBityRatesSucceededSwapAction { - return { - type: 'SWAP_LOAD_BITY_RATES_SUCCEEDED', - value - }; -} - -export function destinationAddressSwap( - value: ?string -): DestinationAddressSwapAction { - return { - type: 'SWAP_DESTINATION_ADDRESS', - value - }; -} - -export function restartSwap(): RestartSwapAction { - return { - type: 'SWAP_RESTART' - }; -} - -export function loadBityRatesRequestedSwap(): LoadBityRatesRequestedSwapAction { - return { - type: 'SWAP_LOAD_BITY_RATES_REQUESTED' - }; -} - -export function stopLoadBityRatesSwap(): StopLoadBityRatesSwapAction { - return { - type: 'SWAP_STOP_LOAD_BITY_RATES' - }; -} - -export function orderTimeSwap(value: number) { - return { - type: 'SWAP_ORDER_TIME', - value - }; -} - -export function bityOrderCreateSucceededSwap( - payload: BityOrderPostResponse -): BityOrderCreateSucceededSwapAction { - return { - type: 'SWAP_BITY_ORDER_CREATE_SUCCEEDED', - payload - }; -} - -export function bityOrderCreateRequestedSwap( - amount: number, - destinationAddress: string, - pair: string, - mode: number = 0 -): BityOrderCreateRequestedSwapAction { - return { - type: 'SWAP_ORDER_CREATE_REQUESTED', - payload: { - amount, - destinationAddress, - pair, - mode - } - }; -} - -export function orderStatusSucceededSwap( - payload: BityOrderResponse -): OrderStatusSucceededSwapAction { - return { - type: 'SWAP_BITY_ORDER_STATUS_SUCCEEDED', - payload - }; -} - -export function orderStatusRequestedSwap(): OrderStatusRequestedSwapAction { - return { - type: 'SWAP_BITY_ORDER_STATUS_REQUESTED' - }; -} - -export function startOrderTimerSwap(): StartOrderTimerSwapAction { - return { - type: 'SWAP_ORDER_START_TIMER' - }; -} - -export function stopOrderTimerSwap(): StopOrderTimerSwapAction { - return { - type: 'SWAP_ORDER_STOP_TIMER' - }; -} - -export function startPollBityOrderStatus(): StartPollBityOrderStatusAction { - return { - type: 'SWAP_START_POLL_BITY_ORDER_STATUS' - }; -} - -export function stopPollBityOrderStatus(): StopPollBityOrderStatusAction { - return { - type: 'SWAP_STOP_POLL_BITY_ORDER_STATUS' - }; -} diff --git a/common/actions/swap/actionCreators.ts b/common/actions/swap/actionCreators.ts new file mode 100644 index 00000000..71557b75 --- /dev/null +++ b/common/actions/swap/actionCreators.ts @@ -0,0 +1,182 @@ +import * as interfaces from './actionTypes'; +import { TypeKeys } from './constants'; + +export type TChangeStepSwap = typeof changeStepSwap; +export function changeStepSwap( + payload: number +): interfaces.ChangeStepSwapAction { + return { + type: TypeKeys.SWAP_STEP, + payload + }; +} + +export type TOriginKindSwap = typeof originKindSwap; +export function originKindSwap( + payload: string +): interfaces.OriginKindSwapAction { + return { + type: TypeKeys.SWAP_ORIGIN_KIND, + payload + }; +} + +export type TDestinationKindSwap = typeof destinationKindSwap; +export function destinationKindSwap( + payload: string +): interfaces.DestinationKindSwapAction { + return { + type: TypeKeys.SWAP_DESTINATION_KIND, + payload + }; +} + +export type TOriginAmountSwap = typeof originAmountSwap; +export function originAmountSwap( + payload?: number | null +): interfaces.OriginAmountSwapAction { + return { + type: TypeKeys.SWAP_ORIGIN_AMOUNT, + payload + }; +} + +export type TDestinationAmountSwap = typeof destinationAmountSwap; +export function destinationAmountSwap( + payload?: number | null +): interfaces.DestinationAmountSwapAction { + return { + type: TypeKeys.SWAP_DESTINATION_AMOUNT, + payload + }; +} + +export type TLoadBityRatesSucceededSwap = typeof loadBityRatesSucceededSwap; +export function loadBityRatesSucceededSwap( + payload: interfaces.Pairs +): interfaces.LoadBityRatesSucceededSwapAction { + return { + type: TypeKeys.SWAP_LOAD_BITY_RATES_SUCCEEDED, + payload + }; +} + +export type TDestinationAddressSwap = typeof destinationAddressSwap; +export function destinationAddressSwap( + payload?: string +): interfaces.DestinationAddressSwapAction { + return { + type: TypeKeys.SWAP_DESTINATION_ADDRESS, + payload + }; +} + +export type TRestartSwap = typeof restartSwap; +export function restartSwap(): interfaces.RestartSwapAction { + return { + type: TypeKeys.SWAP_RESTART + }; +} + +export type TLoadBityRatesRequestedSwap = typeof loadBityRatesRequestedSwap; +export function loadBityRatesRequestedSwap(): interfaces.LoadBityRatesRequestedSwapAction { + return { + type: TypeKeys.SWAP_LOAD_BITY_RATES_REQUESTED + }; +} + +export type TStopLoadBityRatesSwap = typeof stopLoadBityRatesSwap; +export function stopLoadBityRatesSwap(): interfaces.StopLoadBityRatesSwapAction { + return { + type: TypeKeys.SWAP_STOP_LOAD_BITY_RATES + }; +} + +export type TOrderTimeSwap = typeof orderTimeSwap; +export function orderTimeSwap( + payload: number +): interfaces.OrderSwapTimeSwapAction { + return { + type: TypeKeys.SWAP_ORDER_TIME, + payload + }; +} + +export type TBityOrderCreateSucceededSwap = typeof bityOrderCreateSucceededSwap; +export function bityOrderCreateSucceededSwap( + payload: interfaces.BityOrderPostResponse +): interfaces.BityOrderCreateSucceededSwapAction { + return { + type: TypeKeys.SWAP_BITY_ORDER_CREATE_SUCCEEDED, + payload + }; +} + +export type TBityOrderCreateRequestedSwap = typeof bityOrderCreateRequestedSwap; +export function bityOrderCreateRequestedSwap( + amount: number, + destinationAddress: string, + pair: string, + mode: number = 0 +): interfaces.BityOrderCreateRequestedSwapAction { + return { + type: TypeKeys.SWAP_ORDER_CREATE_REQUESTED, + payload: { + amount, + destinationAddress, + pair, + mode + } + }; +} + +export function bityOrderCreateFailedSwap(): interfaces.BityOrderCreateFailedSwapAction { + return { + type: TypeKeys.SWAP_ORDER_CREATE_FAILED + }; +} + +export type TOrderStatusSucceededSwap = typeof orderStatusSucceededSwap; +export function orderStatusSucceededSwap( + payload: interfaces.BityOrderResponse +): interfaces.OrderStatusSucceededSwapAction { + return { + type: TypeKeys.SWAP_BITY_ORDER_STATUS_SUCCEEDED, + payload + }; +} + +export type TOrderStatusRequestedSwap = typeof orderStatusRequestedSwap; +export function orderStatusRequestedSwap(): interfaces.OrderStatusRequestedSwapAction { + return { + type: TypeKeys.SWAP_BITY_ORDER_STATUS_REQUESTED + }; +} + +export type TStartOrderTimerSwap = typeof startOrderTimerSwap; +export function startOrderTimerSwap(): interfaces.StartOrderTimerSwapAction { + return { + type: TypeKeys.SWAP_ORDER_START_TIMER + }; +} + +export type TStopOrderTimerSwap = typeof stopOrderTimerSwap; +export function stopOrderTimerSwap(): interfaces.StopOrderTimerSwapAction { + return { + type: TypeKeys.SWAP_ORDER_STOP_TIMER + }; +} + +export type TStartPollBityOrderStatus = typeof startPollBityOrderStatus; +export function startPollBityOrderStatus(): interfaces.StartPollBityOrderStatusAction { + return { + type: TypeKeys.SWAP_START_POLL_BITY_ORDER_STATUS + }; +} + +export type TStopPollBityOrderStatus = typeof stopPollBityOrderStatus; +export function stopPollBityOrderStatus(): interfaces.StopPollBityOrderStatusAction { + return { + type: TypeKeys.SWAP_STOP_POLL_BITY_ORDER_STATUS + }; +} diff --git a/common/actions/swap/actionTypes.ts b/common/actions/swap/actionTypes.ts new file mode 100644 index 00000000..75ef19f4 --- /dev/null +++ b/common/actions/swap/actionTypes.ts @@ -0,0 +1,152 @@ +import { TypeKeys } from './constants'; +export interface Pairs { + ETHBTC: number; + ETHREP: number; + BTCETH: number; + BTCREP: number; +} + +export interface OriginKindSwapAction { + type: TypeKeys.SWAP_ORIGIN_KIND; + payload: string; +} + +export interface DestinationKindSwapAction { + type: TypeKeys.SWAP_DESTINATION_KIND; + payload: string; +} + +export interface OriginAmountSwapAction { + type: TypeKeys.SWAP_ORIGIN_AMOUNT; + payload?: number | null; +} + +export interface DestinationAmountSwapAction { + type: TypeKeys.SWAP_DESTINATION_AMOUNT; + payload?: number | null; +} + +export interface LoadBityRatesSucceededSwapAction { + type: TypeKeys.SWAP_LOAD_BITY_RATES_SUCCEEDED; + payload: Pairs; +} + +export interface DestinationAddressSwapAction { + type: TypeKeys.SWAP_DESTINATION_ADDRESS; + payload?: string; +} + +export interface RestartSwapAction { + type: TypeKeys.SWAP_RESTART; +} + +export interface LoadBityRatesRequestedSwapAction { + type: TypeKeys.SWAP_LOAD_BITY_RATES_REQUESTED; + payload?: null; +} + +export interface ChangeStepSwapAction { + type: TypeKeys.SWAP_STEP; + payload: number; +} + +export interface StopLoadBityRatesSwapAction { + type: TypeKeys.SWAP_STOP_LOAD_BITY_RATES; +} + +export interface OrderSwapTimeSwapAction { + type: TypeKeys.SWAP_ORDER_TIME; + payload: number; +} + +export interface BityOrderCreateRequestedSwapAction { + type: TypeKeys.SWAP_ORDER_CREATE_REQUESTED; + payload: { + amount: number; + destinationAddress: string; + pair: string; + mode: number; + }; +} + +interface BityOrderInput { + amount: string; + currency: string; + reference: string; + status: string; +} + +interface BityOrderOutput { + amount: string; + currency: string; + reference: string; + status: string; +} + +export interface BityOrderResponse { + input: BityOrderInput; + output: BityOrderOutput; + status: string; +} + +export type BityOrderPostResponse = BityOrderResponse & { + payment_address: string; + status: string; + input: BityOrderInput; + output: BityOrderOutput; + timestamp_created: string; + validFor: number; + id: string; +}; + +export interface BityOrderCreateSucceededSwapAction { + type: TypeKeys.SWAP_BITY_ORDER_CREATE_SUCCEEDED; + payload: BityOrderPostResponse; +} + +export interface BityOrderCreateFailedSwapAction { + type: TypeKeys.SWAP_ORDER_CREATE_FAILED; +} +export interface OrderStatusRequestedSwapAction { + type: TypeKeys.SWAP_BITY_ORDER_STATUS_REQUESTED; +} + +export interface OrderStatusSucceededSwapAction { + type: TypeKeys.SWAP_BITY_ORDER_STATUS_SUCCEEDED; + payload: BityOrderResponse; +} + +export interface StartOrderTimerSwapAction { + type: TypeKeys.SWAP_ORDER_START_TIMER; +} + +export interface StopOrderTimerSwapAction { + type: TypeKeys.SWAP_ORDER_STOP_TIMER; +} + +export interface StartPollBityOrderStatusAction { + type: TypeKeys.SWAP_START_POLL_BITY_ORDER_STATUS; +} + +export interface StopPollBityOrderStatusAction { + type: TypeKeys.SWAP_STOP_POLL_BITY_ORDER_STATUS; +} + +/*** Action Type Union ***/ +export type SwapAction = + | ChangeStepSwapAction + | OriginKindSwapAction + | DestinationKindSwapAction + | OriginAmountSwapAction + | DestinationAmountSwapAction + | LoadBityRatesSucceededSwapAction + | DestinationAddressSwapAction + | RestartSwapAction + | LoadBityRatesRequestedSwapAction + | StopLoadBityRatesSwapAction + | BityOrderCreateRequestedSwapAction + | BityOrderCreateSucceededSwapAction + | OrderStatusSucceededSwapAction + | StartPollBityOrderStatusAction + | BityOrderCreateFailedSwapAction + | OrderSwapTimeSwapAction; diff --git a/common/actions/swap/constants.ts b/common/actions/swap/constants.ts new file mode 100644 index 00000000..e343436f --- /dev/null +++ b/common/actions/swap/constants.ts @@ -0,0 +1,22 @@ +export enum TypeKeys { + SWAP_STEP = 'SWAP_STEP', + SWAP_ORIGIN_KIND = 'SWAP_ORIGIN_KIND', + SWAP_DESTINATION_KIND = 'SWAP_DESTINATION_KIND', + SWAP_ORIGIN_AMOUNT = 'SWAP_ORIGIN_AMOUNT', + SWAP_DESTINATION_AMOUNT = 'SWAP_DESTINATION_AMOUNT', + SWAP_LOAD_BITY_RATES_SUCCEEDED = 'SWAP_LOAD_BITY_RATES_SUCCEEDED', + SWAP_DESTINATION_ADDRESS = 'SWAP_DESTINATION_ADDRESS', + SWAP_RESTART = 'SWAP_RESTART', + SWAP_LOAD_BITY_RATES_REQUESTED = 'SWAP_LOAD_BITY_RATES_REQUESTED', + SWAP_STOP_LOAD_BITY_RATES = 'SWAP_STOP_LOAD_BITY_RATES', + SWAP_ORDER_TIME = 'SWAP_ORDER_TIME', + SWAP_BITY_ORDER_CREATE_SUCCEEDED = 'SWAP_BITY_ORDER_CREATE_SUCCEEDED', + SWAP_BITY_ORDER_STATUS_SUCCEEDED = 'SWAP_BITY_ORDER_STATUS_SUCCEEDED', + SWAP_BITY_ORDER_STATUS_REQUESTED = 'SWAP_BITY_ORDER_STATUS_REQUESTED', + SWAP_ORDER_START_TIMER = 'SWAP_ORDER_START_TIMER', + SWAP_ORDER_STOP_TIMER = 'SWAP_ORDER_STOP_TIMER', + SWAP_START_POLL_BITY_ORDER_STATUS = 'SWAP_START_POLL_BITY_ORDER_STATUS', + SWAP_STOP_POLL_BITY_ORDER_STATUS = 'SWAP_STOP_POLL_BITY_ORDER_STATUS', + SWAP_ORDER_CREATE_REQUESTED = 'SWAP_ORDER_CREATE_REQUESTED', + SWAP_ORDER_CREATE_FAILED = 'SWAP_ORDER_CREATE_FAILED' +} diff --git a/common/actions/swap/index.ts b/common/actions/swap/index.ts new file mode 100644 index 00000000..2608a18e --- /dev/null +++ b/common/actions/swap/index.ts @@ -0,0 +1,2 @@ +export * from './actionTypes'; +export * from './actionCreators'; diff --git a/common/actions/swapTypes.js b/common/actions/swapTypes.js deleted file mode 100644 index c9001734..00000000 --- a/common/actions/swapTypes.js +++ /dev/null @@ -1,128 +0,0 @@ -export type Pairs = { - ETHBTC: number, - ETHREP: number, - BTCETH: number, - BTCREP: number -}; - -export type OriginKindSwapAction = { - type: 'SWAP_ORIGIN_KIND', - value: string -}; -export type DestinationKindSwapAction = { - type: 'SWAP_DESTINATION_KIND', - value: string -}; -export type OriginAmountSwapAction = { - type: 'SWAP_ORIGIN_AMOUNT', - value: ?number -}; -export type DestinationAmountSwapAction = { - type: 'SWAP_DESTINATION_AMOUNT', - value: ?number -}; -export type LoadBityRatesSucceededSwapAction = { - type: 'SWAP_LOAD_BITY_RATES_SUCCEEDED', - value: Pairs -}; -export type DestinationAddressSwapAction = { - type: 'SWAP_DESTINATION_ADDRESS', - value: ?number -}; - -export type RestartSwapAction = { - type: 'SWAP_RESTART' -}; - -export type LoadBityRatesRequestedSwapAction = { - type: 'SWAP_LOAD_BITY_RATES_REQUESTED' -}; - -export type ChangeStepSwapAction = { - type: 'SWAP_STEP', - value: number -}; - -export type StopLoadBityRatesSwapAction = { - type: 'SWAP_STOP_LOAD_BITY_RATES' -}; - -export type BityOrderCreateRequestedSwapAction = { - type: 'SWAP_ORDER_CREATE_REQUESTED', - payload: { - amount: number, - destinationAddress: string, - pair: string, - mode: number - } -}; - -type BityOrderInput = { - amount: string -}; - -type BityOrderOutput = { - amount: string -}; - -export type BityOrderResponse = { - status: string -}; - -export type BityOrderPostResponse = BityOrderResponse & { - payment_address: string, - status: string, - input: BityOrderInput, - output: BityOrderOutput, - timestamp_created: string, - validFor: number -}; - -export type BityOrderCreateSucceededSwapAction = { - type: 'SWAP_BITY_ORDER_CREATE_SUCCEEDED', - payload: BityOrderPostResponse -}; - -export type OrderStatusRequestedSwapAction = { - type: 'SWAP_BITY_ORDER_STATUS_REQUESTED', - payload: BityOrderResponse -}; - -export type OrderStatusSucceededSwapAction = { - type: 'SWAP_BITY_ORDER_STATUS_SUCCEEDED', - payload: BityOrderResponse -}; - -export type StartOrderTimerSwapAction = { - type: 'SWAP_ORDER_START_TIMER' -}; - -export type StopOrderTimerSwapAction = { - type: 'SWAP_ORDER_STOP_TIMER' -}; - -export type StartPollBityOrderStatusAction = { - type: 'SWAP_START_POLL_BITY_ORDER_STATUS' -}; - -export type StopPollBityOrderStatusAction = { - type: 'SWAP_STOP_POLL_BITY_ORDER_STATUS' -}; - -/*** Action Type Union ***/ -export type SwapAction = - | ChangeStepSwapAction - | OriginKindSwapAction - | DestinationKindSwapAction - | OriginAmountSwapAction - | DestinationAmountSwapAction - | LoadBityRatesSucceededSwapAction - | DestinationAddressSwapAction - | RestartSwapAction - | LoadBityRatesRequestedSwapAction - | StopLoadBityRatesSwapAction - | BityOrderCreateRequestedSwapAction - | BityOrderCreateSucceededSwapAction - | BityOrderResponse - | OrderStatusSucceededSwapAction - | StartPollBityOrderStatusAction; diff --git a/common/actions/wallet.js b/common/actions/wallet.js deleted file mode 100644 index aafe9131..00000000 --- a/common/actions/wallet.js +++ /dev/null @@ -1,134 +0,0 @@ -// @flow -import type { IWallet } from 'libs/wallet/IWallet'; -import Big from 'bignumber.js'; -import { Wei } from 'libs/units'; - -/*** Unlock Private Key ***/ -export type PrivateKeyUnlockParams = { - key: string, - password: string -}; - -export type UnlockPrivateKeyAction = { - type: 'WALLET_UNLOCK_PRIVATE_KEY', - payload: PrivateKeyUnlockParams -}; - -export function unlockPrivateKey( - value: PrivateKeyUnlockParams -): UnlockPrivateKeyAction { - return { - type: 'WALLET_UNLOCK_PRIVATE_KEY', - payload: value - }; -} - -/*** Unlock Keystore File ***/ -export type KeystoreUnlockParams = { - file: string, - password: string -}; - -export type UnlockKeystoreAction = { - type: 'WALLET_UNLOCK_KEYSTORE', - payload: KeystoreUnlockParams -}; - -export function unlockKeystore( - value: KeystoreUnlockParams -): UnlockKeystoreAction { - return { - type: 'WALLET_UNLOCK_KEYSTORE', - payload: value - }; -} - -/*** Unlock Mnemonic ***/ -export type MnemonicUnlockParams = { - phrase: string, - pass: string, - path: string, - address: string -}; - -export type UnlockMnemonicAction = { - type: 'WALLET_UNLOCK_MNEMONIC', - payload: MnemonicUnlockParams -}; - -export function unlockMnemonic( - value: MnemonicUnlockParams -): UnlockMnemonicAction { - return { - type: 'WALLET_UNLOCK_MNEMONIC', - payload: value - }; -} - -/*** Set Wallet ***/ -export type SetWalletAction = { - type: 'WALLET_SET', - payload: IWallet -}; - -export function setWallet(value: IWallet): SetWalletAction { - return { - type: 'WALLET_SET', - payload: value - }; -} - -/*** Set Balance ***/ -export type SetBalanceAction = { - type: 'WALLET_SET_BALANCE', - payload: Wei -}; - -export function setBalance(value: Wei): SetBalanceAction { - return { - type: 'WALLET_SET_BALANCE', - payload: value - }; -} - -/*** Set Token Balance ***/ -export type SetTokenBalancesAction = { - type: 'WALLET_SET_TOKEN_BALANCES', - payload: { - [string]: Big - } -}; - -export function setTokenBalances(payload: { - [string]: Big -}): SetTokenBalancesAction { - return { - type: 'WALLET_SET_TOKEN_BALANCES', - payload - }; -} - -/*** Broadcast Tx ***/ -export type BroadcastTxRequestedAction = { - type: 'WALLET_BROADCAST_TX_REQUESTED', - payload: { - signedTx: string - } -}; - -export function broadcastTx(signedTx: string): BroadcastTxRequestedAction { - return { - type: 'WALLET_BROADCAST_TX_REQUESTED', - payload: { - signedTx - } - }; -} - -/*** Union Type ***/ -export type WalletAction = - | UnlockPrivateKeyAction - | SetWalletAction - | SetBalanceAction - | SetTokenBalancesAction - | BroadcastTxRequestedAction; diff --git a/common/actions/wallet/actionCreators.ts b/common/actions/wallet/actionCreators.ts new file mode 100644 index 00000000..ed079345 --- /dev/null +++ b/common/actions/wallet/actionCreators.ts @@ -0,0 +1,101 @@ +import { BigNumber } from 'bignumber.js'; +import { Wei } from 'libs/units'; +import { IWallet } from 'libs/wallet/IWallet'; +import * as types from './actionTypes'; +import * as constants from './constants'; + +export type TUnlockPrivateKey = typeof unlockPrivateKey; +export function unlockPrivateKey( + value: types.PrivateKeyUnlockParams +): types.UnlockPrivateKeyAction { + return { + type: constants.WALLET_UNLOCK_PRIVATE_KEY, + payload: value + }; +} + +export type TUnlockKeystore = typeof unlockKeystore; +export function unlockKeystore( + value: types.KeystoreUnlockParams +): types.UnlockKeystoreAction { + return { + type: constants.WALLET_UNLOCK_KEYSTORE, + payload: value + }; +} + +export type TUnlockMnemonic = typeof unlockMnemonic; +export function unlockMnemonic( + value: types.MnemonicUnlockParams +): types.UnlockMnemonicAction { + return { + type: constants.WALLET_UNLOCK_MNEMONIC, + payload: value + }; +} + +export type TSetWallet = typeof setWallet; +export function setWallet(value: IWallet): types.SetWalletAction { + return { + type: constants.WALLET_SET, + payload: value + }; +} + +export type TSetBalance = typeof setBalance; +export function setBalance(value: Wei): types.SetBalanceAction { + return { + type: constants.WALLET_SET_BALANCE, + payload: value + }; +} + +export type TSetTokenBalances = typeof setTokenBalances; +export function setTokenBalances(payload: { + [key: string]: BigNumber; +}): types.SetTokenBalancesAction { + return { + type: constants.WALLET_SET_TOKEN_BALANCES, + payload + }; +} + +export type TBroadcastTx = typeof broadcastTx; +export function broadcastTx( + signedTx: string +): types.BroadcastTxRequestedAction { + return { + type: constants.WALLET_BROADCAST_TX_REQUESTED, + payload: { + signedTx + } + }; +} + +export type TBroadcastTxSucceded = typeof broadcastTxSucceded; +export function broadcastTxSucceded( + txHash: string, + signedTx: string +): types.BroadcastTxSuccededAction { + return { + type: constants.WALLET_BROADCAST_TX_SUCCEEDED, + payload: { + txHash, + signedTx + } + }; +} + +export type TBroadCastTxFailed = typeof broadCastTxFailed; +export function broadCastTxFailed( + signedTx: string, + errorMsg: string +): types.BroadcastTxFailedAction { + return { + type: constants.WALLET_BROADCAST_TX_FAILED, + payload: { + signedTx, + error: errorMsg + } + }; +} diff --git a/common/actions/wallet/actionTypes.ts b/common/actions/wallet/actionTypes.ts new file mode 100644 index 00000000..8ad65b5e --- /dev/null +++ b/common/actions/wallet/actionTypes.ts @@ -0,0 +1,91 @@ +import { BigNumber } from 'bignumber.js'; +import { Wei } from 'libs/units'; +import { IWallet } from 'libs/wallet/IWallet'; + +/*** Unlock Private Key ***/ +export interface PrivateKeyUnlockParams { + key: string; + password: string; +} + +export interface UnlockPrivateKeyAction { + type: 'WALLET_UNLOCK_PRIVATE_KEY'; + payload: PrivateKeyUnlockParams; +} +export interface UnlockMnemonicAction { + type: 'WALLET_UNLOCK_MNEMONIC'; + payload: MnemonicUnlockParams; +} + +/*** Set Wallet ***/ +export interface SetWalletAction { + type: 'WALLET_SET'; + payload: IWallet; +} + +/*** Set Balance ***/ +export interface SetBalanceAction { + type: 'WALLET_SET_BALANCE'; + payload: Wei; +} + +/*** Set Token Balance ***/ +export interface SetTokenBalancesAction { + type: 'WALLET_SET_TOKEN_BALANCES'; + payload: { + [key: string]: BigNumber; + }; +} + +/*** Broadcast Tx ***/ +export interface BroadcastTxRequestedAction { + type: 'WALLET_BROADCAST_TX_REQUESTED'; + payload: { + signedTx: string; + }; +} + +/*** Unlock Mnemonic ***/ +export interface MnemonicUnlockParams { + phrase: string; + pass: string; + path: string; + address: string; +} + +/*** Unlock Keystore File ***/ +export interface KeystoreUnlockParams { + file: string; + password: string; +} + +export interface UnlockKeystoreAction { + type: 'WALLET_UNLOCK_KEYSTORE'; + payload: KeystoreUnlockParams; +} + +export interface BroadcastTxSuccededAction { + type: 'WALLET_BROADCAST_TX_SUCCEEDED'; + payload: { + txHash: string; + signedTx: string; + }; +} + +export interface BroadcastTxFailedAction { + type: 'WALLET_BROADCAST_TX_FAILED'; + payload: { + signedTx: string; + error: string; + }; +} + +/*** Union Type ***/ +export type WalletAction = + | UnlockPrivateKeyAction + | SetWalletAction + | SetBalanceAction + | SetTokenBalancesAction + | BroadcastTxRequestedAction + | BroadcastTxFailedAction + | BroadcastTxSuccededAction; diff --git a/common/actions/wallet/constants.ts b/common/actions/wallet/constants.ts new file mode 100644 index 00000000..1569aeb9 --- /dev/null +++ b/common/actions/wallet/constants.ts @@ -0,0 +1,9 @@ +export const WALLET_UNLOCK_PRIVATE_KEY = 'WALLET_UNLOCK_PRIVATE_KEY'; +export const WALLET_UNLOCK_KEYSTORE = 'WALLET_UNLOCK_KEYSTORE'; +export const WALLET_UNLOCK_MNEMONIC = 'WALLET_UNLOCK_MNEMONIC'; +export const WALLET_SET = 'WALLET_SET'; +export const WALLET_SET_BALANCE = 'WALLET_SET_BALANCE'; +export const WALLET_SET_TOKEN_BALANCES = 'WALLET_SET_TOKEN_BALANCES'; +export const WALLET_BROADCAST_TX_REQUESTED = 'WALLET_BROADCAST_TX_REQUESTED'; +export const WALLET_BROADCAST_TX_FAILED = 'WALLET_BROADCAST_TX_FAILED'; +export const WALLET_BROADCAST_TX_SUCCEEDED = 'WALLET_BROADCAST_TX_SUCCEEDED'; diff --git a/common/actions/wallet/index.ts b/common/actions/wallet/index.ts new file mode 100644 index 00000000..fee14683 --- /dev/null +++ b/common/actions/wallet/index.ts @@ -0,0 +1,3 @@ +export * from './constants'; +export * from './actionTypes'; +export * from './actionCreators'; diff --git a/common/api/bity.js b/common/api/bity.ts similarity index 60% rename from common/api/bity.js rename to common/api/bity.ts index 06b49204..dc66c24d 100644 --- a/common/api/bity.js +++ b/common/api/bity.ts @@ -1,22 +1,10 @@ -// @flow import bityConfig from 'config/bity'; import { checkHttpStatus, parseJSON } from './utils'; -// import { combineAndUpper } from 'utils/formatters'; - -// function findRateFromBityRateList(rateObjects, pairName: string) { -// return rateObjects.find(x => x.pair === pairName); -// } - -// function _getRate(bityRates, originKind: string, destinationKind: string) { -// const pairName = combineAndUpper(originKind, destinationKind); -// const rateObjects = bityRates.objects; -// return findRateFromBityRateList(rateObjects, pairName); -// } export function getAllRates() { const mappedRates = {}; - return _getAllRates().then(bityRates => { - bityRates.objects.forEach(each => { + return _getAllRates().then((bityRates) => { + bityRates.objects.forEach((each) => { const pairName = each.pair; mappedRates[pairName] = parseFloat(each.rate_we_sell); }); @@ -44,11 +32,11 @@ export function postOrder( .then(parseJSON); } -export function getOrderStatus(orderid: string) { +export function getOrderStatus(orderId: string) { return fetch(`${bityConfig.serverURL}/status`, { method: 'POST', body: JSON.stringify({ - orderid + orderid: orderId }), headers: bityConfig.postConfig.headers }) @@ -60,6 +48,4 @@ function _getAllRates() { return fetch(`${bityConfig.bityURL}/v1/rate2/`) .then(checkHttpStatus) .then(parseJSON); -} - -// function requestOrderStatus() {} +} \ No newline at end of file diff --git a/common/api/utils.js b/common/api/utils.ts similarity index 79% rename from common/api/utils.js rename to common/api/utils.ts index 2418a367..b212ea59 100644 --- a/common/api/utils.js +++ b/common/api/utils.ts @@ -2,8 +2,9 @@ export function checkHttpStatus(response) { if (response.status >= 200 && response.status < 300) { return response; } else { - let error = new Error(response.statusText); - error.response = response; + const error = new Error(response.statusText); + // TODO: why assign response? + // error.response = response; throw error; } } diff --git a/common/components/AlphaAgreement/index.jsx b/common/components/AlphaAgreement/index.tsx similarity index 76% rename from common/components/AlphaAgreement/index.jsx rename to common/components/AlphaAgreement/index.tsx index 526fcaf6..0be1ea3e 100644 --- a/common/components/AlphaAgreement/index.jsx +++ b/common/components/AlphaAgreement/index.tsx @@ -3,35 +3,17 @@ import './index.scss'; const LS_KEY = 'acknowledged-alpha'; -export default class AlphaAgreement extends React.Component { - state = { - isFading: false, - hasAcknowledged: false +interface State { + isFading: boolean; + hasAcknowledged: boolean; +} +export default class AlphaAgreement extends React.Component<{}, State> { + public state = { + hasAcknowledged: !!localStorage.getItem(LS_KEY), + isFading: false }; - constructor(props) { - super(props); - - this.state = { - hasAcknowledged: localStorage.getItem(LS_KEY), - isFading: false - }; - } - - _continue = () => { - localStorage.setItem(LS_KEY, true); - this.setState({ isFading: true }); - - setTimeout(() => { - this.setState({ hasAcknowledged: true }); - }, 1000); - }; - - _reject = () => { - window.location = 'https://myetherwallet.com'; - }; - - render() { + public render() { if (this.state.hasAcknowledged) { return null; } @@ -58,13 +40,13 @@ export default class AlphaAgreement extends React.Component {
@@ -73,4 +55,17 @@ export default class AlphaAgreement extends React.Component {
); } + + private doContinue = () => { + localStorage.setItem(LS_KEY, 'true'); + this.setState({ isFading: true }); + + setTimeout(() => { + this.setState({ hasAcknowledged: true }); + }, 1000); + }; + + private reject = () => { + window.location.assign('https://myetherwallet.com'); + }; } diff --git a/common/components/BalanceSidebar/AccountInfo.jsx b/common/components/BalanceSidebar/AccountInfo.tsx similarity index 83% rename from common/components/BalanceSidebar/AccountInfo.jsx rename to common/components/BalanceSidebar/AccountInfo.tsx index efbd28f0..f6d228e1 100644 --- a/common/components/BalanceSidebar/AccountInfo.jsx +++ b/common/components/BalanceSidebar/AccountInfo.tsx @@ -1,37 +1,39 @@ -// @flow -import './AccountInfo.scss'; +import { FiatRequestedRatesAction } from 'actions/rates'; +import { Identicon } from 'components/ui'; +import { NetworkConfig } from 'config/data'; +import { Ether } from 'libs/units'; +import { IWallet } from 'libs/wallet'; import React from 'react'; import translate from 'translations'; -import { Identicon } from 'components/ui'; import { formatNumber } from 'utils/formatters'; -import type { IWallet } from 'libs/wallet'; -import type { NetworkConfig } from 'config/data'; -import { Ether } from 'libs/units'; -import type { FiatRequestedRatesAction } from 'actions/rates'; +import './AccountInfo.scss'; -type Props = { - balance: Ether, - wallet: IWallet, - network: NetworkConfig, - fiatRequestedRates: () => FiatRequestedRatesAction -}; +interface Props { + balance: Ether; + wallet: IWallet; + network: NetworkConfig; + fiatRequestedRates(): FiatRequestedRatesAction; +} -export default class AccountInfo extends React.Component { - props: Props; - - state = { +interface State { + showLongBalance: boolean; + address: string; +} +export default class AccountInfo extends React.Component { + public state = { showLongBalance: false, address: '' }; - componentDidMount() { + public componentDidMount() { this.props.fiatRequestedRates(); this.props.wallet.getAddress().then(addr => { this.setState({ address: addr }); }); } - toggleShowLongBalance = (e: SyntheticMouseEvent) => { + // TODO: don't use any; + public toggleShowLongBalance = (e: any) => { e.preventDefault(); this.setState(state => { return { @@ -40,7 +42,7 @@ export default class AccountInfo extends React.Component { }); }; - render() { + public render() { const { network, balance } = this.props; const { blockExplorer, tokenExplorer } = network; const { address } = this.state; diff --git a/common/components/BalanceSidebar/EquivalentValues.jsx b/common/components/BalanceSidebar/EquivalentValues.tsx similarity index 82% rename from common/components/BalanceSidebar/EquivalentValues.jsx rename to common/components/BalanceSidebar/EquivalentValues.tsx index 3c9ffaec..61f82afb 100644 --- a/common/components/BalanceSidebar/EquivalentValues.jsx +++ b/common/components/BalanceSidebar/EquivalentValues.tsx @@ -1,21 +1,18 @@ -// @flow -import './EquivalentValues.scss'; +import { Ether } from 'libs/units'; import React from 'react'; import translate from 'translations'; import { formatNumber } from 'utils/formatters'; -import { Ether } from 'libs/units'; +import './EquivalentValues.scss'; const ratesKeys = ['BTC', 'REP', 'EUR', 'USD', 'GBP', 'CHF']; -type Props = { - balance: ?Ether, - rates: ?{ [string]: number } -}; +interface Props { + balance?: Ether; + rates?: { [key: string]: number }; +} -export default class EquivalentValues extends React.Component { - props: Props; - - render() { +export default class EquivalentValues extends React.Component { + public render() { const { balance, rates } = this.props; return ( @@ -27,7 +24,9 @@ export default class EquivalentValues extends React.Component {
    {rates ? ratesKeys.map(key => { - if (!rates[key]) return null; + if (!rates[key]) { + return null; + } return (
  • diff --git a/common/components/BalanceSidebar/Promos.jsx b/common/components/BalanceSidebar/Promos.tsx similarity index 63% rename from common/components/BalanceSidebar/Promos.jsx rename to common/components/BalanceSidebar/Promos.tsx index d2334fff..95eb7cfd 100644 --- a/common/components/BalanceSidebar/Promos.jsx +++ b/common/components/BalanceSidebar/Promos.tsx @@ -1,14 +1,14 @@ -// @flow -import './Promos.scss'; import React from 'react'; import { Link } from 'react-router'; +import './Promos.scss'; const promos = [ { + isExternal: true, color: '#6e9a3e', href: 'https://myetherwallet.groovehq.com/knowledge_base/topics/protecting-yourself-and-your-funds', - isExternal: true, + texts: [
    Learn more about protecting your funds.
    ], images: [ require('assets/images/logo-ledger.svg'), @@ -16,10 +16,10 @@ const promos = [ ] }, { + isExternal: true, color: '#2b71b1', href: 'https://buy.coinbase.com?code=a6e1bd98-6464-5552-84dd-b27f0388ac7d&address=0xA7DeFf12461661212734dB35AdE9aE7d987D648c&crypto_currency=ETH¤cy=USD', - isExternal: true, texts: [

    It’s now easier to get more ETH

    ,
    Buy ETH with USD
    @@ -27,6 +27,7 @@ const promos = [ images: [require('assets/images/logo-coinbase.svg')] }, { + isExternal: false, color: '#006e79', href: '/swap', texts: [ @@ -37,64 +38,60 @@ const promos = [ } ]; -export default class Promos extends React.Component { - state: { activePromo: number }; +interface State { + activePromo: number; +} - state = { - activePromo: parseInt(Math.random() * promos.length) +export default class Promos extends React.Component<{}, State> { + public state = { + activePromo: parseInt(String(Math.random() * promos.length), 10) }; - _navigateToPromo = (idx: number) => { - this.setState({ activePromo: Math.max(0, Math.min(promos.length, idx)) }); - }; - - render() { + public render() { const { activePromo } = this.state; const promo = promos[activePromo]; const promoContent = (
    -
    - {promo.texts} -
    +
    {promo.texts}
    {promo.images.map((img, idx) => )}
    ); - const promoEl = promo.isExternal - ? - {promoContent} - - : -
    - {promoContent} -
    - ; + const promoEl = promo.isExternal ? ( + + {promoContent} + + ) : ( + +
    {promoContent}
    + + ); return (
    {promoEl}
    - {promos.map((promo, idx) => { + {promos.map((_, index) => { return (
    ); } + + private navigateToPromo = (idx: number) => () => { + this.setState({ activePromo: Math.max(0, Math.min(promos.length, idx)) }); + }; } diff --git a/common/components/BalanceSidebar/TokenBalances/AddCustomTokenForm.jsx b/common/components/BalanceSidebar/TokenBalances/AddCustomTokenForm.tsx similarity index 69% rename from common/components/BalanceSidebar/TokenBalances/AddCustomTokenForm.jsx rename to common/components/BalanceSidebar/TokenBalances/AddCustomTokenForm.tsx index 921bb69e..f07cff3b 100644 --- a/common/components/BalanceSidebar/TokenBalances/AddCustomTokenForm.jsx +++ b/common/components/BalanceSidebar/TokenBalances/AddCustomTokenForm.tsx @@ -1,20 +1,27 @@ -// @flow -import React from 'react'; import classnames from 'classnames'; -import { isValidETHAddress, isPositiveIntegerOrZero } from 'libs/validators'; +import { Token } from 'config/data'; +import { isPositiveIntegerOrZero, isValidETHAddress } from 'libs/validators'; +import React from 'react'; import translate from 'translations'; -export default class AddCustomTokenForm extends React.Component { - props: { - onSave: ({ address: string, symbol: string, decimal: number }) => void - }; - state = { +interface Props { + onSave(params: Token): void; +} + +interface State { + address: string; + symbol: string; + decimal: string; +} + +export default class AddCustomTokenForm extends React.Component { + public state = { address: '', symbol: '', decimal: '' }; - render() { + public render() { const { address, symbol, decimal } = this.state; const inputClasses = 'AddCustom-field-input form-control input-sm'; const errors = this.getErrors(); @@ -42,9 +49,7 @@ export default class AddCustomTokenForm extends React.Component { {fields.map(field => { return (
  • - {linkEl} -
  • - ); - } -} diff --git a/common/components/Header/components/NavigationLink.tsx b/common/components/Header/components/NavigationLink.tsx new file mode 100644 index 00000000..322c49e5 --- /dev/null +++ b/common/components/Header/components/NavigationLink.tsx @@ -0,0 +1,49 @@ +import classnames from 'classnames'; +import React from 'react'; +import { Link } from 'react-router'; +import translate, { translateRaw } from 'translations'; +import './NavigationLink.scss'; + +interface Props { + link: { + name: string; + to?: string; + external?: boolean; + }; + location: any; +} + +export default class NavigationLink extends React.Component { + public render() { + const { link, location } = this.props; + const linkClasses = classnames({ + 'NavigationLink-link': true, + 'is-disabled': !link.to, + 'is-active': + location.pathname === link.to || + location.pathname.substring(1) === link.to + }); + const linkLabel = `nav item: ${translateRaw(link.name)}`; + + const linkEl = link.external ? ( + + {translate(link.name)} + + ) : ( + + {translate(link.name)} + + ); + + return
  • {linkEl}
  • ; + } +} diff --git a/common/components/Header/index.jsx b/common/components/Header/index.tsx similarity index 70% rename from common/components/Header/index.jsx rename to common/components/Header/index.tsx index 908e6e0c..c549f889 100644 --- a/common/components/Header/index.jsx +++ b/common/components/Header/index.tsx @@ -1,49 +1,53 @@ -// @flow -import React, { Component } from 'react'; -import Navigation from './components/Navigation'; -import GasPriceDropdown from './components/GasPriceDropdown'; -import { Link } from 'react-router'; -import { Dropdown } from 'components/ui'; -import { - languages, - NODES, - NETWORKS, - VERSION, - ANNOUNCEMENT_TYPE, - ANNOUNCEMENT_MESSAGE -} from '../../config/data'; +import { TChangeGasPrice, TChangeLanguage, TChangeNode } from 'actions/config'; import logo from 'assets/images/logo-myetherwallet.svg'; +import { Dropdown } from 'components/ui'; +import React, { Component } from 'react'; +import { Link } from 'react-router'; +import { + ANNOUNCEMENT_MESSAGE, + ANNOUNCEMENT_TYPE, + languages, + NETWORKS, + NODES, + VERSION +} from '../../config/data'; +import GasPriceDropdown from './components/GasPriceDropdown'; +import Navigation from './components/Navigation'; import './index.scss'; -export default class Header extends Component { - props: { - location: {}, - languageSelection: string, - nodeSelection: string, - gasPriceGwei: number, +interface Props { + location: {}; + languageSelection: string; + nodeSelection: string; + gasPriceGwei: number; - changeLanguage: (sign: string) => any, - changeNode: (key: string) => any, - changeGasPrice: (price: number) => any - }; + changeLanguage: TChangeLanguage; + changeNode: TChangeNode; + changeGasPrice: TChangeGasPrice; +} - render() { +export default class Header extends Component { + public render() { const { languageSelection, changeNode, nodeSelection } = this.props; const selectedLanguage = languages.find(l => l.sign === languageSelection) || languages[0]; const selectedNode = NODES[nodeSelection]; const selectedNetwork = NETWORKS[selectedNode.network]; - + const LanguageDropDown = Dropdown as new () => Dropdown< + typeof selectedLanguage + >; + const NodeDropDown = Dropdown as new () => Dropdown; return (
    - {ANNOUNCEMENT_MESSAGE && + {ANNOUNCEMENT_MESSAGE && (
    } + /> + )}
    @@ -71,10 +75,10 @@ export default class Header extends Component { onChange={this.props.changeGasPrice} /> - o.name} + formatTitle={this.extractName} value={selectedLanguage} extra={[
  • , @@ -87,20 +91,14 @@ export default class Header extends Component { onChange={this.changeLanguage} /> - [ - NODES[o].network, - ' ', - - ({NODES[o].service}) - - ]} + formatTitle={this.nodeNetworkAndService} value={nodeSelection} extra={
  • - {}}>Add Custom Node + Add Custom Node
  • } onChange={changeNode} @@ -111,13 +109,23 @@ export default class Header extends Component {
    ); } - changeLanguage = (value: { sign: string }) => { + public changeLanguage = (value: { sign: string }) => { this.props.changeLanguage(value.sign); }; + + private extractName(): (option: { sign: string; name: string }) => string { + return name; + } + + private nodeNetworkAndService = (option: string) => [ + NODES[option].network, + ' ', + ({NODES[option].service}) + ]; } diff --git a/common/components/PaperWallet/index.jsx b/common/components/PaperWallet/index.tsx similarity index 89% rename from common/components/PaperWallet/index.jsx rename to common/components/PaperWallet/index.tsx index 840b5b4c..1bef1481 100644 --- a/common/components/PaperWallet/index.jsx +++ b/common/components/PaperWallet/index.tsx @@ -1,16 +1,15 @@ -// @flow +import { Identicon, QRCode } from 'components/ui'; +import PrivKeyWallet from 'libs/wallet/privkey'; import React from 'react'; -import { QRCode, Identicon } from 'components/ui'; -import type PrivKeyWallet from 'libs/wallet/privkey'; import ethLogo from 'assets/images/logo-ethereum-1.png'; -import sidebarImg from 'assets/images/print-sidebar.png'; import notesBg from 'assets/images/notes-bg.png'; +import sidebarImg from 'assets/images/print-sidebar.png'; const walletWidth = 680; const walletHeight = 280; -const styles = { +const styles: any = { container: { position: 'relative', margin: '0 auto', @@ -91,22 +90,26 @@ const styles = { } }; -type Props = { - wallet: PrivKeyWallet -}; +interface Props { + wallet: PrivKeyWallet; +} -export default class PaperWallet extends React.Component { - props: Props; - state = { address: '' }; +interface State { + address: string; +} +export default class PaperWallet extends React.Component { + public state = { address: '' }; - componentDidMount() { - if (!this.props.wallet) return; + public componentDidMount() { + if (!this.props.wallet) { + return; + } this.props.wallet.getAddress().then(addr => { this.setState({ address: addr }); }); } - render() { + public render() { const privateKey = this.props.wallet.getPrivateKey(); return ( diff --git a/common/components/PrintableWallet/index.jsx b/common/components/PrintableWallet/index.tsx similarity index 74% rename from common/components/PrintableWallet/index.jsx rename to common/components/PrintableWallet/index.tsx index d14f9d5f..205d56b1 100644 --- a/common/components/PrintableWallet/index.jsx +++ b/common/components/PrintableWallet/index.tsx @@ -1,22 +1,15 @@ -// @flow +import { PaperWallet } from 'components'; +import PrivKeyWallet from 'libs/wallet/privkey'; import React, { Component } from 'react'; -import PropTypes from 'prop-types'; import translate from 'translations'; import printElement from 'utils/printElement'; -import { PaperWallet } from 'components'; -import type PrivKeyWallet from 'libs/wallet/privkey'; -type Props = { - wallet: PrivKeyWallet -}; +interface Props { + wallet: PrivKeyWallet; +} -export default class PrintableWallet extends Component { - props: Props; - static propTypes = { - wallet: PropTypes.object.isRequired - }; - - print = () => { +export default class PrintableWallet extends Component { + public print = () => { printElement(, { popupFeatures: { scrollbars: 'no' @@ -36,7 +29,7 @@ export default class PrintableWallet extends Component { }); }; - render() { + public render() { return (
    diff --git a/common/components/Root/index.jsx b/common/components/Root/index.tsx similarity index 68% rename from common/components/Root/index.jsx rename to common/components/Root/index.tsx index a8a24b11..1bfaaa8b 100644 --- a/common/components/Root/index.jsx +++ b/common/components/Root/index.tsx @@ -1,16 +1,16 @@ import React, { Component } from 'react'; import { Provider } from 'react-redux'; import { Router } from 'react-router'; -import PropTypes from 'prop-types'; -export default class Root extends Component { - static propTypes = { - store: PropTypes.object, - history: PropTypes.object, - routes: PropTypes.func - }; +// TODO: fix this +interface Props { + store: any; + history: any; + routes(): null; +} - render() { +export default class Root extends Component { + public render() { const { store, history, routes } = this.props; // key={Math.random()} = hack for HMR from https://github.com/webpack/webpack-dev-server/issues/395 return ( diff --git a/common/components/Translate.jsx b/common/components/Translate.tsx similarity index 90% rename from common/components/Translate.jsx rename to common/components/Translate.tsx index d192983a..c1a2e383 100644 --- a/common/components/Translate.jsx +++ b/common/components/Translate.tsx @@ -1,11 +1,10 @@ -// @flow import React from 'react'; import Markdown from 'react-markdown'; import { translateRaw } from 'translations'; -type Props = { - translationKey: string -}; +interface Props { + translationKey: string; +} const Translate = ({ translationKey }: Props) => { const source = translateRaw(translationKey); diff --git a/common/components/WalletDecrypt/DeterministicWalletsModal.jsx b/common/components/WalletDecrypt/DeterministicWalletsModal.tsx similarity index 70% rename from common/components/WalletDecrypt/DeterministicWalletsModal.jsx rename to common/components/WalletDecrypt/DeterministicWalletsModal.tsx index 032441ff..40e953d1 100644 --- a/common/components/WalletDecrypt/DeterministicWalletsModal.jsx +++ b/common/components/WalletDecrypt/DeterministicWalletsModal.tsx @@ -1,60 +1,59 @@ -// @flow -import './DeterministicWalletsModal.scss'; -import React from 'react'; -import { connect } from 'react-redux'; -import Modal from 'components/ui/Modal'; import { - getDeterministicWallets, - setDesiredToken -} from 'actions/deterministicWallets'; -import { getNetworkConfig } from 'selectors/config'; -import { getTokens } from 'selectors/wallet'; -import { isValidPath } from 'libs/validators'; -import type { DeterministicWalletData, - GetDeterministicWalletsArgs, + getDeterministicWallets, GetDeterministicWalletsAction, + GetDeterministicWalletsArgs, + setDesiredToken, SetDesiredTokenAction } from 'actions/deterministicWallets'; -import type { NetworkConfig, Token } from 'config/data'; +import Modal, { IButton } from 'components/ui/Modal'; +import { NetworkConfig, Token } from 'config/data'; +import { isValidPath } from 'libs/validators'; +import React from 'react'; +import { connect } from 'react-redux'; +import { getNetworkConfig } from 'selectors/config'; +import { getTokens, MergedToken } from 'selectors/wallet'; +import './DeterministicWalletsModal.scss'; const WALLETS_PER_PAGE = 5; -type Props = { +interface Props { + // Passed props + isOpen?: boolean; + walletType?: string; + dPath: string; + dPaths: { label: string; value: string }[]; + publicKey?: string; + chainCode?: string; + seed?: string; + // Redux state - wallets: DeterministicWalletData[], - desiredToken: string, - network: NetworkConfig, - tokens: Token[], + wallets: DeterministicWalletData[]; + desiredToken: string; + network: NetworkConfig; + tokens: MergedToken[]; // Redux actions - getDeterministicWallets: GetDeterministicWalletsArgs => GetDeterministicWalletsAction, - setDesiredToken: (tkn: ?string) => SetDesiredTokenAction, + getDeterministicWallets( + args: GetDeterministicWalletsArgs + ): GetDeterministicWalletsAction; + setDesiredToken(tkn: string | undefined): SetDesiredTokenAction; - // Passed props - isOpen?: boolean, - walletType: ?string, - dPath: string, - dPaths: { label: string, value: string }[], - publicKey: ?string, - chainCode: ?string, - seed: ?string, - onCancel: () => void, - onConfirmAddress: (string, number) => void, - onPathChange: string => void -}; + onCancel(): void; + onConfirmAddress(address: string, addressIndex: number): void; + onPathChange(path: string): void; +} -type State = { - selectedAddress: string, - selectedAddrIndex: number, - isCustomPath: boolean, - customPath: string, - page: number -}; +interface State { + selectedAddress: string; + selectedAddrIndex: number; + isCustomPath: boolean; + customPath: string; + page: number; +} -class DeterministicWalletsModal extends React.Component { - props: Props; - state: State = { +class DeterministicWalletsModal extends React.Component { + public state = { selectedAddress: '', selectedAddrIndex: 0, isCustomPath: false, @@ -62,11 +61,11 @@ class DeterministicWalletsModal extends React.Component { page: 0 }; - componentDidMount() { - this._getAddresses(); + public componentDidMount() { + this.getAddresses(); } - componentWillReceiveProps(nextProps) { + public componentWillReceiveProps(nextProps) { const { publicKey, chainCode, seed, dPath } = this.props; if ( nextProps.publicKey !== publicKey || @@ -74,11 +73,125 @@ class DeterministicWalletsModal extends React.Component { nextProps.dPath !== dPath || nextProps.seed !== seed ) { - this._getAddresses(nextProps); + this.getAddresses(nextProps); } } - _getAddresses(props: Props = this.props) { + public render() { + const { + wallets, + desiredToken, + network, + tokens, + dPath, + dPaths, + onCancel, + walletType + } = this.props; + const { selectedAddress, isCustomPath, customPath, page } = this.state; + const validPathClass = isValidPath(customPath) ? 'is-valid' : 'is-invalid'; + + const buttons: IButton[] = [ + { + text: 'Unlock this Address', + type: 'primary', + onClick: this.handleConfirmAddress, + disabled: !selectedAddress + }, + { + text: 'Cancel', + type: 'default', + onClick: onCancel + } + ]; + + return ( + +
    +
    + Addresses for + + {isCustomPath && + } +
    + +
    + + + + + + + + + + + + {wallets.map(wallet => this.renderWalletRow(wallet))} + +
    #Address + {network.unit} + + + More
    + +
    + + +
    +
    +
    +
    + ); + } + + private getAddresses(props: Props = this.props) { const { dPath, publicKey, chainCode, seed } = props; if (dPath && ((publicKey && chainCode) || seed) && isValidPath(dPath)) { @@ -93,8 +206,8 @@ class DeterministicWalletsModal extends React.Component { } } - _handleChangePath = (ev: SyntheticInputEvent) => { - const { value } = ev.target; + private handleChangePath = (ev: React.SyntheticEvent) => { + const { value } = ev.target as HTMLSelectElement; if (value === 'custom') { this.setState({ isCustomPath: true }); @@ -106,21 +219,29 @@ class DeterministicWalletsModal extends React.Component { } }; - _handleChangeCustomPath = (ev: SyntheticInputEvent) => { - this.setState({ customPath: ev.target.value }); + private handleChangeCustomPath = ( + ev: React.SyntheticEvent + ) => { + this.setState({ customPath: (ev.target as HTMLInputElement).value }); }; - _handleSubmitCustomPath = (ev: SyntheticInputEvent) => { + private handleSubmitCustomPath = ( + ev: React.SyntheticEvent + ) => { ev.preventDefault(); - if (!isValidPath(this.state.customPath)) return; + if (!isValidPath(this.state.customPath)) { + return; + } this.props.onPathChange(this.state.customPath); }; - _handleChangeToken = (ev: SyntheticInputEvent) => { - this.props.setDesiredToken(ev.target.value || null); + private handleChangeToken = (ev: React.SyntheticEvent) => { + this.props.setDesiredToken( + (ev.target as HTMLSelectElement).value || undefined + ); }; - _handleConfirmAddress = () => { + private handleConfirmAddress = () => { if (this.state.selectedAddress) { this.props.onConfirmAddress( this.state.selectedAddress, @@ -129,22 +250,22 @@ class DeterministicWalletsModal extends React.Component { } }; - _selectAddress(selectedAddress, selectedAddrIndex) { + private selectAddress(selectedAddress, selectedAddrIndex) { this.setState({ selectedAddress, selectedAddrIndex }); } - _nextPage = () => { - this.setState({ page: this.state.page + 1 }, this._getAddresses); + private nextPage = () => { + this.setState({ page: this.state.page + 1 }, this.getAddresses); }; - _prevPage = () => { + private prevPage = () => { this.setState( { page: Math.max(this.state.page - 1, 0) }, - this._getAddresses + this.getAddresses ); }; - _renderWalletRow(wallet) { + private renderWalletRow(wallet) { const { desiredToken, network } = this.props; const { selectedAddress } = this.state; @@ -157,7 +278,7 @@ class DeterministicWalletsModal extends React.Component { return ( {wallet.index + 1} @@ -188,120 +309,6 @@ class DeterministicWalletsModal extends React.Component { ); } - - render() { - const { - wallets, - desiredToken, - network, - tokens, - dPath, - dPaths, - onCancel, - walletType - } = this.props; - const { selectedAddress, isCustomPath, customPath, page } = this.state; - const validPathClass = isValidPath(customPath) ? 'is-valid' : 'is-invalid'; - - const buttons = [ - { - text: 'Unlock this Address', - type: 'primary', - onClick: this._handleConfirmAddress, - disabled: !selectedAddress - }, - { - text: 'Cancel', - type: 'default', - onClick: onCancel - } - ]; - - return ( - -
    -
    - Addresses for - - {isCustomPath && - } -
    - -
    - - - - - - - - - - - - {wallets.map(wallet => this._renderWalletRow(wallet))} - -
    #Address - {network.unit} - - - More
    - -
    - - -
    -
    -
    -
    - ); - } } function mapStateToProps(state) { diff --git a/common/components/WalletDecrypt/Keystore.jsx b/common/components/WalletDecrypt/Keystore.tsx similarity index 80% rename from common/components/WalletDecrypt/Keystore.jsx rename to common/components/WalletDecrypt/Keystore.tsx index 729c815c..aaa07112 100644 --- a/common/components/WalletDecrypt/Keystore.jsx +++ b/common/components/WalletDecrypt/Keystore.tsx @@ -1,33 +1,33 @@ +import { isKeystorePassRequired } from 'libs/keystore'; import React, { Component } from 'react'; import translate, { translateRaw } from 'translations'; -import { isKeystorePassRequired } from 'libs/keystore'; -export type KeystoreValue = { - file: string, - password: string, - valid: boolean -}; +export interface KeystoreValue { + file: string; + password: string; + valid: boolean; +} function isPassRequired(file: string): boolean { let passReq = false; try { passReq = isKeystorePassRequired(file); } catch (e) { - //TODO: communicate invalid file to user + // TODO: communicate invalid file to user } return passReq; } export default class KeystoreDecrypt extends Component { - props: { - value: KeystoreValue, - onChange: (value: KeystoreValue) => void, - onUnlock: () => void + public props: { + value: KeystoreValue; + onChange(value: KeystoreValue): void; + onUnlock(): void; }; - render() { + public render() { const { file, password } = this.props.value; - let passReq = isPassRequired(file); + const passReq = isPassRequired(file); return (
    @@ -47,7 +47,7 @@ export default class KeystoreDecrypt extends Component { {translate('ADD_Radio_2_short')} @@ -74,7 +74,7 @@ export default class KeystoreDecrypt extends Component { ); } - onKeyDown = (e: SyntheticKeyboardEvent) => { + public onKeyDown = (e: any) => { if (e.keyCode === 13) { e.preventDefault(); e.stopPropagation(); @@ -82,7 +82,7 @@ export default class KeystoreDecrypt extends Component { } }; - onPasswordChange = (e: SyntheticInputEvent) => { + public onPasswordChange = (e: any) => { const valid = this.props.value.file.length && e.target.value.length; this.props.onChange({ ...this.props.value, @@ -91,13 +91,14 @@ export default class KeystoreDecrypt extends Component { }); }; - handleFileSelection = (e: SyntheticInputEvent) => { + public handleFileSelection = (e: any) => { const fileReader = new FileReader(); - const inputFile = e.target.files[0]; + const target = e.target; + const inputFile = target.files[0]; fileReader.onload = () => { const keystore = fileReader.result; - let passReq = isPassRequired(keystore); + const passReq = isPassRequired(keystore); this.props.onChange({ ...this.props.value, diff --git a/common/components/WalletDecrypt/LedgerNano.jsx b/common/components/WalletDecrypt/LedgerNano.tsx similarity index 82% rename from common/components/WalletDecrypt/LedgerNano.jsx rename to common/components/WalletDecrypt/LedgerNano.tsx index 735ee37b..b17fa0db 100644 --- a/common/components/WalletDecrypt/LedgerNano.jsx +++ b/common/components/WalletDecrypt/LedgerNano.tsx @@ -2,11 +2,13 @@ import React, { Component } from 'react'; import translate from 'translations'; export default class LedgerNanoSDecrypt extends Component { - render() { + public render() { return (
    -

    {translate('ADD_Radio_2_alt')}

    +

    + {translate('ADD_Radio_2_alt')} +

    @@ -14,7 +16,7 @@ export default class LedgerNanoSDecrypt extends Component { {translate('ADD_Radio_2_short')} diff --git a/common/components/WalletDecrypt/Mnemonic.jsx b/common/components/WalletDecrypt/Mnemonic.tsx similarity index 67% rename from common/components/WalletDecrypt/Mnemonic.jsx rename to common/components/WalletDecrypt/Mnemonic.tsx index 98cc58ce..c170d0dd 100644 --- a/common/components/WalletDecrypt/Mnemonic.jsx +++ b/common/components/WalletDecrypt/Mnemonic.tsx @@ -1,29 +1,30 @@ +import { mnemonicToSeed, validateMnemonic } from 'bip39'; +import DPATHS from 'config/dpaths'; import React, { Component } from 'react'; import translate, { translateRaw } from 'translations'; -import { validateMnemonic, mnemonicToSeed } from 'bip39'; - import DeterministicWalletsModal from './DeterministicWalletsModal'; -import DPATHS from 'config/dpaths.js'; const DEFAULT_PATH = DPATHS.MNEMONIC[0].value; -type State = { - phrase: string, - pass: string, - seed: string, - dPath: string -}; +interface Props { + onUnlock(param: any): void; +} +interface State { + phrase: string; + pass: string; + seed: string; + dPath: string; +} -export default class MnemonicDecrypt extends Component { - props: { onUnlock: any => void }; - state: State = { +export default class MnemonicDecrypt extends Component { + public state: State = { phrase: '', pass: '', seed: '', dPath: DEFAULT_PATH }; - render() { + public render() { const { phrase, seed, dPath, pass } = this.state; const isValidMnemonic = validateMnemonic(phrase); @@ -42,7 +43,7 @@ export default class MnemonicDecrypt extends Component { value={phrase} onChange={this.onMnemonicChange} placeholder={translateRaw('x_Mnemonic')} - rows="4" + rows={4} />
    @@ -72,45 +73,47 @@ export default class MnemonicDecrypt extends Component { seed={seed} dPath={dPath} dPaths={DPATHS.MNEMONIC} - onCancel={this._handleCancel} - onConfirmAddress={this._handleUnlock} - onPathChange={this._handlePathChange} + onCancel={this.handleCancel} + onConfirmAddress={this.handleUnlock} + onPathChange={this.handlePathChange} walletType={translateRaw('x_Mnemonic')} />
    ); } - onPasswordChange = (e: SyntheticInputEvent) => { - this.setState({ pass: e.target.value }); + public onPasswordChange = (e: React.SyntheticEvent) => { + this.setState({ pass: (e.target as HTMLInputElement).value }); }; - onMnemonicChange = (e: SyntheticInputEvent) => { - this.setState({ phrase: e.target.value }); + public onMnemonicChange = (e: React.SyntheticEvent) => { + this.setState({ phrase: (e.target as HTMLTextAreaElement).value }); }; - onDWModalOpen = (e: SyntheticInputEvent) => { + public onDWModalOpen = (e: React.SyntheticEvent) => { const { phrase, pass } = this.state; - if (!validateMnemonic(phrase)) return; + if (!validateMnemonic(phrase)) { + return; + } try { - let seed = mnemonicToSeed(phrase.trim(), pass).toString('hex'); + const seed = mnemonicToSeed(phrase.trim(), pass).toString('hex'); this.setState({ seed }); } catch (err) { console.log(err); } }; - _handleCancel = () => { + private handleCancel = () => { this.setState({ seed: '' }); }; - _handlePathChange = (dPath: string) => { + private handlePathChange = (dPath: string) => { this.setState({ dPath }); }; - _handleUnlock = (address, index) => { + private handleUnlock = (address, index) => { const { phrase, pass, dPath } = this.state; this.props.onUnlock({ diff --git a/common/components/WalletDecrypt/PrivateKey.jsx b/common/components/WalletDecrypt/PrivateKey.tsx similarity index 76% rename from common/components/WalletDecrypt/PrivateKey.jsx rename to common/components/WalletDecrypt/PrivateKey.tsx index 101e03bf..0e564144 100644 --- a/common/components/WalletDecrypt/PrivateKey.jsx +++ b/common/components/WalletDecrypt/PrivateKey.tsx @@ -1,13 +1,12 @@ -// @flow +import { isValidEncryptedPrivKey, isValidPrivKey } from 'libs/validators'; import React, { Component } from 'react'; import translate, { translateRaw } from 'translations'; -import { isValidPrivKey, isValidEncryptedPrivKey } from 'libs/validators'; -export type PrivateKeyValue = { - key: string, - password: string, - valid: boolean -}; +export interface PrivateKeyValue { + key: string; + password: string; + valid: boolean; +} function fixPkey(key) { if (key.indexOf('0x') === 0) { @@ -16,14 +15,14 @@ function fixPkey(key) { return key; } -type validated = { - fixedPkey: string, - isValidPkey: boolean, - isPassRequired: boolean, - valid: boolean -}; +interface Validated { + fixedPkey: string; + isValidPkey: boolean; + isPassRequired: boolean; + valid: boolean; +} -function validatePkeyAndPass(pkey: string, pass: string): validated { +function validatePkeyAndPass(pkey: string, pass: string): Validated { const fixedPkey = fixPkey(pkey); const validPkey = isValidPrivKey(fixedPkey); const validEncPkey = isValidEncryptedPrivKey(fixedPkey); @@ -46,13 +45,13 @@ function validatePkeyAndPass(pkey: string, pass: string): validated { } export default class PrivateKeyDecrypt extends Component { - props: { - value: PrivateKeyValue, - onChange: (value: PrivateKeyValue) => void, - onUnlock: () => void + public props: { + value: PrivateKeyValue; + onChange(value: PrivateKeyValue): void; + onUnlock(): void; }; - render() { + public render() { const { key, password } = this.props.value; const { isValidPkey, isPassRequired } = validatePkeyAndPass(key, password); @@ -72,7 +71,7 @@ export default class PrivateKeyDecrypt extends Component { onChange={this.onPkeyChange} onKeyDown={this.onKeyDown} placeholder={translateRaw('x_PrivKey2')} - rows="4" + rows={4} />
    {isValidPkey && @@ -97,17 +96,17 @@ export default class PrivateKeyDecrypt extends Component { ); } - onPkeyChange = (e: SyntheticInputEvent) => { - const pkey = e.target.value; + public onPkeyChange = (e: React.SyntheticEvent) => { + const pkey = (e.target as HTMLInputElement).value; const pass = this.props.value.password; const { fixedPkey, valid } = validatePkeyAndPass(pkey, pass); this.props.onChange({ ...this.props.value, key: fixedPkey, valid }); }; - onPasswordChange = (e: SyntheticInputEvent) => { + public onPasswordChange = (e: React.SyntheticEvent) => { const pkey = this.props.value.key; - const pass = e.target.value; + const pass = (e.target as HTMLInputElement).value; const { valid } = validatePkeyAndPass(pkey, pass); this.props.onChange({ @@ -117,7 +116,7 @@ export default class PrivateKeyDecrypt extends Component { }); }; - onKeyDown = (e: SyntheticKeyboardEvent) => { + public onKeyDown = (e: any) => { if (e.keyCode === 13) { e.preventDefault(); e.stopPropagation(); diff --git a/common/components/WalletDecrypt/Trezor.jsx b/common/components/WalletDecrypt/Trezor.tsx similarity index 70% rename from common/components/WalletDecrypt/Trezor.jsx rename to common/components/WalletDecrypt/Trezor.tsx index dba45ddc..cd29ebef 100644 --- a/common/components/WalletDecrypt/Trezor.jsx +++ b/common/components/WalletDecrypt/Trezor.tsx @@ -1,24 +1,25 @@ -// @flow -import './Trezor.scss'; +import DPATHS from 'config/dpaths'; +import TrezorWallet from 'libs/wallet/trezor'; import React, { Component } from 'react'; -import translate from 'translations'; +import translate, { translateRaw } from 'translations'; import TrezorConnect from 'vendor/trezor-connect'; import DeterministicWalletsModal from './DeterministicWalletsModal'; -import TrezorWallet from 'libs/wallet/trezor'; -import DPATHS from 'config/dpaths.js'; +import './Trezor.scss'; const DEFAULT_PATH = DPATHS.TREZOR[0].value; -type State = { - publicKey: string, - chainCode: string, - dPath: string, - error: ?string, - isLoading: boolean -}; +interface Props { + onUnlock(param: any): void; +} +interface State { + publicKey: string; + chainCode: string; + dPath: string; + error: string | null; + isLoading: boolean; +} -export default class TrezorDecrypt extends Component { - props: { onUnlock: any => void }; - state: State = { +export default class TrezorDecrypt extends Component { + public state: State = { publicKey: '', chainCode: '', dPath: DEFAULT_PATH, @@ -26,50 +27,7 @@ export default class TrezorDecrypt extends Component { isLoading: false }; - _handlePathChange = (dPath: string) => { - this._handleConnect(dPath); - }; - - _handleConnect = (dPath: string = this.state.dPath) => { - this.setState({ - isLoading: true, - error: null - }); - - TrezorConnect.getXPubKey( - dPath, - res => { - if (res.success) { - this.setState({ - dPath, - publicKey: res.publicKey, - chainCode: res.chainCode, - isLoading: false - }); - } else { - this.setState({ - error: res.error, - isLoading: false - }); - } - }, - '1.5.2' - ); - }; - - _handleCancel = () => { - this.setState({ - publicKey: '', - chainCode: '', - dPath: DEFAULT_PATH - }); - }; - - _handleUnlock = (address: string, index: number) => { - this.props.onUnlock(new TrezorWallet(address, this.state.dPath, index)); - }; - - render() { + public render() { const { dPath, publicKey, chainCode, error, isLoading } = this.state; const showErr = error ? 'is-showing' : ''; @@ -77,7 +35,7 @@ export default class TrezorDecrypt extends Component {
    ); } + + private handlePathChange = (dPath: string) => { + this.handleConnect(dPath); + }; + + private handleConnect = (dPath: string = this.state.dPath): void => { + this.setState({ + isLoading: true, + error: null + }); + + // TODO: type vendor file + (TrezorConnect as any).getXPubKey( + dPath, + res => { + if (res.success) { + this.setState({ + dPath, + publicKey: res.publicKey, + chainCode: res.chainCode, + isLoading: false + }); + } else { + this.setState({ + error: res.error, + isLoading: false + }); + } + }, + '1.5.2' + ); + }; + + private handleCancel = () => { + this.setState({ + publicKey: '', + chainCode: '', + dPath: DEFAULT_PATH + }); + }; + + private handleUnlock = (address: string, index: number) => { + this.props.onUnlock(new TrezorWallet(address, this.state.dPath, index)); + }; + + private handleNullConnect(): void { + return this.handleConnect(); + } } diff --git a/common/components/WalletDecrypt/ViewOnly.jsx b/common/components/WalletDecrypt/ViewOnly.tsx similarity index 82% rename from common/components/WalletDecrypt/ViewOnly.jsx rename to common/components/WalletDecrypt/ViewOnly.tsx index 5c593e1c..d19dfa0a 100644 --- a/common/components/WalletDecrypt/ViewOnly.jsx +++ b/common/components/WalletDecrypt/ViewOnly.tsx @@ -2,11 +2,13 @@ import React, { Component } from 'react'; import translate from 'translations'; export default class ViewOnlyDecrypt extends Component { - render() { + public render() { return (
    -

    {translate('ADD_Radio_2_alt')}

    +

    + {translate('ADD_Radio_2_alt')} +

    @@ -14,7 +16,7 @@ export default class ViewOnlyDecrypt extends Component { {translate('ADD_Radio_2_short')} diff --git a/common/components/WalletDecrypt/index.jsx b/common/components/WalletDecrypt/index.tsx similarity index 76% rename from common/components/WalletDecrypt/index.jsx rename to common/components/WalletDecrypt/index.tsx index 4935b81f..15ff4b4f 100644 --- a/common/components/WalletDecrypt/index.jsx +++ b/common/components/WalletDecrypt/index.tsx @@ -1,22 +1,24 @@ -// @flow +import { + setWallet, + unlockKeystore, + UnlockKeystoreAction, + unlockMnemonic, + UnlockMnemonicAction, + unlockPrivateKey, + UnlockPrivateKeyAction +} from 'actions/wallet'; +import isEmpty from 'lodash/isEmpty'; +import map from 'lodash/map'; import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import { Dispatch } from 'redux'; import translate from 'translations'; import KeystoreDecrypt from './Keystore'; -import PrivateKeyDecrypt from './PrivateKey'; -import type { PrivateKeyValue } from './PrivateKey'; -import MnemonicDecrypt from './Mnemonic'; import LedgerNanoSDecrypt from './LedgerNano'; +import MnemonicDecrypt from './Mnemonic'; +import PrivateKeyDecrypt, { PrivateKeyValue } from './PrivateKey'; import TrezorDecrypt from './Trezor'; import ViewOnlyDecrypt from './ViewOnly'; -import map from 'lodash/map'; -import { - unlockPrivateKey, - unlockKeystore, - unlockMnemonic, - setWallet -} from 'actions/wallet'; -import { connect } from 'react-redux'; -import isEmpty from 'lodash/isEmpty'; const WALLETS = { 'keystore-file': { @@ -26,7 +28,8 @@ const WALLETS = { file: '', password: '' }, - unlock: unlockKeystore + unlock: unlockKeystore, + disabled: false }, 'private-key': { lid: 'x_PrivKey2', @@ -35,13 +38,15 @@ const WALLETS = { key: '', password: '' }, - unlock: unlockPrivateKey + unlock: unlockPrivateKey, + disabled: false }, 'mnemonic-phrase': { lid: 'x_Mnemonic', component: MnemonicDecrypt, initialParams: {}, - unlock: unlockMnemonic + unlock: unlockMnemonic, + disabled: false }, 'ledger-nano-s': { lid: 'x_Ledger', @@ -52,7 +57,8 @@ const WALLETS = { lid: 'x_Trezor', component: TrezorDecrypt, initialParams: {}, - unlock: setWallet + unlock: setWallet, + disabled: false }, 'view-only': { lid: 'View with Address Only', @@ -63,22 +69,25 @@ const WALLETS = { type UnlockParams = {} | PrivateKeyValue; -type State = { - selectedWalletKey: string, - value: UnlockParams -}; +interface Props { + // FIXME + dispatch: Dispatch< + UnlockKeystoreAction | UnlockMnemonicAction | UnlockPrivateKeyAction + >; +} -export class WalletDecrypt extends Component { - props: { - // FIXME - dispatch: (action: any) => void - }; - state: State = { +interface State { + selectedWalletKey: string; + value: UnlockParams; +} + +export class WalletDecrypt extends Component { + public state: State = { selectedWalletKey: 'keystore-file', value: WALLETS['keystore-file'].initialParams }; - getDecryptionComponent() { + public getDecryptionComponent() { const { selectedWalletKey, value } = this.state; const selectedWallet = WALLETS[selectedWalletKey]; @@ -95,7 +104,7 @@ export class WalletDecrypt extends Component { ); } - buildWalletOptions() { + public buildWalletOptions() { return map(WALLETS, (wallet, key) => { const isSelected = this.state.selectedWalletKey === key; @@ -119,20 +128,22 @@ export class WalletDecrypt extends Component { }); } - handleDecryptionChoiceChange = (event: SyntheticInputEvent) => { - const wallet = WALLETS[event.target.value]; + public handleDecryptionChoiceChange = ( + event: React.SyntheticEvent + ) => { + const wallet = WALLETS[(event.target as HTMLInputElement).value]; if (!wallet) { return; } this.setState({ - selectedWalletKey: event.target.value, + selectedWalletKey: (event.target as HTMLInputElement).value, value: wallet.initialParams }); }; - render() { + public render() { const decryptionComponent = this.getDecryptionComponent(); return ( @@ -146,14 +157,14 @@ export class WalletDecrypt extends Component {
    {decryptionComponent} - {!!this.state.value.valid && + {!!(this.state.value as PrivateKeyValue).valid &&

    {translate('ADD_Label_6')}

    { + public onChange = (value: UnlockParams) => { this.setState({ value }); }; - onUnlock = (payload: any) => { + public onUnlock = (payload: any) => { // some components (TrezorDecrypt) don't take an onChange prop, and thus this.state.value will remain unpopulated. // in this case, we can expect the payload to contain the unlocked wallet info. const unlockValue = diff --git a/common/components/index.js b/common/components/index.ts similarity index 96% rename from common/components/index.js rename to common/components/index.ts index b703b27b..ff1aa68b 100644 --- a/common/components/index.js +++ b/common/components/index.ts @@ -1,5 +1,3 @@ -// @flow - export { default as Header } from './Header'; export { default as Footer } from './Footer'; export { default as Root } from './Root'; diff --git a/common/components/ui/Dropdown.jsx b/common/components/ui/Dropdown.tsx similarity index 73% rename from common/components/ui/Dropdown.jsx rename to common/components/ui/Dropdown.tsx index e7948c58..18cc22d1 100644 --- a/common/components/ui/Dropdown.jsx +++ b/common/components/ui/Dropdown.tsx @@ -1,38 +1,31 @@ -// @flow import React, { Component } from 'react'; -type Props = { - value: T, - options: T[], - ariaLabel: string, - formatTitle: (option: T) => any, - extra?: any, - onChange: (value: T) => void -}; +interface Props { + value: T; + options: T[]; + ariaLabel: string; + extra?: any; + formatTitle(option: T): any; + onChange(value: T): void; +} -type State = { - expanded: boolean -}; +interface State { + expanded: boolean; +} -export default class DropdownComponent extends Component< - void, - Props, - State -> { - props: Props; - - state = { +export default class DropdownComponent extends Component, State> { + public state = { expanded: false }; - render() { + public render() { const { options, value, ariaLabel, extra } = this.props; const { expanded } = this.state; return (
    - {content || children} {/* Keep content for short-hand text insertion */} - ; - -export default NewTabLink; diff --git a/common/components/ui/NewTabLink.tsx b/common/components/ui/NewTabLink.tsx new file mode 100644 index 00000000..520986fe --- /dev/null +++ b/common/components/ui/NewTabLink.tsx @@ -0,0 +1,41 @@ +import React from 'react'; + +interface AAttributes { + charset?: string; + coords?: string; + download?: string; + href: string; + hreflang?: string; + media?: string; + name?: string; + rel?: + | 'alternate' + | 'author' + | 'bookmark' + | 'external' + | 'help' + | 'license' + | 'next' + | 'nofollow' + | 'noreferrer' + | 'noopener' + | 'prev' + | 'search' + | 'tag'; + rev?: string; + shape?: 'default' | 'rect' | 'circle' | 'poly'; + target?: '_blank' | '_parent' | '_self' | '_top'; + type?: string; +} + +interface NewTabLinkProps extends AAttributes { + content?: React.ReactElement | string; + children?: React.ReactElement | string; +} + +const NewTabLink = ({ content, children, ...rest }: NewTabLinkProps) => + + {content || children} {/* Keep content for short-hand text insertion */} + ; + +export default NewTabLink; diff --git a/common/components/ui/QRCode.jsx b/common/components/ui/QRCode.tsx similarity index 62% rename from common/components/ui/QRCode.jsx rename to common/components/ui/QRCode.tsx index 9f90609a..043f4669 100644 --- a/common/components/ui/QRCode.jsx +++ b/common/components/ui/QRCode.tsx @@ -1,59 +1,36 @@ -// @flow -import React from 'react'; import QRCodeLib from 'qrcode'; +import React from 'react'; // FIXME should store limited amount if history // data -> qr cache const cache: { [key: string]: string } = {}; -type Props = { - data: string -}; +interface Props { + data: string; +} -type State = { - qr?: string -}; +interface State { + qr?: string; +} -export default class QRCode extends React.Component { - props: Props; - state: State = {}; - - componentWillMount() { +export default class QRCode extends React.Component { + public state: State = {} + public componentWillMount() { + console.error(this.props.data) // Start generating QR codes immediately - this._generateQrCode(this.props.data); + this.generateQrCode(this.props.data); } - componentWillReceiveProps(nextProps: Props) { + public componentWillReceiveProps(nextProps: Props) { + console.error(this.props.data) + // Regenerate QR codes if props change if (nextProps.data !== this.props.data) { - this._generateQrCode(nextProps.data); + this.generateQrCode(nextProps.data); } } - _generateQrCode(value: string) { - if (cache[value]) { - this.setState({ qr: cache[value] }); - return; - } - QRCodeLib.toDataURL( - value, - { - color: { - dark: '#000', - light: '#fff' - }, - margin: 0, - errorCorrectionLevel: 'H' - }, - (err, qr) => { - if (err) return; - cache[value] = qr; - this.setState({ qr }); - } - ); - } - - render() { + public render() { const { qr } = this.state; if (!qr) { return null; @@ -68,4 +45,30 @@ export default class QRCode extends React.Component { /> ); } + + private generateQrCode(value: string) { + if (cache[value]) { + this.setState({ qr: cache[value] }); + return; + } + console.error(value, 'Value') + QRCodeLib.toDataURL( + value, + { + color: { + dark: '#000', + light: '#fff' + }, + margin: 0, + errorCorrectionLevel: 'H' + }, + (err, qr) => { + if (err) { + return; + } + cache[value] = qr; + this.setState({ qr }); + } + ); + } } diff --git a/common/components/ui/SimpleButton.jsx b/common/components/ui/SimpleButton.tsx similarity index 66% rename from common/components/ui/SimpleButton.jsx rename to common/components/ui/SimpleButton.tsx index 08daa490..9d6c00b4 100644 --- a/common/components/ui/SimpleButton.jsx +++ b/common/components/ui/SimpleButton.tsx @@ -1,12 +1,9 @@ -// @flow import React, { Component } from 'react'; -import type { Element } from 'react'; +import Spinner from './Spinner'; const DEFAULT_BUTTON_TYPE = 'primary'; const DEFAULT_BUTTON_SIZE = 'lg'; -import Spinner from './Spinner'; - type ButtonType = | 'default' | 'primary' @@ -16,26 +13,24 @@ type ButtonType = | 'danger'; type ButtonSize = 'lg' | 'sm' | 'xs'; -type Props = { - onClick: () => any, - text: Element<*> | string, - loading?: boolean, - disabled?: boolean, - loadingText?: string, - size?: ButtonSize, - type?: ButtonType -}; +interface Props { + text: React.ReactElement | string; + loading?: boolean; + disabled?: boolean; + loadingText?: string; + size?: ButtonSize; + type?: ButtonType; + onClick(): any; +} -export default class SimpleButton extends Component { - props: Props; - - computedClass = () => { +export default class SimpleButton extends Component { + public computedClass = () => { return `btn btn-${this.props.size || DEFAULT_BUTTON_TYPE} btn-${this.props .type || DEFAULT_BUTTON_SIZE}`; }; - render() { - let { loading, disabled, loadingText, text, onClick } = this.props; + public render() { + const { loading, disabled, loadingText, text, onClick } = this.props; return (
    diff --git a/common/components/ui/SimpleDropDown.jsx b/common/components/ui/SimpleDropDown.tsx similarity index 71% rename from common/components/ui/SimpleDropDown.jsx rename to common/components/ui/SimpleDropDown.tsx index fa951cb4..90793f8d 100644 --- a/common/components/ui/SimpleDropDown.jsx +++ b/common/components/ui/SimpleDropDown.tsx @@ -1,33 +1,32 @@ -// @flow import React, { Component } from 'react'; -type Props = { - value?: string, - options: string[], - onChange: (value: string) => void -}; +interface Props { + value?: string; + options: string[]; + onChange(value: string): void; +} -export default class SimpleDropDown extends Component { - props: Props; - state: { - expanded: boolean - } = { +interface State { + expanded: boolean; +} +export default class SimpleDropDown extends Component { + public state = { expanded: false }; - toggleExpanded = () => { + public toggleExpanded = () => { this.setState(state => { return { expanded: !state.expanded }; }); }; - onClick = (event: SyntheticInputEvent) => { - const value = event.target.getAttribute('data-value') || ''; + public onClick = (event: React.SyntheticEvent) => { + const value = (event.target as HTMLAnchorElement).getAttribute('data-value') || ''; this.props.onChange(value); this.setState({ expanded: false }); }; - render() { + public render() { const { options, value } = this.props; const { expanded } = this.state; return ( diff --git a/common/components/ui/SimpleSelect.jsx b/common/components/ui/SimpleSelect.tsx similarity index 66% rename from common/components/ui/SimpleSelect.jsx rename to common/components/ui/SimpleSelect.tsx index 49cca406..c9b57c78 100644 --- a/common/components/ui/SimpleSelect.jsx +++ b/common/components/ui/SimpleSelect.tsx @@ -1,16 +1,13 @@ -// @flow import React, { Component } from 'react'; -type Props = { - value?: string, - options: string[], - onChange: (event: SyntheticInputEvent) => void -}; +interface Props { + value?: string; + options: string[]; + onChange(event: React.SyntheticEvent): void; +} -export default class SimpleSelect extends Component { - props: Props; - - render() { +export default class SimpleSelect extends Component { + public render() { return (