Migrate to Typescript (#224)
* Refactor babel/types * Refactor entry point * Refactor actions * Refactor api * Full project refactor -- Broad type fixing sweep * - completely fix merge conflicts - handle various type errors * Add tslint to package.json * Dependency cleanup * Fix module resolution * Work on type definitions for untyped libs * progress commit * Add more definition typing * various type additions * Add unit types * Fix sagaiterator + unit types * various types added * additional type additions * Fix typing on Sagas * remove flowfixmes; swap translate for translateRaw * Get rid of contracts - awaiting Henry's contract PR * Remove contracts from routing * Fix most of actions/reducers * refactor actions directory structure * fix reducer action type imports * Fix most of type errors pre-actions refactor * fix action creator imports in containers * Refactor more * Refactor index of actions * fix action imports; use module level index export * package-lock.json updated * Use action types in props * Type up action creators * Fix most of connect errors * Typefixing progress * More types * Fix run-time errors * Caching improvements for webpack * Remove path resolve from webpack * Update non-breaking packages to latest version * Fix token typing * Remove unused color code * Fix wallet decrypt dispatch * Set redux-form related props/functions to ANY, since we're stripping it out later on * Revert BigNumber.js package changes * Extend window to custom object for Perf * Format Navigation * Typecase keystore errors as any (since we shouldnt touch this) * Push wallet context fix * - find/replace value->payload in swap - properly type swap state properties - extract inline reducer into reducer function * - type local storage retrieved items as generic * - bind all RPCClient methods with fat arrow * - reformat * Change to enums for constants * Change state into any * Fix swap errors * ensure that seconds are passed into state as integers * Fix rest of errors * use parseInt explicitly instead of type coercion * Fix derivation-checker, remove flow command, add tslint command, add tslint-react, tell travis to use tslint instead of flow. * Whoops, remove those tests. * Remove unsupported (yet) config option. * Fix precommit to target ts and tsx files. * Fix some errors, ignore some silly rules. * Revert jest to v19, use ts-jest and make all tests typescript. Fixes all but one. * Get rid of saga tests * Fix tslint errors
This commit is contained in:
parent
5e66cccac5
commit
5d4b36d453
25
.babelrc
25
.babelrc
|
@ -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"]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -46,6 +46,7 @@ jspm_packages
|
|||
.vscode/
|
||||
static/dll.vendor.js
|
||||
dll
|
||||
.cache-loader
|
||||
|
||||
# SSL cert stuff
|
||||
webpack_config/server.key
|
||||
|
|
|
@ -15,4 +15,4 @@ notifications:
|
|||
|
||||
script:
|
||||
- npm run test
|
||||
- npm run flow
|
||||
- npm run tslint
|
||||
|
|
|
@ -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;
|
|
@ -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
|
||||
};
|
||||
}
|
|
@ -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;
|
|
@ -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'
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './actionCreators';
|
||||
export * from './actionTypes';
|
|
@ -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<ABIFunctionField>,
|
||||
outputs: Array<ABIFunctionField>
|
||||
};
|
||||
|
||||
export type SetInteractiveContractAction = {
|
||||
type: 'SET_INTERACTIVE_CONTRACT',
|
||||
functions: Array<ABIFunction>
|
||||
};
|
||||
|
||||
export function setInteractiveContract(
|
||||
functions: Array<ABIFunction>
|
||||
): SetInteractiveContractAction {
|
||||
return {
|
||||
type: 'SET_INTERACTIVE_CONTRACT',
|
||||
functions
|
||||
};
|
||||
}
|
|
@ -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
|
||||
};
|
||||
}
|
|
@ -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;
|
|
@ -0,0 +1,4 @@
|
|||
export enum TypeKeys {
|
||||
ACCESS_CONTRACT = 'ACCESS_CONTRACT',
|
||||
SET_INTERACTIVE_CONTRACT = 'SET_INTERACTIVE_CONTRACT'
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export * from './constants';
|
||||
export * from './actionTypes';
|
||||
export * from './actionCreators';
|
|
@ -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;
|
|
@ -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
|
||||
};
|
||||
}
|
|
@ -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;
|
|
@ -0,0 +1,4 @@
|
|||
export enum TypeKeys {
|
||||
CUSTOM_TOKEN_ADD = 'CUSTOM_TOKEN_ADD',
|
||||
CUSTOM_TOKEN_REMOVE = 'CUSTOM_TOKEN_REMOVE'
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './actionCreators';
|
||||
export * from './actionTypes';
|
|
@ -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;
|
|
@ -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
|
||||
};
|
||||
}
|
|
@ -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;
|
|
@ -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'
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './actionTypes';
|
||||
export * from './actionCreators';
|
|
@ -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;
|
|
@ -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
|
||||
}
|
||||
};
|
||||
}
|
|
@ -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;
|
|
@ -0,0 +1,2 @@
|
|||
export const ENS_RESOLVE = 'ENS_RESOLVE';
|
||||
export const ENS_CACHE = 'ENS_CACHE';
|
|
@ -0,0 +1,3 @@
|
|||
export * from './constants';
|
||||
export * from './actionTypes';
|
||||
export * from './actionCreators';
|
|
@ -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;
|
|
@ -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 };
|
||||
}
|
|
@ -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;
|
|
@ -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'
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export * from './constants';
|
||||
export * from './actionTypes';
|
||||
export * from './actionCreators';
|
|
@ -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;
|
|
@ -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<any> | 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
|
||||
};
|
||||
}
|
|
@ -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<any> | 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;
|
|
@ -0,0 +1,4 @@
|
|||
export enum TypeKeys {
|
||||
SHOW_NOTIFICATION = 'SHOW_NOTIFICATION',
|
||||
CLOSE_NOTIFICATION = 'CLOSE_NOTIFICATION'
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './actionTypes';
|
||||
export * from './actionCreators';
|
|
@ -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;
|
|
@ -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
|
||||
};
|
||||
}
|
|
@ -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;
|
|
@ -0,0 +1,4 @@
|
|||
export enum TypeKeys {
|
||||
RATES_FIAT_REQUESTED = 'RATES_FIAT_REQUESTED',
|
||||
RATES_FIAT_SUCCEEDED = 'RATES_FIAT_SUCCEEDED'
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './actionCreators';
|
||||
export * from './actionTypes';
|
|
@ -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'
|
||||
};
|
||||
}
|
|
@ -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
|
||||
};
|
||||
}
|
|
@ -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;
|
|
@ -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'
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
export * from './actionTypes';
|
||||
export * from './actionCreators';
|
|
@ -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;
|
|
@ -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;
|
|
@ -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
|
||||
}
|
||||
};
|
||||
}
|
|
@ -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;
|
|
@ -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';
|
|
@ -0,0 +1,3 @@
|
|||
export * from './constants';
|
||||
export * from './actionTypes';
|
||||
export * from './actionCreators';
|
|
@ -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
|
||||
})
|
||||
|
@ -61,5 +49,3 @@ function _getAllRates() {
|
|||
.then(checkHttpStatus)
|
||||
.then(parseJSON);
|
||||
}
|
||||
|
||||
// function requestOrderStatus() {}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -3,35 +3,17 @@ import './index.scss';
|
|||
|
||||
const LS_KEY = 'acknowledged-alpha';
|
||||
|
||||
export default class AlphaAgreement extends React.Component {
|
||||
state = {
|
||||
isFading: false,
|
||||
hasAcknowledged: false
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
hasAcknowledged: localStorage.getItem(LS_KEY),
|
||||
interface State {
|
||||
isFading: boolean;
|
||||
hasAcknowledged: boolean;
|
||||
}
|
||||
export default class AlphaAgreement extends React.Component<{}, State> {
|
||||
public 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 {
|
|||
<div className="AlphaAgreement-content-buttons">
|
||||
<button
|
||||
className="AlphaAgreement-content-buttons-btn is-reject"
|
||||
onClick={this._reject}
|
||||
onClick={this.reject}
|
||||
>
|
||||
No, Take Me to v3
|
||||
</button>
|
||||
<button
|
||||
className="AlphaAgreement-content-buttons-btn is-continue"
|
||||
onClick={this._continue}
|
||||
onClick={this.doContinue}
|
||||
>
|
||||
Yes, Continue to v4
|
||||
</button>
|
||||
|
@ -73,4 +55,17 @@ export default class AlphaAgreement extends React.Component {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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');
|
||||
};
|
||||
}
|
|
@ -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<Props, State> {
|
||||
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;
|
|
@ -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<Props, {}> {
|
||||
public render() {
|
||||
const { balance, rates } = this.props;
|
||||
|
||||
return (
|
||||
|
@ -27,7 +24,9 @@ export default class EquivalentValues extends React.Component {
|
|||
<ul className="EquivalentValues-values">
|
||||
{rates
|
||||
? ratesKeys.map(key => {
|
||||
if (!rates[key]) return null;
|
||||
if (!rates[key]) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<li className="EquivalentValues-values-currency" key={key}>
|
||||
<span className="EquivalentValues-values-currency-label">
|
|
@ -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: [<h6 key="1">Learn more about protecting your funds.</h6>],
|
||||
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: [
|
||||
<p key="1">It’s now easier to get more ETH</p>,
|
||||
<h5 key="2">Buy ETH with USD</h5>
|
||||
|
@ -27,6 +27,7 @@ const promos = [
|
|||
images: [require('assets/images/logo-coinbase.svg')]
|
||||
},
|
||||
{
|
||||
isExternal: false,
|
||||
color: '#006e79',
|
||||
href: '/swap',
|
||||
texts: [
|
||||
|
@ -37,33 +38,29 @@ 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 = (
|
||||
<div className="Promos-promo-inner">
|
||||
<div className="Promos-promo-text">
|
||||
{promo.texts}
|
||||
</div>
|
||||
<div className="Promos-promo-text">{promo.texts}</div>
|
||||
<div className="Promos-promo-images">
|
||||
{promo.images.map((img, idx) => <img src={img} key={idx} />)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
const promoEl = promo.isExternal
|
||||
? <a
|
||||
const promoEl = promo.isExternal ? (
|
||||
<a
|
||||
className="Promos-promo"
|
||||
key={promo.href}
|
||||
target="_blank"
|
||||
|
@ -72,29 +69,29 @@ export default class Promos extends React.Component {
|
|||
>
|
||||
{promoContent}
|
||||
</a>
|
||||
: <Link
|
||||
) : (
|
||||
<Link
|
||||
className="Promos-promo"
|
||||
key={promo.href}
|
||||
to={promo.href}
|
||||
style={{ backgroundColor: promo.color }}
|
||||
>
|
||||
<div className="Promos-promo-inner">
|
||||
{promoContent}
|
||||
</div>
|
||||
</Link>;
|
||||
<div className="Promos-promo-inner">{promoContent}</div>
|
||||
</Link>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="Promos">
|
||||
{promoEl}
|
||||
<div className="Promos-nav">
|
||||
{promos.map((promo, idx) => {
|
||||
{promos.map((_, index) => {
|
||||
return (
|
||||
<button
|
||||
className={`Promos-nav-btn ${idx === activePromo
|
||||
className={`Promos-nav-btn ${index === activePromo
|
||||
? 'is-active'
|
||||
: ''}`}
|
||||
key={idx}
|
||||
onClick={() => this._navigateToPromo(idx)}
|
||||
key={index}
|
||||
onClick={this.navigateToPromo(index)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
@ -102,4 +99,8 @@ export default class Promos extends React.Component {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private navigateToPromo = (idx: number) => () => {
|
||||
this.setState({ activePromo: Math.max(0, Math.min(promos.length, idx)) });
|
||||
};
|
||||
}
|
|
@ -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<Props, State> {
|
||||
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 (
|
||||
<label className="AddCustom-field form-group" key={field.name}>
|
||||
<span className="AddCustom-field-label">
|
||||
{field.label}
|
||||
</span>
|
||||
<span className="AddCustom-field-label">{field.label}</span>
|
||||
<input
|
||||
className={classnames(
|
||||
inputClasses,
|
||||
|
@ -69,9 +74,13 @@ export default class AddCustomTokenForm extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
getErrors() {
|
||||
public getErrors() {
|
||||
const { address, symbol, decimal } = this.state;
|
||||
const errors = {};
|
||||
const errors = {
|
||||
decimal: false,
|
||||
address: false,
|
||||
symbol: false
|
||||
};
|
||||
|
||||
if (!isPositiveIntegerOrZero(parseInt(decimal, 10))) {
|
||||
errors.decimal = true;
|
||||
|
@ -86,17 +95,18 @@ export default class AddCustomTokenForm extends React.Component {
|
|||
return errors;
|
||||
}
|
||||
|
||||
isValid() {
|
||||
public isValid() {
|
||||
return !Object.keys(this.getErrors()).length;
|
||||
}
|
||||
|
||||
onFieldChange = (e: SyntheticInputEvent) => {
|
||||
var name = e.target.name;
|
||||
var value = e.target.value;
|
||||
public onFieldChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
|
||||
// TODO: typescript bug: https://github.com/Microsoft/TypeScript/issues/13948
|
||||
const name: any = (e.target as HTMLInputElement).name;
|
||||
const value = (e.target as HTMLInputElement).value;
|
||||
this.setState({ [name]: value });
|
||||
};
|
||||
|
||||
onSave = (ev: SyntheticInputEvent) => {
|
||||
public onSave = (ev: React.SyntheticEvent<HTMLFormElement>) => {
|
||||
ev.preventDefault();
|
||||
if (!this.isValid()) {
|
||||
return;
|
|
@ -1,22 +1,24 @@
|
|||
// @flow
|
||||
import './TokenRow.scss';
|
||||
import React from 'react';
|
||||
import Big from 'bignumber.js';
|
||||
import { formatNumber } from 'utils/formatters';
|
||||
import removeIcon from 'assets/images/icon-remove.svg';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import React from 'react';
|
||||
import { formatNumber } from 'utils/formatters';
|
||||
import './TokenRow.scss';
|
||||
|
||||
export default class TokenRow extends React.Component {
|
||||
props: {
|
||||
balance: Big,
|
||||
symbol: string,
|
||||
custom?: boolean,
|
||||
onRemove: (symbol: string) => void
|
||||
};
|
||||
interface Props {
|
||||
balance: BigNumber;
|
||||
symbol: string;
|
||||
custom?: boolean;
|
||||
onRemove(symbol: string): void;
|
||||
}
|
||||
interface State {
|
||||
showLongBalance: boolean;
|
||||
}
|
||||
|
||||
state = {
|
||||
export default class TokenRow extends React.Component<Props, State> {
|
||||
public state = {
|
||||
showLongBalance: false
|
||||
};
|
||||
render() {
|
||||
public render() {
|
||||
const { balance, symbol, custom } = this.props;
|
||||
const { showLongBalance } = this.state;
|
||||
return (
|
||||
|
@ -32,7 +34,7 @@ export default class TokenRow extends React.Component {
|
|||
className="TokenRow-balance-remove"
|
||||
title="Remove Token"
|
||||
onClick={this.onRemove}
|
||||
tabIndex="0"
|
||||
tabIndex={0}
|
||||
/>}
|
||||
<span>
|
||||
{showLongBalance ? balance.toString() : formatNumber(balance)}
|
||||
|
@ -45,7 +47,10 @@ export default class TokenRow extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
toggleShowLongBalance = (e: SyntheticInputEvent) => {
|
||||
public toggleShowLongBalance = (
|
||||
// TODO: don't use any
|
||||
e: any
|
||||
) => {
|
||||
e.preventDefault();
|
||||
this.setState(state => {
|
||||
return {
|
||||
|
@ -54,7 +59,7 @@ export default class TokenRow extends React.Component {
|
|||
});
|
||||
};
|
||||
|
||||
onRemove = () => {
|
||||
public onRemove = () => {
|
||||
this.props.onRemove(this.props.symbol);
|
||||
};
|
||||
}
|
|
@ -1,26 +1,28 @@
|
|||
// @flow
|
||||
import './index.scss';
|
||||
import { Token } from 'config/data';
|
||||
import React from 'react';
|
||||
import { TokenBalance } from 'selectors/wallet';
|
||||
import translate from 'translations';
|
||||
import TokenRow from './TokenRow';
|
||||
import AddCustomTokenForm from './AddCustomTokenForm';
|
||||
import type { TokenBalance } from 'selectors/wallet';
|
||||
import type { Token } from 'config/data';
|
||||
import './index.scss';
|
||||
import TokenRow from './TokenRow';
|
||||
|
||||
type Props = {
|
||||
tokens: TokenBalance[],
|
||||
onAddCustomToken: (token: Token) => any,
|
||||
onRemoveCustomToken: (symbol: string) => any
|
||||
};
|
||||
interface Props {
|
||||
tokens: TokenBalance[];
|
||||
onAddCustomToken(token: Token): any;
|
||||
onRemoveCustomToken(symbol: string): any;
|
||||
}
|
||||
|
||||
export default class TokenBalances extends React.Component {
|
||||
props: Props;
|
||||
state = {
|
||||
interface State {
|
||||
showAllTokens: boolean;
|
||||
showCustomTokenForm: boolean;
|
||||
}
|
||||
export default class TokenBalances extends React.Component<Props, State> {
|
||||
public state = {
|
||||
showAllTokens: false,
|
||||
showCustomTokenForm: false
|
||||
};
|
||||
|
||||
render() {
|
||||
public render() {
|
||||
const { tokens } = this.props;
|
||||
const shownTokens = tokens.filter(
|
||||
token => !token.balance.eq(0) || token.custom || this.state.showAllTokens
|
||||
|
@ -70,7 +72,7 @@ export default class TokenBalances extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
toggleShowAllTokens = () => {
|
||||
public toggleShowAllTokens = () => {
|
||||
this.setState(state => {
|
||||
return {
|
||||
showAllTokens: !state.showAllTokens
|
||||
|
@ -78,7 +80,7 @@ export default class TokenBalances extends React.Component {
|
|||
});
|
||||
};
|
||||
|
||||
toggleShowCustomTokenForm = () => {
|
||||
public toggleShowCustomTokenForm = () => {
|
||||
this.setState(state => {
|
||||
return {
|
||||
showCustomTokenForm: !state.showCustomTokenForm
|
||||
|
@ -86,7 +88,7 @@ export default class TokenBalances extends React.Component {
|
|||
});
|
||||
};
|
||||
|
||||
addCustomToken = (token: Token) => {
|
||||
public addCustomToken = (token: Token) => {
|
||||
this.props.onAddCustomToken(token);
|
||||
this.setState({ showCustomTokenForm: false });
|
||||
};
|
|
@ -1,39 +1,51 @@
|
|||
// @flow
|
||||
import {
|
||||
addCustomToken,
|
||||
removeCustomToken,
|
||||
TAddCustomToken,
|
||||
TRemoveCustomToken
|
||||
} from 'actions/customTokens';
|
||||
import { showNotification, TShowNotification } from 'actions/notifications';
|
||||
import {
|
||||
fiatRequestedRates as dFiatRequestedRates,
|
||||
TFiatRequestedRates
|
||||
} from 'actions/rates';
|
||||
import { NetworkConfig } from 'config/data';
|
||||
import { Ether } from 'libs/units';
|
||||
import { IWallet } from 'libs/wallet/IWallet';
|
||||
import React from 'react';
|
||||
import { IWallet } from 'libs/wallet';
|
||||
import type { NetworkConfig } from 'config/data';
|
||||
import type { State } from 'reducers';
|
||||
import { connect } from 'react-redux';
|
||||
import { getWalletInst, getTokenBalances } from 'selectors/wallet';
|
||||
import type { TokenBalance } from 'selectors/wallet';
|
||||
import { AppState } from 'reducers';
|
||||
import { getNetworkConfig } from 'selectors/config';
|
||||
import * as customTokenActions from 'actions/customTokens';
|
||||
import { showNotification } from 'actions/notifications';
|
||||
import { fiatRequestedRates } from 'actions/rates';
|
||||
import type { FiatRequestedRatesAction } from 'actions/rates';
|
||||
|
||||
import {
|
||||
getTokenBalances,
|
||||
getWalletInst,
|
||||
TokenBalance
|
||||
} from 'selectors/wallet';
|
||||
import AccountInfo from './AccountInfo';
|
||||
import EquivalentValues from './EquivalentValues';
|
||||
import Promos from './Promos';
|
||||
import TokenBalances from './TokenBalances';
|
||||
import EquivalentValues from './EquivalentValues';
|
||||
import { Ether } from 'libs/units';
|
||||
|
||||
type Props = {
|
||||
wallet: IWallet,
|
||||
balance: Ether,
|
||||
network: NetworkConfig,
|
||||
tokenBalances: TokenBalance[],
|
||||
rates: { [string]: number },
|
||||
showNotification: Function,
|
||||
addCustomToken: typeof customTokenActions.addCustomToken,
|
||||
removeCustomToken: typeof customTokenActions.removeCustomToken,
|
||||
fiatRequestedRates: () => FiatRequestedRatesAction
|
||||
};
|
||||
interface Props {
|
||||
wallet: IWallet;
|
||||
balance: Ether;
|
||||
network: NetworkConfig;
|
||||
tokenBalances: TokenBalance[];
|
||||
rates: { [key: string]: number };
|
||||
showNotification: TShowNotification;
|
||||
addCustomToken: TAddCustomToken;
|
||||
removeCustomToken: TRemoveCustomToken;
|
||||
fiatRequestedRates: TFiatRequestedRates;
|
||||
}
|
||||
|
||||
export class BalanceSidebar extends React.Component {
|
||||
props: Props;
|
||||
interface Block {
|
||||
name: string;
|
||||
content: React.ReactElement<any>;
|
||||
isFullWidth?: boolean;
|
||||
}
|
||||
|
||||
render() {
|
||||
export class BalanceSidebar extends React.Component<Props, {}> {
|
||||
public render() {
|
||||
const {
|
||||
wallet,
|
||||
balance,
|
||||
|
@ -46,7 +58,7 @@ export class BalanceSidebar extends React.Component {
|
|||
return null;
|
||||
}
|
||||
|
||||
const blocks = [
|
||||
const blocks: Block[] = [
|
||||
{
|
||||
name: 'Account Info',
|
||||
content: (
|
||||
|
@ -94,7 +106,7 @@ export class BalanceSidebar extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state: State) {
|
||||
function mapStateToProps(state: AppState) {
|
||||
return {
|
||||
wallet: getWalletInst(state),
|
||||
balance: state.wallet.balance,
|
||||
|
@ -105,7 +117,8 @@ function mapStateToProps(state: State) {
|
|||
}
|
||||
|
||||
export default connect(mapStateToProps, {
|
||||
...customTokenActions,
|
||||
addCustomToken,
|
||||
removeCustomToken,
|
||||
showNotification,
|
||||
fiatRequestedRates
|
||||
fiatRequestedRates: dFiatRequestedRates
|
||||
})(BalanceSidebar);
|
|
@ -1,11 +1,11 @@
|
|||
import { BlockExplorerConfig } from 'config/data';
|
||||
import React from 'react';
|
||||
import type { BlockExplorerConfig } from 'config.data';
|
||||
import translate from 'translations';
|
||||
import {translateRaw} from 'translations';
|
||||
|
||||
export type TransactionSucceededProps = {
|
||||
txHash: string,
|
||||
blockExplorer: BlockExplorerConfig
|
||||
};
|
||||
export interface TransactionSucceededProps {
|
||||
txHash: string;
|
||||
blockExplorer: BlockExplorerConfig;
|
||||
}
|
||||
|
||||
const TransactionSucceeded = ({
|
||||
txHash,
|
||||
|
@ -17,7 +17,7 @@ const TransactionSucceeded = ({
|
|||
return (
|
||||
<div>
|
||||
<p>
|
||||
{translate('SUCCESS_3', true) + txHash}
|
||||
{translateRaw('SUCCESS_3') + txHash}
|
||||
</p>
|
||||
<a
|
||||
className="btn btn-xs btn-info string"
|
|
@ -1,10 +1,9 @@
|
|||
import logo from 'assets/images/logo-myetherwallet.svg';
|
||||
import { bityReferralURL, donationAddressMap } from 'config/data';
|
||||
import React, { Component } from 'react';
|
||||
import translate from 'translations';
|
||||
import { donationAddressMap } from 'config/data';
|
||||
import logo from 'assets/images/logo-myetherwallet.svg';
|
||||
import { bityReferralURL } from 'config/data';
|
||||
import PreFooter from './PreFooter';
|
||||
import './index.scss';
|
||||
import PreFooter from './PreFooter';
|
||||
|
||||
const LINKS_LEFT = [
|
||||
{
|
||||
|
@ -93,7 +92,7 @@ const LINKS_SOCIAL = [
|
|||
];
|
||||
|
||||
export default class Footer extends Component {
|
||||
render() {
|
||||
public render() {
|
||||
return (
|
||||
<div>
|
||||
<PreFooter />
|
|
@ -1,30 +1,24 @@
|
|||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import throttle from 'lodash/throttle';
|
||||
|
||||
import './GasPriceDropdown.scss';
|
||||
import { gasPriceDefaults } from 'config/data';
|
||||
import throttle from 'lodash/throttle';
|
||||
import React, { Component } from 'react';
|
||||
import './GasPriceDropdown.scss';
|
||||
|
||||
type Props = {
|
||||
value: number,
|
||||
onChange: (gasPrice: number) => void
|
||||
};
|
||||
|
||||
export default class GasPriceDropdown extends Component {
|
||||
state = { expanded: false };
|
||||
|
||||
static propTypes = {
|
||||
value: PropTypes.number,
|
||||
onChange: PropTypes.func.isRequired
|
||||
};
|
||||
interface Props {
|
||||
value: number;
|
||||
onChange(gasPrice: number): void;
|
||||
}
|
||||
interface State {
|
||||
expanded: boolean;
|
||||
}
|
||||
export default class GasPriceDropdown extends Component<Props, State> {
|
||||
public state = { expanded: false };
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.updateGasPrice = throttle(this.updateGasPrice, 50);
|
||||
}
|
||||
|
||||
render() {
|
||||
public render() {
|
||||
const { expanded } = this.state;
|
||||
return (
|
||||
<span className={`dropdown ${expanded ? 'open' : ''}`}>
|
||||
|
@ -78,7 +72,7 @@ export default class GasPriceDropdown extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
toggleExpanded = () => {
|
||||
public toggleExpanded = () => {
|
||||
this.setState(state => {
|
||||
return {
|
||||
expanded: !state.expanded
|
||||
|
@ -86,11 +80,11 @@ export default class GasPriceDropdown extends Component {
|
|||
});
|
||||
};
|
||||
|
||||
updateGasPrice = (value: string) => {
|
||||
public updateGasPrice = (value: string) => {
|
||||
this.props.onChange(parseInt(value, 10));
|
||||
};
|
||||
|
||||
handleGasPriceChange = (e: SyntheticInputEvent) => {
|
||||
this.updateGasPrice(e.target.value);
|
||||
public handleGasPriceChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
|
||||
this.updateGasPrice((e.target as HTMLInputElement).value);
|
||||
};
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import NavigationLink from './NavigationLink';
|
||||
|
||||
import './Navigation.scss';
|
||||
|
@ -20,10 +20,6 @@ const tabs = [
|
|||
{
|
||||
name: 'NAV_Offline'
|
||||
},
|
||||
{
|
||||
name: 'NAV_Contracts',
|
||||
to: 'contracts'
|
||||
},
|
||||
{
|
||||
name: 'NAV_ViewWallet'
|
||||
// to: 'view-wallet'
|
||||
|
@ -39,27 +35,35 @@ const tabs = [
|
|||
}
|
||||
];
|
||||
|
||||
export default class Navigation extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
interface Props {
|
||||
location: object;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
interface State {
|
||||
showLeftArrow: boolean;
|
||||
showRightArrow: boolean;
|
||||
}
|
||||
|
||||
interface BorderStyle {
|
||||
borderTopColor?: string;
|
||||
}
|
||||
|
||||
export default class Navigation extends Component<Props, State> {
|
||||
public state = {
|
||||
showLeftArrow: false,
|
||||
showRightArrow: false
|
||||
};
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
location: PropTypes.object,
|
||||
color: PropTypes.string
|
||||
};
|
||||
/*
|
||||
* public scrollLeft() {}
|
||||
public scrollRight() {}
|
||||
*
|
||||
*/
|
||||
|
||||
scrollLeft() {}
|
||||
|
||||
scrollRight() {}
|
||||
|
||||
render() {
|
||||
public render() {
|
||||
const { location, color } = this.props;
|
||||
const borderStyle = {};
|
||||
const borderStyle: BorderStyle = {};
|
||||
|
||||
if (color) {
|
||||
borderStyle.borderTopColor = color;
|
||||
|
@ -72,14 +76,15 @@ export default class Navigation extends Component {
|
|||
className="Navigation"
|
||||
style={borderStyle}
|
||||
>
|
||||
{this.state.showLeftArrow &&
|
||||
{this.state.showLeftArrow && (
|
||||
<a
|
||||
aria-hidden="true"
|
||||
className="Navigation-arrow Navigation-arrow--left"
|
||||
onClick={() => this.scrollLeft(100)}
|
||||
// onClick={() => this.scrollLeft()}
|
||||
>
|
||||
«
|
||||
</a>}
|
||||
</a>
|
||||
)}
|
||||
|
||||
<div className="Navigation-scroll container">
|
||||
<ul className="Navigation-links">
|
||||
|
@ -95,14 +100,15 @@ export default class Navigation extends Component {
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
{this.state.showRightArrow &&
|
||||
{this.state.showRightArrow && (
|
||||
<a
|
||||
aria-hidden="true"
|
||||
className="Navigation-arrow Navigation-arrow-right"
|
||||
onClick={() => this.scrollRight(100)}
|
||||
// onClick={() => this.scrollRight()}
|
||||
>
|
||||
»
|
||||
</a>}
|
||||
</a>
|
||||
)}
|
||||
</nav>
|
||||
);
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import translate from 'translations';
|
||||
import { Link } from 'react-router';
|
||||
import './NavigationLink.scss';
|
||||
|
||||
type Props = {
|
||||
link: {
|
||||
name: string,
|
||||
to?: string,
|
||||
external?: boolean
|
||||
},
|
||||
location: Object
|
||||
};
|
||||
|
||||
export default class NavigationLink extends React.Component {
|
||||
props: Props;
|
||||
|
||||
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
|
||||
});
|
||||
// $FlowFixMe flow is wrong, this isn't an element
|
||||
const linkLabel = `nav item: ${translate(link.name, true)}`;
|
||||
|
||||
const linkEl = link.external
|
||||
? <a
|
||||
className={linkClasses}
|
||||
href={link.to}
|
||||
aria-label={linkLabel}
|
||||
target="_blank"
|
||||
>
|
||||
{translate(link.name)}
|
||||
</a>
|
||||
: <Link className={linkClasses} to={link.to} aria-label={linkLabel}>
|
||||
{translate(link.name)}
|
||||
</Link>;
|
||||
|
||||
return (
|
||||
<li className="NavigationLink">
|
||||
{linkEl}
|
||||
</li>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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<Props, {}> {
|
||||
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 ? (
|
||||
<a
|
||||
className={linkClasses}
|
||||
href={link.to}
|
||||
aria-label={linkLabel}
|
||||
target="_blank"
|
||||
>
|
||||
{translate(link.name)}
|
||||
</a>
|
||||
) : (
|
||||
<Link
|
||||
className={linkClasses}
|
||||
to={(link as any).to}
|
||||
aria-label={linkLabel}
|
||||
>
|
||||
{translate(link.name)}
|
||||
</Link>
|
||||
);
|
||||
|
||||
return <li className="NavigationLink">{linkEl}</li>;
|
||||
}
|
||||
}
|
|
@ -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<Props, {}> {
|
||||
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<keyof typeof NODES>;
|
||||
return (
|
||||
<div className="Header">
|
||||
{ANNOUNCEMENT_MESSAGE &&
|
||||
{ANNOUNCEMENT_MESSAGE && (
|
||||
<div
|
||||
className={`Header-announcement is-${ANNOUNCEMENT_TYPE}`}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: ANNOUNCEMENT_MESSAGE
|
||||
}}
|
||||
/>}
|
||||
/>
|
||||
)}
|
||||
|
||||
<section className="Header-branding">
|
||||
<section className="Header-branding-inner container">
|
||||
|
@ -71,10 +75,10 @@ export default class Header extends Component {
|
|||
onChange={this.props.changeGasPrice}
|
||||
/>
|
||||
|
||||
<Dropdown
|
||||
<LanguageDropDown
|
||||
ariaLabel={`change language. current language ${selectedLanguage.name}`}
|
||||
options={languages}
|
||||
formatTitle={o => o.name}
|
||||
formatTitle={this.extractName}
|
||||
value={selectedLanguage}
|
||||
extra={[
|
||||
<li key={'separator'} role="separator" className="divider" />,
|
||||
|
@ -87,20 +91,14 @@ export default class Header extends Component {
|
|||
onChange={this.changeLanguage}
|
||||
/>
|
||||
|
||||
<Dropdown
|
||||
<NodeDropDown
|
||||
ariaLabel={`change node. current node ${selectedNode.network} node by ${selectedNode.service}`}
|
||||
options={Object.keys(NODES)}
|
||||
formatTitle={o => [
|
||||
NODES[o].network,
|
||||
' ',
|
||||
<small key="service">
|
||||
({NODES[o].service})
|
||||
</small>
|
||||
]}
|
||||
formatTitle={this.nodeNetworkAndService}
|
||||
value={nodeSelection}
|
||||
extra={
|
||||
<li>
|
||||
<a onClick={() => {}}>Add Custom Node</a>
|
||||
<a>Add Custom Node</a>
|
||||
</li>
|
||||
}
|
||||
onChange={changeNode}
|
||||
|
@ -111,13 +109,23 @@ export default class Header extends Component {
|
|||
|
||||
<Navigation
|
||||
location={this.props.location}
|
||||
color={selectedNetwork.color}
|
||||
// color={selectedNetwork.color}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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,
|
||||
' ',
|
||||
<small key="service">({NODES[option].service}) </small>
|
||||
];
|
||||
}
|
|
@ -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<Props, State> {
|
||||
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 (
|
|
@ -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<Props, {}> {
|
||||
public print = () => {
|
||||
printElement(<PaperWallet wallet={this.props.wallet} />, {
|
||||
popupFeatures: {
|
||||
scrollbars: 'no'
|
||||
|
@ -36,7 +29,7 @@ export default class PrintableWallet extends Component {
|
|||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
public render() {
|
||||
return (
|
||||
<div>
|
||||
<PaperWallet wallet={this.props.wallet} />
|
|
@ -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<Props, {}> {
|
||||
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 (
|
|
@ -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);
|
|
@ -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<Props, State> {
|
||||
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 (
|
||||
<Modal
|
||||
title={`Unlock your ${walletType || ''} Wallet`}
|
||||
isOpen={this.props.isOpen}
|
||||
buttons={buttons}
|
||||
handleClose={onCancel}
|
||||
>
|
||||
<div className="DWModal">
|
||||
<form
|
||||
className="DWModal-path form-group-sm"
|
||||
onSubmit={this.handleSubmitCustomPath}
|
||||
>
|
||||
<span className="DWModal-path-label">Addresses for</span>
|
||||
<select
|
||||
className="form-control"
|
||||
onChange={this.handleChangePath}
|
||||
value={isCustomPath ? 'custom' : dPath}
|
||||
>
|
||||
{dPaths.map(dp =>
|
||||
<option key={dp.value} value={dp.value}>
|
||||
{dp.label}
|
||||
</option>
|
||||
)}
|
||||
<option value="custom">Custom path...</option>
|
||||
</select>
|
||||
{isCustomPath &&
|
||||
<input
|
||||
className={`form-control ${validPathClass}`}
|
||||
value={customPath}
|
||||
placeholder="m/44'/60'/0'/0"
|
||||
onChange={this.handleChangeCustomPath}
|
||||
/>}
|
||||
</form>
|
||||
|
||||
<div className="DWModal-addresses">
|
||||
<table className="DWModal-addresses-table table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>#</td>
|
||||
<td>Address</td>
|
||||
<td>
|
||||
{network.unit}
|
||||
</td>
|
||||
<td>
|
||||
<select
|
||||
className="DWModal-addresses-table-token"
|
||||
value={desiredToken}
|
||||
onChange={this.handleChangeToken}
|
||||
>
|
||||
<option value="">-Token-</option>
|
||||
{tokens.map(t =>
|
||||
<option key={t.symbol} value={t.symbol}>
|
||||
{t.symbol}
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
</td>
|
||||
<td>More</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{wallets.map(wallet => this.renderWalletRow(wallet))}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div className="DWModal-addresses-nav">
|
||||
<button
|
||||
className="DWModal-addresses-nav-btn btn btn-sm btn-default"
|
||||
disabled={page === 0}
|
||||
onClick={this.prevPage}
|
||||
>
|
||||
← Back
|
||||
</button>
|
||||
<button
|
||||
className="DWModal-addresses-nav-btn btn btn-sm btn-default"
|
||||
onClick={this.nextPage}
|
||||
>
|
||||
More →
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
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<HTMLSelectElement>) => {
|
||||
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<HTMLInputElement>
|
||||
) => {
|
||||
this.setState({ customPath: (ev.target as HTMLInputElement).value });
|
||||
};
|
||||
|
||||
_handleSubmitCustomPath = (ev: SyntheticInputEvent) => {
|
||||
private handleSubmitCustomPath = (
|
||||
ev: React.SyntheticEvent<HTMLFormElement>
|
||||
) => {
|
||||
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<HTMLSelectElement>) => {
|
||||
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 (
|
||||
<tr
|
||||
key={wallet.address}
|
||||
onClick={this._selectAddress.bind(this, wallet.address, wallet.index)}
|
||||
onClick={this.selectAddress.bind(this, wallet.address, wallet.index)}
|
||||
>
|
||||
<td>
|
||||
{wallet.index + 1}
|
||||
|
@ -188,120 +309,6 @@ class DeterministicWalletsModal extends React.Component {
|
|||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
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 (
|
||||
<Modal
|
||||
title={`Unlock your ${walletType || ''} Wallet`}
|
||||
isOpen={this.props.isOpen}
|
||||
buttons={buttons}
|
||||
handleClose={onCancel}
|
||||
>
|
||||
<div className="DWModal">
|
||||
<form
|
||||
className="DWModal-path form-group-sm"
|
||||
onSubmit={this._handleSubmitCustomPath}
|
||||
>
|
||||
<span className="DWModal-path-label">Addresses for</span>
|
||||
<select
|
||||
className="form-control"
|
||||
onChange={this._handleChangePath}
|
||||
value={isCustomPath ? 'custom' : dPath}
|
||||
>
|
||||
{dPaths.map(dp =>
|
||||
<option key={dp.value} value={dp.value}>
|
||||
{dp.label}
|
||||
</option>
|
||||
)}
|
||||
<option value="custom">Custom path...</option>
|
||||
</select>
|
||||
{isCustomPath &&
|
||||
<input
|
||||
className={`form-control ${validPathClass}`}
|
||||
value={customPath}
|
||||
placeholder="m/44'/60'/0'/0"
|
||||
onChange={this._handleChangeCustomPath}
|
||||
/>}
|
||||
</form>
|
||||
|
||||
<div className="DWModal-addresses">
|
||||
<table className="DWModal-addresses-table table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>#</td>
|
||||
<td>Address</td>
|
||||
<td>
|
||||
{network.unit}
|
||||
</td>
|
||||
<td>
|
||||
<select
|
||||
className="DWModal-addresses-table-token"
|
||||
value={desiredToken}
|
||||
onChange={this._handleChangeToken}
|
||||
>
|
||||
<option value="">-Token-</option>
|
||||
{tokens.map(t =>
|
||||
<option key={t.symbol} value={t.symbol}>
|
||||
{t.symbol}
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
</td>
|
||||
<td>More</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{wallets.map(wallet => this._renderWalletRow(wallet))}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div className="DWModal-addresses-nav">
|
||||
<button
|
||||
className="DWModal-addresses-nav-btn btn btn-sm btn-default"
|
||||
disabled={page === 0}
|
||||
onClick={this._prevPage}
|
||||
>
|
||||
← Back
|
||||
</button>
|
||||
<button
|
||||
className="DWModal-addresses-nav-btn btn btn-sm btn-default"
|
||||
onClick={this._nextPage}
|
||||
>
|
||||
More →
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
|
@ -1,12 +1,12 @@
|
|||
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;
|
||||
|
@ -19,15 +19,15 @@ function isPassRequired(file: string): boolean {
|
|||
}
|
||||
|
||||
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 (
|
||||
<section className="col-md-4 col-sm-6">
|
||||
|
@ -47,7 +47,7 @@ export default class KeystoreDecrypt extends Component {
|
|||
<a
|
||||
className="btn btn-default btn-block"
|
||||
id="aria1"
|
||||
tabIndex="0"
|
||||
tabIndex={0}
|
||||
role="button"
|
||||
>
|
||||
{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,
|
|
@ -2,11 +2,13 @@ import React, { Component } from 'react';
|
|||
import translate from 'translations';
|
||||
|
||||
export default class LedgerNanoSDecrypt extends Component {
|
||||
render() {
|
||||
public render() {
|
||||
return (
|
||||
<section className="col-md-4 col-sm-6">
|
||||
<div id="selectedUploadKey">
|
||||
<h4>{translate('ADD_Radio_2_alt')}</h4>
|
||||
<h4>
|
||||
{translate('ADD_Radio_2_alt')}
|
||||
</h4>
|
||||
|
||||
<div className="form-group">
|
||||
<input type="file" id="fselector" />
|
||||
|
@ -14,7 +16,7 @@ export default class LedgerNanoSDecrypt extends Component {
|
|||
<a
|
||||
className="btn-file marg-v-sm"
|
||||
id="aria1"
|
||||
tabIndex="0"
|
||||
tabIndex={0}
|
||||
role="button"
|
||||
>
|
||||
{translate('ADD_Radio_2_short')}
|
|
@ -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<Props, State> {
|
||||
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}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
|
@ -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')}
|
||||
/>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
onPasswordChange = (e: SyntheticInputEvent) => {
|
||||
this.setState({ pass: e.target.value });
|
||||
public onPasswordChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
|
||||
this.setState({ pass: (e.target as HTMLInputElement).value });
|
||||
};
|
||||
|
||||
onMnemonicChange = (e: SyntheticInputEvent) => {
|
||||
this.setState({ phrase: e.target.value });
|
||||
public onMnemonicChange = (e: React.SyntheticEvent<HTMLTextAreaElement>) => {
|
||||
this.setState({ phrase: (e.target as HTMLTextAreaElement).value });
|
||||
};
|
||||
|
||||
onDWModalOpen = (e: SyntheticInputEvent) => {
|
||||
public onDWModalOpen = (e: React.SyntheticEvent<HTMLButtonElement>) => {
|
||||
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({
|
|
@ -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}
|
||||
/>
|
||||
</div>
|
||||
{isValidPkey &&
|
||||
|
@ -97,17 +96,17 @@ export default class PrivateKeyDecrypt extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
onPkeyChange = (e: SyntheticInputEvent) => {
|
||||
const pkey = e.target.value;
|
||||
public onPkeyChange = (e: React.SyntheticEvent<HTMLTextAreaElement>) => {
|
||||
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<HTMLInputElement>) => {
|
||||
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();
|
|
@ -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<Props, State> {
|
||||
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 {
|
|||
<section className="TrezorDecrypt col-md-4 col-sm-6">
|
||||
<button
|
||||
className="TrezorDecrypt-decrypt btn btn-primary btn-lg"
|
||||
onClick={() => this._handleConnect()}
|
||||
onClick={this.handleNullConnect}
|
||||
disabled={isLoading}
|
||||
>
|
||||
{isLoading ? 'Unlocking...' : translate('ADD_Trezor_scan')}
|
||||
|
@ -113,12 +71,60 @@ export default class TrezorDecrypt extends Component {
|
|||
chainCode={chainCode}
|
||||
dPath={dPath}
|
||||
dPaths={DPATHS.TREZOR}
|
||||
onCancel={this._handleCancel}
|
||||
onConfirmAddress={this._handleUnlock}
|
||||
onPathChange={this._handlePathChange}
|
||||
walletType={translate('x_Trezor', true)}
|
||||
onCancel={this.handleCancel}
|
||||
onConfirmAddress={this.handleUnlock}
|
||||
onPathChange={this.handlePathChange}
|
||||
walletType={translateRaw('x_Trezor')}
|
||||
/>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
|
@ -2,11 +2,13 @@ import React, { Component } from 'react';
|
|||
import translate from 'translations';
|
||||
|
||||
export default class ViewOnlyDecrypt extends Component {
|
||||
render() {
|
||||
public render() {
|
||||
return (
|
||||
<section className="col-md-4 col-sm-6">
|
||||
<div id="selectedUploadKey">
|
||||
<h4>{translate('ADD_Radio_2_alt')}</h4>
|
||||
<h4>
|
||||
{translate('ADD_Radio_2_alt')}
|
||||
</h4>
|
||||
|
||||
<div className="form-group">
|
||||
<input type="file" id="fselector" />
|
||||
|
@ -14,7 +16,7 @@ export default class ViewOnlyDecrypt extends Component {
|
|||
<a
|
||||
className="btn-file marg-v-sm"
|
||||
id="aria1"
|
||||
tabIndex="0"
|
||||
tabIndex={0}
|
||||
role="button"
|
||||
>
|
||||
{translate('ADD_Radio_2_short')}
|
|
@ -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
|
||||
};
|
||||
|
||||
export class WalletDecrypt extends Component {
|
||||
props: {
|
||||
interface Props {
|
||||
// FIXME
|
||||
dispatch: (action: any) => void
|
||||
};
|
||||
state: State = {
|
||||
dispatch: Dispatch<
|
||||
UnlockKeystoreAction | UnlockMnemonicAction | UnlockPrivateKeyAction
|
||||
>;
|
||||
}
|
||||
|
||||
interface State {
|
||||
selectedWalletKey: string;
|
||||
value: UnlockParams;
|
||||
}
|
||||
|
||||
export class WalletDecrypt extends Component<Props, State> {
|
||||
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<HTMLInputElement>
|
||||
) => {
|
||||
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 {
|
|||
</section>
|
||||
|
||||
{decryptionComponent}
|
||||
{!!this.state.value.valid &&
|
||||
{!!(this.state.value as PrivateKeyValue).valid &&
|
||||
<section className="col-md-4 col-sm-6">
|
||||
<h4 id="uploadbtntxt-wallet">
|
||||
{translate('ADD_Label_6')}
|
||||
</h4>
|
||||
<div className="form-group">
|
||||
<a
|
||||
tabIndex="0"
|
||||
tabIndex={0}
|
||||
role="button"
|
||||
className="btn btn-primary btn-block"
|
||||
onClick={this.onUnlock}
|
||||
|
@ -166,11 +177,11 @@ export class WalletDecrypt extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
onChange = (value: UnlockParams) => {
|
||||
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 =
|
|
@ -1,5 +1,3 @@
|
|||
// @flow
|
||||
|
||||
export { default as Header } from './Header';
|
||||
export { default as Footer } from './Footer';
|
||||
export { default as Root } from './Root';
|
|
@ -1,38 +1,31 @@
|
|||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
|
||||
type Props<T> = {
|
||||
value: T,
|
||||
options: T[],
|
||||
ariaLabel: string,
|
||||
formatTitle: (option: T) => any,
|
||||
extra?: any,
|
||||
onChange: (value: T) => void
|
||||
};
|
||||
interface Props<T> {
|
||||
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<T: *> extends Component<
|
||||
void,
|
||||
Props<T>,
|
||||
State
|
||||
> {
|
||||
props: Props<T>;
|
||||
|
||||
state = {
|
||||
export default class DropdownComponent<T> extends Component<Props<T>, State> {
|
||||
public state = {
|
||||
expanded: false
|
||||
};
|
||||
|
||||
render() {
|
||||
public render() {
|
||||
const { options, value, ariaLabel, extra } = this.props;
|
||||
const { expanded } = this.state;
|
||||
|
||||
return (
|
||||
<span className={`dropdown ${expanded ? 'open' : ''}`}>
|
||||
<a
|
||||
tabIndex="0"
|
||||
tabIndex={0}
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
aria-label={ariaLabel}
|
||||
|
@ -62,11 +55,11 @@ export default class DropdownComponent<T: *> extends Component<
|
|||
);
|
||||
}
|
||||
|
||||
formatTitle(option: any) {
|
||||
public formatTitle(option: any) {
|
||||
return this.props.formatTitle(option);
|
||||
}
|
||||
|
||||
toggleExpanded = () => {
|
||||
public toggleExpanded = () => {
|
||||
this.setState(state => {
|
||||
return {
|
||||
expanded: !state.expanded
|
||||
|
@ -74,7 +67,7 @@ export default class DropdownComponent<T: *> extends Component<
|
|||
});
|
||||
};
|
||||
|
||||
onChange = (value: any) => {
|
||||
public onChange = (value: any) => {
|
||||
this.props.onChange(value);
|
||||
this.setState({ expanded: false });
|
||||
};
|
|
@ -1,13 +1,11 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { toDataUrl } from 'ethereum-blockies';
|
||||
import { isValidETHAddress } from 'libs/validators';
|
||||
import React from 'react';
|
||||
|
||||
type Props = {
|
||||
address: string,
|
||||
size?: string
|
||||
};
|
||||
interface Props {
|
||||
address: string;
|
||||
size?: string;
|
||||
}
|
||||
|
||||
export default function Identicon(props: Props) {
|
||||
const size = props.size || '4rem';
|
|
@ -1,14 +1,9 @@
|
|||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import closeIcon from 'assets/images/icon-x.svg';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import './Modal.scss';
|
||||
|
||||
type Props = {
|
||||
isOpen?: boolean,
|
||||
title: string,
|
||||
buttons: {
|
||||
text: string,
|
||||
export interface IButton {
|
||||
text: string;
|
||||
type?:
|
||||
| 'default'
|
||||
| 'primary'
|
||||
|
@ -16,46 +11,73 @@ type Props = {
|
|||
| 'info'
|
||||
| 'warning'
|
||||
| 'danger'
|
||||
| 'link',
|
||||
disabled?: boolean,
|
||||
onClick?: () => void
|
||||
}[],
|
||||
handleClose: () => void,
|
||||
disableButtons?: boolean,
|
||||
children: any
|
||||
};
|
||||
|
||||
export default class Modal extends Component {
|
||||
props: Props;
|
||||
|
||||
componentDidMount() {
|
||||
this.updateBodyClass();
|
||||
document.addEventListener('keydown', this._escapeListner);
|
||||
| 'link';
|
||||
disabled?: boolean;
|
||||
onClick?(): void;
|
||||
}
|
||||
interface Props {
|
||||
isOpen?: boolean;
|
||||
title: string;
|
||||
disableButtons?: boolean;
|
||||
children: any;
|
||||
buttons: IButton[];
|
||||
handleClose(): void;
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
export default class Modal extends Component<Props, {}> {
|
||||
public componentDidMount() {
|
||||
this.updateBodyClass();
|
||||
document.addEventListener('keydown', this.escapeListner);
|
||||
}
|
||||
|
||||
public componentDidUpdate() {
|
||||
this.updateBodyClass();
|
||||
}
|
||||
|
||||
updateBodyClass() {
|
||||
// $FlowFixMe
|
||||
public updateBodyClass() {
|
||||
document.body.classList.toggle('no-scroll', !!this.props.isOpen);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('keydown', this._escapeListner);
|
||||
// $FlowFixMe
|
||||
public componentWillUnmount() {
|
||||
document.removeEventListener('keydown', this.escapeListner);
|
||||
document.body.classList.remove('no-scroll');
|
||||
}
|
||||
|
||||
_escapeListner = (ev: KeyboardEvent) => {
|
||||
public render() {
|
||||
const { isOpen, title, children, buttons, handleClose } = this.props;
|
||||
const hasButtons = buttons && buttons.length;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={`Modalshade ${isOpen ? 'is-open' : ''}`} />
|
||||
<div className={`Modal ${isOpen ? 'is-open' : ''}`}>
|
||||
<div className="Modal-header">
|
||||
<h2 className="Modal-header-title">
|
||||
{title}
|
||||
</h2>
|
||||
<button className="Modal-header-close" onClick={handleClose}>
|
||||
<img className="Modal-header-close-icon" src={closeIcon} />
|
||||
</button>
|
||||
</div>
|
||||
<div className="Modal-content">
|
||||
{isOpen && children}
|
||||
</div>
|
||||
{hasButtons &&
|
||||
<div className="Modal-footer">
|
||||
{this.renderButtons()}
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
private escapeListner = (ev: KeyboardEvent) => {
|
||||
// Don't trigger if they hit escape while on an input
|
||||
if (ev.target) {
|
||||
if (
|
||||
ev.target.tagName === 'INPUT' ||
|
||||
ev.target.tagName === 'SELECT' ||
|
||||
ev.target.tagName === 'TEXTAREA' ||
|
||||
ev.target.isContentEditable
|
||||
(ev.target as HTMLElement).tagName === 'INPUT' ||
|
||||
(ev.target as HTMLElement).tagName === 'SELECT' ||
|
||||
(ev.target as HTMLElement).tagName === 'TEXTAREA' ||
|
||||
(ev.target as HTMLElement).isContentEditable
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
@ -66,7 +88,7 @@ export default class Modal extends Component {
|
|||
}
|
||||
};
|
||||
|
||||
_renderButtons = () => {
|
||||
private renderButtons = () => {
|
||||
const { disableButtons, buttons } = this.props;
|
||||
|
||||
return buttons.map((btn, idx) => {
|
||||
|
@ -88,32 +110,4 @@ export default class Modal extends Component {
|
|||
);
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { isOpen, title, children, buttons, handleClose } = this.props;
|
||||
const hasButtons = buttons && buttons.length;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={`Modalshade ${isOpen ? 'is-open' : ''}`} />
|
||||
<div className={`Modal ${isOpen ? 'is-open' : ''}`}>
|
||||
<div className="Modal-header">
|
||||
<h2 className="Modal-header-title">
|
||||
{title}
|
||||
</h2>
|
||||
<button className="Modal-header-close" onClick={handleClose}>
|
||||
<img className="Modal-header-close-icon" src={closeIcon} />
|
||||
</button>
|
||||
</div>
|
||||
<div className="Modal-content">
|
||||
{isOpen && children}
|
||||
</div>
|
||||
{hasButtons &&
|
||||
<div className="Modal-footer">
|
||||
{this._renderButtons()}
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react';
|
||||
|
||||
type 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
|
||||
};
|
||||
|
||||
type NewTabLinkProps = {
|
||||
content?: React.Element<any> | string,
|
||||
children?: React.Element<any> | string,
|
||||
rest?: AAttributes
|
||||
};
|
||||
|
||||
const NewTabLink = ({
|
||||
/* eslint-disable */
|
||||
content, // ESLINT: prop-types validation error, to be fixed in #122
|
||||
children /* eslint-enable */,
|
||||
...rest
|
||||
}: NewTabLinkProps) =>
|
||||
<a target="_blank" rel="noopener" {...rest}>
|
||||
{content || children} {/* Keep content for short-hand text insertion */}
|
||||
</a>;
|
||||
|
||||
export default NewTabLink;
|
|
@ -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<any> | string;
|
||||
children?: React.ReactElement<any> | string;
|
||||
}
|
||||
|
||||
const NewTabLink = ({ content, children, ...rest }: NewTabLinkProps) =>
|
||||
<a target="_blank" rel="noopener" {...rest}>
|
||||
{content || children} {/* Keep content for short-hand text insertion */}
|
||||
</a>;
|
||||
|
||||
export default NewTabLink;
|
|
@ -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
|
||||
};
|
||||
|
||||
type State = {
|
||||
qr?: string
|
||||
};
|
||||
|
||||
export default class QRCode extends React.Component {
|
||||
props: Props;
|
||||
state: State = {};
|
||||
|
||||
componentWillMount() {
|
||||
// Start generating QR codes immediately
|
||||
this._generateQrCode(this.props.data);
|
||||
interface Props {
|
||||
data: string;
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps: Props) {
|
||||
interface State {
|
||||
qr?: string;
|
||||
}
|
||||
|
||||
export default class QRCode extends React.Component<Props, State> {
|
||||
public state: State = {}
|
||||
public componentWillMount() {
|
||||
console.error(this.props.data)
|
||||
// Start generating QR codes immediately
|
||||
this.generateQrCode(this.props.data);
|
||||
}
|
||||
|
||||
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 });
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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<any> | 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<Props, {}> {
|
||||
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 (
|
||||
<div>
|
|
@ -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<Props, State> {
|
||||
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<HTMLAnchorElement>) => {
|
||||
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 (
|
|
@ -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<HTMLSpanElement>): void;
|
||||
}
|
||||
|
||||
export default class SimpleSelect extends Component {
|
||||
props: Props;
|
||||
|
||||
render() {
|
||||
export default class SimpleSelect extends Component<Props, {}> {
|
||||
public render() {
|
||||
return (
|
||||
<select
|
||||
value={this.props.value || this.props.options[0]}
|
|
@ -1,10 +1,10 @@
|
|||
import React from 'react';
|
||||
|
||||
type size = 'lg' | '2x' | '3x' | '4x' | '5x';
|
||||
type Size = 'lg' | '2x' | '3x' | '4x' | '5x';
|
||||
|
||||
type SpinnerProps = {
|
||||
size?: size
|
||||
};
|
||||
interface SpinnerProps {
|
||||
size?: Size;
|
||||
}
|
||||
|
||||
const Spinner = ({ size = 'fa-' }: SpinnerProps) => {
|
||||
return <i className={`fa fa-spinner fa-spin fa-${size ? size : 'fw'}`} />;
|
|
@ -1,30 +1,23 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import translate from 'translations';
|
||||
import WalletDecrypt from 'components/WalletDecrypt';
|
||||
import type { IWallet } from 'libs/wallet/IWallet';
|
||||
import { IWallet } from 'libs/wallet/IWallet';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import type { State } from 'reducers';
|
||||
import { AppState } from 'reducers';
|
||||
import translate from 'translations';
|
||||
|
||||
type Props = {
|
||||
title: string,
|
||||
wallet: IWallet
|
||||
};
|
||||
|
||||
export class UnlockHeader extends React.Component {
|
||||
props: Props;
|
||||
static propTypes = {
|
||||
title: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
state: {
|
||||
expanded: boolean
|
||||
} = {
|
||||
interface Props {
|
||||
title: string;
|
||||
wallet: IWallet;
|
||||
}
|
||||
interface State {
|
||||
expanded: boolean;
|
||||
}
|
||||
export class UnlockHeader extends React.Component<Props, State> {
|
||||
public state = {
|
||||
expanded: !this.props.wallet
|
||||
};
|
||||
|
||||
componentDidUpdate(prevProps: Props) {
|
||||
public componentDidUpdate(prevProps: Props) {
|
||||
if (this.props.wallet && this.props.wallet !== prevProps.wallet) {
|
||||
this.setState({ expanded: false });
|
||||
}
|
||||
|
@ -35,7 +28,7 @@ export class UnlockHeader extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
public render() {
|
||||
return (
|
||||
<article className="collapse-container">
|
||||
<div onClick={this.toggleExpanded}>
|
||||
|
@ -54,14 +47,14 @@ export class UnlockHeader extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
toggleExpanded = () => {
|
||||
public toggleExpanded = () => {
|
||||
this.setState(state => {
|
||||
return { expanded: !state.expanded };
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function mapStateToProps(state: State) {
|
||||
function mapStateToProps(state: AppState) {
|
||||
return {
|
||||
wallet: state.wallet.inst
|
||||
};
|
|
@ -1,8 +1,6 @@
|
|||
// @flow
|
||||
|
||||
export { default as Dropdown } from './Dropdown';
|
||||
export { default as Identicon } from './Identicon';
|
||||
export { default as Modal } from './Modal';
|
||||
export { default as UnlockHeader } from './UnlockHeader';
|
||||
export { default as QRCode } from './QRCode';
|
||||
export { default as NewTabLink } from './NewTabLink.jsx';
|
||||
export { default as NewTabLink } from './NewTabLink';
|
|
@ -1,4 +1,4 @@
|
|||
import { ETHTxExplorer, BTCTxExplorer } from './data';
|
||||
import { BTCTxExplorer, ETHTxExplorer } from './data';
|
||||
|
||||
type SupportedDestinationKind = 'ETH' | 'BTC' | 'REP';
|
||||
|
||||
|
@ -16,16 +16,16 @@ const buffers = {
|
|||
};
|
||||
|
||||
// rate must be BTC[KIND]
|
||||
export function kindMin(
|
||||
export function generateKindMin(
|
||||
BTCKINDRate: number,
|
||||
kind: SupportedDestinationKind
|
||||
): number {
|
||||
const kindMin = BTCKINDRate * BTCMin;
|
||||
return kindMin + kindMin * buffers[kind];
|
||||
const kindMinVal = BTCKINDRate * BTCMin;
|
||||
return kindMinVal + kindMinVal * buffers[kind];
|
||||
}
|
||||
|
||||
// rate must be BTC[KIND]
|
||||
export function kindMax(
|
||||
export function generateKindMax(
|
||||
BTCKINDRate: number,
|
||||
kind: SupportedDestinationKind
|
||||
): number {
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue