1
0
mirror of https://github.com/trezor/trezor-wallet synced 2024-11-24 09:18:09 +00:00

refactoring "coin" to "network" & "checksum" to "deviceState"

This commit is contained in:
Szymon Lesisz 2018-03-29 13:38:09 +02:00
parent 666dae47c2
commit c268c16649
39 changed files with 243 additions and 631 deletions

View File

@ -21,8 +21,8 @@ export const init = (): any => {
const state: State = {
index: parseInt(urlParams.address),
checksum: selected.checksum,
coin: urlParams.coin,
deviceState: selected.state,
network: urlParams.network,
location: location.pathname
};
@ -30,26 +30,6 @@ export const init = (): any => {
type: ACCOUNT.INIT,
state: state
});
// let discoveryProcess: ?Discovery = getState().discovery.find(d => d.checksum === selected.checksum && d.coin === currentAccount.coin);
// const discovering: boolean = (!discoveryProcess || !discoveryProcess.completed);
// const state: State = {
// ...initialState,
// loaded: true,
// checksum: currentAccount.checksum,
// address: currentAccount.address,
// coin: urlParams.coin,
// balance: currentAccount.balance,
// discovering
// };
// dispatch({
// type: ACCOUNT.INIT,
// state
// });
}
}
@ -76,24 +56,6 @@ export const update = (newProps: any): any => {
});
return;
}
// update comes from device
// const device = connect.devices.find(d => d.checksum === accountDetail.checksum);
// if (accountDetail.detail !== device) {
// console.warn("DEV UPDATE!!!!")
// }
// const discoveryProcess = discovery.find(d => d.checksum === device.checksum && d.coin === accountDetail.coin);
// const account = accounts.find(a => a.checksum === accountDetail.checksum && a.index === accountDetail.addressIndex && a.coin === accountDetail.coin);
// if (account && !accountDetail.address) {
// // update current address
// console.warn("ACC UPDATE!!!!")
// }
// isDeviceChanged
// isDiscoveryChanged
}
}

View File

