Unverified Commit 31490a0c authored by Thibaut Sardan's avatar Thibaut Sardan Committed by GitHub
Browse files

Merge branch 'master' into luke-425-startup

parents daecd69a f2cb900f
Pipeline #36384 failed with stage
in 15 seconds
......@@ -10,12 +10,11 @@ variables:
CARGOFLAGS: ''
cache:
key: "${CI_JOB_NAME}"
key: '${CI_JOB_NAME}'
paths:
- node_modules/
- packages/*/node_modules/
.branches: &branches
only:
- beta
......@@ -79,6 +78,9 @@ win-build:
script:
- yarn install
- yarn build
# `win-build` is a linux machine, so it downloaded a linux parity-ethereum.
# We download a windows one to make it cross-compile for windows.
- rm packages/fether-electron/static/parity* && yarn fetch-parity --win
- yarn release --win
tags:
- linux-docker
......
# Contributing
## What?
Individuals making significant and valuable contributions are given commit-access to a project to contribute as they see fit.
A project is more like an open wiki than a standard guarded open source project.
## Rules
There are a few basic ground-rules for contributors (including the maintainer(s) of the project):
1. **No `--force` pushes** or modifying the Git history in any way. If you need to rebase, ensure you do it in your own repo.
2. **Non-master branches**, prefixed with a short name moniker (e.g. `<initials>-<feature>`) must be used for ongoing work.
3. **All modifications** must be made in a **pull-request** to solicit feedback from other contributors.
4. A pull-request *must not be merged until CI* has finished successfully.
#### Merging pull requests once CI is successful:
- A pull request with no large change to logic that is an urgent fix may be merged after a non-author contributor has reviewed it well.
- No PR should be merged until all reviews' comments are addressed.
#### Reviewing pull requests:
When reviewing a pull request, the end-goal is to suggest useful changes to the author. Reviews should finish with approval unless there are issues that would result in:
- Buggy behaviour.
- Undue maintenance burden.
- Breaking with house coding style.
- Pessimisation (i.e. reduction of speed as measured in the projects benchmarks).
- Feature reduction (i.e. it removes some aspect of functionality that a significant minority of users rely on).
- Uselessness (i.e. it does not strictly add a feature or fix a known issue).
#### Reviews may not be used as an effective veto for a PR because:
- There exists a somewhat cleaner/better/faster way of accomplishing the same feature/fix.
- It does not fit well with some other contributors' longer-term vision for the project.
## Releases
Declaring formal releases remains the prerogative of the project maintainer(s).
## Changes to this arrangement
This is an experiment and feedback is welcome! This document may also be subject to pull-requests or changes by contributors where you believe you have something valuable to add or change.
## Heritage
These contributing guidelines are modified from the "OPEN Open Source Project" guidelines for the Level project: [https://github.com/Level/community/blob/master/CONTRIBUTING.md](https://github.com/Level/community/blob/master/CONTRIBUTING.md)
......@@ -11,9 +11,9 @@
Parity Fether aims to be the lightest and simplest decentralized wallet. It supports Ether and ERC-20 tokens, and runs on top of [Parity Ethereum](https://github.com/paritytech/parity-ethereum) light client. This allows smooth synchronization and interaction with the Ethereum blockchain, in a decentralized manner.
By default, Parity Fether alpha runs on the Kovan test network. You can receive free Kovan Ether by posting your address in the [Kovan Faucet](https://gitter.im/kovan-testnet/faucet) Gitter channel. Fether will download and launch Parity Ethereum node at startup if it's not found on the computer. You can also separately launch your Ethereum client, Fether will automatically connect to it.
By default, Fether will launch its embedded Parity Ethereum light client. You can also separately launch your Ethereum client and Fether will automatically connect to it, as described in the [Fether FAQ](https://wiki.parity.io/Fether-FAQ#how-to-launch-fether-with-a-separately-launched-parity-ethereum-node).
Parity Fether connects to the light node using [`@parity/light.js`](https://github.com/paritytech/js-libs/tree/master/packages/light.js), a Javascript library specifically crafted for wallets to connect with light clients.
Parity Fether interacts with the light node using [`@parity/light.js`](https://github.com/paritytech/js-libs/tree/master/packages/light.js), a Javascript library specifically crafted for wallets to connect with light clients.
Parity Fether is licensed under the BSD 3-Clause, and can be used for all your Ethereum needs.
......
......@@ -4,5 +4,5 @@
"packages/*"
],
"useWorkspaces": true,
"version": "0.3.0"
}
"version": "0.4.0"
}
\ No newline at end of file
{
"name": "fether",
"description": "Fether Wallet",
"version": "0.3.0",
"version": "0.4.0",
"private": true,
"author": "Parity Team <admin@parity.io>",
"maintainers": [
"Jaco Greeff",
"Amaury Martiny"
"Axel Chalon",
"Amaury Martiny",
"Thibaut Sardan",
"Luke Schoen"
],
"contributors": [],
"license": "BSD-3-Clause",
......@@ -40,11 +42,12 @@
"yarn": "^1.4.2"
},
"scripts": {
"postinstall": "cd scripts && node ./fetch-latest-parity.js",
"postinstall": "yarn fetch-parity",
"build": "lerna run build",
"preelectron": "yarn build",
"electron": "cd packages/fether-electron && yarn electron",
"lint-files": "./scripts/lint-files.sh '**/*.js'",
"fetch-parity": "cd scripts && node ./fetch-latest-parity.js",
"lint-files": "FILES='**/*.js' ./scripts/lint-files.sh $FILES",
"lint": "yarn lint-files",
"prepackage": "yarn build",
"package": "cd packages/fether-electron && yarn package",
......@@ -58,7 +61,7 @@
},
"husky": {
"hooks": {
"pre-commit": "FILES=`git diff --staged --name-only --diff-filter=d HEAD | grep -E '.js$|.ts$'`; [ -z \"$FILES\" ] && exit 0; yarn lint-files $FILES; git add $FILES"
"pre-commit": "FILES=`git diff --staged --name-only --diff-filter=d HEAD | grep -E '.js$'`; [ -z \"$FILES\" ] && exit 0; yarn lint-files $FILES; git add $FILES"
}
},
"devDependencies": {
......
// https://webpack.electron.build/add-ons
// https://www.npmjs.com/package/webpack-build-notifier
const path = require('path');
const WebpackBuildNotifierPlugin = require('webpack-build-notifier');
const withWebpackBuildNotifier = process.env.NOTIFIER === 'true';
module.exports = withWebpackBuildNotifier
? {
plugins: [
new WebpackBuildNotifierPlugin({
title: 'Fether Webpack Build',
logo: path.resolve('./build/icons/icon.ico'),
suppressSuccess: false,
compileIcon: path.resolve('./build/icons/webpack/compile.png'),
failureIcon: path.resolve('./build/icons/webpack/failure.png'),
successIcon: path.resolve('./build/icons/webpack/success.png'),
warningIcon: path.resolve('./build/icons/webpack/warning.png')
})
]
}
: {};
{
"main": {
"webpackConfig": "custom.webpack.additions.js"
},
"renderer": {
"sourceDirectory": null
}
},
"title": "Fether"
}
{
"name": "fether",
"description": "Fether Wallet",
"version": "0.3.0",
"version": "0.4.0",
"private": true,
"author": "Parity Team <admin@parity.io>",
"maintainers": [
"Jaco Greeff",
"Amaury Martiny"
"Axel Chalon",
"Amaury Martiny",
"Thibaut Sardan",
"Luke Schoen"
],
"contributors": [],
"license": "BSD-3-Clause",
......@@ -25,17 +27,17 @@
],
"homepage": "https://github.com/paritytech/fether",
"parity": {
"version": "~2.4.1"
"version": "~2.5.0"
},
"scripts": {
"prebuild": "copyfiles -u 2 \"../fether-react/build/**/*\" static/ && ./scripts/fixElectronBug.sh",
"build": "electron-webpack",
"electron": "cross-env SKIP_PREFLIGHT_CHECK=true electron dist/main/main.js",
"electron": "electron dist/main/main.js",
"prepackage": "./scripts/revertElectronBug.sh",
"package": "electron-builder",
"prerelease": "./scripts/revertElectronBug.sh",
"release": "electron-builder",
"start": "cross-env ELECTRON_START_URL=http://localhost:3000 electron-webpack dev --ws-origins all",
"start": "cross-env ELECTRON_START_URL=http://localhost:3000 electron-webpack dev",
"test": "jest --all --color --coverage"
},
"dependencies": {
......@@ -45,10 +47,13 @@
"commander-remaining-args": "^1.2.0",
"electron-positioner": "^4.1.0",
"electron-settings": "^3.2.0",
"fether-react": "^0.3.0",
"fether-react": "^0.4.0",
"i18next": "^15.0.4",
"i18next-node-fs-backend": "^2.0.0",
"pino": "^4.16.1",
"pino-multi-stream": "^3.1.2",
"source-map-support": "^0.5.10"
"source-map-support": "^0.5.10",
"url-pattern": "^1.0.3"
},
"devDependencies": {
"auto-launch": "^5.0.5",
......@@ -57,6 +62,7 @@
"electron": "^4.0.1",
"electron-builder": "^20.38.5",
"electron-webpack": "^2.6.1",
"webpack": "^4.29.1"
"webpack": "^4.29.1",
"webpack-build-notifier": "^0.1.30"
}
}
\ No newline at end of file
......@@ -4,7 +4,7 @@
// SPDX-License-Identifier: BSD-3-Clause
import cli from 'commander';
import { DEFAULT_CHAIN, DEFAULT_WS_PORT } from '../constants';
const { productName } = require('../../../../electron-builder.json');
const { version } = require('../../../../package.json');
......@@ -24,22 +24,17 @@ cli
.allowUnknownOption()
.option(
'--chain <chain>',
'The network to connect to, can be one of "foundation", "kovan" or "ropsten". (default: "kovan")',
'kovan'
`The network to connect to, can be one of "foundation", "kovan" or "ropsten". (default: "${DEFAULT_CHAIN}")`,
DEFAULT_CHAIN
)
.option(
'--no-run-parity',
`${productName} will not attempt to run the locally installed parity.`
)
.option(
'--ws-interface <ip>',
`Specify the hostname portion of the WebSockets server ${productName} will connect to. IP should be an interface's IP address. (default: 127.0.0.1)`,
'127.0.0.1'
)
.option(
'--ws-port <port>',
`Specify the port portion of the WebSockets server ${productName} will connect to. (default: 8546)`,
8546
`Specify the port portion of the WebSockets server ${productName} will connect to. (default: ${DEFAULT_WS_PORT})`,
DEFAULT_WS_PORT
)
.parse(
......@@ -47,7 +42,13 @@ cli
// We want to ignore some flags and not pass them down to Parity:
// --inspect: `electron-webpack dev` runs Electron with the `--inspect` flag for HMR
// -psn_*: https://github.com/paritytech/fether/issues/188
.filter(arg => !arg.startsWith('--inspect') && !arg.startsWith('-psn_'))
// --ws-interface: we don't pass down this flag, because fether only allows 127.0.0.1 as WS interface
.filter(
arg =>
!arg.startsWith('--inspect') &&
!arg.startsWith('-psn_') &&
!arg.startsWith('--ws-interface')
)
);
export default cli;
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity.
//
// SPDX-License-Identifier: BSD-3-Clause
import { IS_PACKAGED } from '../utils/paths';
const IS_PROD = process.env.NODE_ENV === 'production';
/**
* Security. Additional network security is configured after `cli` is available:
* in fether-electron/src/main/app/options/config/index.js
*
* Note: 127.0.0.1 is a trusted loopback and more trustworthy than localhost.
* See https://letsencrypt.org/docs/certificates-for-localhost/
*/
const DEFAULT_CHAIN = 'foundation';
const DEFAULT_WS_PORT = '8546';
const TRUSTED_LOOPBACK = '127.0.0.1';
export {
DEFAULT_CHAIN,
DEFAULT_WS_PORT,
IS_PACKAGED,
IS_PROD,
TRUSTED_LOOPBACK
};
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity.
//
// SPDX-License-Identifier: BSD-3-Clause
import i18next from 'i18next';
import Backend from 'i18next-node-fs-backend';
import electron from 'electron';
import settings from 'electron-settings';
import { name } from '../../../../../package.json';
import Pino from '../../utils/pino';
import { en, de } from './locales';
let { app } = electron;
const pino = Pino();
let resourceEnglishNS = {};
let resourceGermanNS = {};
resourceEnglishNS[name] = en;
resourceGermanNS[name] = de;
const packageNS = Object.keys(resourceEnglishNS)[0].toString();
const moduleNS = 'i18n';
const menuNS = `${packageNS}-${moduleNS}`;
const i18n = i18next;
i18n
.use(Backend)
.init({
debug: true,
defaultNS: packageNS,
fallbackLng: ['en-US', 'en', 'de-DE', 'de'],
interpolation: {
escapeValue: false
},
lng: settings.get('fether-language') || 'en',
ns: [packageNS],
resources: {
en: resourceEnglishNS,
de: resourceGermanNS
},
saveMissing: true
})
.then(() => pino.info(`${menuNS}: success`))
.catch(error => pino.info(`${menuNS}: failure`, error));
// https://www.i18next.com/overview/api#changelanguage
i18n.changeLanguage(app.getLocale(), (err, t) => {
if (err) {
pino.info(`${menuNS}: Error loading language ${app.getLocale()}`, err);
}
});
i18next.on('initialized', options => {
pino.debug(`${menuNS}: Detected initialisation of i18n`);
});
i18next.on('loaded', loaded => {
pino.info(`${menuNS}: Detected success loading resources: `, loaded);
});
i18next.on('failedLoading', (lng, ns, msg) => {
pino.info(`${menuNS}: Detected failure loading resources: `, lng, ns, msg);
});
// saveMissing must be configured to `true`
i18next.on('missingKey', (lngs, namespace, key, res) => {
pino.info(`${menuNS}: Detected missing key: `, lngs, namespace, key, res);
});
i18next.store.on('added', (lng, ns) => {
pino.debug(`${menuNS}: Detected resources added: `, lng, ns);
});
i18next.store.on('removed', (lng, ns) => {
pino.debug(`${menuNS}: Detected resources removed: `, lng, ns);
});
// https://www.i18next.com/overview/api#changelanguage
i18next.on('languageChanged', lng => {
pino.info(`${menuNS}: Detected language change to: `, lng);
});
export default i18n;
{
"menu": {
"file": {
"submenu_name": "Datei",
"about": "Über",
"preferences": {
"submenu_name": "Einstellungen",
"languages": {
"submenu_name": "Sprachen",
"language": "Sprache",
"english": "Englisch",
"german": "Deutsch"
}
},
"services": "Dienstleistungen",
"hide": "Verbergen",
"hide_others": "Andere Ausblenden",
"unhide": "Einblenden",
"quit": "Verlassen"
},
"edit": {
"submenu_name": "Bearbeiten",
"undo": "Rückgängig Machen",
"redo": "Wiederholen",
"cut": "Ausschneiden",
"copy": "Kopieren",
"paste": "Einfügen",
"delete": "Löschen",
"select_all": "Alle Auswählen",
"speech": {
"submenu_name": "Reden",
"start_speaking": "Beginnen Sie zu Sprechen",
"stop_speaking": "Hör auf zu Sprechen"
}
},
"view": {
"submenu_name": "Ansicht",
"reload": "Neu Laden",
"toggle_developer_tools": "Entwicklerwerkzeuge"
},
"window": {
"submenu_name": "Fenster",
"close": "Schließen",
"minimize": "Minimieren",
"zoom": "Zoomen",
"bring_all_to_front": "Alle Nach Vorne Bringen"
},
"help": {
"submenu_name": "Hilfe",
"search": "Suchen",
"learn_more": "Weitere Informationen"
},
"show_hide_fether": "Fether Anzeigen/Ausblenden"
}
}
{
"menu": {
"file": {
"submenu_name": "File",
"about": "About",
"preferences": {
"submenu_name": "Preferences",
"languages": {
"submenu_name": "Languages",
"language": "Language",
"english": "English",
"german": "German"
}
},
"services": "Services",
"hide": "Hide",
"hide_others": "Hide Others",
"unhide": "Unhide",
"quit": "Quit"
},
"edit": {
"submenu_name": "Edit",
"undo": "Undo",
"redo": "Redo",
"cut": "Cut",
"copy": "Copy",
"paste": "Paste",
"delete": "Delete",
"select_all": "Select All",
"speech": {
"submenu_name": "Speech",
"start_speaking": "Start Speaking",
"stop_speaking": "Stop Speaking"
}
},
"view": {
"submenu_name": "View",
"reload": "Reload",
"toggle_developer_tools": "Toggle Developer Tools"
},
"window": {
"submenu_name": "Window",
"close": "Close",
"minimize": "Minimize",
"zoom": "Zoom",
"bring_all_to_front": "Bring All to Front"
},
"help": {
"submenu_name": "Help",
"search": "Search",
"learn_more": "Learn More"
},
"show_hide_fether": "Show/Hide Fether"
}
}
import en from './en.json';
import de from './de.json';
export { en, de };
......@@ -6,22 +6,46 @@
import path from 'path';
import electron from 'electron';
import settings from 'electron-settings';
// https://www.npmjs.com/package/auto-launch
import AutoLaunch from 'auto-launch';
import Pino from '../../utils/pino';
// Only use 'auto-launch' library on Linux since Electron API's
// `setLoginItemSettings` is only supported on macOS and Windows
// https://electronjs.org/docs/api/app#appsetloginitemsettingssettings-macos-windows
const fetherAutoLauncher = new AutoLaunch({
name: 'Fether',
path: '/usr/local/bin/fether'
});
import { IS_PROD } from '../../constants';
import i18n from '../i18n';
const { shell } = electron;
const pino = Pino();
// Preferences menu
const getPreferences = fetherApp => {
return {
label: i18n.t('menu.file.preferences.languages.submenu_name'),
submenu: [
{
label: i18n.t('menu.file.preferences.languages.english'),
type: 'radio',
checked: settings.get('fether-language') === 'en',
click () {
// Backend menu change language
i18n.changeLanguage('en');
settings.set('fether-language', 'en');
fetherApp.setupMenu(fetherApp);
// Frontend change language
fetherApp.win.webContents.emit('set-language', 'en');
}
},
{
label: i18n.t('menu.file.preferences.languages.german'),
type: 'radio',
checked: settings.get('fether-language') === 'de',
click () {
// Backend menu change language
i18n.changeLanguage('de');
settings.set('fether-language', 'de');
fetherApp.setupMenu(fetherApp);
// Frontend change language
fetherApp.win.webContents.emit('set-language', 'de');
}
}
]
};
};
// Create the Application's main menu
// https://github.com/electron/electron/blob/master/docs/api/menu.md#examples
......@@ -30,37 +54,46 @@ const getMenubarMenuTemplate = fetherApp => {
const fileTab =
process.platform === 'darwin'
? {
label: 'File',
label: i18n.t('menu.file.submenu_name'),
submenu: [
{ role: 'about' },
{ role: 'about', label: i18n.t('menu.file.about') },
{ type: 'separator' },