committed by
GitHub
30 changed files with 1638 additions and 147 deletions
@ -0,0 +1,24 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import Login from './Login' |
|||
import Signup from './Signup' |
|||
import styles from './InitWallet.scss' |
|||
|
|||
const InitWallet = ({ hasSeed, loginProps, signupProps }) => ( |
|||
<div className={styles.container}> |
|||
{ |
|||
hasSeed ? |
|||
<Login {...loginProps} /> |
|||
: |
|||
<Signup {...signupProps} /> |
|||
} |
|||
</div> |
|||
) |
|||
|
|||
InitWallet.propTypes = { |
|||
hasSeed: PropTypes.bool.isRequired, |
|||
loginProps: PropTypes.object.isRequired, |
|||
signupProps: PropTypes.object.isRequired |
|||
} |
|||
|
|||
export default InitWallet |
@ -0,0 +1,60 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.container { |
|||
position: relative; |
|||
} |
|||
|
|||
.password { |
|||
background: transparent; |
|||
outline: none; |
|||
border: 0; |
|||
color: $gold; |
|||
-webkit-text-fill-color: $white; |
|||
font-size: 22px; |
|||
} |
|||
|
|||
.password::-webkit-input-placeholder { |
|||
text-shadow: none; |
|||
-webkit-text-fill-color: initial; |
|||
} |
|||
|
|||
.buttons { |
|||
margin-top: 15%; |
|||
text-align: center; |
|||
|
|||
div { |
|||
color: $white; |
|||
|
|||
&:nth-child(1) { |
|||
text-align: center; |
|||
margin-bottom: 40px; |
|||
|
|||
span { |
|||
padding: 15px 35px; |
|||
background: $darkspaceblue; |
|||
font-size: 14px; |
|||
opacity: 0.5; |
|||
transition: all 0.25s; |
|||
|
|||
&.active { |
|||
opacity: 1.0; |
|||
cursor: pointer; |
|||
|
|||
&:hover { |
|||
background: lighten($darkspaceblue, 10%); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
&:nth-child(2), &:nth-child(3) { |
|||
font-size: 12px; |
|||
cursor: pointer; |
|||
margin: 10px 0; |
|||
|
|||
&:hover { |
|||
text-decoration: underline; |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,49 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import styles from './Login.scss' |
|||
|
|||
const Login = ({ |
|||
password, |
|||
updatePassword, |
|||
unlockingWallet, |
|||
unlockWallet, |
|||
unlockWalletError |
|||
}) => ( |
|||
<div className={styles.container}> |
|||
<input |
|||
type='password' |
|||
placeholder='Password' |
|||
className={`${styles.password} ${unlockWalletError.isError && styles.inputError}`} |
|||
ref={input => input && input.focus()} |
|||
value={password} |
|||
onChange={event => updatePassword(event.target.value)} |
|||
/> |
|||
<p className={`${unlockWalletError.isError && styles.active} ${styles.error}`}> |
|||
{unlockWalletError.message} |
|||
</p> |
|||
|
|||
<section className={styles.buttons}> |
|||
<div> |
|||
<span className={`${!unlockingWallet && styles.active} ${styles.button}`} onClick={() => unlockWallet(password)}> |
|||
{ |
|||
unlockingWallet ? |
|||
<i className={styles.spinner} /> |
|||
: |
|||
'Log In' |
|||
} |
|||
</span> |
|||
</div> |
|||
<div>Recover existing wallet</div> |
|||
</section> |
|||
</div> |
|||
) |
|||
|
|||
Login.propTypes = { |
|||
password: PropTypes.string.isRequired, |
|||
updatePassword: PropTypes.func.isRequired, |
|||
unlockingWallet: PropTypes.bool.isRequired, |
|||
unlockWallet: PropTypes.func.isRequired, |
|||
unlockWalletError: PropTypes.object.isRequired |
|||
} |
|||
|
|||
export default Login |
@ -0,0 +1,124 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.container { |
|||
position: relative; |
|||
} |
|||
|
|||
.password { |
|||
background: transparent; |
|||
outline: none; |
|||
border: 0; |
|||
color: $gold; |
|||
-webkit-text-fill-color: $white; |
|||
font-size: 22px; |
|||
border-bottom: 1px solid transparent; |
|||
transition: all 0.25s; |
|||
|
|||
&.inputError { |
|||
border-bottom: 1px solid $red; |
|||
} |
|||
} |
|||
|
|||
.password::-webkit-input-placeholder { |
|||
text-shadow: none; |
|||
-webkit-text-fill-color: initial; |
|||
} |
|||
|
|||
.error { |
|||
margin-top: 20px; |
|||
color: $red; |
|||
visibility: hidden; |
|||
font-size: 12px; |
|||
transition: all 0.25s; |
|||
|
|||
&.active { |
|||
visibility: visible; |
|||
} |
|||
} |
|||
|
|||
.buttons { |
|||
margin-top: 15%; |
|||
text-align: center; |
|||
|
|||
div { |
|||
color: $white; |
|||
|
|||
&:nth-child(1) { |
|||
text-align: center; |
|||
margin-bottom: 40px; |
|||
|
|||
span { |
|||
padding: 15px 35px; |
|||
background: $darkspaceblue; |
|||
font-size: 14px; |
|||
opacity: 0.5; |
|||
transition: all 0.25s; |
|||
|
|||
&.button { |
|||
position: relative; |
|||
} |
|||
|
|||
&.active { |
|||
opacity: 1.0; |
|||
cursor: pointer; |
|||
|
|||
&:hover { |
|||
background: lighten($darkspaceblue, 10%); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
&:nth-child(2), &:nth-child(3) { |
|||
font-size: 12px; |
|||
cursor: pointer; |
|||
margin: 10px 0; |
|||
|
|||
&:hover { |
|||
text-decoration: underline; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.spinner { |
|||
height: 20px; |
|||
width: 20px; |
|||
border: 1px solid rgba(235, 184, 100, 0.1); |
|||
border-left-color: rgba(235, 184, 100, 0.4); |
|||
-webkit-border-radius: 999px; |
|||
-moz-border-radius: 999px; |
|||
border-radius: 999px; |
|||
-webkit-animation: animation-rotate 1000ms linear infinite; |
|||
-moz-animation: animation-rotate 1000ms linear infinite; |
|||
-o-animation: animation-rotate 1000ms linear infinite; |
|||
animation: animation-rotate 1000ms linear infinite; |
|||
display: inline-block; |
|||
position: absolute; |
|||
top: calc(50% - 10px); |
|||
left: calc(50% - 10px); |
|||
} |
|||
|
|||
@-webkit-keyframes animation-rotate { |
|||
100% { |
|||
-webkit-transform: rotate(360deg); |
|||
} |
|||
} |
|||
|
|||
@-moz-keyframes animation-rotate { |
|||
100% { |
|||
-moz-transform: rotate(360deg); |
|||
} |
|||
} |
|||
|
|||
@-o-keyframes animation-rotate { |
|||
100% { |
|||
-o-transform: rotate(360deg); |
|||
} |
|||
} |
|||
|
|||
@keyframes animation-rotate { |
|||
100% { |
|||
transform: rotate(360deg); |
|||
} |
|||
} |
@ -0,0 +1,45 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import styles from './NewAezeedPassword.scss' |
|||
|
|||
const NewAezeedPassword = ({ |
|||
aezeedPassword, |
|||
aezeedPasswordConfirmation, |
|||
showAezeedPasswordConfirmationError, |
|||
updateAezeedPassword, |
|||
updateAezeedPasswordConfirmation |
|||
}) => ( |
|||
<div className={styles.container}> |
|||
<section className={styles.input}> |
|||
<input |
|||
type='password' |
|||
placeholder='Password' |
|||
className={styles.password} |
|||
value={aezeedPassword} |
|||
onChange={event => updateAezeedPassword(event.target.value)} |
|||
/> |
|||
</section> |
|||
|
|||
<section className={styles.input}> |
|||
<input |
|||
type='password' |
|||
placeholder='Confirm Password' |
|||
className={`${styles.password} ${showAezeedPasswordConfirmationError && styles.error}`} |
|||
value={aezeedPasswordConfirmation} |
|||
onChange={event => updateAezeedPasswordConfirmation(event.target.value)} |
|||
/> |
|||
<p className={`${styles.errorMessage} ${showAezeedPasswordConfirmationError && styles.visible}`}>Passwords do not match</p> |
|||
</section> |
|||
</div> |
|||
) |
|||
|
|||
NewAezeedPassword.propTypes = { |
|||
aezeedPassword: PropTypes.string.isRequired, |
|||
aezeedPasswordConfirmation: PropTypes.string.isRequired, |
|||
showAezeedPasswordConfirmationError: PropTypes.bool.isRequired, |
|||
updateAezeedPassword: PropTypes.func.isRequired, |
|||
updateAezeedPasswordConfirmation: PropTypes.func.isRequired |
|||
} |
|||
|
|||
export default NewAezeedPassword |
|||
|
@ -0,0 +1,35 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.input:nth-child(2) { |
|||
margin-top: 40px; |
|||
} |
|||
|
|||
.password { |
|||
background: transparent; |
|||
outline: none; |
|||
border: 0; |
|||
color: $gold; |
|||
-webkit-text-fill-color: $white; |
|||
font-size: 22px; |
|||
transition: all 0.25s; |
|||
|
|||
&.error { |
|||
border-bottom: 1px solid $red; |
|||
} |
|||
} |
|||
|
|||
.password::-webkit-input-placeholder { |
|||
text-shadow: none; |
|||
-webkit-text-fill-color: initial; |
|||
} |
|||
|
|||
.errorMessage { |
|||
color: $red; |
|||
margin-top: 10px; |
|||
font-size: 10px; |
|||
visibility: hidden; |
|||
|
|||
&.visible { |
|||
visibility: visible; |
|||
} |
|||
} |
@ -0,0 +1,45 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import styles from './NewWalletPassword.scss' |
|||
|
|||
const NewWalletPassword = ({ |
|||
createWalletPassword, |
|||
createWalletPasswordConfirmation, |
|||
showCreateWalletPasswordConfirmationError, |
|||
|
|||
updateCreateWalletPassword, |
|||
updateCreateWalletPasswordConfirmation |
|||
}) => ( |
|||
<div className={styles.container}> |
|||
<section className={styles.input}> |
|||
<input |
|||
type='password' |
|||
placeholder='Password' |
|||
className={styles.password} |
|||
value={createWalletPassword} |
|||
onChange={event => updateCreateWalletPassword(event.target.value)} |
|||
/> |
|||
</section> |
|||
|
|||
<section className={styles.input}> |
|||
<input |
|||
type='password' |
|||
placeholder='Confirm Password' |
|||
className={`${styles.password} ${showCreateWalletPasswordConfirmationError && styles.error}`} |
|||
value={createWalletPasswordConfirmation} |
|||
onChange={event => updateCreateWalletPasswordConfirmation(event.target.value)} |
|||
/> |
|||
<p className={`${styles.errorMessage} ${showCreateWalletPasswordConfirmationError && styles.visible}`}>Passwords do not match</p> |
|||
</section> |
|||
</div> |
|||
) |
|||
|
|||
NewWalletPassword.propTypes = { |
|||
createWalletPassword: PropTypes.string.isRequired, |
|||
createWalletPasswordConfirmation: PropTypes.string.isRequired, |
|||
showCreateWalletPasswordConfirmationError: PropTypes.bool.isRequired, |
|||
updateCreateWalletPassword: PropTypes.func.isRequired, |
|||
updateCreateWalletPasswordConfirmation: PropTypes.func.isRequired |
|||
} |
|||
|
|||
export default NewWalletPassword |
@ -0,0 +1,35 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.input:nth-child(2) { |
|||
margin-top: 40px; |
|||
} |
|||
|
|||
.password { |
|||
background: transparent; |
|||
outline: none; |
|||
border: 0; |
|||
color: $gold; |
|||
-webkit-text-fill-color: $white; |
|||
font-size: 22px; |
|||
transition: all 0.25s; |
|||
|
|||
&.error { |
|||
border-bottom: 1px solid $red; |
|||
} |
|||
} |
|||
|
|||
.password::-webkit-input-placeholder { |
|||
text-shadow: none; |
|||
-webkit-text-fill-color: initial; |
|||
} |
|||
|
|||
.errorMessage { |
|||
color: $red; |
|||
margin-top: 10px; |
|||
font-size: 10px; |
|||
visibility: hidden; |
|||
|
|||
&.visible { |
|||
visibility: visible; |
|||
} |
|||
} |
@ -0,0 +1,28 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import styles from './NewWalletSeed.scss' |
|||
|
|||
const NewWalletSeed = ({ seed }) => ( |
|||
<div className={styles.container}> |
|||
<ul className={styles.seedContainer}> |
|||
{ |
|||
seed.map((word, index) => ( |
|||
<li key={index}> |
|||
<section> |
|||
<label htmlFor={word}>{index + 1}</label> |
|||
</section> |
|||
<section> |
|||
<span>{word}</span> |
|||
</section> |
|||
</li> |
|||
)) |
|||
} |
|||
</ul> |
|||
</div> |
|||
) |
|||
|
|||
NewWalletSeed.propTypes = { |
|||
seed: PropTypes.array.isRequired |
|||
} |
|||
|
|||
export default NewWalletSeed |
@ -0,0 +1,49 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.container { |
|||
font-size: 14px; |
|||
color: $white; |
|||
font-family: 'Roboto'; |
|||
letter-spacing: 1.5px; |
|||
|
|||
li { |
|||
display: inline-block; |
|||
margin: 5px 0; |
|||
width: 25%; |
|||
font-family: 'Courier'; |
|||
|
|||
section { |
|||
display: inline-block; |
|||
vertical-align: middle; |
|||
color: $white; |
|||
|
|||
&:nth-child(1) { |
|||
width: 15%; |
|||
text-align: center; |
|||
opacity: 0.5; |
|||
} |
|||
|
|||
&:nth-child(2) { |
|||
width: calc(85% - 10px); |
|||
margin: 0 5px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.word { |
|||
margin: 0 3px; |
|||
background-color: #1c1e26; |
|||
outline: 0; |
|||
border: none; |
|||
padding: 10px; |
|||
color: $white; |
|||
|
|||
&.valid { |
|||
color: $green; |
|||
} |
|||
|
|||
&.invalid { |
|||
color: $red; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,38 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import styles from './ReEnterSeed.scss' |
|||
|
|||
const ReEnterSeed = ({ seed, seedInput, updateSeedInput }) => ( |
|||
<div className={styles.container}> |
|||
<ul className={styles.seedContainer}> |
|||
{ |
|||
seed.map((word, index) => ( |
|||
<li key={index}> |
|||
<section> |
|||
<label htmlFor={word}>{index + 1}</label> |
|||
</section> |
|||
<section> |
|||
<input |
|||
type='text' |
|||
id={word} |
|||
placeholder='word' |
|||
value={seedInput[index] ? seedInput[index].word : ''} |
|||
onChange={event => updateSeedInput({ word: event.target.value, index })} |
|||
className={`${styles.word} ${seedInput[index] && word === seedInput[index].word ? styles.valid : styles.invalid}`} |
|||
/> |
|||
</section> |
|||
</li> |
|||
)) |
|||
} |
|||
</ul> |
|||
</div> |
|||
) |
|||
|
|||
|
|||
ReEnterSeed.propTypes = { |
|||
seed: PropTypes.array.isRequired, |
|||
seedInput: PropTypes.array.isRequired, |
|||
updateSeedInput: PropTypes.func.isRequired |
|||
} |
|||
|
|||
export default ReEnterSeed |
@ -0,0 +1,61 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.seedContainer { |
|||
position: relative; |
|||
display: inline-block; |
|||
font-size: 12px; |
|||
|
|||
li { |
|||
display: inline-block; |
|||
margin: 5px 0; |
|||
width: 25%; |
|||
|
|||
section { |
|||
display: inline-block; |
|||
vertical-align: middle; |
|||
color: $white; |
|||
|
|||
&:nth-child(1) { |
|||
width: 15%; |
|||
text-align: center; |
|||
opacity: 0.5; |
|||
} |
|||
|
|||
&:nth-child(2) { |
|||
width: calc(85% - 10px); |
|||
margin: 0 5px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
.word { |
|||
margin: 0 3px; |
|||
background-color: #1c1e26; |
|||
outline: 0; |
|||
border: none; |
|||
padding: 5px 10px; |
|||
color: $white; |
|||
font-family: courier; |
|||
font-family: 'Courier'; |
|||
|
|||
&.valid { |
|||
color: $green; |
|||
} |
|||
|
|||
&.invalid { |
|||
color: $red; |
|||
} |
|||
} |
|||
|
|||
.word::-webkit-input-placeholder { |
|||
text-shadow: none; |
|||
-webkit-text-fill-color: initial; |
|||
} |
|||
|
|||
.contentEditable { |
|||
width: 100px; |
|||
background: red; |
|||
} |
@ -0,0 +1,43 @@ |
|||
import React from 'react' |
|||
import PropTypes from 'prop-types' |
|||
import { FaCircle, FaCircleThin } from 'react-icons/lib/fa' |
|||
import styles from './Signup.scss' |
|||
|
|||
const Signup = ({ signupForm, setSignupCreate, setSignupImport }) => ( |
|||
<div className={styles.container}> |
|||
<section className={`${styles.enable} ${signupForm.create && styles.active}`}> |
|||
<div onClick={setSignupCreate}> |
|||
{ |
|||
signupForm.create ? |
|||
<FaCircle /> |
|||
: |
|||
<FaCircleThin /> |
|||
} |
|||
<span className={styles.label}> |
|||
Create new wallet |
|||
</span> |
|||
</div> |
|||
</section> |
|||
<section className={`${styles.disable} ${signupForm.import && styles.active}`}> |
|||
<div onClick={setSignupImport}> |
|||
{ |
|||
signupForm.import ? |
|||
<FaCircle /> |
|||
: |
|||
<FaCircleThin /> |
|||
} |
|||
<span className={styles.label}> |
|||
Import existing wallet |
|||
</span> |
|||
</div> |
|||
</section> |
|||
</div> |
|||
) |
|||
|
|||
Signup.propTypes = { |
|||
signupForm: PropTypes.object.isRequired, |
|||
setSignupCreate: PropTypes.func.isRequired, |
|||
setSignupImport: PropTypes.func.isRequired |
|||
} |
|||
|
|||
export default Signup |
@ -0,0 +1,52 @@ |
|||
@import '../../variables.scss'; |
|||
|
|||
.container { |
|||
color: $white; |
|||
|
|||
section { |
|||
margin: 20px 0; |
|||
|
|||
&.enable { |
|||
&.active { |
|||
div { |
|||
color: $gold; |
|||
border-color: $gold; |
|||
} |
|||
} |
|||
|
|||
div:hover { |
|||
color: $gold; |
|||
border-color: $gold; |
|||
} |
|||
} |
|||
|
|||
&.disable { |
|||
&.active { |
|||
div { |
|||
color: $gold; |
|||
border-color: $gold; |
|||
} |
|||
} |
|||
|
|||
div:hover { |
|||
color: $gold; |
|||
border-color: $gold; |
|||
} |
|||
} |
|||
|
|||
div { |
|||
width: 185px; |
|||
display: inline-block; |
|||
padding: 20px; |
|||
border: 1px solid $white; |
|||
border-radius: 5px; |
|||
font-weight: 200; |
|||
cursor: pointer; |
|||
transition: all 0.25s; |
|||
} |
|||
|
|||
.label { |
|||
margin-left: 15px; |
|||
} |
|||
} |
|||
} |
After Width: | Height: | Size: 316 B |
@ -0,0 +1,29 @@ |
|||
import fs from 'fs' |
|||
import path from 'path' |
|||
import grpc from 'grpc' |
|||
import config from '../config' |
|||
|
|||
// Default is ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384
|
|||
// https://github.com/grpc/grpc/blob/master/doc/environment_variables.md
|
|||
//
|
|||
// Current LND cipher suites here:
|
|||
// https://github.com/lightningnetwork/lnd/blob/master/lnd.go#L80
|
|||
//
|
|||
// We order the suites by priority, based on the recommendations provided by SSL Labs here:
|
|||
// https://github.com/ssllabs/research/wiki/SSL-and-TLS-Deployment-Best-Practices#23-use-secure-cipher-suites
|
|||
process.env.GRPC_SSL_CIPHER_SUITES = process.env.GRPC_SSL_CIPHER_SUITES || [ |
|||
'ECDHE-ECDSA-AES128-GCM-SHA256', |
|||
'ECDHE-ECDSA-AES256-GCM-SHA384', |
|||
'ECDHE-ECDSA-AES128-CBC-SHA256', |
|||
'ECDHE-ECDSA-CHACHA20-POLY1305' |
|||
].join(':') |
|||
|
|||
const walletUnlocker = (rpcpath, host) => { |
|||
const lndCert = fs.readFileSync(config.cert) |
|||
const credentials = grpc.credentials.createSsl(lndCert) |
|||
const rpc = grpc.load(path.join(__dirname, 'rpc.proto')) |
|||
|
|||
return new rpc.lnrpc.WalletUnlocker(host, credentials) |
|||
} |
|||
|
|||
export default walletUnlocker |
@ -0,0 +1,24 @@ |
|||
/* eslint no-console: 0 */ // --> OFF
|
|||
|
|||
import * as walletController from '../methods/walletController' |
|||
|
|||
export default function (walletUnlocker, event, msg, data) { |
|||
switch (msg) { |
|||
case 'genSeed': |
|||
walletController.genSeed(walletUnlocker) |
|||
.then(genSeedData => event.sender.send('receiveSeed', genSeedData)) |
|||
.catch(error => event.sender.send('receiveSeedError', error)) |
|||
break |
|||
case 'unlockWallet': |
|||
walletController.unlockWallet(walletUnlocker, data) |
|||
.then(() => event.sender.send('walletUnlocked')) |
|||
.catch(() => event.sender.send('unlockWalletError')) |
|||
break |
|||
case 'initWallet': |
|||
walletController.initWallet(walletUnlocker, data) |
|||
.then(() => event.sender.send('successfullyCreatedWallet')) |
|||
.catch(error => console.log('initWallet error: ', error)) |
|||
break |
|||
default: |
|||
} |
|||
} |
Loading…
Reference in new issue