@ -34,8 +34,8 @@ export function loadTokensFromJSON(): any {
const ERC20Abi = await httpRequest('data/ERC20Abi.json', 'json');
// load tokens
const tokens = await config.coins.reduce(async (previousPromise: Promise<any>, coin: any): Promise<any> => {
const collection = await previousPromise;
const tokens = await config.coins.reduce(async (promise: Promise<any>, coin: any): Promise<any> => {
const collection = await promise;
const json: JSON = await httpRequest(coin.tokens, 'json');
collection[ coin.network ] = json;
return collection;

View File

@ -20,9 +20,9 @@ export const init = (): any => {
const state: State = {
...initialState,
checksum: selected.checksum,
deviceState: selected.state,
accountIndex: parseInt(urlParams.address),
coin: urlParams.coin,
network: urlParams.network,
location: location.pathname,
};
@ -78,7 +78,7 @@ export const showAddress = (address_n: string): any => {
device: {
path: selected.path,
instance: selected.instance,
state: selected.checksum
state: selected.state
},
path: address_n,
});

View File

@ -46,7 +46,7 @@ export const calculateMaxAmount = (balance: string, gasPrice: string, gasLimit:
}
export const getFeeLevels = (coin: string, gasPrice: BigNumber | string, gasLimit: string): Array<FeeLevel> => {
export const getFeeLevels = (symbol: string, gasPrice: BigNumber | string, gasLimit: string): Array<FeeLevel> => {
if (typeof gasPrice === 'string') gasPrice = new BigNumber(gasPrice);
const quarter: BigNumber = gasPrice.dividedBy(4);
const high: string = gasPrice.plus(quarter.times(2)).toString();
@ -56,17 +56,17 @@ export const getFeeLevels = (coin: string, gasPrice: BigNumber | string, gasLimi
{
value: 'High',
gasPrice: high,
label: `${ calculateFee(high, gasLimit) } ${ coin }`
label: `${ calculateFee(high, gasLimit) } ${ symbol }`
},
{
value: 'Normal',
gasPrice: gasPrice.toString(),
label: `${ calculateFee(gasPrice.toString(), gasLimit) } ${ coin }`
label: `${ calculateFee(gasPrice.toString(), gasLimit) } ${ symbol }`
},
{
value: 'Low',
gasPrice: low,
label: `${ calculateFee(low, gasLimit) } ${ coin }`
label: `${ calculateFee(low, gasLimit) } ${ symbol }`
},
{
value: 'Custom',
@ -77,10 +77,10 @@ export const getFeeLevels = (coin: string, gasPrice: BigNumber | string, gasLimi
}
export const findBalance = (getState: any): string => {
const state = getState().sendForm;
const account = getState().accounts.find(a => a.checksum === state.checksum && a.index === state.accountIndex && a.coin === state.coin);
const state = getState().sendForm;
const account = getState().accounts.find(a => a.deviceState === state.deviceState && a.index === state.accountIndex && a.network === state.network);
if (state.token !== state.coin) {
if (state.token !== state.network) {
return getState().tokens.find(t => t.ethAddress === account.address && t.symbol === state.token).balance;
} else {
return account.balance;
@ -98,15 +98,15 @@ export const init = (): any => {
const selected = findSelectedDevice( getState().connect );
if (!selected) return;
const web3instance = getState().web3.find(w3 => w3.coin === urlParams.coin);
const web3instance = getState().web3.find(w3 => w3.network === urlParams.network);
if (!web3instance) {
// no backend for this coin
// no backend for this network
//return;
}
// TODO: check if there are some unfinished tx in localStorage
const { config } = getState().localStorage;
const coin = config.coins.find(c => c.network === urlParams.coin);
const coin = config.coins.find(c => c.network === urlParams.network);
const gasPrice: BigNumber = new BigNumber( EthereumjsUnits.convert(web3instance.gasPrice, 'wei', 'gwei') ) || new BigNumber(coin.defaultGasPrice);
const gasLimit: string = coin.defaultGasLimit.toString();
@ -116,11 +116,11 @@ export const init = (): any => {
const state: State = {
...initialState,
checksum: selected.checksum,
deviceState: selected.state,
accountIndex: parseInt(urlParams.address),
coin: urlParams.coin,
network: urlParams.network,
coinSymbol: coin.symbol,
token: urlParams.coin,
token: urlParams.network,
location: location.pathname,
feeLevels,
@ -186,11 +186,11 @@ export const validation = (): any => {
} else if (!EthereumjsUtil.isValidAddress(state.address)) {
errors.address = 'Address is not valid';
} else if (myAccount) {
if (myAccount.coin === state.coin) {
if (myAccount.network === state.network) {
infos.address = `TREZOR Address #${ (myAccount.index + 1) }`;
} else {
// TODO: load coins from config
warnings.address = `Looks like it's TREZOR address in Account #${ (myAccount.index + 1) } of ${ myAccount.coin.toUpperCase() }`;
warnings.address = `Looks like it's TREZOR address in Account #${ (myAccount.index + 1) } of ${ myAccount.network.toUpperCase() } network`;
}
}
}
@ -204,10 +204,10 @@ export const validation = (): any => {
} else if (state.amount.length > 0 && !state.amount.match(numberRegExp)) {
errors.amount = 'Amount is not a number';
} else {
const account = getState().accounts.find(a => a.checksum === state.checksum && a.index === state.accountIndex && a.coin === state.coin);
const account = getState().accounts.find(a => a.deviceState === state.deviceState && a.index === state.accountIndex && a.network === state.network);
let decimalRegExp;
if (state.token !== state.coin) {
if (state.token !== state.network) {
const token: any = getState().tokens.find(t => t.ethAddress === account.address && t.symbol === state.token);
if (parseInt(token.decimals) > 0) {
@ -270,7 +270,7 @@ export const validation = (): any => {
}
// valid data
if (state.touched.data && state.coin === state.token && state.data.length > 0) {
if (state.touched.data && state.network === state.token && state.data.length > 0) {
const re = /^[0-9A-Fa-f]+$/g;
//const re = /^[0-9A-Fa-f]{6}$/g;
if (!re.test(state.data)) {
@ -320,7 +320,7 @@ export const onAmountChange = (amount: string): any => {
const currentState: State = getState().sendForm;
const touched = { ...currentState.touched };
touched.amount = true;
const total: string = calculateTotal(currentState.token !== currentState.coin ? '0' : amount, currentState.gasPrice, currentState.gasLimit);
const total: string = calculateTotal(currentState.token !== currentState.network ? '0' : amount, currentState.gasPrice, currentState.gasLimit);
const state: State = {
...currentState,
@ -345,20 +345,20 @@ export const onCurrencyChange = (currency: any): any => {
const currentState = getState().sendForm;
const account = getState().accounts.find(a => a.checksum === currentState.checksum && a.index === currentState.accountIndex && a.coin === currentState.coin);
const account = getState().accounts.find(a => a.deviceState === currentState.deviceState && a.index === currentState.accountIndex && a.network === currentState.network);
if (!account) {
// account not found
return;
}
const { config } = getState().localStorage;
const coin = config.coins.find(c => c.network === currentState.coin);
const coin = config.coins.find(c => c.network === currentState.network);
let gasLimit: string = '';
let amount: string = currentState.amount;
let total: string;
if (currentState.coin !== currency.value) {
if (currentState.network !== currency.value) {
gasLimit = coin.defaultGasLimitTokens.toString();
if (currentState.setMax) {
const tokenBalance: string = getState().tokens.find(t => t.ethAddress === account.address && t.symbol === currency.value).balance;
@ -401,7 +401,7 @@ export const onSetMax = (): any => {
const touched = { ...currentState.touched };
touched.amount = true;
const account = getState().accounts.find(a => a.checksum === currentState.checksum && a.index === currentState.accountIndex && a.coin === currentState.coin);
const account = getState().accounts.find(a => a.deviceState === currentState.deviceState && a.index === currentState.accountIndex && a.network === currentState.network);
if (!account) {
// account not found
return;
@ -410,7 +410,7 @@ export const onSetMax = (): any => {
let amount: string = currentState.amount;
let total: string = currentState.total;
if (!currentState.setMax) {
if (currentState.token !== currentState.coin) {
if (currentState.token !== currentState.network) {
const tokenBalance: string = getState().tokens.find(t => t.ethAddress === account.address && t.symbol === currentState.token).balance;
amount = tokenBalance;
total = calculateTotal('0', currentState.gasPrice, currentState.gasLimit);
@ -459,15 +459,15 @@ export const onFeeLevelChange = (feeLevel: any): any => {
}
if (currentState.setMax) {
const account = getState().accounts.find(a => a.checksum === currentState.checksum && a.index === currentState.accountIndex && a.coin === currentState.coin);
if (state.token !== state.coin) {
const account = getState().accounts.find(a => a.deviceState === currentState.deviceState && a.index === currentState.accountIndex && a.network === currentState.network);
if (state.token !== state.network) {
const tokenBalance: string = getState().tokens.find(t => t.ethAddress === account.address && t.symbol === currentState.token).balance;
state.amount = tokenBalance;
} else {
state.amount = calculateMaxAmount(account.balance, state.gasPrice, state.gasLimit);
}
}
state.total = calculateTotal(state.token !== state.coin ? '0' : state.amount, state.gasPrice, state.gasLimit);
state.total = calculateTotal(state.token !== state.network ? '0' : state.amount, state.gasPrice, state.gasLimit);
dispatch({
type: SEND.FEE_LEVEL_CHANGE,
@ -492,15 +492,15 @@ export const updateFeeLevels = (): any => {
};
if (currentState.setMax) {
const account = getState().accounts.find(a => a.checksum === currentState.checksum && a.index === currentState.accountIndex && a.coin === currentState.coin);
if (state.token !== state.coin) {
const account = getState().accounts.find(a => a.deviceState === currentState.deviceState && a.index === currentState.accountIndex && a.network === currentState.network);
if (state.token !== state.network) {
const tokenBalance: string = getState().tokens.find(t => t.ethAddress === account.address && t.symbol === currentState.token).balance;
state.amount = tokenBalance;
} else {
state.amount = calculateMaxAmount(account.balance, state.gasPrice, state.gasLimit);
}
}
state.total = calculateTotal(state.token !== state.coin ? '0' : state.amount, state.gasPrice, state.gasLimit);
state.total = calculateTotal(state.token !== state.network ? '0' : state.amount, state.gasPrice, state.gasLimit);
dispatch({
type: SEND.UPDATE_FEE_LEVELS,
@ -532,8 +532,8 @@ export const onGasPriceChange = (gasPrice: string): any => {
state.selectedFeeLevel = customLevel;
if (currentState.setMax) {
const account = getState().accounts.find(a => a.checksum === currentState.checksum && a.index === currentState.accountIndex && a.coin === currentState.coin);
if (state.token !== state.coin) {
const account = getState().accounts.find(a => a.deviceState === currentState.deviceState && a.index === currentState.accountIndex && a.network === currentState.network);
if (state.token !== state.network) {
const tokenBalance: string = getState().tokens.find(t => t.ethAddress === account.address && t.symbol === currentState.token).balance;
state.amount = tokenBalance;
} else {
@ -542,7 +542,7 @@ export const onGasPriceChange = (gasPrice: string): any => {
}
}
state.total = calculateTotal(state.token !== state.coin ? '0' : state.amount, state.gasPrice, state.gasLimit);
state.total = calculateTotal(state.token !== state.network ? '0' : state.amount, state.gasPrice, state.gasLimit);
dispatch({
type: SEND.GAS_PRICE_CHANGE,
@ -572,8 +572,8 @@ export const onGasLimitChange = (gasLimit: string): any => {
state.selectedFeeLevel = customLevel;
if (currentState.setMax) {
const account = getState().accounts.find(a => a.checksum === currentState.checksum && a.index === currentState.accountIndex && a.coin === currentState.coin);
if (state.token !== state.coin) {
const account = getState().accounts.find(a => a.deviceState === currentState.deviceState && a.index === currentState.accountIndex && a.network === currentState.network);
if (state.token !== state.network) {
const tokenBalance: string = getState().tokens.find(t => t.ethAddress === account.address && t.symbol === currentState.token).balance;
state.amount = tokenBalance;
} else {
@ -582,7 +582,7 @@ export const onGasLimitChange = (gasLimit: string): any => {
}
}
state.total = calculateTotal(state.token !== state.coin ? '0' : state.amount, state.gasPrice, state.gasLimit);
state.total = calculateTotal(state.token !== state.network ? '0' : state.amount, state.gasPrice, state.gasLimit);
dispatch({
type: SEND.GAS_LIMIT_CHANGE,
@ -619,17 +619,17 @@ export const onSend = (): any => {
return async (dispatch, getState): Promise<any> => {
const state: State = getState().sendForm;
const web3instance = getState().web3.filter(w3 => w3.coin === state.coin)[0];
const web3instance = getState().web3.filter(w3 => w3.network === state.network)[0];
const web3 = web3instance.web3;
const account = getState().accounts.find(a => a.checksum === state.checksum && a.index === state.accountIndex && a.coin === state.coin);
const account = getState().accounts.find(a => a.deviceState === state.deviceState && a.index === state.accountIndex && a.network === state.network);
const address_n = account.addressPath;
let data: string = '';
let txAmount = web3.toHex(web3.toWei(state.amount, 'ether'));
let txAddress = state.address;
if (state.coin !== state.token) {
if (state.network !== state.token) {
const tokens = getState().tokens
const t = tokens.find(t => t.ethAddress === account.address && t.symbol === state.token);
const contract = web3instance.erc20.at(t.address);
@ -683,7 +683,7 @@ export const onSend = (): any => {
device: {
path: selected.path,
instance: selected.instance,
state: selected.checksum
state: selected.state
},
//path: "m/44'/60'/0'/0/0",
path: txData.address_n,
@ -719,7 +719,7 @@ export const onSend = (): any => {
// console.log("---->GASSS", txData, gasLimit2.toString() );
const { config } = getState().localStorage;
const selectedCoin = config.coins.find(c => c.network === state.coin);
const selectedCoin = config.coins.find(c => c.network === state.network);
try {
const tx = new EthereumjsTx(txData);

View File

@ -24,9 +24,9 @@ export const init = (): any => {
const state: State = {
...initialState,
checksum: selected.checksum,
deviceState: selected.state,
accountIndex: parseInt(urlParams.address),
coin: urlParams.coin,
network: urlParams.network,
location: location.pathname,
};
@ -65,53 +65,13 @@ export const onDetailsToggle = (): any => {
}
}
// export const init = (address: string): any => {
// return (dispatch, getState): void => {
// const { location } = getState().router;
// const urlParams = location.params;
// const selected = findSelectedDevice(getState().connect);
// const accounts = getState().accounts;
// // const currentAccount = accounts.find(a => a.index === parseInt(urlParams.address) && a.coin === urlParams.coin && a.deviceId === urlParams.device && a.loaded);
// const currentAccount = accounts.find(a => a.index === parseInt(urlParams.address) && a.coin === urlParams.coin && a.checksum === selected.checksum);
// if (!currentAccount) {
// console.log("STATER", getState())
// // account not found
// return;
// }
// const web3instance = getState().web3.find(w3 => w3.coin === urlParams.coin);
// if (!web3instance) {
// // no backend for this coin
// return;
// }
// const state: State = {
// ...initialState,
// loaded: true,
// address: currentAccount.address,
// coin: urlParams.coin,
// balance: currentAccount.balance,
// };
// dispatch({
// type: SUMMARY.INIT,
// state
// });
// }
// }
export const loadTokens = (input: string, account: any): any => {
return async (dispatch, getState): Promise<any> => {
if (input.length < 1) return null;
const tokens = getState().localStorage.tokens[ account.coin ];
const tokens = getState().localStorage.tokens[ account.network ];
const value = input.toLowerCase();
const result = tokens.filter(t =>
t.symbol.toLowerCase().indexOf(value) >= 0 ||
@ -122,7 +82,7 @@ export const loadTokens = (input: string, account: any): any => {
if (result.length > 0) {
return { options: result };
} else {
const web3instance = getState().web3.find(w3 => w3.coin === account.coin);
const web3instance = getState().web3.find(w3 => w3.network === account.network);
const info = await getTokenInfoAsync(web3instance.erc20, input);
info.address = input;
@ -148,13 +108,13 @@ export const loadTokens = (input: string, account: any): any => {
export const selectToken = (token: any, account: any): any => {
return async (dispatch, getState): Promise<any> => {
const web3instance = getState().web3.find(w3 => w3.coin === account.coin);
const web3instance = getState().web3.find(w3 => w3.network === account.network);
dispatch({
type: TOKEN.ADD,
payload: {
...token,
ethAddress: account.address,
checksum: account.checksum
deviceState: account.deviceState
}
});
@ -195,9 +155,8 @@ export const onCustomTokenToggle = (): any => {
export const onCustomTokenAddressChange = (value: string): any => {
// todo:
// -validate addres
// - if adress is ok, try to fetch token info
// - check if addres does not exist in predefined coins
// -validate address
// - if adresss is ok, try to fetch token info
// return {
// type: ACTIONS.TOKENS_CUSTOM_ADDRESS_CHANGE,
// value

View File

@ -55,15 +55,10 @@ export const init = (): any => {
try {
await TrezorConnect.init({
// transportReconnect: true,
// coinsSrc: './data/coins.json',
// firmwareReleasesSrc: './data/releases-1.json',
// transportConfigSrc: './data/config_signed.bin',
transportReconnect: false,
// latestBridgeSrc: './data/latest.txt',
// connectSrc: 'https://localhost:8088/',
connectSrc: 'https://sisyfos.trezor.io/',
debug: true,
debug: false,
popup: false,
// webusb: false
});
@ -132,7 +127,7 @@ export const initConnectedDevice = (device: any): any => {
//dispatch( onSelectDevice(device) );
const selected = findSelectedDevice(getState().connect);
if (selected && selected.checksum) {
if (selected && selected.state) {
dispatch( onSelectDevice(device) );
} else if (!selected) {
dispatch( onSelectDevice(device) );
@ -157,7 +152,7 @@ export function onSelectDevice(device: any): any {
} else if (device.instance) {
dispatch( push(`/device/${ device.features.device_id }:${ device.instance }`) );
} else {
//dispatch( push(`/device/${ device.features.device_id }/coin/etc/address/0`) );
//dispatch( push(`/device/${ device.features.device_id }/network/etc/address/0`) );
dispatch( push(`/device/${ device.features.device_id }`) );
}
}
@ -219,7 +214,7 @@ export const getSelectedDeviceState = (): any => {
&& selected.connected
&& !selected.unacquired
&& !selected.acquiring
&& !selected.checksum) {
&& !selected.state) {
const response = await __getDeviceState(selected.path, selected.instance);
@ -227,7 +222,7 @@ export const getSelectedDeviceState = (): any => {
dispatch({
type: CONNECT.AUTH_DEVICE,
device: selected,
checksum: response.payload.xpub
state: response.payload.xpub
});
} else {
dispatch({
@ -262,7 +257,7 @@ export const deviceDisconnect = (device: any): any => {
stopDiscoveryProcess(selected);
}
const affected = getState().connect.devices.filter(d => d.features && d.checksum && !d.remember && d.features.device_id === device.features.device_id);
const affected = getState().connect.devices.filter(d => d.features && d.state && !d.remember && d.features.device_id === device.features.device_id);
if (affected.length > 0) {
dispatch({
type: CONNECT.REMEMBER_REQUEST,
@ -279,13 +274,13 @@ export const deviceDisconnect = (device: any): any => {
}
}
export const coinChanged = (coin: ?string): any => {
export const coinChanged = (network: ?string): any => {
return (dispatch, getState): void => {
const selected = findSelectedDevice(getState().connect);
dispatch( stopDiscoveryProcess(selected) );
if (coin) {
dispatch( startDiscoveryProcess(selected, coin) );
if (network) {
dispatch( startDiscoveryProcess(selected, network) );
}
}
}
@ -297,10 +292,10 @@ export function acquire(): any {
const selected = findSelectedDevice(getState().connect);
const saved = getState().connect.devices.map(d => {
if (d.checksum) {
if (d.state) {
return {
instance: d.instance,
checksum: d.checksum
state: d.state
}
} else {
return null;
@ -329,7 +324,6 @@ export function acquire(): any {
if (response && response.success) {
dispatch({
type: DEVICE.ACQUIRED,
// checksum: response
})
} else {
// TODO: handle invalid pin?
@ -360,11 +354,11 @@ export const forgetDevice = (device: any) => {
return (dispatch: any, getState: any): any => {
// find accounts associated with this device
const accounts: Array<any> = getState().accounts.find(a => a.checksum === device.checksum);
const accounts: Array<any> = getState().accounts.find(a => a.deviceState === device.state);
// find discovery processes associated with this device
const discovery: Array<any> = getState().discovery.find(d => d.checksum === device.checksum);
const discovery: Array<any> = getState().discovery.find(d => d.deviceState === device.state);
}
}
@ -393,17 +387,17 @@ export const onDuplicateDevice = () => {
}
}
export const beginDiscoveryProcess = (device: any, coin: string): any => {
export const beginDiscoveryProcess = (device: any, network: string): any => {
return async (dispatch, getState) => {
const { config } = getState().localStorage;
const coinToDiscover = config.coins.find(c => c.network === coin);
const coinToDiscover = config.coins.find(c => c.network === network);
// TODO: validate device checksum
// const checksum = await __acquire(device.path, device.instance);
// if (checksum && checksum.success) {
// if (checksum.payload.xpub !== device.checksum) {
// console.error("Incorrect checksum!");
// TODO: validate device deviceState
// const deviceState = await __acquire(device.path, device.instance);
// if (deviceState && deviceState.success) {
// if (deviceState.payload.xpub !== device.state) {
// console.error("Incorrect deviceState!");
// return;
// }
// }
@ -413,7 +407,7 @@ export const beginDiscoveryProcess = (device: any, coin: string): any => {
device: {
path: device.path,
instance: device.instance,
state: device.checksum
state: device.state
},
path: coinToDiscover.bip44,
confirmation: false,
@ -434,7 +428,7 @@ export const beginDiscoveryProcess = (device: any, coin: string): any => {
{
label: 'Try again',
callback: () => {
dispatch(startDiscoveryProcess(device, coin))
dispatch(startDiscoveryProcess(device, network))
}
}
]
@ -454,14 +448,14 @@ export const beginDiscoveryProcess = (device: any, coin: string): any => {
// send data to reducer
dispatch({
type: DISCOVERY.START,
coin: coinToDiscover.network,
network: coinToDiscover.network,
device,
xpub: response.payload.publicKey,
basePath,
hdKey,
});
dispatch( startDiscoveryProcess(device, coin) );
dispatch( startDiscoveryProcess(device, network) );
}
}
@ -472,12 +466,12 @@ export const discoverAddress = (device: any, discoveryProcess: Discovery): any =
const path = discoveryProcess.basePath.concat(discoveryProcess.accountIndex);
const publicAddress: string = EthereumjsUtil.publicToAddress(derivedKey.publicKey, true).toString('hex');
const ethAddress: string = EthereumjsUtil.toChecksumAddress(publicAddress);
const coin = discoveryProcess.coin;
const network = discoveryProcess.network;
dispatch({
type: ADDRESS.CREATE,
device,
coin,
network,
index: discoveryProcess.accountIndex,
path,
address: ethAddress
@ -490,7 +484,7 @@ export const discoverAddress = (device: any, discoveryProcess: Discovery): any =
device: {
path: device.path,
instance: device.instance,
state: device.checksum
state: device.state
},
path,
showOnTrezor: false
@ -515,7 +509,7 @@ export const discoverAddress = (device: any, discoveryProcess: Discovery): any =
{
label: 'Try again',
callback: () => {
dispatch(startDiscoveryProcess(device, discoveryProcess.coin))
dispatch(startDiscoveryProcess(device, discoveryProcess.network))
}
}
]
@ -536,7 +530,7 @@ export const discoverAddress = (device: any, discoveryProcess: Discovery): any =
{
label: 'Try again',
callback: () => {
dispatch(startDiscoveryProcess(device, discoveryProcess.coin))
dispatch(startDiscoveryProcess(device, discoveryProcess.network))
}
}
]
@ -545,14 +539,14 @@ export const discoverAddress = (device: any, discoveryProcess: Discovery): any =
return;
}
const web3instance = getState().web3.find(w3 => w3.coin === coin);
const web3instance = getState().web3.find(w3 => w3.network === network);
const balance = await getBalanceAsync(web3instance.web3, ethAddress);
if (discoveryProcess.interrupted) return;
dispatch({
type: ADDRESS.SET_BALANCE,
address: ethAddress,
coin,
network,
balance: web3instance.web3.fromWei(balance.toString(), 'ether')
});
@ -579,14 +573,14 @@ export const discoverAddress = (device: any, discoveryProcess: Discovery): any =
dispatch({
type: ADDRESS.SET_NONCE,
address: ethAddress,
coin,
network,
nonce: nonce
});
const addressIsEmpty = nonce < 1 && !balance.greaterThan(0);
if (!addressIsEmpty) {
//dispatch( startDiscoveryProcess(device, discoveryProcess.coin) );
//dispatch( startDiscoveryProcess(device, discoveryProcess.network) );
dispatch( discoverAddress(device, discoveryProcess) );
} else {
// release acquired sesssion
@ -594,7 +588,7 @@ export const discoverAddress = (device: any, discoveryProcess: Discovery): any =
device: {
path: device.path,
instance: device.instance,
state: device.checksum
state: device.state
},
path: "m/44'/60'/0'/0",
confirmation: false,
@ -605,13 +599,13 @@ export const discoverAddress = (device: any, discoveryProcess: Discovery): any =
dispatch({
type: DISCOVERY.COMPLETE,
device,
coin
network
});
}
}
}
export function startDiscoveryProcess(device: any, coin: string, ignoreCompleted?: boolean): any {
export function startDiscoveryProcess(device: any, network: string, ignoreCompleted?: boolean): any {
return (dispatch, getState) => {
const selected = findSelectedDevice(getState().connect);
@ -622,37 +616,37 @@ export function startDiscoveryProcess(device: any, coin: string, ignoreCompleted
} else if (selected.path !== device.path) {
console.error("Start discovery: requested device is not selected", device, selected)
return;
} else if (!selected.checksum) {
} else if (!selected.state) {
console.warn("Start discovery: Selected device wasn't authenticated yet...")
return;
}
const discovery = getState().discovery;
let discoveryProcess: ?Discovery = discovery.find(d => d.checksum === device.checksum && d.coin === coin);
let discoveryProcess: ?Discovery = discovery.find(d => d.deviceState === device.state && d.network === network);
if (!selected.connected && (!discoveryProcess || !discoveryProcess.completed)) {
dispatch({
type: DISCOVERY.WAITING,
device,
coin
network
});
return;
}
if (!discoveryProcess) {
dispatch( beginDiscoveryProcess(device, coin) );
dispatch( beginDiscoveryProcess(device, network) );
return;
} else {
if (discoveryProcess.completed && !ignoreCompleted) {
dispatch({
type: DISCOVERY.COMPLETE,
device,
coin
network
});
} else if (discoveryProcess.interrupted || discoveryProcess.waitingForDevice) {
// discovery cycle was interrupted
// start from beginning
dispatch( beginDiscoveryProcess(device, coin) );
dispatch( beginDiscoveryProcess(device, network) );
} else {
dispatch( discoverAddress(device, discoveryProcess) );
}
@ -665,16 +659,16 @@ export const restoreDiscovery = (): any => {
const selected = findSelectedDevice(getState().connect);
if (selected && selected.connected && !selected.unacquired) {
const discoveryProcess: ?Discovery = getState().discovery.find(d => d.checksum === selected.checksum && d.waitingForDevice);
const discoveryProcess: ?Discovery = getState().discovery.find(d => d.deviceState === selected.state && d.waitingForDevice);
if (discoveryProcess) {
dispatch( startDiscoveryProcess(selected, discoveryProcess.coin) );
dispatch( startDiscoveryProcess(selected, discoveryProcess.network) );
}
}
}
}
// there is no discovery process but it should be
// this is possible race condition when coin was changed in url but device wasn't authenticated yet
// this is possible race condition when "network" was changed in url but device wasn't authenticated yet
// try to discovery after CONNECT.AUTH_DEVICE action
export const checkDiscoveryStatus = (): any => {
return (dispatch, getState): void => {
@ -682,10 +676,10 @@ export const checkDiscoveryStatus = (): any => {
if (!selected) return;
const urlParams = getState().router.location.params;
if (urlParams.coin) {
const discoveryProcess: ?Discovery = getState().discovery.find(d => d.checksum === selected.checksum && d.coin === urlParams.coin);
if (urlParams.network) {
const discoveryProcess: ?Discovery = getState().discovery.find(d => d.deviceState === selected.state && d.network === urlParams.network);
if (!discoveryProcess) {
dispatch( startDiscoveryProcess(selected, urlParams.coin) );
dispatch( startDiscoveryProcess(selected, urlParams.network) );
}
}
}
@ -706,6 +700,6 @@ export function stopDiscoveryProcess(device: any): any {
export function addAddress(): any {
return (dispatch, getState) => {
const selected = findSelectedDevice(getState().connect);
dispatch( startDiscoveryProcess(selected, getState().router.location.params.coin, true) ); // TODO: coin nicer
dispatch( startDiscoveryProcess(selected, getState().router.location.params.network, true) ); // TODO: network nicer
}
}

View File

@ -65,7 +65,7 @@ export function init(web3: ?Web3, coinIndex: number = 0): ActionMethod {
return;
}
const coinName = coin.network;
const network = coin.network;
const urls = coin.backends[0].urls;
let web3host: string = urls[0];
@ -77,7 +77,7 @@ export function init(web3: ?Web3, coinIndex: number = 0): ActionMethod {
if (currentHostIndex + 1 < urls.length) {
web3host = urls[currentHostIndex + 1];
} else {
console.error("TODO: Backend " + coinName + " not working");
console.error("TODO: Backend " + network + " not working");
// try next coin
dispatch( init(web3, coinIndex + 1) );
return;
@ -111,7 +111,7 @@ export function init(web3: ?Web3, coinIndex: number = 0): ActionMethod {
dispatch({
type: WEB3.CREATE,
name: coinName,
network,
web3: instance,
erc20,
chainId: instance.version.network
@ -119,7 +119,7 @@ export function init(web3: ?Web3, coinIndex: number = 0): ActionMethod {
dispatch({
type: WEB3.GAS_PRICE_UPDATED,
coin: coinName,
network,
gasPrice
});
@ -154,21 +154,21 @@ export function init(web3: ?Web3, coinIndex: number = 0): ActionMethod {
if (blockHash) {
dispatch({
type: WEB3.BLOCK_UPDATED,
name: coinName,
network,
blockHash
});
}
// TODO: filter only current device
const accounts = getState().accounts.filter(a => a.coin === coinName);
const accounts = getState().accounts.filter(a => a.network === network);
for (const addr of accounts) {
dispatch( getBalance(addr) );
dispatch( getNonce(addr) );
}
dispatch( getGasPrice(coinName) );
dispatch( getGasPrice(network) );
const pending = getState().pending.filter(p => p.coin === coinName);
const pending = getState().pending.filter(p => p.network === network);
for (const tx of pending) {
dispatch( getTransactionReceipt(tx) );
}
@ -236,19 +236,17 @@ export function initContracts(): ActionMethod {
}
export function getGasPrice(coinName: string): ActionMethod {
export function getGasPrice(network: string): ActionMethod {
return async (dispatch, getState) => {
const index: number = getState().web3.findIndex(w3 => {
return w3.coin === coinName;
});
const index: number = getState().web3.findIndex(w3 => w3.network === network);
const web3 = getState().web3[ index ].web3;
web3.eth.getGasPrice((error, gasPrice) => {
if (!error) {
dispatch({
type: WEB3.GAS_PRICE_UPDATED,
coin: coinName,
network: network,
gasPrice
});
}
@ -259,7 +257,7 @@ export function getGasPrice(coinName: string): ActionMethod {
export function getBalance(addr: Address): ActionMethod {
return async (dispatch, getState) => {
const web3instance = getState().web3.filter(w3 => w3.coin === addr.coin)[0];
const web3instance = getState().web3.filter(w3 => w3.network === addr.network)[0];
const web3 = web3instance.web3;
web3.eth.getBalance(addr.address, (error, balance) => {
@ -269,7 +267,7 @@ export function getBalance(addr: Address): ActionMethod {
dispatch({
type: ADDRESS.SET_BALANCE,
address: addr.address,
coin: addr.coin,
network: addr.network,
balance: newBalance
});
@ -284,7 +282,7 @@ export function getNonce(addr: Address) {
return async (dispatch, getState) => {
const web3instance = getState().web3.filter(w3 => w3.coin === addr.coin)[0];
const web3instance = getState().web3.filter(w3 => w3.network === addr.network)[0];
const web3 = web3instance.web3;
web3.eth.getTransactionCount(addr.address, (error, result) => {
@ -293,7 +291,7 @@ export function getNonce(addr: Address) {
dispatch({
type: ADDRESS.SET_NONCE,
address: addr.address,
coin: addr.coin,
network: addr.network,
nonce: result
});
}
@ -305,7 +303,7 @@ export function getNonce(addr: Address) {
export function getTransactionReceipt(tx: any): any {
return async (dispatch, getState) => {
const web3instance = getState().web3.filter(w3 => w3.coin === tx.coin)[0];
const web3instance = getState().web3.filter(w3 => w3.network === tx.network)[0];
const web3 = web3instance.web3;
//web3.eth.getTransactionReceipt(txid, (error, tx) => {

View File

@ -6,9 +6,9 @@ import { findSelectedDevice } from '../../reducers/TrezorConnectReducer';
const ConfirmAddress = (props: any): any => {
const account = props.accounts.find(a => a.checksum === props.receive.checksum && a.index === props.receive.accountIndex && a.coin === props.receive.coin);
const account = props.accounts.find(a => a.deviceState === props.receive.deviceState && a.index === props.receive.accountIndex && a.network === props.receive.network);
const { config } = props.localStorage;
const selectedCoin = config.coins.find(c => c.network === account.coin);
const selectedCoin = config.coins.find(c => c.network === account.network);
return (
<div className="confirm-address">
@ -27,7 +27,7 @@ export default ConfirmAddress;
export const ConfirmUnverifiedAddress = (props: any): any => {
const account = props.accounts.find(a => a.checksum === props.receive.checksum && a.index === props.receive.accountIndex && a.coin === props.receive.coin);
const account = props.accounts.find(a => a.deviceState === props.receive.deviceState && a.index === props.receive.accountIndex && a.network === props.receive.network);
const {
onCancel

View File

@ -7,7 +7,7 @@ const Confirmation = (props): any => {
const {
amount,
address,
coin,
network,
coinSymbol,
token,
total,

View File

@ -16,15 +16,14 @@ export default class Receive extends AbstractAccount {
const _render = (props: any): any => {
const {
checksum,
deviceState,
accountIndex,
coin,
addressVerified,
addressUnverified,
} = props.receive;
const device = props.devices.find(d => d.checksum === checksum);
const account = props.accounts.find(a => a.checksum === checksum && a.index === accountIndex && a.coin === coin);
const device = props.devices.find(d => d.state === deviceState);
const account = props.accounts.find(a => a.deviceState === deviceState && a.index === accountIndex && a.network === network);
let qrCode = null;
let address = `${account.address.substring(0, 20)}...`;

View File

@ -22,13 +22,13 @@ export default class AbstractAccount extends Component {
const props = this.props;
if (!state.checksum) {
if (!state.deviceState) {
return (<section></section>);
}
const device = this.props.devices.find(d => d.checksum === state.checksum);
const discovery = props.discovery.find(d => d.checksum === device.checksum && d.coin === state.coin);
const account = props.accounts.find(a => a.checksum === state.checksum && a.index === state.accountIndex && a.coin === state.coin);
const device = this.props.devices.find(d => d.state === state.deviceState);
const discovery = props.discovery.find(d => d.deviceState === device.state && d.network === state.network);
const account = props.accounts.find(a => a.deviceState === state.deviceState && a.index === state.accountIndex && a.network === state.network);
if (!account) {
if (!discovery || discovery.waitingForDevice) {

View File

@ -71,7 +71,7 @@ const AccountTabs = (props: any): any => {
const urlParams = props.match.params;
//const urlParams = props.match ? props.match.params : { address: '0' };
const basePath = `/device/${urlParams.device}/coin/${urlParams.coin}/address/${urlParams.address}`;
const basePath = `/device/${urlParams.device}/network/${urlParams.network}/address/${urlParams.address}`;
return (
<div className="account-tabs">

View File

@ -21,15 +21,15 @@ const AccountSelection = (props: any): any => {
const baseUrl: string = `/device/${location.params.device}`;
const { config } = props.localStorage;
const selectedCoin = config.coins.find(c => c.network === location.params.coin);
const selectedCoin = config.coins.find(c => c.network === location.params.network);
const fiatRate = props.fiat.find(f => f.network === selectedCoin.network);
// console.warn("AccountSelectionRender", selected, props);
const deviceAddresses: Array<any> = getAccounts(accounts, selected, location.params.coin);
const deviceAddresses: Array<any> = getAccounts(accounts, selected, location.params.network);
let selectedAccounts = deviceAddresses.map((address, i) => {
// const url: string = `${baseUrl}/coin/${location.params.coin}/address/${i}`;
// const url: string = `${baseUrl}/network/${location.params.network}/address/${i}`;
const url: string = location.pathname.replace(/address+\/([0-9]*)/, `address/${i}`);
let balance: string = 'Loading...';
@ -64,7 +64,7 @@ const AccountSelection = (props: any): any => {
}
let discoveryStatus = null;
const discovery = props.discovery.find(d => d.checksum === selected.checksum && d.coin === location.params.coin);
const discovery = props.discovery.find(d => d.deviceState === selected.state && d.network === location.params.network);
if (discovery) {
if (discovery.completed) {

View File

@ -52,7 +52,7 @@ const Aside = (props: any): any => {
if (props.deviceDropdownOpened) {
menu = <DeviceDropdown {...props} />;
} else if (location.params.coin) {
} else if (location.params.network) {
menu = (
<TransitionMenu animationType={"slide-left"}>
<AccountSelection { ...props} />

View File

@ -9,7 +9,7 @@ const CoinSelection = (props: any): any => {
const { config } = props.localStorage;
const walletCoins = config.coins.map(item => {
const url = `${ location.pathname }/coin/${ item.network }/address/0`;
const url = `${ location.pathname }/network/${ item.network }/address/0`;
const className = `coin ${ item.network }`
return (
<NavLink key={ item.network } to={ url } className={ className }>

View File

@ -7,7 +7,7 @@ import Tooltip from 'rc-tooltip';
const AdvancedForm = (props: any): any => {
const {
coin,
network,
token,
gasPrice,
gasLimit,
@ -115,7 +115,7 @@ const AdvancedForm = (props: any): any => {
<span className="what-is-it"></span>
</Tooltip>
</label>
<textarea disabled={ coin !== token } value={ coin !== token ? '' : data } onChange={ event => onDataChange(event.target.value) }></textarea>
<textarea disabled={ network !== token } value={ network !== token ? '' : data } onChange={ event => onDataChange(event.target.value) }></textarea>
{ errors.data ? (<span className="error">{ errors.data }</span>) : null }
</div>

View File

@ -7,8 +7,8 @@ import ScaleText from 'react-scale-text';
const PendingTransactions = (props: any): any => {
const account = props.accounts.find(a => a.checksum === props.sendForm.checksum && a.index === props.sendForm.accountIndex && a.coin === props.sendForm.coin);
const pending = props.pending.filter(p => p.coin === account.coin && p.address === account.address);
const account = props.accounts.find(a => a.deviceState === props.sendForm.deviceState && a.index === props.sendForm.accountIndex && a.network === props.sendForm.network);
const pending = props.pending.filter(p => p.network === account.network && p.address === account.address);
if (pending.length < 1) return null;
@ -21,7 +21,7 @@ const PendingTransactions = (props: any): any => {
let iconColor, symbol, name;
if (tx.token !== tx.coin) {
if (tx.token !== tx.network) {
const token = tokens.find(t => t.symbol === tx.token);
iconColor = {
color: textColor.hex(token.name),
@ -32,9 +32,9 @@ const PendingTransactions = (props: any): any => {
name = token.name;
} else {
iconColor = {
color: textColor.hex(tx.coin),
background: bgColor.hex(tx.coin),
borderColor: bgColor.hex(tx.coin)
color: textColor.hex(tx.network),
background: bgColor.hex(tx.network),
borderColor: bgColor.hex(tx.network)
}
symbol = props.selectedCoin.symbol;
name = props.selectedCoin.name;

View File

@ -18,16 +18,16 @@ export default class Send extends AbstractAccount {
const _render = (props: any): any => {
const device = props.devices.find(d => d.checksum === props.sendForm.checksum);
const discovery = props.discovery.find(d => d.checksum === device.checksum && d.coin === props.sendForm.coin);
const account = props.accounts.find(a => a.checksum === props.sendForm.checksum && a.index === props.sendForm.accountIndex && a.coin === props.sendForm.coin);
const device = props.devices.find(device => device.state === props.sendForm.deviceState);
const discovery = props.discovery.find(d => d.deviceState === device.state && d.network === props.sendForm.network);
const account = props.accounts.find(a => a.deviceState === props.sendForm.deviceState && a.index === props.sendForm.accountIndex && a.network === props.sendForm.network);
const addressTokens = props.tokens.filter(t => t.ethAddress === account.address);
const {
address,
amount,
setMax,
coin,
network,
coinSymbol,
token,
feeLevels,
@ -53,7 +53,7 @@ const _render = (props: any): any => {
} = props.sendFormActions;
const { config } = props.localStorage;
const selectedCoin = config.coins.find(c => c.network === coin);
const selectedCoin = config.coins.find(c => c.network === network);
const fiatRate = props.fiat.find(f => f.network === selectedCoin.network);
const tokens = addressTokens.map(t => {
@ -81,13 +81,12 @@ const _render = (props: any): any => {
let buttonDisabled: boolean = Object.keys(errors).length > 0 || total === '0' || amount.length === 0 || address.length === 0 || sending;
let buttonLabel: string = 'Send';
if (coin !== token && amount.length > 0 && !errors.amount) {
if (network !== token && amount.length > 0 && !errors.amount) {
buttonLabel += ` ${amount} ${ token.toUpperCase() }`
} else if (coin === token && total !== '0') {
} else if (network === token && total !== '0') {
buttonLabel += ` ${total} ${ selectedCoin.symbol }`;
}
//const device = props.devices.find(d => d.checksum === currentAccount.checksum);
if (device && !device.connected) {
buttonLabel = 'Device is not connected';
buttonDisabled = true;

View File

@ -19,9 +19,9 @@ export default class Summary extends AbstractAccount {
const _render = (props: any): any => {
const device = props.devices.find(d => d.checksum === props.summary.checksum);
const discovery = props.discovery.find(d => d.checksum === device.checksum && d.coin === props.summary.coin);
const account = props.accounts.find(a => a.checksum === props.summary.checksum && a.index === props.summary.accountIndex && a.coin === props.summary.coin);
const device = props.devices.find(d => d.state === props.summary.deviceState);
const discovery = props.discovery.find(d => d.deviceState === device.state && d.network === props.summary.network);
const account = props.accounts.find(a => a.deviceState === props.summary.deviceState && a.index === props.summary.accountIndex && a.network === props.summary.network);
const tokens = props.tokens.filter(t => t.ethAddress === account.address);
return (
@ -31,12 +31,12 @@ const _render = (props: any): any => {
<Notification className="info" title={ `Device ${ device.instanceLabel } is disconnected` } />
) : null }
<h2 className={ `summary-header ${props.summary.coin}` }>Address #{ parseInt(props.match.params.address) + 1 }</h2>
<h2 className={ `summary-header ${props.summary.network}` }>Address #{ parseInt(props.match.params.address) + 1 }</h2>
<SummaryDetails
summary={ props.summary }
balance={ account.balance }
coin={ props.summary.coin }
network={ props.summary.network }
fiat={ props.fiat }
localStorage={ props.localStorage }
onToggle={ props.summaryActions.onDetailsToggle } />

View File

@ -13,7 +13,7 @@ const SummaryDetails = (props: any): any => {
);
const { config } = props.localStorage;
const selectedCoin = config.coins.find(c => c.network === props.coin);
const selectedCoin = config.coins.find(c => c.network === props.network);
const fiatRate = props.fiat.find(f => f.network === selectedCoin.network);
let balanceColumn = null;

View File

@ -19,7 +19,7 @@ const Article = (props) => {
return (
<article>
<nav>
<Route path="/device/:device/coin/:coin/address/:address" component={ AccountTabs } />
<Route path="/device/:device/network/:network/address/:address" component={ AccountTabs } />
</nav>
<Notifications />
<Log />

View File

@ -6,15 +6,15 @@ import * as CONNECT from '../actions/constants/TrezorConnect';
export type State = {
+index: number;
+checksum: ?string;
+coin: string;
+ch: ?string;
+network: string;
location: string;
}
export const initialState: State = {
index: 0,
checksum: null,
coin: '',
deviceState: null,
network: '',
};

View File

@ -6,8 +6,9 @@ import * as ADDRESS from '../actions/constants/Address';
export type Account = {
loaded: boolean;
+checksum: string;
+coin: string;
+network: string;
+deviceID: string;
+deviceState: ?string;
+index: number;
+addressPath: Array<number>;
+address: string;
@ -21,15 +22,17 @@ const createAccount = (state: Array<Account>, action: any): Array<Account> => {
// TODO check with device_id
// check if account was created before
const exist: ?Account = state.find(addr => addr.address === action.address && addr.coin === action.coin);
const exist: ?Account = state.find((account: Account) => account.address === action.address && account.network === action.network && account.deviceID === action.device.features.device_id);
console.warn("MAM?", exist, action)
if (exist) {
return state;
}
const address: Account = {
loaded: false,
checksum: action.device.checksum,
coin: action.coin,
network: action.network,
deviceID: action.device.features.device_id,
deviceState: action.device.state,
index: action.index,
addressPath: action.path,
address: action.address,
@ -43,16 +46,15 @@ const createAccount = (state: Array<Account>, action: any): Array<Account> => {
}
const removeAccounts = (state: Array<Account>, action: any): Array<Account> => {
// TODO: all instances od device (multiple checksums)
return state.filter(addr => addr.checksum !== action.device.checksum);
return state.filter(account => account.deviceID !== action.device.features.device_id);
}
const forgetAccounts = (state: Array<Account>, action: any): Array<Account> => {
return state.filter(addr => action.accounts.indexOf(addr) === -1);
return state.filter(account => action.accounts.indexOf(account) === -1);
}
const setBalance = (state: Array<Account>, action: any): Array<Account> => {
const index: number = state.findIndex(addr => addr.address === action.address && addr.coin === action.coin);
const index: number = state.findIndex(account => account.address === action.address && account.network === action.network);
const newState: Array<Account> = [ ...state ];
newState[index].loaded = true;
newState[index].balance = action.balance;
@ -60,7 +62,7 @@ const setBalance = (state: Array<Account>, action: any): Array<Account> => {
}
const setNonce = (state: Array<Account>, action: any): Array<Account> => {
const index: number = state.findIndex(addr => addr.address === action.address && addr.coin === action.coin);
const index: number = state.findIndex(account => account.address === action.address && account.network === action.network);
const newState: Array<Account> = [ ...state ];
newState[index].loaded = true;
newState[index].nonce = action.nonce;

View File

@ -6,8 +6,8 @@ import * as ADDRESS from '../actions/constants/Address';
import * as CONNECT from '../actions/constants/TrezorConnect';
export type Discovery = {
coin: string;
checksum: string;
network: string;
deviceState: string;
xpub: string;
accountIndex: number;
interrupted: boolean;
@ -18,14 +18,18 @@ export type Discovery = {
const initialState: Array<Discovery> = [];
const findIndex = (state: Array<Discovery>, network: string, deviceState: string): number => {
return state.findIndex(d => d.network === network && d.deviceState === deviceState);
}
const start = (state: Array<Discovery>, action: any): Array<Discovery> => {
const instance: Discovery = {
coin: action.coin,
network: action.network,
xpub: action.xpub,
hdKey: action.hdKey,
basePath: action.basePath,
checksum: action.device.checksum,
deviceState: action.device.state,
accountIndex: 0,
interrupted: false,
completed: false,
@ -33,12 +37,7 @@ const start = (state: Array<Discovery>, action: any): Array<Discovery> => {
}
const newState: Array<Discovery> = [ ...state ];
const index: number = state.findIndex(d => {
return d.coin === action.coin && d.checksum === action.device.checksum;
});
console.warn("START DISCO", index);
const index: number = findIndex(state, action.network, action.device.state);
if (index >= 0) {
newState[index] = instance;
} else {
@ -48,31 +47,27 @@ const start = (state: Array<Discovery>, action: any): Array<Discovery> => {
}
const complete = (state: Array<Discovery>, action: any): Array<Discovery> => {
const index: number = state.findIndex(d => {
return d.coin === action.coin && d.checksum === action.device.checksum;
});
const index: number = findIndex(state, action.network, action.device.state);
const newState: Array<Discovery> = [ ...state ];
newState[index].completed = true;
return newState;
}
const addressCreate = (state: Array<Discovery>, action: any): Array<Discovery> => {
const index: number = state.findIndex(d => {
return d.coin === action.coin && d.checksum === action.device.checksum;
});
const index: number = findIndex(state, action.network, action.device.state);
const newState: Array<Discovery> = [ ...state ];
newState[index].accountIndex++;
return newState;
}
const forgetDiscovery = (state: Array<Discovery>, action: any): Array<Discovery> => {
return state.filter(d => d.checksum !== action.device.checksum);
return state.filter(d => d.deviceState !== action.device.state);
}
const stop = (state: Array<Discovery>, action: any): Array<Discovery> => {
const newState: Array<Discovery> = [ ...state ];
return newState.map( (d: Discovery) => {
if (d.checksum === action.device.checksum && !d.completed) {
if (d.deviceState === action.device.state && !d.completed) {
d.interrupted = true;
d.waitingForDevice = false;
}
@ -83,8 +78,8 @@ const stop = (state: Array<Discovery>, action: any): Array<Discovery> => {
const waiting = (state: Array<Discovery>, action: any): Array<Discovery> => {
const instance: Discovery = {
coin: action.coin,
checksum: action.device.checksum,
network: action.network,
deviceState: action.device.state,
xpub: '',
accountIndex: 0,
interrupted: false,
@ -92,10 +87,7 @@ const waiting = (state: Array<Discovery>, action: any): Array<Discovery> => {
waitingForDevice: true
}
const index: number = state.findIndex(d => {
return d.coin === action.coin && d.checksum === action.device.checksum;
});
const index: number = findIndex(state, action.network, action.device.state);
const newState: Array<Discovery> = [ ...state ];
if (index >= 0) {
newState[index] = instance;

View File

@ -6,7 +6,7 @@ import * as WEB3 from '../actions/constants/Web3';
export type PendingTx = {
+id: string;
+coin: string;
+network: string;
+token: string;
+amount: string;
+address: string;
@ -18,7 +18,7 @@ const add = (state: Array<PendingTx>, action: any) => {
const newState = [ ...state ];
newState.push({
id: action.txid,
coin: action.address.coin,
network: action.address.network,
token: action.token,
amount: action.amount,
address: action.address.address,

View File

@ -4,18 +4,18 @@
import * as RECEIVE from '../actions/constants/receive';
export type State = {
+checksum: ?string;
+deviceState: ?string;
+accountIndex: ?number;
+coin: ?string;
+network: ?string;
location: string;
addressVerified: boolean;
adressUnverified: boolean;
}
export const initialState: State = {
checksum: null,
deviceState: null,
accountIndex: null,
coin: null,
network: null,
location: '',
addressVerified: false,
addressUnverified: false,

View File

@ -10,9 +10,9 @@ import BigNumber from 'bignumber.js';
import { getFeeLevels } from '../actions/SendFormActions';
export type State = {
+checksum: ?string;
+deviceState: ?string;
+accountIndex: number;
+coin: string;
+network: string;
+coinSymbol: string;
token: string;
location: string;
@ -50,9 +50,9 @@ export type FeeLevel = {
export const initialState: State = {
checksum: null,
deviceState: null,
accountIndex: 0,
coin: '',
network: '',
coinSymbol: '',
token: '',
location: '',
@ -88,13 +88,13 @@ const onGasPriceUpdated = (state: State, action: any): State => {
}
const newPrice = getRandomInt(10, 50).toString();
//const newPrice = EthereumjsUnits.convert(action.gasPrice, 'wei', 'gwei');
if (action.coin === state.coin && newPrice !== state.recommendedGasPrice) {
if (action.network === state.network && newPrice !== state.recommendedGasPrice) {
const newState: State = { ...state };
if (!state.untouched) {
newState.gasPriceNeedsUpdate = true;
newState.recommendedGasPrice = newPrice;
} else {
const newFeeLevels = getFeeLevels(state.coin, newPrice, state.gasLimit);
const newFeeLevels = getFeeLevels(state.network, newPrice, state.gasLimit);
const selectedFeeLevel = newFeeLevels.find(f => f.value === 'Normal');
newState.recommendedGasPrice = newPrice;
newState.feeLevels = newFeeLevels;

View File

@ -4,9 +4,9 @@
import * as SUMMARY from '../actions/constants/summary';
export type State = {
+checksum: ?string;
+deviceState: ?string;
+accountIndex: ?number;
+coin: ?string;
+network: ?string;
location: string;
details: boolean;
@ -14,9 +14,9 @@ export type State = {
}
export const initialState: State = {
checksum: null,
deviceState: null,
accountIndex: null,
coin: null,
network: null,
location: '',
details: true,

View File

@ -6,7 +6,7 @@ import * as TOKEN from '../actions/constants/Token';
export type Token = {
loaded: boolean;
+checksum: string;
+deviceState: string;
+name: string;
+symbol: string;
+address: string;
@ -31,7 +31,7 @@ const create = (state: Array<Token>, payload: any): Array<Token> => {
const newState: Array<Token> = [ ...state ];
const token: Token = {
loaded: false,
checksum: payload.checksum,
deviceState: payload.deviceState,
name: payload.name,
symbol: payload.symbol,
address: payload.address,
@ -44,7 +44,7 @@ const create = (state: Array<Token>, payload: any): Array<Token> => {
}
const forget = (state: Array<Token>, action: any): Array<Token> => {
return state.filter(t => t.checksum !== action.device.checksum);
return state.filter(t => t.deviceState !== action.device.deviceState);
}
const remove = (state: Array<Token>, action: any): Array<Token> => {

View File

@ -9,7 +9,7 @@ export type TrezorDevice = {
connected: boolean;
path: string;
+label: string;
+checksum: string;
+state: string;
+instance?: number;
instanceLabel: string;
features?: Object;
@ -81,12 +81,12 @@ const mergeDevices = (current: TrezorDevice, upcoming: Object): TrezorDevice =>
remember: typeof upcoming.remember === 'boolean' ? upcoming.remember : current.remember,
instance: current.instance,
instanceLabel: current.instanceLabel,
checksum: current.checksum,
state: current.state,
acquiring: typeof upcoming.acquiring === 'boolean' ? upcoming.acquiring : current.acquiring,
ts: new Date().getTime(),
}
if (upcoming.unacquired && current.checksum) {
if (upcoming.unacquired && current.state) {
dev.instanceLabel = current.instanceLabel;
dev.features = current.features;
dev.label = current.label;
@ -135,7 +135,7 @@ const addDevice = (state: State, device: Object): State => {
connected: true,
path: device.path,
label: device.label,
checksum: null,
state: null,
// instance: 0,
instanceLabel: device.label,
ts: 0,
@ -157,7 +157,7 @@ const setDeviceState = (state: State, action: any): State => {
if (index > -1) {
const changedDevice: TrezorDevice = {
...newState.devices[index],
checksum: action.checksum
state: action.state
};
newState.devices[index] = changedDevice;
//newState.selectedDevice = changedDevice;
@ -219,7 +219,7 @@ const disconnectDevice = (state: State, device: Object): State => {
const otherDevices: Array<TrezorDevice> = state.devices.filter(d => affectedDevices.indexOf(d) === -1);
if (affectedDevices.length > 0) {
const acquiredDevices = affectedDevices.filter(d => !d.unacquired && d.checksum);
const acquiredDevices = affectedDevices.filter(d => !d.unacquired && d.state);
newState.devices = otherDevices.concat( acquiredDevices.map(d => {
d.connected = false;
d.isUsedElsewhere = false;
@ -276,7 +276,7 @@ const duplicate = (state: State, device: any): State => {
// if (affectedDevices.length > 0) {
const newDevice: TrezorDevice = {
...device,
checksum: null,
state: null,
remember: device.remember,
connected: device.connected,
path: device.path,

View File

@ -8,7 +8,7 @@ const WIDTH: number = 1080;
const HEIGHT: number = 1920;
type State = {
coin: string;
network: string;
device: string;
}

View File

@ -1,70 +0,0 @@
/* @flow */
'use strict';
import Web3 from 'web3';
import { UI, DEVICE } from 'trezor-connect';
import * as ACTIONS from '../actions';
import * as STORAGE from '../actions/constants/LocalStorage';
import * as WEB3 from '../actions/constants/Web3';
type State = {
web3: Web3;
url: Array<string>;
customUrl: string;
tokens: JSON;
abi: JSON;
gasPrice: any;
latestBlock: any;
fiatRate: ?string;
}
const initialState: State = {
web3: null,
url: [
'https://ropsten.infura.io/QGyVKozSUEh2YhL4s2G4',
'https://api.myetherapi.com/rop',
'https://pyrus2.ubiqscan.io',
],
customUrl: 's',
gasPrice: 0,
latestBlock: 0,
};
export default function web3(state: State = initialState, action: any): any {
switch (action.type) {
case 'rate__update' :
return {
...state,
fiatRate: action.rate.price_usd
}
case STORAGE.READY :
return {
...state,
tokens: action.tokens,
abi: action.abi
}
case WEB3.READY :
return {
...state,
web3: action.web3
}
case WEB3.BLOCK_UPDATED :
return {
...state,
latestBlock: action.blockHash
}
case WEB3.GAS_PRICE_UPDATED :
return {
...state,
gasPrice: action.gasPrice
}
default:
return state;
}
}

View File

@ -7,7 +7,7 @@ import * as STORAGE from '../actions/constants/LocalStorage';
import * as WEB3 from '../actions/constants/Web3';
type Web3Instance = {
coin: string;
network: string;
web3: Web3;
chainId: number;
latestBlock: any;
@ -19,7 +19,7 @@ const initialState: Array<Web3Instance> = [];
const createWeb3 = (state: Array<Web3Instance>, action: any): Array<Web3Instance> => {
const instance: Web3Instance = {
coin: action.name,
network: action.network,
web3: action.web3,
chainId: parseInt(action.chainId),
latestBlock: '0',
@ -32,18 +32,14 @@ const createWeb3 = (state: Array<Web3Instance>, action: any): Array<Web3Instance
}
const updateLatestBlock = (state: Array<Web3Instance>, action: any): Array<Web3Instance> => {
const index: number = state.findIndex(w3 => {
return w3.coin === action.name;
});
const index: number = state.findIndex(w3 => w3.network === action.network);
const newState: Array<Web3Instance> = [ ...state ];
newState[index].latestBlock = action.blockHash;
return newState;
}
const updateGasPrice = (state: Array<Web3Instance>, action: any): Array<Web3Instance> => {
const index: number = state.findIndex(w3 => {
return w3.coin === action.coin;
});
const index: number = state.findIndex(w3 => w3.network === action.network);
const newState: Array<Web3Instance> = [ ...state ];
newState[index].gasPrice = action.gasPrice;
return newState;

View File

@ -35,14 +35,14 @@ export default (
<Route>
<WalletContainer>
<Route exact path="/device/:device/" component={ DashboardContainer } />
<Route exact path="/device/:device/coin/:coin" component={ DashboardContainer } />
<Route exact path="/device/:device/network/:network" component={ DashboardContainer } />
<Route exact path="/device/:device/acquire" component={ AcquireContainer } />
<Route exact path="/device/:device/bootloader" component={ BootloaderContainer } />
<Route exact path="/device/:device/coin/:coin/address/:address" component={ SummaryContainer } />
<Route path="/device/:device/coin/:coin/address/:address/send" component={ SendFormContainer } />
<Route path="/device/:device/coin/:coin/address/:address/send/override" component={ SendFormContainer } />
<Route path="/device/:device/coin/:coin/address/:address/receive" component={ ReceiveContainer } />
<Route path="/device/:device/coin/:coin/address/:address/signverify" component={ SignVerifyContainer } />
<Route exact path="/device/:device/network/:network/address/:address" component={ SummaryContainer } />
<Route path="/device/:device/network/:network/address/:address/send" component={ SendFormContainer } />
<Route path="/device/:device/network/:network/address/:address/send/override" component={ SendFormContainer } />
<Route path="/device/:device/network/:network/address/:address/receive" component={ ReceiveContainer } />
<Route path="/device/:device/network/:network/address/:address/signverify" component={ SignVerifyContainer } />
{/* <Route path="/device/:device/address/:address/history" component={ HistoryContainer } /> */}
</WalletContainer>

View File

@ -20,7 +20,7 @@ import * as WEB3 from '../actions/constants/Web3';
const findAccounts = (devices, accounts) => {
return devices.reduce((arr, dev) => {
return arr.concat(accounts.filter(a => a.checksum === dev.checksum));
return arr.concat(accounts.filter(a => a.deviceState === dev.state));
}, []);
}
@ -32,7 +32,7 @@ const findTokens = (accounts, tokens) => {
const findDiscovery = (devices, discovery) => {
return devices.reduce((arr, dev) => {
return arr.concat(discovery.filter(a => a.checksum === dev.checksum));
return arr.concat(discovery.filter(a => a.deviceState === dev.state));
}, []);
}

View File

@ -48,9 +48,9 @@ const validation = (store: any, params: UrlParams): boolean => {
if (!device) return false;
}
if (params.hasOwnProperty('coin')) {
if (params.hasOwnProperty('network')) {
const { config } = store.getState().localStorage;
const coin = config.coins.find(c => c.network === params.coin);
const coin = config.coins.find(coin => coin.network === params.network);
if (!coin) return false;
if (!params.address) return false;
}
@ -84,7 +84,7 @@ const RouterService = (store: any) => (next: any) => (action: any) => {
initSearch: action.payload.search
}
// check if there are initial parameters in url (coin)
// check if there are initial parameters in url (network/ device / account)
if (action.payload.search.length > 0) {
// save it in WalletReducer, after device detection will redirect to this request
redirectPath = '/';
@ -125,11 +125,11 @@ const RouterService = (store: any) => (next: any) => (action: any) => {
});
}
if (requestedParams.coin !== currentParams.coin) {
if (requestedParams.network !== currentParams.network) {
store.dispatch({
type: CONNECT.COIN_CHANGED,
payload: {
coin: requestedParams.coin
network: requestedParams.network
}
});
}

View File

@ -1,219 +0,0 @@
/* @flow */
'use strict';
import { LOCATION_CHANGE, push } from 'react-router-redux';
import TrezorConnect, { TRANSPORT, DEVICE_EVENT, UI_EVENT, UI, DEVICE } from 'trezor-connect';
import * as TrezorConnectActions from '../actions/TrezorConnectActions';
import * as ModalActions from '../actions/ModalActions';
import { init as initWeb3 } from '../actions/Web3Actions';
import * as WEB3 from '../actions/constants/Web3';
import * as STORAGE from '../actions/constants/LocalStorage';
import * as CONNECT from '../actions/constants/TrezorConnect';
const initSelectedDevice = async (store: any, device: any): void => {
const { selectedDevice } = store.getState().connect;
console.log("WHATSUP?", device, selectedDevice)
// if we are in LandingPage view switch it to Wallet
if (selectedDevice && selectedDevice.path === device.path && selectedDevice.instance === device.instance) {
if (selectedDevice.unacquired || selectedDevice.isUsedElsewhere) {
store.dispatch( push(`/device/${ selectedDevice.path }/acquire`) );
} else {
if (device.features.bootloader_mode) {
store.dispatch( push(`/device/${ selectedDevice.path }/bootloader`) );
} else {
if (device.instance) {
store.dispatch( push(`/device/${ device.features.device_id }:${ device.instance }`) );
} else {
store.dispatch( push(`/device/${ device.features.device_id }`) );
}
// if (!selectedDevice.initialized && selectedDevice.connected) {
// const response = await TrezorConnect.getPublicKey({
// selectedDevice: selectedDevice.path,
// instance: selectedDevice.instance,
// path: "m/1'/0'/0'",
// confirmation: false
// });
// if (response && response.success) {
// const xpub = response.payload.xpub;
// store.dispatch({
// type: CONNECT.AUTH_DEVICE,
// device: selectedDevice,
// xpub
// });
// } else {
// // TODO: error
// }
// console.log("INIT SELECTED!", device, response)
// }
//store.dispatch( push(`/device/${ device.features.device_id }/coin/eth/address/0/send`) );
//store.dispatch( push(`/device/${ device.features.device_id }/coin/eth/address/0`) );
// store.dispatch( push(`/device/${ device.features.device_id }`) );
// store.dispatch( TrezorConnectActions.startDiscoveryProcess(device) );
// get xpub to force
}
}
}
}
const TrezorConnectService = (store: any) => (next: any) => (action: any) => {
if (action.type === DEVICE.DISCONNECT) {
const previous = store.getState().connect.selectedDevice;
next(action);
if (previous && action.device.path === previous.path) {
if (previous.unacquired) {
} else if (previous.initialized) {
// interrupt discovery process
store.dispatch( TrezorConnectActions.stopDiscoveryProcess(previous) );
if (!previous.remember) {
store.dispatch(ModalActions.askForRemember(previous));
}
}
}
return;
}
if (action.type === DEVICE.ACQUIRED) {
const { selectedDevice } = store.getState().connect;
initSelectedDevice(store, selectedDevice);
}
if (action.type === DEVICE.CHANGED) {
const previousSelectedDevice = store.getState().connect.selectedDevice;
// Pass actions BEFORE
next(action);
if (previousSelectedDevice && action.device.path === previousSelectedDevice.path) {
//console.warn("TODO: Handle device changed, interrupt running async action (like discovery)", action.device);
}
} else if (action.type === DEVICE.DISCONNECT || action.type === CONNECT.SELECT_DEVICE) {
const previousSelectedDevice = store.getState().connect.selectedDevice;
// Pass actions BEFORE
next(action);
const { devices, selectedDevice } = store.getState().connect;
if (!selectedDevice) {
store.dispatch( push('/') );
} else if (previousSelectedDevice.path !== selectedDevice.path || previousSelectedDevice.instance !== selectedDevice.instance) {
// interrupt discovery process
store.dispatch( TrezorConnectActions.stopDiscoveryProcess(previousSelectedDevice) );
initSelectedDevice(store, selectedDevice);
}
} else if (action.type === TRANSPORT.ERROR) {
next(action);
store.dispatch( push('/') );
} else {
// Pass all actions through by default
next(action);
}
if (action.type === STORAGE.READY) {
// TODO: check offline devices
// set listeners
TrezorConnect.on(DEVICE_EVENT, (event: DeviceMessage): void => {
// post event to TrezorConnectReducer
store.dispatch({
type: event.type,
device: event.payload
});
});
const version: Object = TrezorConnect.getVersion();
if (version.type === 'library') {
// handle UI events only if TrezorConnect isn't using popup
TrezorConnect.on(UI_EVENT, (type: string, data: any): void => {
// post event to reducers
store.dispatch({
type,
data
});
});
}
// init TrezorConnect library
TrezorConnect.init({
hostname: 'localhost', // TODO: controll it in Connect
transport_reconnect: false,
})
.then(() => {
// post action inited
//store.dispatch({ type: 'WEB3_START' });
setTimeout(() => {
store.dispatch( initWeb3() );
}, 2000)
})
.catch(error => {
store.dispatch({
type: CONNECT.INITIALIZATION_ERROR,
error
})
});
} else if (action.type === WEB3.READY) {
const handleDeviceConnect = (device) => {
initSelectedDevice(store, device);
}
const handleDeviceDisconnect = (device) => {
// remove addresses and discovery from state
store.dispatch( TrezorConnectActions.remove(device) );
}
TrezorConnect.on(DEVICE.CONNECT, handleDeviceConnect);
TrezorConnect.on(DEVICE.CONNECT_UNACQUIRED, handleDeviceConnect);
TrezorConnect.on(DEVICE.DISCONNECT, handleDeviceDisconnect);
TrezorConnect.on(DEVICE.CONNECT_UNACQUIRED, handleDeviceDisconnect);
// solve possible race condition:
// device was connected before Web3 initialized so we need to force DEVICE.CONNECT event on them
const { devices } = store.getState().connect;
for (let d of devices) {
handleDeviceConnect(d);
}
}
};
export default TrezorConnectService;

View File

@ -114,7 +114,7 @@ const TrezorConnectService = (store: any) => (next: any) => (action: any) => {
store.dispatch( TrezorConnectActions.getSelectedDeviceState() );
} else if (action.type === CONNECT.COIN_CHANGED) {
store.dispatch( TrezorConnectActions.coinChanged( action.payload.coin ) );
store.dispatch( TrezorConnectActions.coinChanged( action.payload.network ) );
}
}

View File

@ -2,11 +2,11 @@
'use strict';
export const getAccounts = (accounts: Array<any>, device: any, coin: ?string): Array<any> => {
if (coin) {
return accounts.filter((addr) => addr.checksum === device.checksum && addr.coin === coin);
export const getAccounts = (accounts: Array<any>, device: any, network: ?string): Array<any> => {
if (network) {
return accounts.filter((addr) => addr.deviceState === device.state && addr.network === network);
} else {
return accounts.filter((addr) => addr.checksum === device.checksum);
return accounts.filter((addr) => addr.deviceState === device.state);
}
}