Merge branch 'master' of github.com:andrerfneves/zec-react-wallet

This commit is contained in:
George Lima 2019-05-31 17:25:32 -03:00
commit d29b2c7584
37 changed files with 881 additions and 343 deletions

View File

@ -5,7 +5,7 @@
"browser": true,
"node": true,
"mocha": true,
"jest/globals": true
"jest": true
},
"plugins": ["flowtype", "jest"],
"settings": {

View File

@ -4,13 +4,12 @@ When contributing to this repository, please first discuss the change you wish t
## Pull Request Process
1. Ensure any install or build dependencies are removed before the end of the layer when doing a
build.
1. Ensure any extraneous install or build dependencies are removed before doing a build.
2. Update the README.md with details of changes to the interface, this includes new environment
variables, exposed ports, useful file locations and container parameters.
3. Increase the version numbers in any examples files and the README.md to the new version that this
Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/).
4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
4. You may merge the Pull Request in once you have the sign-off of at least two other developers, or if you
do not have permission to do that, you may request the second reviewer to merge it for you.
Learn more about this project's [development workflow](https://github.com/ZcashFoundation/zepio/blob/master/DEVELOPMENT_WORKFLOW.md).

View File

@ -18,13 +18,14 @@ List of the main open source libraries and technologies used in building **Zepio
- [zcashd](https://github.com/zcash/zcash): Zcash node daemon
- [Electron](https://github.com/electron/electron): Desktop application builder
- [React](https://facebook.github.io/react/): User interface view layer
- [Redux](http://redux.js.org/): Predictable application state container
- [Redux](https://redux.js.org/): Predictable application state container
- [Styled Components](https://www.styled-components.com/): Visual primitives for theming and styling applications
- [webpack](http://webpack.github.io/): Application module bundler (and more)
- [Babel](http://babeljs.io/): ES7/JSX transpilling
- [ESLint](http://eslint.org/): Code linting rules
- [webpack](https://webpack.github.io/): Application module bundler (and more)
- [Babel](https://babeljs.io/): ES7/JSX transpilling
- [ESLint](https://eslint.org/): Code linting rules
- [Flow](https://flow.org): JavaScript static type checker
- [Docz](https://docz.site): Documentation builder
- [BigNumber.js](https://github.com/MikeMcl/bignumber.js#readme): Arbitrary-precision decimal and non-decimal arithmetic with safety
## Installing and Running From Source
@ -122,4 +123,4 @@ In order to contribute and submit PRs to improve the **Zepio** codebase, please
## License
MIT © Zcash Foundation 2019 zfnd.org
MIT © Zcash Foundation 2019 [zfnd.org](zfnd.org)

View File

@ -5,6 +5,6 @@ module.exports = class {
}
get() {
return 'test value';
return 'TESTNET';
}
};

View File

@ -27,6 +27,7 @@ beforeAll(() => {
});
afterAll(() => {
global.Date = originalDate;
// $FlowFixMe
dateFns.format.mockRestore();
cleanup();
});

View File

@ -27,6 +27,7 @@ beforeAll(() => {
});
afterAll(() => {
global.Date = originalDate;
// $FlowFixMe
dateFns.format.mockRestore();
cleanup();
});
@ -48,7 +49,7 @@ describe('<TransactionDailyComponent />', () => {
zecPrice: 1.345,
date: '2019-02-20T19:31:57.117Z',
theme: appTheme,
fees: 0.001,
fees: 0.0001,
confirmations: 10,
confirmed: true,
},
@ -60,7 +61,7 @@ describe('<TransactionDailyComponent />', () => {
zecPrice: 1.344,
date: '2019-02-20T19:31:57.117Z',
theme: appTheme,
fees: 0.001,
fees: 0.0001,
confirmed: false,
confirmations: 3,
},

View File

@ -18,15 +18,19 @@ describe('Startup', () => {
expect(app.client.getTitle()).resolves.toEqual('Zepio');
});
test('should show the text "Zepio Starting" in loading screen', async () => expect(app.client.element('#loading-screen:first-child p').getHTML()).resolves.toEqual(
expect.stringContaining('Zepio Starting'),
));
test('should show the text "Zepio Starting" in loading screen', async () => {
expect(
app.client.element('div[data-testid~="LoadingScreen"]:first-child p').getHTML(),
).resolves.toEqual(expect.stringContaining('Zepio Starting'));
});
test('should show the zcash logo in loading screen', () => expect(app.client.getAttribute('#loading-screen:first-child img', 'src')).resolves.toEqual(
expect.stringContaining('/assets/zcash-simple-icon.svg'),
));
test('should show the zcash logo in loading screen', () => expect(
app.client.getAttribute('div[data-testid~="LoadingScreen"]:first-child img', 'src'),
).resolves.toEqual(expect.stringContaining('/assets/zcash-simple-icon.svg')));
test('should show the loading circle in loading screen', () => {
expect(app.client.element('#loading-screen svg').isExisting()).resolves.toEqual(true);
expect(
app.client.element('div[data-testid~="LoadingScreen"] svg').isExisting(),
).resolves.toEqual(true);
});
});

View File

@ -14,6 +14,6 @@ afterAll(() => app.stop());
describe('Status Pill', () => {
test('should show status pill in the header', async () => expect(
app.client.waitUntilTextExists('#status-pill', 'SYNCED').getText('#status-pill'),
).resolves.toEqual(expect.stringContaining('SYNCED')));
app.client.waitUntilTextExists('#status-pill', 'READY', 30000).getText('#status-pill'),
).resolves.toEqual(expect.stringContaining('READY')));
});

View File

@ -3,7 +3,7 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import 'babel-polyfill';
import createTestServer from 'create-test-server';
import createTestServer from '@astrocoders/create-test-server';
const transactions = [];
@ -21,7 +21,7 @@ const handler = (server) => {
switch (method) {
case 'getinfo':
sleep(1500).then(() => res.send({ result: { version: 1.0 } }));
sleep(500).then(() => res.send({ result: { version: 1.0 } }));
break;
case 'getblockchaininfo':
return res.send({ result: { verificationprogress: 1 } });
@ -43,7 +43,7 @@ const handler = (server) => {
});
case 'z_sendmany':
// eslint-disable-next-line
sleep(2000).then(() => {
sleep(1000).then(() => {
const [, [obj], amount, fee] = req.body.params;
if ((obj.address[0] === 'z' || obj.address[0] === 't') && amount > 0) {
@ -109,6 +109,8 @@ const handler = (server) => {
return res.send({
result: 10,
});
case 'ping':
return res.send(null);
default:
return null;
}
@ -117,8 +119,10 @@ const handler = (server) => {
createTestServer({
httpPort: '8232',
bodyParser: true,
}).then(handler);
createTestServer({
httpPort: '18232',
bodyParser: true,
}).then(handler);

View File

@ -20,6 +20,7 @@ type State = {
const getInitialTheme = () => {
const themeInStore = String(electronStore.get(THEME_MODE));
if (themeInStore === DARK || themeInStore === LIGHT) return themeInStore;
return DARK;
};

View File

@ -1,6 +1,6 @@
// @flow
import React, { type Element } from 'react';
import React, { type Node } from 'react';
import styled from 'styled-components';
import { TextComponent } from './text';
@ -64,14 +64,17 @@ const Btn = styled(Button)`
`;
type Props = {
renderTrigger: (() => void) => Element<*>,
renderTrigger?: (() => void) => Node,
title: string,
onConfirm: () => void,
onConfirm: (() => void) => void,
onClose?: () => void,
showButtons?: boolean,
showSingleConfirmButton?: boolean,
singleConfirmButtonText?: string,
width?: number,
isLoading?: boolean,
children: (() => void) => Element<*>,
isVisible?: boolean,
children: (() => void) => Node,
};
export const ConfirmDialogComponent = ({
@ -81,7 +84,10 @@ export const ConfirmDialogComponent = ({
onClose,
renderTrigger,
showButtons,
showSingleConfirmButton,
singleConfirmButtonText,
isLoading,
isVisible,
width,
}: Props) => {
const handleClose = toggle => () => {
@ -95,6 +101,7 @@ export const ConfirmDialogComponent = ({
renderTrigger={renderTrigger}
closeOnBackdropClick={false}
closeOnEsc={false}
isVisible={isVisible}
>
{toggle => (
<Wrapper width={Number(width)}>
@ -106,12 +113,12 @@ export const ConfirmDialogComponent = ({
</TitleWrapper>
<Divider opacity={0.3} />
{children(handleClose(toggle))}
{showButtons && (
{showButtons && !showSingleConfirmButton && (
<ButtonWrapper>
<Btn
id='confirm-modal-button'
label='Confirm'
onClick={onConfirm}
onClick={() => onConfirm(handleClose(toggle))}
isLoading={isLoading}
/>
<Btn
@ -122,6 +129,16 @@ export const ConfirmDialogComponent = ({
/>
</ButtonWrapper>
)}
{showSingleConfirmButton && (
<ButtonWrapper>
<Btn
id='confirm-modal-button'
label={String(singleConfirmButtonText)}
onClick={() => onConfirm(handleClose(toggle))}
isLoading={isLoading}
/>
</ButtonWrapper>
)}
</Wrapper>
)}
</ModalComponent>
@ -130,7 +147,11 @@ export const ConfirmDialogComponent = ({
ConfirmDialogComponent.defaultProps = {
showButtons: true,
showSingleConfirmButton: false,
singleConfirmButtonText: 'Ok!',
width: 460,
isLoading: false,
isVisible: false,
onClose: () => {},
renderTrigger: () => null,
};

View File

@ -1,6 +1,6 @@
// @flow
import React, { PureComponent, Fragment, type Element } from 'react';
import React, { PureComponent, Fragment, type Node } from 'react';
import { createPortal } from 'react-dom';
import styled from 'styled-components';
@ -22,10 +22,11 @@ const ChildrenWrapper = styled.div`
`;
type Props = {
renderTrigger: (() => void) => Element<*>,
children: (() => void) => Element<*>,
renderTrigger?: (() => void) => Node,
children: (() => void) => Node,
closeOnBackdropClick?: boolean,
closeOnEsc?: boolean,
isVisible?: boolean,
};
type State = {
@ -40,14 +41,25 @@ export class ModalComponent extends PureComponent<Props, State> {
static defaultProps = {
closeOnBackdropClick: true,
closeOnEsc: true,
isVisible: false,
renderTrigger: () => null,
};
state = {
isVisible: false,
};
constructor(props: Props) {
super(props);
this.state = {
isVisible: props.isVisible || false,
};
}
componentDidMount() {
const { closeOnEsc } = this.props;
const { isVisible } = this.state;
if (isVisible) {
if (modalRoot) modalRoot.appendChild(this.element);
}
if (closeOnEsc) {
window.addEventListener('keydown', this.handleEscPress);
@ -89,26 +101,25 @@ export class ModalComponent extends PureComponent<Props, State> {
const { isVisible } = this.state;
const toggleVisibility = isVisible ? this.close : this.open;
const renderTriggerProps = () => (renderTrigger ? renderTrigger(toggleVisibility) : null);
return (
<Fragment>
{renderTrigger(toggleVisibility)}
{!isVisible ? null : createPortal(
<ModalWrapper
id='modal-portal-wrapper'
data-testid='Modal'
onClick={(event) => {
if (
closeOnBackdropClick
&& event.target.id === 'modal-portal-wrapper'
) this.close();
}}
>
<ChildrenWrapper>
{children(toggleVisibility)}
</ChildrenWrapper>
</ModalWrapper>,
this.element,
)}
{renderTriggerProps()}
{!isVisible
? null
: createPortal(
<ModalWrapper
id='modal-portal-wrapper'
data-testid='Modal'
onClick={(event) => {
if (closeOnBackdropClick && event.target.id === 'modal-portal-wrapper') this.close();
}}
>
<ChildrenWrapper>{children(toggleVisibility)}</ChildrenWrapper>
</ModalWrapper>,
this.element,
)}
</Fragment>
);
}

View File

@ -99,12 +99,15 @@ type State = {
showTooltip: boolean,
};
const MINUTE_IN_MILI = 60000;
const INTERVAL_AFTER_READY = 60000;
const INTERVAL_BEFORE_READY = 10000;
class Component extends PureComponent<Props, State> {
timer: ?IntervalID = null;
constructor(props) {
requestOnTheFly: boolean = false;
constructor(props: Props) {
super(props);
this.state = {
@ -113,20 +116,18 @@ class Component extends PureComponent<Props, State> {
}
componentDidMount() {
const { getBlockchainStatus } = this.props;
this.timer = setInterval(() => getBlockchainStatus(), 2000);
this.timer = setInterval(() => this.updateStatus(), INTERVAL_BEFORE_READY);
}
componentDidUpdate(prevProps: Props) {
const { getBlockchainStatus, nodeSyncType } = this.props;
const { nodeSyncType } = this.props;
if (
prevProps.nodeSyncType === NODE_SYNC_TYPES.SYNCING
&& nodeSyncType === NODE_SYNC_TYPES.READY
) {
// if the status is "ready", we can increase the interval to avoid useless rpc calls
this.cleanUpdateInterval();
this.timer = setInterval(() => getBlockchainStatus(), MINUTE_IN_MILI);
this.timer = setInterval(() => this.updateStatus(), INTERVAL_AFTER_READY);
}
}
@ -134,6 +135,22 @@ class Component extends PureComponent<Props, State> {
this.cleanUpdateInterval();
}
updateStatus = () => {
if (this.requestOnTheFly) return;
this.requestOnTheFly = true;
const { getBlockchainStatus } = this.props;
getBlockchainStatus()
.then(() => {
this.requestOnTheFly = false;
})
.catch(() => {
this.requestOnTheFly = false;
});
};
cleanUpdateInterval = () => {
if (this.timer) {
clearInterval(this.timer);

View File

@ -2,6 +2,8 @@
import electron from 'electron'; // eslint-disable-line
import React, { type ComponentType, Component } from 'react';
import store from '../../config/electron-store';
import { LoadingScreen } from './loading-screen';
import rpc from '../../services/api';
@ -20,7 +22,7 @@ export const withDaemonStatusCheck = <PassedProps: {}>(
): ComponentType<$Diff<PassedProps, Props>> => class extends Component<PassedProps, State> {
timer: ?IntervalID = null;
hasDaemonError: boolean = false;
requestOnTheFly: boolean = false;
state = {
isRunning: false,
@ -30,20 +32,27 @@ export const withDaemonStatusCheck = <PassedProps: {}>(
componentDidMount() {
this.runTest();
this.timer = setInterval(this.runTest, 2000);
this.timer = setInterval(this.runTest, 3000);
electron.ipcRenderer.on('zcash-daemon-status', (event: empty, message: Object) => {
this.hasDaemonError = message.error;
electron.ipcRenderer.on(
'zcash-daemon-status',
(
event: empty,
message: {
error: boolean,
status: string,
},
) => {
if (message.error) {
clearInterval(this.timer);
}
if (message.error) {
clearInterval(this.timer);
}
this.setState({
message: message.status,
...(message.error ? { progress: 0, isRunning: false } : {}),
});
});
this.setState({
message: message.status,
...(message.error ? { progress: 0, isRunning: false } : {}),
});
},
);
}
componentWillUnmount() {
@ -54,30 +63,31 @@ export const withDaemonStatusCheck = <PassedProps: {}>(
}
runTest = () => {
if (this.hasDaemonError) return;
const daemonPID: number = store.get('DAEMON_PROCESS_PID');
if (this.requestOnTheFly || !daemonPID) return;
this.requestOnTheFly = true;
rpc
.getinfo()
.then((response) => {
if (this.hasDaemonError) return;
.ping()
.then(() => {
this.requestOnTheFly = false;
if (response) {
setTimeout(() => {
this.setState(() => ({ isRunning: true }));
}, 500);
this.setState(() => ({ progress: 100 }));
setTimeout(() => {
this.setState(() => ({ isRunning: true }));
}, 500);
this.setState(() => ({ progress: 100 }));
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
})
.catch((error) => {
if (this.hasDaemonError) return;
const statusMessage = error.message === 'Something went wrong' ? 'Zepio Starting' : error.message;
this.requestOnTheFly = false;
const statusMessage: string = error.message === 'Something went wrong' ? 'Zepio Starting' : error.message;
const isRpcOff = Math.trunc(error.statusCode / 100) === 5;
this.setState({

View File

@ -1,8 +1,8 @@
// @flow
export const FEES = {
LOW: 0.001,
MEDIUM: 0.005,
HIGH: 0.009,
LOW: 0.0001,
MEDIUM: 0.0005,
HIGH: 0.0009,
CUSTOM: 'custom',
};

78
app/menu.js Normal file
View File

@ -0,0 +1,78 @@
// @flow
import { openExternal } from './utils/open-external';
import packageJson from '../package.json';
const DOCS_URL = 'https://zepiowallet.com/';
const REPOSITORY_URL = 'https://github.com/ZcashFoundation/zepio/issues';
const menu = [
{
label: 'Edit',
submenu: [
{ role: 'undo' },
{ role: 'redo' },
{ type: 'separator' },
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' },
{ role: 'delete' },
{ role: 'selectall' },
],
},
{
label: 'View',
submenu: [
{ role: 'togglefullscreen' },
],
},
];
const helpMenu = {
role: 'help',
submenu: [
{
label: `Zepio Version v${packageJson.version}`,
enabled: false,
},
{ type: 'separator' },
{
label: 'Help / FAQ',
click() {
openExternal(DOCS_URL);
},
},
{
label: 'Search Issues',
click() {
openExternal(REPOSITORY_URL);
},
},
],
};
if (process.platform === 'darwin') {
menu.unshift({
label: packageJson.name,
submenu: [
{ role: 'about' },
{ type: 'separator' },
{ role: 'hide' },
{ role: 'hideothers' },
{ role: 'unhide' },
{ type: 'separator' },
{ role: 'quit' },
],
});
menu.push({
...helpMenu,
submenu: [
...helpMenu.submenu,
],
});
} else {
menu.push(helpMenu);
}
export const MENU = menu;

View File

@ -5,7 +5,7 @@ import { ThemeProvider } from 'styled-components';
import { appTheme } from './theme';
import { GlobalStyle } from './global';
export const DoczWrapper = ({ children }: { children: () => Node<*> }) => (
export const DoczWrapper = ({ children }: { children: () => Node }) => (
<ThemeProvider theme={appTheme}>
<Fragment>
<GlobalStyle />

View File

@ -2,7 +2,7 @@
import type { AppState } from './app-state';
export type Action = { type: $Subtype<string>, payload: Object };
export type Action = { type: string, payload: Object };
export type GetState = () => AppState;
export type Dispatch = (action: Action) => void;
export type Middleware = ({ dispatch: Dispatch, getState: GetState }) => (

View File

@ -1,4 +1,9 @@
// @flow
import electron from 'electron'; // eslint-disable-line
import { isTestnet } from '../../config/is-testnet';
export const getCoinName = () => (isTestnet() ? 'TAZ' : 'ZEC');
export const getCoinName = () => {
if (electron.remote.process.env.NODE_ENV === 'test' || isTestnet()) return 'TAZ';
return 'ZEC';
};

View File

@ -1,14 +1,62 @@
// @flow
import React, { PureComponent, Fragment } from 'react';
import styled from 'styled-components';
import electron from 'electron'; // eslint-disable-line import/no-extraneous-dependencies
import { WalletSummaryComponent } from '../components/wallet-summary';
import { TransactionDailyComponent } from '../components/transaction-daily';
import { TextComponent } from '../components/text';
import { EmptyTransactionsComponent } from '../components/empty-transactions';
import { ConfirmDialogComponent } from '../components/confirm-dialog';
import { ColumnComponent } from '../components/column';
import store from '../../config/electron-store';
import type { TransactionsList } from '../redux/modules/transactions';
import zepioLogo from '../assets/images/zcash-icon.png';
const ModalContent = styled(ColumnComponent)`
min-height: 400px;
align-items: center;
justify-content: center;
p {
word-break: break-word;
}
`;
const LogoComponent = styled.img`
max-width: 5rem;
margin-bottom: 1.5rem;
`;
const TitleComponent = styled(TextComponent)`
font-size: 18px;
`;
const ContentWrapper = styled.div`
margin: 0 auto;
max-width: 350px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
`;
const WelcomeText = styled(TextComponent)`
line-height: 1.7;
text-align: center;
margin-top: 1rem;
`;
const AdditionalText = styled(TextComponent)`
margin-top: 2rem;
font-style: italic;
font-size: 10px;
`;
type Props = {
getSummary: () => void,
total: number,
@ -22,7 +70,8 @@ type Props = {
transactions: TransactionsList,
};
const UPDATE_INTERVAL = 5000;
const UPDATE_INTERVAL = 10000;
const DISPLAY_WELCOME_MODAL = 'DISPLAY_WELCOME_MODAL';
export class DashboardView extends PureComponent<Props> {
interval = null;
@ -41,6 +90,8 @@ export class DashboardView extends PureComponent<Props> {
clearInterval(this.interval);
}
shouldShowWelcomeModal = () => store.get(DISPLAY_WELCOME_MODAL) !== false;
render() {
const {
error,
@ -79,6 +130,31 @@ export class DashboardView extends PureComponent<Props> {
/>
))
)}
{electron.remote.process.env.NODE_ENV !== 'test' && (
<ConfirmDialogComponent
title='Welcome to Zepio'
onConfirm={(toggle) => {
store.set(DISPLAY_WELCOME_MODAL, false);
toggle();
}}
onClose={() => store.set(DISPLAY_WELCOME_MODAL, false)}
showSingleConfirmButton
singleConfirmButtonText='Ok. Let me in!'
isVisible={this.shouldShowWelcomeModal()}
>
{() => (
<ModalContent>
<ContentWrapper>
<LogoComponent src={zepioLogo} alt='Zepio' />
<TitleComponent value='Hello from Zepio' isBold />
<WelcomeText value='Zepio is a cross-platform full-node Zcash wallet that allows users to easily send and receive ZEC. With first-class support for Sapling shielded addresses, users are able to create truly private transactions using a modern and intuitive interface.' />
<WelcomeText value='Zepio aims to improve the user experience for those seeking true financial privacy online.' />
<AdditionalText value='Zepio will need to sync the Zcash blockchain data before using all features.' />
</ContentWrapper>
</ModalContent>
)}
</ConfirmDialogComponent>
)}
</Fragment>
);
}

View File

@ -373,32 +373,33 @@ export class SettingsView extends PureComponent<Props, State> {
return (
<Wrapper>
<ConfirmDialogComponent
title='Confirm'
onConfirm={() => updateZcashNetwork(zcashNetwork === MAINNET ? TESTNET : MAINNET)}
showButtons={embeddedDaemon}
renderTrigger={toggleVisibility => (
<ThemeSelectWrapper>
<SettingsTitle value='Zcash Network' />
<SelectComponent
onChange={value => (zcashNetwork !== value ? toggleVisibility() : undefined)}
value={zcashNetwork}
options={networkOptions}
/>
</ThemeSelectWrapper>
)}
>
{() => (
<ModalContent>
<TextComponent
value={
embeddedDaemon ? CONFIRM_RELAUNCH_CONTENT : RUNNING_NON_EMBEDDED_DAEMON_WARNING
}
/>
</ModalContent>
)}
</ConfirmDialogComponent>
{embeddedDaemon && (
<ConfirmDialogComponent
title='Confirm'
onConfirm={() => updateZcashNetwork(zcashNetwork === MAINNET ? TESTNET : MAINNET)}
showButtons={embeddedDaemon}
renderTrigger={toggleVisibility => (
<ThemeSelectWrapper>
<SettingsTitle value='Zcash Network' />
<SelectComponent
onChange={value => (zcashNetwork !== value ? toggleVisibility() : undefined)}
value={zcashNetwork}
options={networkOptions}
/>
</ThemeSelectWrapper>
)}
>
{() => (
<ModalContent>
<TextComponent
value={
embeddedDaemon ? CONFIRM_RELAUNCH_CONTENT : RUNNING_NON_EMBEDDED_DAEMON_WARNING
}
/>
</ModalContent>
)}
</ConfirmDialogComponent>
)}
<ThemeSelectWrapper>
<SettingsTitle value='Theme' />
<SelectComponent

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,19 @@
// @flow
import fs from 'fs';
import path from 'path';
import { promisify } from 'util';
import eres from 'eres';
import { getZcashFolder } from './get-zcash-folder';
const ZCASH_LOCK_FILE = '.lock';
export const checkLockFile = async (zcashPath?: string) => {
try {
const myPath = zcashPath || getZcashFolder();
const [cannotAccess] = await eres(promisify(fs.access)(path.join(myPath, ZCASH_LOCK_FILE)));
return !cannotAccess;
} catch (err) {
return false;
}
};

View File

@ -0,0 +1,17 @@
// @flow
import fs from 'fs';
import path from 'path';
import { getZcashFolder } from './get-zcash-folder';
const ZCASH_PID_FILE = 'zcashd.pid';
export const getDaemonProcessId = (zcashPath?: string) => {
try {
const myPath = zcashPath || getZcashFolder();
const buffer = fs.readFileSync(path.join(myPath, ZCASH_PID_FILE));
const pid = Number(buffer.toString().trim());
return pid;
} catch (err) {
return null;
}
};

View File

@ -0,0 +1,18 @@
// @flow
import os from 'os';
import path from 'path';
import electron from 'electron'; // eslint-disable-line
export const getZcashFolder = () => {
const { app } = electron;
if (os.platform() === 'darwin') {
return path.join(app.getPath('appData'), 'Zcash');
}
if (os.platform() === 'linux') {
return path.join(app.getPath('home'), '.zcash');
}
return path.join(app.getPath('appData'), 'Zcash');
};

View File

@ -67,17 +67,23 @@ export const generateArgsFromConf = (obj: ZcashConfFile): Array<string> => Objec
return acc.concat(`-${key}=${String(obj[key])}`);
}, []);
export const parseCmdArgs = (
cmd: string,
): { user: string, password: string, isTestnet: boolean } => {
type ParseCmdArgsPayload = {
rpcuser: string,
rpcpassword: string,
rpcconnect: string,
rpcport: string,
testnet: string,
};
const ARGS = ['rpcuser', 'rpcpassword', 'testnet', 'rpcport', 'rpcconnect'];
export const parseCmdArgs = (cmd: string): ParseCmdArgsPayload => {
const splitArgs = cmd.split(' ');
const rpcUserInArgs = splitArgs.find(x => x.startsWith('-rpcuser'));
const rpcPasswordInArgs = splitArgs.find(x => x.startsWith('-rpcpassword'));
const testnetInArgs = splitArgs.find(x => x.startsWith('-testnet'));
return ARGS.reduce((acc, cur) => {
const configKey = `-${cur}`;
const inArgs = splitArgs.find(x => x.startsWith(configKey));
const rpcUser = rpcUserInArgs ? rpcUserInArgs.replace('-rpcuser=', '') : '';
const rpcPassword = rpcPasswordInArgs ? rpcPasswordInArgs.replace('-rpcpassword=', '') : '';
return { user: rpcUser, password: rpcPassword, isTestnet: Boolean(testnetInArgs) };
return { ...acc, [cur]: inArgs ? inArgs.replace(`${configKey}=`, '') : '' };
}, {});
};

View File

@ -4,7 +4,6 @@ import cp from 'child_process';
import path from 'path';
import os from 'os';
import fs from 'fs';
import processExists from 'process-exists';
/* eslint-disable import/no-extraneous-dependencies */
import isDev from 'electron-is-dev';
import type { ChildProcess } from 'child_process';
@ -24,6 +23,7 @@ import { log } from './logger';
import store from '../electron-store';
import { parseZcashConf, parseCmdArgs, generateArgsFromConf } from './parse-zcash-conf';
import { isTestnet } from '../is-testnet';
import { getDaemonProcessId } from './get-daemon-process-id';
import {
EMBEDDED_DAEMON,
ZCASH_NETWORK,
@ -46,8 +46,8 @@ const getDaemonOptions = ({
const defaultOptions = [
'-server=1',
'-showmetrics',
'--metricsui=0',
'-showmetrics=1',
'-metricsui=0',
'-metricsrefreshtime=1',
`-rpcuser=${username}`,
`-rpcpassword=${password}`,
@ -64,6 +64,7 @@ const getDaemonOptions = ({
let resolved = false;
const ZCASHD_PROCESS_NAME = getDaemonName();
const DAEMON_PROCESS_PID = 'DAEMON_PROCESS_PID';
let isWindowOpened = false;
@ -91,6 +92,9 @@ const runDaemon: () => Promise<?ChildProcess> = () => new Promise(async (resolve
mainWindow.webContents.on('dom-ready', () => {
isWindowOpened = true;
});
store.delete('rpcconnect');
store.delete('rpcport');
store.delete(DAEMON_PROCESS_PID);
const processName = path.join(getBinariesPath(), getOsFolder(), ZCASHD_PROCESS_NAME);
const isRelaunch = Boolean(process.argv.find(arg => arg === '--relaunch'));
@ -125,8 +129,6 @@ const runDaemon: () => Promise<?ChildProcess> = () => new Promise(async (resolve
await waitForDaemonClose(ZCASHD_PROCESS_NAME);
}
const [, isRunning] = await eres(processExists(ZCASHD_PROCESS_NAME));
// This will parse and save rpcuser and rpcpassword in the store
let [, optionsFromZcashConf] = await eres(parseZcashConf());
@ -146,30 +148,50 @@ const runDaemon: () => Promise<?ChildProcess> = () => new Promise(async (resolve
}
}
if (optionsFromZcashConf.rpcconnect) store.set('rpcconnect', optionsFromZcashConf.rpcconnect);
if (optionsFromZcashConf.rpcport) store.set('rpcport', optionsFromZcashConf.rpcport);
if (optionsFromZcashConf.rpcuser) store.set('rpcuser', optionsFromZcashConf.rpcuser);
if (optionsFromZcashConf.rpcpassword) store.set('rpcpassword', optionsFromZcashConf.rpcpassword);
if (isRunning) {
log('Already is running!');
log('Searching for zcashd.pid');
const daemonProcessId = getDaemonProcessId(optionsFromZcashConf.datadir);
if (daemonProcessId) {
store.set(EMBEDDED_DAEMON, false);
// We need grab the rpcuser and rpcpassword from either process args or zcash.conf
log(
// eslint-disable-next-line
`A daemon was found running in PID: ${daemonProcessId}. Starting Zepio in external daemon mode.`,
);
// Command line args override zcash.conf
const [{ cmd }] = await findProcess('name', ZCASHD_PROCESS_NAME);
const { user, password, isTestnet: isTestnetFromCmd } = parseCmdArgs(cmd);
const [{ cmd, pid }] = await findProcess('pid', daemonProcessId);
store.set(DAEMON_PROCESS_PID, pid);
// We need grab the rpcuser and rpcpassword from either process args or zcash.conf
const {
rpcuser, rpcpassword, rpcconnect, rpcport, testnet: isTestnetFromCmd,
} = parseCmdArgs(
cmd,
);
store.set(
ZCASH_NETWORK,
isTestnetFromCmd || optionsFromZcashConf.testnet === '1' ? TESTNET : MAINNET,
isTestnetFromCmd === '1' || optionsFromZcashConf.testnet === '1' ? TESTNET : MAINNET,
);
if (user) store.set('rpcuser', user);
if (password) store.set('rpcpassword', password);
if (rpcuser) store.set('rpcuser', rpcuser);
if (rpcpassword) store.set('rpcpassword', rpcpassword);
if (rpcport) store.set('rpcport', rpcport);
if (rpcconnect) store.set('rpcconnect', rpcconnect);
return resolve();
}
log(
"Zepio couldn't find a `zcashd.pid`, that means there is no instance of zcash running on the machine, trying start built-in daemon",
);
store.set(EMBEDDED_DAEMON, true);
if (!isRelaunch) {
@ -198,6 +220,8 @@ const runDaemon: () => Promise<?ChildProcess> = () => new Promise(async (resolve
},
);
store.set(DAEMON_PROCESS_PID, childProcess.pid);
childProcess.stdout.on('data', (data) => {
sendToRenderer('zcashd-log', data.toString(), false);
if (!resolved) {

View File

@ -6,7 +6,9 @@ import dotenv from 'dotenv';
import path from 'path';
/* eslint-disable import/no-extraneous-dependencies */
import { app, BrowserWindow, typeof BrowserWindow as BrowserWindowType } from 'electron';
import {
app, BrowserWindow, typeof BrowserWindow as BrowserWindowType, Menu,
} from 'electron';
import { autoUpdater } from 'electron-updater';
import isDev from 'electron-is-dev';
import { registerDebugShortcut } from '../utils/debug-shortcut';
@ -15,6 +17,7 @@ import { log as zcashLog, cleanLogs } from './daemon/logger';
import getZecPrice from '../services/zec-price';
import store from './electron-store';
import { handleDeeplink } from './handle-deeplink';
import { MENU } from '../app/menu';
dotenv.config();
@ -63,7 +66,6 @@ const createWindow = () => {
resizable: true,
webPreferences: {
devTools: true,
// devTools: false,
webSecurity: true,
},
});
@ -77,6 +79,8 @@ const createWindow = () => {
isDev ? 'http://localhost:8080/' : `file://${path.join(__dirname, '../build/index.html')}`,
);
Menu.setApplicationMenu(Menu.buildFromTemplate(MENU));
exports.app = app;
exports.mainWindow = mainWindow;
};

View File

@ -0,0 +1,15 @@
declare module 'find-process' {
declare type searchType = 'pid' | 'port' | 'name';
declare type searchValue = string | number;
declare type process = {
pid: number,
ppid: number,
uid: string,
gid: string,
name: string,
bin: string,
cmd: string,
};
declare module.exports: (type: searchType, value: searchValue) => Array<process>;
}

View File

@ -98,7 +98,7 @@ declare module 'styled-components' {
declare type InjectedProps = { theme: Theme | void };
declare export function withTheme<Props: {}, Component: React$ComponentType<Props>>(
WrappedComponent: Component,
): React$ComponentType<$Diff<React$ElementConfig<$Supertype<Component>>, InjectedProps>>;
): React$ComponentType<$Diff<React$ElementConfig<Component>, InjectedProps>>;
// @HACK This is a cheat to hide that the underlying type is "just a string"
// once we know of a better way, we should be able to update this accordingly.
@ -350,7 +350,7 @@ declare module 'styled-components/native' {
declare type InjectedProps = { theme: Theme | void };
declare export function withTheme<Props: {}, Component: React$ComponentType<Props>>(
WrappedComponent: Component,
): React$ComponentType<$Diff<React$ElementConfig<$Supertype<Component>>, InjectedProps>>;
): React$ComponentType<$Diff<React$ElementConfig<Component>, InjectedProps>>;
// @HACK This is a cheat to hide that the underlying type is "just a string"
// once we know of a better way, we should be able to update this accordingly.

View File

@ -1,10 +1,23 @@
{
"name": "zepio",
"version": "0.6.2",
"description": "Zepio",
"productName": "Zepio",
"version": "0.7.2",
"description": "Zepio | Cross-platform sapling-enabled full-node Zcash wallet",
"main": "config/main.js",
"license": "MIT",
"homepage": "https://zepiowallet.com",
"license": "MIT",
"author": {
"name": "André Neves",
"email": "andrerfneves@protonmail.com",
"url": "https://andrenev.es"
},
"bugs": {
"url": "https://github.com/ZcashFoundation/zepio/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/ZcashFoundation/zepio"
},
"scripts": {
"start": "yarn check --integrity && concurrently \"cross-env BROWSER=none yarn dev\" \"wait-on http://0.0.0.0:8080 && yarn electron:dev\"",
"dev": "webpack-dev-server --config config/webpack-dev.config.js --mode development --open --hot",
@ -32,115 +45,12 @@
"e2e:serve": "node -r @babel/register ./__tests__/setup/mockAPI.js",
"e2e:run": "yarn test e2e"
},
"author": {
"name": "André Neves",
"email": "andrerfneves@protonmail.com",
"url": "https://andrenev.es"
"husky": {
"hooks": {
"pre-commit": "yarn lint:precommit && yarn flow:precommit",
"pre-push": "yarn flow:generate-coverage-badge && git add ./public/flow-badge.svg ./public/flow-coverage-badge.svg && git commit -m \"type(flow): update flowtype badge\" --no-verify --allow-empty"
}
},
"private": true,
"devDependencies": {
"@babel/cli": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.2.0",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-transform-regenerator": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@octokit/rest": "^16.23.4",
"babel-eslint": "^10.0.1",
"babel-loader": "^8.0.4",
"concurrently": "^4.1.0",
"create-test-server": "georgelima/create-test-server",
"cross-env": "^5.2.0",
"css-loader": "^1.0.1",
"docz": "0.13.4",
"docz-plugin-css": "^0.11.0",
"docz-theme-default": "0.13.4",
"electron": "^4.0.1",
"electron-builder": "^20.38.4",
"electron-compilers": "^5.9.0",
"electron-icon-maker": "^0.0.4",
"electron-log": "^2.2.17",
"electron-positioner": "^4.1.0",
"eslint": "^5.8.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-plugin-flowtype": "^3.2.1",
"eslint-plugin-import": "^2.16.0",
"eslint-plugin-jest": "^22.1.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.12.4",
"file-loader": "^2.0.0",
"flow-bin": "^0.95.1",
"flow-coverage-report": "^0.6.1",
"flow-typed": "^2.5.1",
"glow": "^1.2.2",
"html-webpack-plugin": "^3.1.0",
"jest": "^24.5.0",
"jest-dom": "^2.1.1",
"jest-extended": "^0.11.0",
"mime-types": "^2.1.22",
"node-sass": "^4.8.3",
"postcss-loader": "^3.0.0",
"pre-commit": "^1.2.2",
"react-testing-library": "^5.3.1",
"redux-logger": "^3.0.6",
"redux-mock-store": "^1.5.3",
"sass-loader": "^7.1.0",
"spectron": "^5.0.0",
"style-loader": "^0.23.1",
"terser-webpack-plugin": "^1.1.0",
"wait-on": "^3.2.0",
"webpack": "^4.4.1",
"webpack-bundle-analyzer": "^3.0.3",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.1"
},
"dependencies": {
"@babel/core": "^7.0.0",
"@babel/polyfill": "^7.0.0",
"@babel/register": "^7.0.0",
"autoprefixer": "^9.3.1",
"bignumber.js": "^8.0.1",
"connected-react-router": "^5.0.1",
"copy-to-clipboard": "^3.0.8",
"date-fns": "^1.30.1",
"dotenv": "^6.2.0",
"electron-compile": "^6.4.4",
"electron-is-dev": "^1.0.1",
"electron-store": "^2.0.0",
"electron-updater": "^4.0.4",
"eres": "^1.0.1",
"find-process": "^1.2.1",
"got": "^9.3.2",
"history": "^4.7.2",
"lodash.flow": "^3.5.0",
"lodash.groupby": "^4.6.0",
"lodash.uniqby": "^4.7.0",
"p-queue": "^3.0.0",
"process-exists": "^3.1.0",
"qrcode.react": "^0.8.0",
"react": "^16.6.0",
"react-circle": "^1.1.1",
"react-click-outside": "tj/react-click-outside",
"react-dom": "^16.6.0",
"react-popover": "^0.5.10",
"react-redux": "^5.0.7",
"react-router-dom": "^4.2.2",
"react-spring": "^7.2.10",
"react-virtualized": "^9.21.0",
"redux": "^4.0.1",
"redux-thunk": "^2.2.0",
"styled-components": "^4.1.1",
"styled-theming": "^2.2.0",
"uuid": "^3.3.2"
},
"pre-commit": [
"flow:generate-coverage-badge",
"lint:precommit",
"flow:precommit"
],
"build": {
"appId": "com.zcashfoundation",
"productName": "Zepio",
@ -159,19 +69,33 @@
"public/",
"build/"
],
"extraFiles": [
{
"from": "bin/",
"to": "resources/bin",
"filter": [
"**/*"
]
}
],
"deb": {
"depends": [
"gconf2",
"gconf-service",
"libnotify4",
"libappindicator1",
"libxtst6",
"libnss3"
]
},
"linux": {
"icon": "./build/icons/png",
"target": [
"deb"
],
"extraFiles": [
{
"from": "bin/linux",
"to": "resources/bin/linux",
"filter": [
"**/*"
]
},
{
"from": "bin/zcash-fetch-params",
"to": "resources/bin/zcash-fetch-params"
}
]
},
"mac": {
@ -180,11 +104,33 @@
"target": [
"dmg"
],
"icon": "./build/icons/mac/icon.icns"
"icon": "./build/icons/mac/icon.icns",
"extraFiles": [
{
"from": "bin/mac",
"to": "resources/bin/mac",
"filter": [
"**/*"
]
},
{
"from": "bin/zcash-fetch-params",
"to": "resources/bin/zcash-fetch-params"
}
]
},
"win": {
"target": "nsis",
"icon": "./build/icons/win/icon.ico"
"icon": "./build/icons/win/icon.ico",
"extraFiles": [
{
"from": "bin/win",
"to": "resources/bin/win",
"filter": [
"**/*"
]
}
]
},
"protocols": {
"name": "zcash",
@ -206,5 +152,103 @@
},
"resolutions": {
"babel-core": "7.0.0-bridge.0"
},
"devDependencies": {
"@babel/cli": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.2.0",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-transform-regenerator": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@octokit/rest": "^16.23.4",
"babel-eslint": "^10.0.1",
"babel-loader": "^8.0.4",
"concurrently": "^4.1.0",
"cross-env": "^5.2.0",
"css-loader": "^1.0.1",
"docz": "0.13.4",
"docz-plugin-css": "^0.11.0",
"docz-theme-default": "0.13.4",
"electron": "^4.2.2",
"electron-builder": "^20.38.4",
"electron-compilers": "^5.9.0",
"electron-icon-maker": "^0.0.4",
"electron-log": "^2.2.17",
"electron-positioner": "^4.1.0",
"eslint": "^5.8.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-plugin-flowtype": "^3.2.1",
"eslint-plugin-import": "^2.16.0",
"eslint-plugin-jest": "^22.1.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.12.4",
"file-loader": "^2.0.0",
"flow-bin": "^0.99.1",
"flow-coverage-report": "^0.6.1",
"flow-typed": "^2.5.1",
"glow": "^1.2.2",
"html-webpack-plugin": "^3.1.0",
"husky": "^2.3.0",
"jest": "^24.5.0",
"jest-dom": "^2.1.1",
"jest-extended": "^0.11.0",
"mime-types": "^2.1.22",
"node-sass": "^4.8.3",
"postcss-loader": "^3.0.0",
"react-testing-library": "^5.3.1",
"redux-logger": "^3.0.6",
"redux-mock-store": "^1.5.3",
"sass-loader": "^7.1.0",
"spectron": "^5.0.0",
"style-loader": "^0.23.1",
"terser-webpack-plugin": "^1.1.0",
"wait-on": "^3.2.0",
"webpack": "^4.4.1",
"webpack-bundle-analyzer": "^3.0.3",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.1"
},
"dependencies": {
"@astrocoders/create-test-server": "^3.0.2",
"@babel/core": "^7.0.0",
"@babel/polyfill": "^7.0.0",
"@babel/register": "^7.0.0",
"autoprefixer": "^9.3.1",
"bignumber.js": "^8.0.1",
"connected-react-router": "^5.0.1",
"copy-to-clipboard": "^3.0.8",
"date-fns": "^1.30.1",
"dotenv": "^6.2.0",
"electron-compile": "^6.4.4",
"electron-is-dev": "^1.0.1",
"electron-store": "^2.0.0",
"electron-updater": "^4.0.4",
"eres": "^1.0.1",
"find-process": "^1.2.1",
"got": "^9.6.0",
"history": "^4.7.2",
"lodash.flow": "^3.5.0",
"lodash.groupby": "^4.6.0",
"lodash.uniqby": "^4.7.0",
"p-queue": "^3.0.0",
"process-exists": "^3.1.0",
"qrcode.react": "^0.8.0",
"react": "^16.6.0",
"react-circle": "^1.1.1",
"react-click-outside": "tj/react-click-outside",
"react-dom": "^16.6.0",
"react-popover": "^0.5.10",
"react-redux": "^5.0.7",
"react-router-dom": "^4.2.2",
"react-spring": "^7.2.10",
"react-virtualized": "^9.21.0",
"redux": "^4.0.1",
"redux-thunk": "^2.2.0",
"styled-components": "^4.1.1",
"styled-theming": "^2.2.0",
"uuid": "^3.3.2"
}
}

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="88" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><mask id="a"><rect width="88" height="20" rx="3" fill="#fff"/></mask><g mask="url(#a)"><path fill="#555" d="M0 0h34v20H0z"/><path fill="#4C1" d="M34 0h54v20H34z"/><path fill="url(#b)" d="M0 0h88v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,DejaVu Sans,Geneva,sans-serif" font-size="11"><text x="17" y="15" fill="#010101" fill-opacity=".3">flow</text><text x="17" y="14">flow</text><text x="60" y="15" fill="#010101" fill-opacity=".3">passing</text><text x="60" y="14">passing</text></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="81" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><mask id="a"><rect width="81" height="20" rx="3" fill="#fff"/></mask><g mask="url(#a)"><path fill="#555" d="M0 0h34v20H0z"/><path fill="#E05D44" d="M34 0h47v20H34z"/><path fill="url(#b)" d="M0 0h81v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,DejaVu Sans,Geneva,sans-serif" font-size="11"><text x="17" y="15" fill="#010101" fill-opacity=".3">flow</text><text x="17" y="14">flow</text><text x="56.5" y="15" fill="#010101" fill-opacity=".3">failing</text><text x="56.5" y="14">failing</text></g></svg>

Before

Width:  |  Height:  |  Size: 726 B

After

Width:  |  Height:  |  Size: 733 B

30
public_key.asc Normal file
View File

@ -0,0 +1,30 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFytZOEBCACrWnKE0mORJtmkGXCiQFkeXO3pGWe3eYNGFBPXWRDySIAIksfP
EcoUjocJduU5D+BPrarn6xodvHqSB/GACuO720rUKOebLi3Il2V3PjRDOnpLO43S
Sn2Hm3CIHPScXXFI4LjkjhKjgoIZ/uYey7hbvEoaqx7Flp8kzlou+6pWv3Xd/ccT
H1fWFnV0lHXctxVbcla5IQqWS0SCR/gWsanvfZNxexMqWXoqIMX0o8HRBNuw/CC/
jWfyZzn6V8cYp/dicdqaL6fiPsdZV3XcEbCySYggL05lL9Ow7BuLCdq5/Dqzq8CE
Qdjhkf68GzqjXRBBEJV8VVGCQ31a823g1129ABEBAAG0KUdlb3JnZSBMaW1hIDxn
ZW9yZ2UubGltYUBhc3Ryb2NvZGVycy5jb20+iQFOBBMBCAA4FiEEWTvjLapnaQHb
TMDd7cRAMzmPHNkFAlytZOECGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQ
7cRAMzmPHNmGmQf/dMcfIe7o/G0ShG2ILJLkUl4K/mwd1sTu8LOVlor5WyxYU2F9
TSgdKzOxiOXFdwD/INXF+3y4T31+69wtZF7gCbKz8tH8Md//mn2MyNOxAbetxVBv
SYu13H6XY+rtPdVGnWQvg6vlmhXjA4/GFFftddiciNkNhRxeLOEUhSgyJbHKac0o
RlllVLeJHly8vB+cEKhkWV5Hj6TDzcIKuKgXDeQrhQTCSL4jXdkCCgH3FObZqtTx
Ps7zTq/SyFonny7VuNqzpw484ByhbhNB5+BjaDUGmD+GHQU9u+oKrHM+QmRseEJe
a+K7mqPgQJRz1TUsK67tgBbGbsoC3B5cucRpbrkBDQRcrWThAQgAnfR+/OccfXhO
1R7tUOqPfw14BlSRhfzOqQt8iCrqP2/ucnNpJtIpw4DpFnrlX8Fw6ST9OQ62FwR0
NNsKSPegOh5M3KaE5SIwLQx0dUQ4ogF8bwQ8fWgG08JSjpyoRA3KS7w8hf/aKjoW
fbvjg/kyl28oWxf4fQemnaVqCeLc88N14a3h3gZgUh2BkfD/O0kOgXMKr+Er5F0U
xdpqaNkss2Zt6D6Q0lxXgH6jLN0HlirUhF5Qf/vQah6Wsl4Jyp6fTmD5FzXE6qzI
U3tXbjj8fxKH2SGEikhF/dRPfmDLIqVY0oif2ueJPZ/GgtCtTqecNZL09bML6gC5
X5PBl7nf+wARAQABiQE2BBgBCAAgFiEEWTvjLapnaQHbTMDd7cRAMzmPHNkFAlyt
ZOECGwwACgkQ7cRAMzmPHNl4AQf9EVVrpipv0rb8laW3cVint0gGL/NfhS1JTPot
hdCB+odJiPikUnnEwcn5ePIc8m3c1/fTPEg1uMxEdUKUps66VCvRYqRFVQbrjg8q
8Isfuv+pyEKE0T8kighkr04cVjXYRzbV5PdCnycLGlEu78wayJFvY8SwOC3LGlWp
uSa09g6F+i97fblzMW5Owv7FaWEPw/aLJ1kmV14voNuanpy1QcDS5oG4xVH4F75p
G3pwoEgT7+Eg/Oo6wbnjqgtDiWwYgdNGMkpEroN42M4MumGUf4dQCHxbgHSlb/iP
dQqvZhdDw59uM+qzoGOolPPVLfx3n6WzmUOI+FTyy7Grje4RKg==
=/JKD
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -7,14 +7,19 @@ import { METHODS, type APIMethods } from './utils';
import store from '../config/electron-store';
import { isTestnet } from '../config/is-testnet';
const getRPCConfig = () => ({
host: '127.0.0.1',
port: isTestnet() ? 18232 : 8232,
user: store.get('rpcuser'),
password: store.get('rpcpassword'),
});
const getRPCConfig = () => {
const rpcport: string = store.get('rpcport');
const rpcconnect: string = store.get('rpcconnect');
const getMessage = (statusCode, isECONNREFUSED) => {
return {
host: rpcconnect || '127.0.0.1',
port: rpcport || (isTestnet() ? 18232 : 8232),
user: (store.get('rpcuser'): string),
password: (store.get('rpcpassword'): string),
};
};
const getMessage = (statusCode: number, isECONNREFUSED: boolean) => {
if (isECONNREFUSED) {
return 'Zepio could not find a daemon running, please check the logs!';
}
@ -48,7 +53,10 @@ const api: APIMethods = METHODS.reduce(
params: args,
},
})
.then(data => Promise.resolve(data.body && data.body.result))
.then((data) => {
console.log('[RPC CALL SUCCESS] -', method, data.body.result);
return Promise.resolve(data.body && data.body.result);
})
.catch((payload) => {
console.log(
'[RPC CALL ERROR] - ',

247
yarn.lock
View File

@ -6,6 +6,16 @@
version "4.1.0"
resolved "https://registry.yarnpkg.com/7zip-bin/-/7zip-bin-4.1.0.tgz#33eff662a5c39c0c2061170cc003c5120743fff0"
"@astrocoders/create-test-server@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@astrocoders/create-test-server/-/create-test-server-3.0.2.tgz#d849279d0e63e2c293e32c3db70eac4799cfeb9d"
integrity sha512-I11U6GJzF2U3akSOrE5uR+Woqfm33x9U4iiT1N71RXcb3UyaYzXH5eD2LcLCCcMCtwlMyFdJBt2WWnGjkvd/aw==
dependencies:
body-parser "^1.18.2"
create-cert "^1.0.2"
express "^4.15.3"
pify "^3.0.0"
"@babel/cli@^7.0.0":
version "7.1.5"
resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.1.5.tgz#4ccf0a8cdabeefdd8ce955384530f050935bc4d7"
@ -1534,11 +1544,10 @@
"@shellscape/koa-send" "^4.1.0"
debug "^2.6.8"
"@sindresorhus/is@^0.12.0":
version "0.12.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.12.0.tgz#55c37409c809e802efea25911a579731adfc6e07"
dependencies:
symbol-observable "^1.2.0"
"@sindresorhus/is@^0.14.0":
version "0.14.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
"@sindresorhus/is@^0.7.0":
version "0.7.0"
@ -1649,9 +1658,10 @@
"@svgr/plugin-svgo" "^4.0.3"
loader-utils "^1.1.0"
"@szmarczak/http-timer@^1.1.0":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.1.tgz#6402258dfe467532b26649ef076b4d11f74fb612"
"@szmarczak/http-timer@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
dependencies:
defer-to-connect "^1.0.1"
@ -1705,6 +1715,11 @@
version "7.10.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.10.2.tgz#a98845168012d7a63a84d50e738829da43bdb0de"
"@types/normalize-package-data@^2.4.0":
version "2.4.0"
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==
"@types/q@^1.5.1":
version "1.5.1"
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.1.tgz#48fd98c1561fe718b61733daed46ff115b496e18"
@ -3542,9 +3557,10 @@ cache-loader@^1.2.2, cache-loader@^1.2.5:
neo-async "^2.5.0"
schema-utils "^0.4.2"
cacheable-request@^5.1.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-5.2.0.tgz#00c87097835af4caf92a97390660ecadce51187d"
cacheable-request@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.0.0.tgz#4a1727414e02ac4af82560c4da1b61daa3fa2b63"
integrity sha512-2N7AmszH/WPPpl5Z3XMw1HAP+8d+xugnKQAeKvxFZ/04dbT/CAznqwbl+7eSr3HkwdepNwtb2yx3CAMQWvG01Q==
dependencies:
clone-response "^1.0.2"
get-stream "^4.0.0"
@ -4219,7 +4235,7 @@ concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
concat-stream@1.6.2, concat-stream@^1.4.7, concat-stream@^1.5.0:
concat-stream@1.6.2, concat-stream@^1.5.0:
version "1.6.2"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
dependencies:
@ -4243,8 +4259,9 @@ concurrently@^4.1.0:
yargs "^12.0.1"
conf@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/conf/-/conf-2.1.0.tgz#43ade5879a82ff23dbeb466995d50209f7dfcd07"
version "2.2.0"
resolved "https://registry.yarnpkg.com/conf/-/conf-2.2.0.tgz#ee282efafc1450b61e205372041ad7d866802d9a"
integrity sha512-93Kz74FOMo6aWRVpAZsonOdl2I57jKtHrNmxhumehFQw4X8Sk37SohNY11PG7Q8Okta+UnrVaI006WLeyp8/XA==
dependencies:
dot-prop "^4.1.0"
env-paths "^1.0.0"
@ -4415,6 +4432,16 @@ cosmiconfig@^5.0.0, cosmiconfig@^5.0.2, cosmiconfig@^5.0.5, cosmiconfig@^5.0.7:
js-yaml "^3.9.0"
parse-json "^4.0.0"
cosmiconfig@^5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==
dependencies:
import-fresh "^2.0.0"
is-directory "^0.3.1"
js-yaml "^3.13.1"
parse-json "^4.0.0"
cp-file@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-6.0.0.tgz#f38477ece100b403fcf780fd34d030486beb693e"
@ -4502,15 +4529,6 @@ create-react-context@^0.2.2, create-react-context@^0.2.3:
fbjs "^0.8.0"
gud "^1.0.0"
create-test-server@georgelima/create-test-server:
version "2.4.0"
resolved "https://codeload.github.com/georgelima/create-test-server/tar.gz/0f4133ca2d53f7084f34e77ca72536890614c96a"
dependencies:
body-parser "^1.18.2"
create-cert "^1.0.2"
express "^4.15.3"
pify "^3.0.0"
cross-env@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.0.tgz#6ecd4c015d5773e614039ee529076669b9d126f2"
@ -5846,6 +5864,7 @@ electron-publish@20.38.3:
electron-store@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/electron-store/-/electron-store-2.0.0.tgz#1035cca2a95409d1f54c7466606345852450d64a"
integrity sha512-1WCFYHsYvZBqDsoaS0Relnz0rd81ZkBAI0Fgx7Nq2UWU77rSNs1qxm4S6uH7TCZ0bV3LQpJFk7id/is/ZgoOPA==
dependencies:
conf "^2.0.0"
@ -5871,9 +5890,10 @@ electron-updater@^4.0.4:
semver "^5.6.0"
source-map-support "^0.5.9"
electron@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/electron/-/electron-4.0.1.tgz#c41eaee9e081c2e5e4a4a4a761b7577a77d2eb18"
electron@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/electron/-/electron-4.2.2.tgz#e8720e68b2ef3dcf4ab721f9546cf436e08576d2"
integrity sha512-SNRr83kbsnNZU9AdYkAJZEW7UH9Q9Fvl0ynuKBXgFFulTX+Gkw5JATl2Tt4OQIKdCGUuBDaw+MEMXlaroNpceA==
dependencies:
"@types/node" "^10.12.18"
electron-download "^4.1.0"
@ -6771,6 +6791,13 @@ find-up@^2.0.0, find-up@^2.1.0:
dependencies:
locate-path "^2.0.0"
find-up@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.0.0.tgz#c367f8024de92efb75f2d4906536d24682065c3a"
integrity sha512-zoH7ZWPkRdgwYCDVoQTzqjG8JSPANhtvLhh4KVUHyKnaUJJrNeFmWIkTcNuJmR3GLMEmGYEf2S2bjgx26JTF+Q==
dependencies:
locate-path "^5.0.0"
flat-cache@^1.2.1:
version "1.3.4"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f"
@ -6793,10 +6820,10 @@ flow-annotation-check@1.8.1:
glob "7.1.1"
load-pkg "^3.0.1"
flow-bin@^0.95.1:
version "0.95.1"
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.95.1.tgz#633113831ccff4b7ee70a2730f63fc43b69ba85f"
integrity sha512-06IOC/pqPMNRYtC6AMZEWYR9Fi6UdBC7gImGinPuNUpPZFnP5E9/0cBCl3DWrH4zz/gSM2HdDilU7vPGpYIr2w==
flow-bin@^0.99.1:
version "0.99.1"
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.99.1.tgz#0d4f413ca84a3a95d0aa64214178684dd7c6a4c5"
integrity sha512-dipNwJlb4MsVt3IuDgPTymCNL4GFoq3pG+GbY6DmBbl0dJPWFSA383rCTmgbfFhoeJ1XCfYBan0BPryToSxiiQ==
flow-coverage-report@^0.6.1:
version "0.6.1"
@ -7083,6 +7110,11 @@ get-stdin@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
get-stdin@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-7.0.0.tgz#8d5de98f15171a125c5e516643c7a6d0ea8a96f6"
integrity sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==
get-stream@^2.1.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de"
@ -7357,13 +7389,14 @@ got@^7.1.0:
url-parse-lax "^1.0.0"
url-to-options "^1.0.1"
got@^9.3.2:
version "9.3.2"
resolved "https://registry.yarnpkg.com/got/-/got-9.3.2.tgz#f6e3bd063aa8f461ccd924afa2ba2b61deab3989"
got@^9.6.0:
version "9.6.0"
resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==
dependencies:
"@sindresorhus/is" "^0.12.0"
"@szmarczak/http-timer" "^1.1.0"
cacheable-request "^5.1.0"
"@sindresorhus/is" "^0.14.0"
"@szmarczak/http-timer" "^1.1.2"
cacheable-request "^6.0.0"
decompress-response "^3.3.0"
duplexer3 "^0.1.4"
get-stream "^4.1.0"
@ -7860,6 +7893,22 @@ humanize-string@^1.0.2:
dependencies:
decamelize "^1.0.0"
husky@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/husky/-/husky-2.3.0.tgz#8b78ed24d763042df7fd899991985d65a976dd13"
integrity sha512-A/ZQSEILoq+mQM3yC3RIBSaw1bYXdkKnyyKVSUiJl+iBjVZc5LQEXdGY1ZjrDxC4IzfRPiJ0IqzEQGCN5TQa/A==
dependencies:
cosmiconfig "^5.2.0"
execa "^1.0.0"
find-up "^3.0.0"
get-stdin "^7.0.0"
is-ci "^2.0.0"
pkg-dir "^4.1.0"
please-upgrade-node "^3.1.1"
read-pkg "^5.1.1"
run-node "^1.0.0"
slash "^3.0.0"
icon-gen@1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/icon-gen/-/icon-gen-1.0.7.tgz#0c710adccbf96e10d05c4595d549df43e423a20a"
@ -9127,6 +9176,14 @@ js-yaml@3.x, js-yaml@^3.12.0, js-yaml@^3.9.0:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^3.13.1:
version "3.13.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@~3.7.0:
version "3.7.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80"
@ -9627,6 +9684,13 @@ locate-path@^3.0.0:
p-locate "^3.0.0"
path-exists "^3.0.0"
locate-path@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
dependencies:
p-locate "^4.1.0"
lodash._getnative@^3.0.0:
version "3.9.1"
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
@ -10627,6 +10691,16 @@ normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-
semver "2 || 3 || 4 || 5"
validate-npm-package-license "^3.0.1"
normalize-package-data@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==
dependencies:
hosted-git-info "^2.1.4"
resolve "^1.10.0"
semver "2 || 3 || 4 || 5"
validate-npm-package-license "^3.0.1"
normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
@ -10929,10 +11003,6 @@ os-name@^3.0.0:
macos-release "^2.0.0"
windows-release "^3.1.0"
os-shim@^0.1.2:
version "0.1.3"
resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917"
os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
@ -10991,6 +11061,13 @@ p-limit@^2.0.0:
dependencies:
p-try "^2.0.0"
p-limit@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2"
integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==
dependencies:
p-try "^2.0.0"
p-locate@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
@ -11003,6 +11080,13 @@ p-locate@^3.0.0:
dependencies:
p-limit "^2.0.0"
p-locate@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
dependencies:
p-limit "^2.2.0"
p-map@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
@ -11356,6 +11440,13 @@ pkg-dir@^3.0.0:
dependencies:
find-up "^3.0.0"
pkg-dir@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
dependencies:
find-up "^4.0.0"
pkg-up@2.0.0, pkg-up@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f"
@ -11366,6 +11457,13 @@ pkginfo@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.0.tgz#349dbb7ffd38081fcadc0853df687f0c7744cd65"
please-upgrade-node@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac"
integrity sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ==
dependencies:
semver-compare "^1.0.0"
plist@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.1.tgz#a9b931d17c304e8912ef0ba3bdd6182baf2e1f8c"
@ -11916,14 +12014,6 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.2, postcss@^7.0.5:
source-map "^0.6.1"
supports-color "^5.5.0"
pre-commit@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/pre-commit/-/pre-commit-1.2.2.tgz#dbcee0ee9de7235e57f79c56d7ce94641a69eec6"
dependencies:
cross-spawn "^5.0.1"
spawn-sync "^1.0.15"
which "1.2.x"
prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
@ -12686,6 +12776,16 @@ read-pkg@^4.0.1:
parse-json "^4.0.0"
pify "^3.0.0"
read-pkg@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.1.1.tgz#5cf234dde7a405c90c88a519ab73c467e9cb83f5"
integrity sha512-dFcTLQi6BZ+aFUaICg7er+/usEoqFdQxiEBsEMNGoipenihtxxtdrQuBXvyANCEI8VuUIVYFgeHGx9sLLvim4w==
dependencies:
"@types/normalize-package-data" "^2.4.0"
normalize-package-data "^2.5.0"
parse-json "^4.0.0"
type-fest "^0.4.1"
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
version "2.3.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
@ -13285,6 +13385,13 @@ resolve@1.1.7, resolve@1.1.x:
version "1.1.7"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
resolve@^1.10.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.0.tgz#4014870ba296176b86343d50b60f3b50609ce232"
integrity sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==
dependencies:
path-parse "^1.0.6"
resolve@^1.2.0, resolve@^1.3.2, resolve@^1.6.0, resolve@^1.7.1, resolve@^1.8.1, resolve@^1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06"
@ -13366,6 +13473,11 @@ run-async@^2.2.0:
dependencies:
is-promise "^2.1.0"
run-node@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e"
integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==
run-queue@^1.0.0, run-queue@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47"
@ -13543,6 +13655,11 @@ selfsigned@^1.9.1:
dependencies:
node-forge "0.7.5"
semver-compare@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
semver-diff@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"
@ -13735,6 +13852,11 @@ slash@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
slash@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
slice-ansi@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d"
@ -13908,13 +14030,6 @@ spawn-rx@^2.0.3:
lodash.assign "^4.2.0"
rxjs "^5.1.1"
spawn-sync@^1.0.15:
version "1.0.15"
resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476"
dependencies:
concat-stream "^1.4.7"
os-shim "^0.1.2"
spawndamnit@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/spawndamnit/-/spawndamnit-1.0.0.tgz#b5d4a1a73016dbcca8f8b1e283eee76a649161b8"
@ -14826,6 +14941,11 @@ type-check@~0.3.2:
dependencies:
prelude-ls "~1.1.2"
type-fest@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8"
integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==
type-is@^1.6.16, type-is@~1.6.16:
version "1.6.16"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194"
@ -15788,12 +15908,6 @@ which@1, which@^1.1.1, which@^1.2.10, which@^1.2.12, which@^1.2.14, which@^1.2.9
dependencies:
isexe "^2.0.0"
which@1.2.x:
version "1.2.14"
resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5"
dependencies:
isexe "^2.0.0"
wide-align@^1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
@ -15880,7 +15994,7 @@ write-file-atomic@2.4.1:
imurmurhash "^0.1.4"
signal-exit "^3.0.2"
write-file-atomic@^2.0.0, write-file-atomic@^2.3.0:
write-file-atomic@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab"
dependencies:
@ -15888,6 +16002,15 @@ write-file-atomic@^2.0.0, write-file-atomic@^2.3.0:
imurmurhash "^0.1.4"
signal-exit "^3.0.2"
write-file-atomic@^2.3.0:
version "2.4.3"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481"
integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==
dependencies:
graceful-fs "^4.1.11"
imurmurhash "^0.1.4"
signal-exit "^3.0.2"
write@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"