Browse Source

fix(merge): fix merging conflicts with master

renovate/lint-staged-8.x
Jack Mallers 7 years ago
parent
commit
4017e29cdb
  1. 2
      .eslintrc
  2. 3
      .gitignore
  3. 14
      README.md
  4. 3
      app/app.global.scss
  5. 2
      app/components/ChannelForm/StepOne.js
  6. 4
      app/components/Channels/Channel.scss
  7. 25
      app/components/Channels/OpenPendingChannel.js
  8. 13
      app/components/Channels/OpenPendingChannel.scss
  9. 2
      app/components/LndSyncing/LndSyncing.js
  10. 55
      app/components/Peers/PeerModal.js
  11. 42
      app/components/Peers/PeerModal.scss
  12. 56
      app/components/Wallet/ReceiveModal.js
  13. 79
      app/components/Wallet/ReceiveModal.scss
  14. 21
      app/components/Wallet/Wallet.js
  15. 4
      app/components/Wallet/Wallet.scss
  16. 14
      app/containers/Root.js
  17. 22
      app/index.js
  18. 2
      app/lnd/config/index.js
  19. 2
      app/lnd/lib/lightning.js
  20. 2
      app/lnd/methods/paymentsController.js
  21. 2
      app/lnd/subscribe/transactions.js
  22. 42
      app/lnd/utils/index.js
  23. 1
      app/main.dev.js
  24. 2
      app/package.json
  25. 2
      app/reducers/address.js
  26. 19
      app/reducers/channels.js
  27. 5
      app/reducers/info.js
  28. 4
      app/reducers/lnd.js
  29. 6
      app/reducers/network.js
  30. 2
      app/reducers/peers.js
  31. 49
      app/routes/activity/components/components/Modal/Invoice/Invoice.js
  32. 79
      app/routes/activity/components/components/Modal/Invoice/Invoice.scss
  33. 13
      app/routes/activity/components/components/Modal/Modal.js
  34. 13
      app/routes/activity/components/components/Modal/Modal.scss
  35. 33
      app/routes/activity/components/components/Modal/Payment/Payment.js
  36. 48
      app/routes/activity/components/components/Modal/Payment/Payment.scss
  37. 54
      app/routes/activity/components/components/Modal/Transaction/Transaction.js
  38. 53
      app/routes/activity/components/components/Modal/Transaction/Transaction.scss
  39. 2
      app/routes/app/components/App.js
  40. 10
      app/routes/channels/components/Channels.js
  41. 2
      app/routes/peers/components/Peers.js
  42. 34
      app/store/configureStore.dev.js
  43. 4
      app/store/configureStore.js
  44. 35
      app/yarn.lock
  45. 2
      internals/mocks/fileMock.js
  46. 16
      internals/scripts/CheckBuiltsExist.js
  47. 8
      internals/scripts/CheckNodeEnv.js
  48. 2
      package.json
  49. BIN
      resources/bin/darwin/lnd
  50. 3
      test/components/Nav.spec.js
  51. 6
      test/example.js
  52. 11
      test/reducers/__snapshots__/peers.spec.js.snap
  53. 12
      test/runTests.js
  54. 6
      webpack.config.base.js
  55. 4
      webpack.config.eslint.js
  56. 16
      webpack.config.main.prod.js
  57. 18
      webpack.config.renderer.dev.dll.js
  58. 20
      webpack.config.renderer.prod.js
  59. 6
      yarn.lock

2
.eslintrc

@ -11,7 +11,7 @@
},
"rules": {
"comma-dangle": ["error", "never"],
"semi": 0,
"semi": ["error", "never"],
"indent": 2,
"jsx-quotes": ["error", "prefer-single"],
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],

3
.gitignore

@ -50,3 +50,6 @@ main.js.map
.idea
npm-debug.log.*
# lnd binary
resources/bin/*

14
README.md

@ -33,6 +33,18 @@ $ cd zap-desktop
$ yarn
$ npm run install-grpc
```
Zap does not store `lnd` binaries in the Github repo so you will now need to go [install lnd](https://github.com/lightningnetwork/lnd/blob/master/docs/INSTALL.md). You can then copy the `lnd` binary that will be located in your `$GOPATH/bin` and paste it into Zap. Zap expectes `lnd` to be in one of these directories depending on your OS:
```
# mac
resources/bin/darwin
#linux
resources/bin/linux
#win32
resources/bin/win32
```
Then to start it:
```bash
@ -53,7 +65,7 @@ $ npm run lint
Please see the [contributing guide](https://github.com/LN-Zap/zap-desktop/blob/master/CONTRIBUTING.md)
## Todos (Last updated August 16th):
Join us on [slack](https://join.slack.com/t/zaphq/shared_invite/enQtMjYzNDQyMTQxOTU4LTY3ZDk4M2Y3YmEzOTM1ODk1NjEwYjJmMmY3NmU2YTM3ZmJmOTViODcxN2E3MmYyNjAxOGNmNzY1ZDhhYmEwMDI) before tackling a todo to avoid duplicate work.
Join us on [slack](https://join.slack.com/t/zaphq/shared_invite/enQtMjc5Njg3NjU5MzMzLWE1M2RiNjYxNWEyMTRjMzhmZDIyNTQ0YTRjNDg4MWNiMzI1ODNlODhhMzE5ZWVmMGVkOWVkMTVmNzBhNDhiZjQ) before tackling a todo to avoid duplicate work.
The old todo list was recently removed. Come on slack or check open Github issues to see what contributions are needed.

3
app/app.global.scss

@ -86,7 +86,8 @@ body {
padding-bottom: 15px;
border-radius: 2px;
text-align: center;
font-size: 18px;
font-size: 16px;
letter-spacing: 1.5px;
transition: none;
position: relative;
color: white;

2
app/components/ChannelForm/StepOne.js

@ -5,7 +5,7 @@ import styles from './StepOne.scss'
class StepOne extends Component {
constructor(props) {
super(props);
super(props)
this.state = {
peers: props.peers,
searchQuery: ''

4
app/components/Channels/Channel.scss

@ -2,15 +2,17 @@
.channel {
position: relative;
background: $lightgrey;
background: $white;
margin: 5px 0;
padding: 10px;
border-top: 1px solid $white;
cursor: pointer;
transition: all 0.25s;
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
&:hover {
opacity: 0.75;
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}
&:first-child {

25
app/components/Channels/OpenPendingChannel.js

@ -4,17 +4,20 @@ import PropTypes from 'prop-types'
import { btc } from 'utils'
import styles from './OpenPendingChannel.scss'
const OpenPendingChannel = ({ ticker, channel: { channel }, currentTicker, explorerLinkBase }) => (
<li className={styles.channel} onClick={() => shell.openExternal(`${explorerLinkBase}/tx/${channel.channel_point.split(':')[0]}`)}>
<h1 className={styles.pending}>Opening Channel...</h1>
const OpenPendingChannel = ({ ticker, channel, currentTicker, explorerLinkBase }) => (
<li className={styles.channel} onClick={() => shell.openExternal(`${explorerLinkBase}/tx/${channel.channel.channel_point.split(':')[0]}`)}>
<div className={styles.pending}>
<h1>Opening Channel...</h1>
<span>Blocks till open: {channel.blocks_till_open}</span>
</div>
<div className={styles.left}>
<section className={styles.remotePubkey}>
<span>Remote Pubkey</span>
<h4>{channel.remote_node_pub}</h4>
<h4>{channel.channel.remote_node_pub}</h4>
</section>
<section className={styles.channelPoint}>
<span>Channel Point</span>
<h4>{channel.channel_point}</h4>
<h4>{channel.channel.channel_point}</h4>
</section>
</div>
<div className={styles.right}>
@ -23,9 +26,9 @@ const OpenPendingChannel = ({ ticker, channel: { channel }, currentTicker, explo
<h2>
{
ticker.currency === 'btc' ?
btc.satoshisToBtc(channel.capacity)
btc.satoshisToBtc(channel.channel.capacity)
:
btc.satoshisToUsd(channel.capacity, currentTicker.price_usd)
btc.satoshisToUsd(channel.channel.capacity, currentTicker.price_usd)
}
</h2>
</section>
@ -34,9 +37,9 @@ const OpenPendingChannel = ({ ticker, channel: { channel }, currentTicker, explo
<h4>
{
ticker.currency === 'btc' ?
btc.satoshisToBtc(channel.local_balance)
btc.satoshisToBtc(channel.channel.local_balance)
:
btc.satoshisToUsd(channel.local_balance, currentTicker.price_usd)
btc.satoshisToUsd(channel.channel.local_balance, currentTicker.price_usd)
}
</h4>
<span>Local</span>
@ -45,9 +48,9 @@ const OpenPendingChannel = ({ ticker, channel: { channel }, currentTicker, explo
<h4>
{
ticker.currency === 'btc' ?
btc.satoshisToBtc(channel.remote_balance)
btc.satoshisToBtc(channel.channel.remote_balance)
:
btc.satoshisToUsd(channel.remote_balance, currentTicker.price_usd)
btc.satoshisToUsd(channel.channel.remote_balance, currentTicker.price_usd)
}
</h4>
<span>Remote</span>

13
app/components/Channels/OpenPendingChannel.scss

@ -13,14 +13,21 @@
opacity: 0.5;
.pending {
color: $main;
position: absolute;
top: 0;
left: 10px;
padding: 10px;
text-transform: uppercase;
font-weight: bold;
font-size: 10px;
h1 {
color: $main;
font-size: 10px;
}
span {
font-size: 8px;
}
}
&:first-child {
@ -30,7 +37,7 @@
.left, .right {
padding: 0 10px;
margin-bottom: 5;
margin-top: 25px;
margin-top: 40px;
section {
margin-bottom: 20px;

2
app/components/LndSyncing/LndSyncing.js

@ -4,7 +4,7 @@ import styles from './LndSyncing.scss'
class LndSyncing extends Component {
constructor(props) {
super(props);
super(props)
this.state = {
facts: [
{

55
app/components/Peers/PeerModal.js

@ -1,6 +1,9 @@
import React from 'react'
import PropTypes from 'prop-types'
import ReactModal from 'react-modal'
import { MdClose } from 'react-icons/lib/md'
import styles from './PeerModal.scss'
const PeerModal = ({ isOpen, resetPeer, peer, disconnect }) => {
@ -16,7 +19,8 @@ const PeerModal = ({ isOpen, resetPeer, peer, disconnect }) => {
bottom: 'auto',
width: '40%',
margin: '50px auto',
padding: '40px'
borderRadius: 'none',
padding: '0'
}
}
@ -30,32 +34,35 @@ const PeerModal = ({ isOpen, resetPeer, peer, disconnect }) => {
parentSelector={() => document.body}
style={customStyles}
>
<div className={styles.closeContainer}>
<span onClick={() => resetPeer(null)}>
<MdClose />
</span>
</div>
{
peer ?
<div className={styles.peer}>
<header className={styles.header}>
<h1 data-hint='Peer address' className='hint--top-left'>{peer.address}</h1>
<h2 data-hint='Peer public key' className='hint--top-left'>{peer.pub_key}</h2>
</header>
peer &&
<div className={styles.peer}>
<header className={styles.header}>
<h1 data-hint='Peer address' className='hint--top-left'>{peer.address}</h1>
<h2 data-hint='Peer public key' className='hint--top-left'>{peer.pub_key}</h2>
</header>
<div className={styles.details}>
<dl>
<dt>Satoshis Received</dt>
<dd>{peer.sat_recv}</dd>
<dt>Satoshis Sent</dt>
<dd>{peer.sat_sent}</dd>
<dt>Bytes Received</dt>
<dd>{peer.bytes_recv}</dd>
<dt>Bytes Sent</dt>
<dd>{peer.bytes_sent}</dd>
</dl>
</div>
<div className={styles.close} onClick={() => disconnect({ pubkey: peer.pub_key })}>
<div>Disconnect peer</div>
</div>
<div className={styles.details}>
<dl>
<dt>Satoshis Received</dt>
<dd>{peer.sat_recv}</dd>
<dt>Satoshis Sent</dt>
<dd>{peer.sat_sent}</dd>
<dt>Bytes Received</dt>
<dd>{peer.bytes_recv}</dd>
<dt>Bytes Sent</dt>
<dd>{peer.bytes_sent}</dd>
</dl>
</div>
<div className={styles.close} onClick={() => disconnect({ pubkey: peer.pub_key })}>
<div>Disconnect peer</div>
</div>
:
null
</div>
}
</ReactModal>
)

42
app/components/Peers/PeerModal.scss

@ -1,29 +1,39 @@
@import '../../variables.scss';
.peer {
padding: 40px;
.closeContainer {
background: $lightgrey;
text-align: right;
padding: 10px;
span {
color: $darkestgrey;
font-size: 20px;
cursor: pointer;
}
}
.header {
margin-bottom: 50px;
background: $lightgrey;
padding: 20px;
h1 {
color: $black;
text-align: center;
margin-bottom: 5px;
margin-bottom: 20px;
font-weight: bold;
}
h2 {
color: $darkestgrey;
font-size: 14px;
font-size: 12px;
text-align: center;
}
}
.details {
width: 75%;
margin: 20px auto;
dl {
padding: 40px 40px 40px 40px;
}
dt {
text-align: left;
@ -38,36 +48,28 @@
dd {
text-align: right;
font-weight: 400;
padding: 19px 0;
padding: 30px 0 10px 0;
margin-left: 0;
border-top: 1px solid $darkgrey;
border-bottom: 1px solid $darkgrey;
}
}
.close {
text-align: center;
padding-bottom: 40px;
div {
width: 35%;
margin: 0 auto;
cursor: pointer;
height: 55px;
min-height: 55px;
text-transform: none;
font-size: 18px;
transition: opacity .2s ease-out;
background: $red;
color: $white;
color: $red;
border: none;
font-weight: 500;
padding: 0;
text-align: center;
line-height: 55px;
transition: all 0.25s;
border-radius: 5px;
&:hover {
background: darken($red, 10%);
color: lighten($red, 10%);
}
}
}

56
app/components/Wallet/ReceiveModal.js

@ -4,9 +4,11 @@ import ReactModal from 'react-modal'
import copy from 'copy-to-clipboard'
import QRCode from 'qrcode.react'
import { showNotification } from 'notifications'
import { MdClose } from 'react-icons/lib/md'
import { FaCopy } from 'react-icons/lib/fa'
import styles from './ReceiveModal.scss'
const ReceiveModal = ({ isOpen, hideActivityModal, pubkey, address, newAddress }) => {
const ReceiveModal = ({ isOpen, hideActivityModal, pubkey, address, newAddress, qrCodeType, changeQrCode }) => {
const customStyles = {
overlay: {
cursor: 'pointer'
@ -16,8 +18,10 @@ const ReceiveModal = ({ isOpen, hideActivityModal, pubkey, address, newAddress }
left: '20%',
right: '0',
bottom: 'auto',
width: '60%',
margin: '50px auto'
width: '40%',
margin: '50px auto',
borderRadius: 'none',
padding: '0'
}
}
@ -36,22 +40,48 @@ const ReceiveModal = ({ isOpen, hideActivityModal, pubkey, address, newAddress }
parentSelector={() => document.body}
style={customStyles}
>
<div className={styles.closeContainer}>
<span onClick={() => hideActivityModal()}>
<MdClose />
</span>
</div>
<div className={styles.container}>
<section>
<h4>Node Public Key (<span onClick={() => copyOnClick(pubkey)}>Copy</span>)</h4>
<p>{pubkey}</p>
</section>
<header>
<div className={styles.qrcodes}>
<QRCode value={qrCodeType === 1 ? address : pubkey} />
</div>
<ul className={styles.tabs}>
<li className={qrCodeType === 1 && styles.active} onClick={changeQrCode}>
Wallet address
</li>
<li className={qrCodeType === 2 && styles.active} onClick={changeQrCode}>
Node pubkey
</li>
</ul>
</header>
<section>
<div className={styles.addressHeader}>
<h4>Deposit Address (<span onClick={() => copyOnClick(address)}>Copy</span>)</h4>
<span className={styles.newAddress} onClick={() => newAddress('p2pkh')}>New Address</span>
<h4>Deposit Address</h4>
<span className={styles.newAddress} onClick={() => newAddress('np2wkh')}>New Address</span>
</div>
<p>{address}</p>
<p>
<span>{address}</span>
<span onClick={() => copyOnClick(address)} className='hint--left' data-hint='Copy address'>
<FaCopy />
</span>
</p>
</section>
<div className={styles.qrcode}>
<QRCode value={address} />
</div>
<section>
<h4>Node Public Key</h4>
<p>
<span>{pubkey}</span>
<span onClick={() => copyOnClick(pubkey)} className='hint--left' data-hint='Copy pubkey'>
<FaCopy />
</span>
</p>
</section>
</div>
</ReactModal>

79
app/components/Wallet/ReceiveModal.scss

@ -1,15 +1,59 @@
@import '../../variables.scss';
.closeContainer {
background: $lightgrey;
text-align: right;
padding: 10px;
span {
color: $darkestgrey;
font-size: 20px;
cursor: pointer;
}
}
.container {
header {
background: $lightgrey;
padding: 10px 40px 40px;
text-align: center;
.qrcodes {
text-align: center;
margin-top: 20px;
}
.tabs {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-top: 20px;
li {
margin: 0 20px;
color: $darkestgrey;
transition: all 0.25s;
&:hover {
color: $black;
}
&.active {
color: $black;
font-weight: bold;
}
}
}
}
section {
margin: 25px 0;
padding: 25px;
border-bottom: 1px solid $darkestgrey;
h4 {
font-size: 14px;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 1.5px;
margin-bottom: 10px;
@ -19,20 +63,33 @@
}
}
.qrcode {
text-align: center;
margin-top: 20px;
}
p {
display: flex;
flex-direction: row;
font-family: 'Roboto';
text-align: center;
font-size: 14px;
font-weight: 200;
border-radius: 7px;
background: $lightgrey;
border: 1px solid $main;
padding: 10px;
span {
padding: 15px;
}
span:nth-child(1) {
flex: 9;
overflow-x: scroll;
}
span:nth-child(2) {
background: $darkgrey;
color: $black;
cursor: pointer;
transition: all 0.25s;
&:hover {
background: $darkestgrey;
}
}
}
}
}

21
app/components/Wallet/Wallet.js

@ -13,7 +13,8 @@ class Wallet extends Component {
super(props)
this.state = {
modalOpen: false
modalOpen: false,
qrCodeType: 1
}
}
@ -25,19 +26,29 @@ class Wallet extends Component {
newAddress
} = this.props
const { modalOpen } = this.state
const { modalOpen, qrCodeType } = this.state
const changeQrCode = () => {
const qrCodeType = this.state.qrCodeType === 1 ? 2 : 1
this.setState({ qrCodeType })
}
return (
<div className={styles.wallet}>
{
(modalOpen &&
(
modalOpen &&
<ReceiveModal
isOpen={modalOpen}
hideActivityModal={() => this.setState({ modalOpen: false })}
pubkey={info.data.identity_pubkey}
address={address}
newAddress={newAddress}
/>)
qrCodeType={qrCodeType}
changeQrCode={changeQrCode}
/>
)
}
<div className={styles.content}>
<div className={styles.left}>
@ -52,7 +63,7 @@ class Wallet extends Component {
</div>
<div className={styles.right}>
<div className={styles.rightContent}>
<div onClick={() => this.setState({ modalOpen: true })}>
<div className={'buttonPrimary'} onClick={() => this.setState({ modalOpen: true })}>
<FaQrcode />
Address
</div>

4
app/components/Wallet/Wallet.scss

@ -58,10 +58,10 @@
height: calc(100% - 50px);
div {
font-size: 20px;
padding: 10px 25px;
padding: 7px 20px;
background: $main;
transition: background 0.25s;
color: $black;
&:hover {
background: darken($main, 10%);

14
app/containers/Root.js

@ -3,9 +3,10 @@ import React from 'react'
import { Provider, connect } from 'react-redux'
import { ConnectedRouter } from 'react-router-redux'
import PropTypes from 'prop-types'
import { fetchBlockHeight, lndSelectors } from 'reducers/lnd'
import LoadingBolt from 'components/LoadingBolt'
import LndSyncing from 'components/LndSyncing'
import LoadingBolt from '../components/LoadingBolt'
import LndSyncing from '../components/LndSyncing'
import { fetchBlockHeight, lndSelectors } from '../reducers/lnd'
import Routes from '../routes'
const mapDispatchToProps = {
@ -18,11 +19,6 @@ const mapStateToProps = state => ({
syncPercentage: lndSelectors.syncPercentage(state)
})
type RootType = {
store: {},
history: {}
};
const Root = ({
store,
history,
@ -40,7 +36,7 @@ const Root = ({
/>
)
}
// Don't launch the app without gRPC connection
if (!lnd.grpcStarted) { return <LoadingBolt /> }

22
app/index.js

@ -1,27 +1,27 @@
import React from 'react';
import { render } from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import Root from './containers/Root';
import { configureStore, history } from './store/configureStore';
import './app.global.scss';
import React from 'react'
import { render } from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import Root from './containers/Root'
import { configureStore, history } from './store/configureStore'
import './app.global.scss'
const store = configureStore();
const store = configureStore()
render(
<AppContainer>
<Root store={store} history={history} />
</AppContainer>,
document.getElementById('root')
);
)
if (module.hot) {
module.hot.accept('./containers/Root', () => {
const NextRoot = require('./containers/Root'); // eslint-disable-line global-require
const NextRoot = require('./containers/Root') // eslint-disable-line global-require
render(
<AppContainer>
<NextRoot store={store} history={history} />
</AppContainer>,
document.getElementById('root')
);
});
)
})
}

2
app/lnd/config/index.js

@ -8,7 +8,7 @@ import { join } from 'path'
let loc
switch (platform()) {
case 'darwin':
loc = 'Library/Application\ Support/Lnd/tls.cert'
loc = 'Library/Application Support/Lnd/tls.cert'
break
case 'linux':
loc = '.lnd/tls.cert'

2
app/lnd/lib/lightning.js

@ -6,7 +6,7 @@ import config from '../config'
module.exports = (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.Lightning(host, credentials)

2
app/lnd/methods/paymentsController.js

@ -12,7 +12,7 @@ export function sendPaymentSync(lnd, { paymentRequest }) {
return
}
if (!data.payment_route) { reject({ error: data.payment_error }) }
if (!data || !data.payment_route) { reject({ error: data.payment_error }) }
resolve(data)
})

2
app/lnd/subscribe/transactions.js

@ -9,5 +9,5 @@ export default function subscribeToTransactions(mainWindow, lnd) {
})
call.on('end', () => console.log('end'))
call.on('error', error => console.log('error: ', error))
call.on('status', status => console.log('status: ', status))
call.on('status', status => console.log('TRANSACTION STATUS: ', status))
}

42
app/lnd/utils/index.js

@ -0,0 +1,42 @@
import zbase32 from 'zbase32'
function convertBigEndianBufferToLong(longBuffer) {
let longValue = 0
const byteArray = Buffer.from(longBuffer).swap64()
for (let i = byteArray.length - 1; i >= 0; i -= 1) {
longValue = (longValue * 256) + byteArray[i]
}
return longValue
}
export function decodeInvoice(payreq) {
const payreqBase32 = zbase32.decode(payreq)
const bufferHexRotated = Buffer.from(payreqBase32).toString('hex')
const bufferHex = bufferHexRotated.substr(bufferHexRotated.length - 1, bufferHexRotated.length)
+ bufferHexRotated.substr(0, bufferHexRotated.length - 1)
const buffer = Buffer.from(bufferHex, 'hex')
const pubkeyBuffer = buffer.slice(0, 33)
const pubkey = pubkeyBuffer.toString('hex')
const paymentHashBuffer = buffer.slice(33, 65)
const paymentHashHex = paymentHashBuffer.toString('hex')
const valueBuffer = buffer.slice(65, 73)
const amount = convertBigEndianBufferToLong(valueBuffer)
return {
payreq,
pubkey,
amount,
r_hash: paymentHashHex
}
}
export default {
decodeInvoice
}

1
app/main.dev.js

@ -165,6 +165,7 @@ export const startLnd = () => {
'--bitcoin.active',
'--bitcoin.testnet',
'--neutrino.active',
'--neutrino.connect=btcd0.lightning.computer:18333',
'--neutrino.connect=faucet.lightning.community:18333',
'--autopilot.active',
'--debuglevel=debug',

2
app/package.json

@ -15,7 +15,7 @@
},
"license": "MIT",
"dependencies": {
"grpc": "^1.6.6",
"grpc": "^1.7.3",
"ps-node": "^0.1.6",
"react-icons": "^2.2.5"
}

2
app/reducers/address.js

@ -5,7 +5,7 @@ import { ipcRenderer } from 'electron'
export const GET_ADDRESS = 'GET_ADDRESS'
export const RECEIVE_ADDRESS = 'RECEIVE_ADDRESS'
// LND expects types to be sent as int, so this object will allow mapping from string to int
// LND expects types to be sent as int, so this object will allow mapping from string to int
const addressTypes = {
p2wkh: 0,
np2wkh: 1,

19
app/reducers/channels.js

@ -165,27 +165,32 @@ export const closeChannel = ({ channel_point }) => (dispatch) => {
// TODO: Decide how to handle streamed updates for closing channels
// Receive IPC event for closeChannel
export const closeChannelSuccessful = () => (dispatch) => {
export const closeChannelSuccessful = (event, data) => (dispatch) => {
console.log('PUSH CLOSE CHANNEL SUCCESSFUL: ', data)
dispatch(fetchChannels())
}
// Receive IPC event for updated closing channel
export const pushclosechannelupdated = () => (dispatch) => {
export const pushclosechannelupdated = (event, data) => (dispatch) => {
console.log('PUSH CLOSE CHANNEL UPDATED: ', data)
dispatch(fetchChannels())
}
// Receive IPC event for closing channel end
export const pushclosechannelend = () => (dispatch) => {
export const pushclosechannelend = (event, data) => (dispatch) => {
console.log('PUSH CLOSE CHANNEL END: ', data)
dispatch(fetchChannels())
}
// Receive IPC event for closing channel error
export const pushclosechannelerror = () => (dispatch) => {
export const pushclosechannelerror = (event, data) => (dispatch) => {
console.log('PUSH CLOSE CHANNEL END: ', data)
dispatch(fetchChannels())
}
// Receive IPC event for closing channel status
export const pushclosechannelstatus = () => (dispatch) => {
export const pushclosechannelstatus = (event, data) => (dispatch) => {
console.log('PUSH CLOSE CHANNEL STATUS: ', data)
dispatch(fetchChannels())
}
@ -201,13 +206,13 @@ export const channelGraphData = (event, data) => (dispatch, getState) => {
// dispatch(fetchDescribeNetwork())
// loop through the channel updates
for (let i = 0; i < channel_updates.length; i++) {
for (let i = 0; i < channel_updates.length; i += 1) {
const channel_update = channel_updates[i]
const { advertising_node, connecting_node } = channel_update
// if our node is involved in this update we wanna show a notification
if (info.data.identity_pubkey === advertising_node || info.data.identity_pubkey === connecting_node) {
// this channel has to do with the user, lets fetch a new channel list for them
// this channel has to do with the user, lets fetch a new channel list for them
// TODO: full fetch is probably not necessary
dispatch(fetchChannels())

5
app/reducers/info.js

@ -1,7 +1,6 @@
import { createSelector } from 'reselect'
import { ipcRenderer } from 'electron'
import { fetchBalance } from './balance'
import { newAddress } from './address'
// ------------------------------------
// Constants
// ------------------------------------
@ -25,8 +24,6 @@ export const fetchInfo = () => async (dispatch) => {
// Receive IPC event for info
export const receiveInfo = (event, data) => (dispatch) => {
dispatch(fetchBalance())
dispatch(newAddress('p2pkh'))
dispatch({ type: RECEIVE_INFO, data })
}

4
app/reducers/lnd.js

@ -59,7 +59,7 @@ export const lndStdout = (event, line) => (dispatch) => {
trimmed = line.slice(line.indexOf('Catching up block hashes to height') + 'Catching up block hashes to height'.length).trim()
height = trimmed.match(/[-]{0,1}[\d.]*[\d]+/g)[0]
}
dispatch({ type: RECEIVE_LINE, lndBlockHeight: height })
}
@ -95,7 +95,7 @@ const ACTION_HANDLERS = {
[GET_BLOCK_HEIGHT]: state => ({ ...state, fetchingBlockHeight: true }),
[RECEIVE_BLOCK_HEIGHT]: (state, { blockHeight }) => ({ ...state, blockHeight, fetchingBlockHeight: false }),
[GRPC_DISCONNECTED]: state => ({ ...state, grpcStarted: false }),
[GRPC_CONNECTED]: state => ({ ...state, grpcStarted: true })
}

6
app/reducers/network.js

@ -172,9 +172,9 @@ const ACTION_HANDLERS = {
[SET_CURRENT_ROUTE]: (state, { route }) => ({ ...state, currentRoute: route }),
[SET_CURRENT_CHANNEL]: (state, { selectedChannel }) => ({ ...state, selectedChannel }),
[SET_CURRENT_TAB]: (state, { currentTab }) => ({ ...state, currentTab }),
[SET_CURRENT_PEER]: (state, { currentPeer }) => ({ ...state, currentPeer }),
[UPDATE_PAY_REQ]: (state, { pay_req }) => ({ ...state, pay_req }),
@ -280,7 +280,7 @@ const initialState = {
nodes: [],
edges: [],
selectedChannel: {},
currentTab: 1,
currentPeer: {},

2
app/reducers/peers.js

@ -124,7 +124,7 @@ const ACTION_HANDLERS = {
[GET_PEERS]: state => ({ ...state, peersLoading: true }),
[RECEIVE_PEERS]: (state, { peers }) => ({ ...state, peersLoading: false, peers }),
[UPDATE_SEARCH_QUERY]: (state, { searchQuery }) => ({ ...state, searchQuery })
}

49
app/routes/activity/components/components/Modal/Invoice/Invoice.js

@ -6,7 +6,7 @@ import 'moment-timezone'
import QRCode from 'qrcode.react'
import { MdCheck } from 'react-icons/lib/md'
import { FaCircle } from 'react-icons/lib/fa'
import CurrencyIcon from 'components/CurrencyIcon'
import { btc } from 'utils'
@ -16,20 +16,33 @@ import styles from './Invoice.scss'
const Invoice = ({ invoice, ticker, currentTicker }) => (
<div className={styles.container}>
<h3>{invoice.memo}</h3>
<h1>
<CurrencyIcon currency={ticker.currency} crypto={ticker.crypto} styles={{ verticalAlign: 'top' }} />
<span className={styles.value}>
{
ticker.currency === 'usd' ?
btc.satoshisToUsd(invoice.value, currentTicker.price_usd)
:
btc.satoshisToBtc(invoice.value)
}
</span>
</h1>
<div className={styles.settled}>
{
!invoice.settled &&
<p>
<FaCircle />
<span>Not Paid</span>
</p>
}
</div>
<header>
<h3>{invoice.memo}</h3>
<h1>
<span className={styles.value}>
{
ticker.currency === 'usd' ?
btc.satoshisToUsd(invoice.value, currentTicker.price_usd)
:
btc.satoshisToBtc(invoice.value)
}
</span>
<i>BTC</i>
</h1>
</header>
<div className={styles.qrcode}>
<QRCode value={invoice.payment_request} size={200} />
<QRCode value={invoice.payment_request} size={150} />
</div>
<div className={styles.input}>
<input
readOnly
className={styles.paymentRequest}
@ -37,14 +50,6 @@ const Invoice = ({ invoice, ticker, currentTicker }) => (
defaultValue={invoice.payment_request}
/>
</div>
<div className={styles.settled}>
{
invoice.settled ?
<p><MdCheck style={{ verticalAlign: 'top' }} /> Paid</p>
:
<p>Not Paid</p>
}
</div>
<p className={styles.date}>
Created on
<Moment format='MMM Do'>{invoice.creation_date * 1000}</Moment>

79
app/routes/activity/components/components/Modal/Invoice/Invoice.scss

@ -1,72 +1,75 @@
@import '../../../../../../variables.scss';
.container {
padding: 40px;
.settled {
position: absolute;
top: 0;
padding: 10px 0 10px 40px;
color: $darkestgrey;
svg {
line-height: 20px;
font-size: 10px;
vertical-align: middle;
}
span {
font-size: 12px;
margin-left: 5px;
}
}
header {
background: $lightgrey;
padding-bottom: 20px;
}
h3 {
font-size: 24px;
font-size: 20px;
color: $black;
font-weight: bold;
text-align: center;
margin-bottom: 10px;
padding: 10px 40px;
}
h1 {
text-align: center;
color: $main;
margin: 20px 20px 60px 0;
padding: 10px 40px;
svg {
.value {
font-size: 30px;
vertical-align: top;
}
span svg[data-icon='ltc'] {
width: 30px;
height: 30px;
i {
margin-left: 2px;
vertical-align: top;
g {
transform: scale(1.75) translate(-5px, -5px);
}
}
.value {
font-size: 60px;
}
}
.qrcode {
text-align: center;
margin-top: 40px;
}
.input {
padding: 10px 40px;
.paymentRequest {
text-align: center;
font-size: 0.5vw;
margin-top: 20px;
padding: 5px;
border-radius: 5px;
font-size: 12px;
padding: 15px;
background: $lightgrey;
border: 1px solid $darkgrey;
border: 1px solid transparent;
display: block;
width: 100%;
}
}
.settled {
text-align: center;
color: $main;
text-transform: uppercase;
font-size: 20px;
margin: 30px 0;
font-weight: bold;
svg {
line-height: 20px;
width: 90%;
margin: 20px auto 0 auto;
}
}
.date {
text-align: center;
padding-bottom: 40px;
margin-top: 20px;
time {
margin-left: 3px;

13
app/routes/activity/components/components/Modal/Modal.js

@ -6,6 +6,10 @@ import Transaction from './Transaction'
import Payment from './Payment'
import Invoice from './Invoice'
import { MdClose } from 'react-icons/lib/md'
import styles from './Modal.scss'
const Modal = ({ modalType, modalProps, hideActivityModal, ticker, currentTicker }) => {
const MODAL_COMPONENTS = {
TRANSACTION: Transaction,
@ -23,7 +27,9 @@ const Modal = ({ modalType, modalProps, hideActivityModal, ticker, currentTicker
right: '0',
bottom: 'auto',
width: '40%',
margin: '50px auto'
margin: '50px auto',
borderRadius: 'none',
padding: '0'
}
}
@ -41,6 +47,11 @@ const Modal = ({ modalType, modalProps, hideActivityModal, ticker, currentTicker
parentSelector={() => document.body}
style={customStyles}
>
<div className={styles.closeContainer}>
<span onClick={() => hideActivityModal()}>
<MdClose />
</span>
</div>
<SpecificModal {...modalProps} ticker={ticker} currentTicker={currentTicker} />
</ReactModal>
)

13
app/routes/activity/components/components/Modal/Modal.scss

@ -0,0 +1,13 @@
@import '../../../../../variables.scss';
.closeContainer {
background: $lightgrey;
text-align: right;
padding: 10px;
span {
color: $darkestgrey;
font-size: 20px;
cursor: pointer;
}
}

33
app/routes/activity/components/components/Modal/Payment/Payment.js

@ -12,21 +12,30 @@ import styles from './Payment.scss'
const Payment = ({ payment, ticker, currentTicker }) => (
<div className={styles.container}>
<h3>{payment.payment_hash}</h3>
<h1>
<CurrencyIcon currency={ticker.currency} crypto={ticker.crypto} styles={{ verticalAlign: 'top' }} />
<span className={styles.value}>
{
ticker.currency === 'usd' ?
btc.satoshisToUsd(payment.value, currentTicker.price_usd)
:
btc.satoshisToBtc(payment.value)
}
</span>
</h1>
<header>
<div className={styles.title}>
<h2>Sent</h2>
<h1>
<span className={styles.value}>
{
ticker.currency === 'usd' ?
btc.satoshisToUsd(payment.value, currentTicker.price_usd)
:
btc.satoshisToBtc(payment.value)
}
</span>
<i>
BTC
</i>
</h1>
</div>
<h3>{payment.payment_hash}</h3>
</header>
<dl>
<dt>Fee</dt>
<dd>{payment.fee}</dd>
<dt>Hops</dt>
<dd>{payment.path.length}</dd>
<dt>Date</dt>
<dd>
<Moment format='MMM Do'>{payment.creation_date * 1000}</Moment>

48
app/routes/activity/components/components/Modal/Payment/Payment.scss

@ -1,38 +1,44 @@
@import '../../../../../../variables.scss';
.container {
padding: 40px;
header {
padding: 5px 40px 20px 40px;
background: $lightgrey;
.title {
display: flex;
flex-direction: row;
margin-bottom: 30px;
h2 {
text-transform: uppercase;
font-size: 24px;
margin-right: 10px;
}
}
}
h1 {
text-align: center;
color: $main;
margin: 60px 30px 60px 0;
svg {
font-size: 30px;
vertical-align: top;
.value {
font-size: 24px;
}
span svg[data-icon='ltc'] {
width: 30px;
height: 30px;
i {
margin-left: 2px;
vertical-align: top;
g {
transform: scale(1.75) translate(-5px, -5px);
}
}
.value {
font-size: 80px;
}
}
h3 {
font-size: 14px;
text-align: center;
color: $black;
font-weight: bold;
color: $darkestgrey;
}
dl {
padding: 40px 40px 40px 40px;
}
dt {
@ -48,8 +54,8 @@
dd {
text-align: right;
font-weight: 400;
padding: 19px 0;
padding: 30px 0 10px 0;
margin-left: 0;
border-top: 1px solid $darkgrey;
border-bottom: 1px solid $darkgrey;
}
}

54
app/routes/activity/components/components/Modal/Transaction/Transaction.js

@ -1,3 +1,4 @@
import { shell } from 'electron'
import React from 'react'
import PropTypes from 'prop-types'
@ -12,31 +13,42 @@ import styles from './Transaction.scss'
const Transaction = ({ transaction, ticker, currentTicker }) => (
<div className={styles.container}>
<h2>
{
transaction.amount < 0 ?
'Sent'
:
'Received'
}
</h2>
<h3>{transaction.tx_hash}</h3>
<h1>
<CurrencyIcon currency={ticker.currency} crypto={ticker.crypto} styles={{ verticalAlign: 'top' }} />
<span className={styles.value}>
{
ticker.currency === 'usd' ?
btc.satoshisToUsd(transaction.amount, currentTicker.price_usd)
:
btc.satoshisToBtc(transaction.amount)
}
</span>
</h1>
<header>
<div className={styles.title}>
<h2>
{
transaction.amount < 0 ?
'Sent'
:
'Received'
}
</h2>
<h1>
<span className={styles.value}>
{
ticker.currency === 'usd' ?
btc.satoshisToUsd(transaction.amount, currentTicker.price_usd)
:
btc.satoshisToBtc(transaction.amount)
}
</span>
<i>BTC</i>
</h1>
</div>
<h3 onClick={() => shell.openExternal(`https://testnet.smartbit.com.au/tx/${transaction.tx_hash}`)}>{transaction.tx_hash}</h3>
</header>
<dl>
<dt>Confirmations</dt>
<dd>{transaction.num_confirmations}</dd>
<dt>Fee</dt>
<dd>{transaction.total_fees}</dd>
<dd>
{
ticker.currency === 'usd' ?
btc.satoshisToUsd(transaction.total_fees)
:
btc.satoshisToBtc(transaction.total_fees)
}
</dd>
<dt>Date</dt>
<dd>
<Moment format='MMM Do'>{transaction.time_stamp * 1000}</Moment>

53
app/routes/activity/components/components/Modal/Transaction/Transaction.scss

@ -1,48 +1,57 @@
@import '../../../../../../variables.scss';
.container {
padding: 40px;
header {
padding: 5px 40px 20px 40px;
background: $lightgrey;
.title {
display: flex;
flex-direction: row;
h2 {
text-transform: uppercase;
}
}
}
h1 {
text-align: center;
color: $main;
margin: 60px 30px 60px 0;
svg {
font-size: 30px;
vertical-align: top;
.value {
font-size: 24px;
}
span svg[data-icon='ltc'] {
width: 30px;
height: 30px;
i {
margin-left: 2px;
vertical-align: top;
g {
transform: scale(1.75) translate(-5px, -5px);
}
}
.value {
font-size: 75px;
}
}
h3 {
font-size: 14px;
text-align: center;
color: $black;
font-weight: bold;
color: $darkestgrey;
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
h2 {
text-align: center;
margin-right: 10px;
margin-bottom: 30px;
text-transform: uppercase;
letter-spacing: 1.5px;
font-size: 24px;
}
dl {
padding: 40px 40px 40px 40px;
}
dt {
text-align: left;
float: left;
@ -56,8 +65,8 @@
dd {
text-align: right;
font-weight: 400;
padding: 19px 0;
padding: 30px 0 10px 0;
margin-left: 0;
border-top: 1px solid $darkgrey;
border-bottom: 1px solid $darkgrey;
}
}
}

2
app/routes/app/components/App.js

@ -13,7 +13,7 @@ class App extends Component {
fetchTicker()
fetchInfo()
newAddress('p2pkh')
newAddress('np2wkh')
}
render() {

10
app/routes/channels/components/Channels.js

@ -22,7 +22,7 @@ class Channels extends Component {
componentWillMount() {
const { fetchChannels, fetchPeers } = this.props
fetchChannels()
fetchPeers()
}
@ -64,7 +64,7 @@ class Channels extends Component {
fetchChannels()
// wait for the svg to appear as child
const svgTimeout = setTimeout(() => {
const svgTimeout = setTimeout(() => {
if (icon[0].tagName === 'svg') {
// spin icon for 1 sec
icon[0].style.animation = 'spin 1000ms linear 1'
@ -73,7 +73,7 @@ class Channels extends Component {
}, 1)
// clear animation after the second so we can reuse it
const refreshTimeout = setTimeout(() => {
const refreshTimeout = setTimeout(() => {
icon[0].style.animation = ''
this.setState({ refreshing: false })
clearTimeout(refreshTimeout)
@ -96,7 +96,7 @@ class Channels extends Component {
</div>
</div>
</header>
<div className={styles.search}>
<label className={`${styles.label} ${styles.input}`} htmlFor='channelSearch'>
<MdSearch />
@ -187,7 +187,7 @@ Channels.propTypes = {
channels: PropTypes.object.isRequired,
currentChannels: PropTypes.array.isRequired,
nonActiveFilters: PropTypes.array.isRequired,
updateChannelSearchQuery: PropTypes.func.isRequired,
setCurrentChannel: PropTypes.func.isRequired,
openChannelForm: PropTypes.func.isRequired,

2
app/routes/peers/components/Peers.js

@ -24,7 +24,7 @@ class Peers extends Component {
}
render() {
const {
const {
fetchPeers,
peerFormProps,
setPeerForm,

34
app/store/configureStore.dev.js

@ -6,31 +6,31 @@ import { createLogger } from 'redux-logger'
import rootReducer from '../reducers'
import ipc from '../reducers/ipc'
const history = createHashHistory();
const history = createHashHistory()
const configureStore = (initialState?: counterStateType) => {
// Redux Configuration
const middleware = [];
const enhancers = [];
const middleware = []
const enhancers = []
// Thunk Middleware
middleware.push(thunk);
middleware.push(thunk)
// Logging Middleware
const logger = createLogger({
level: 'info',
collapsed: true
});
middleware.push(logger);
})
middleware.push(logger)
// Router Middleware
const router = routerMiddleware(history);
middleware.push(router);
const router = routerMiddleware(history)
middleware.push(router)
// Redux DevTools Configuration
const actionCreators = {
...routerActions
};
}
// If Redux DevTools Extension is installed use it, otherwise use Redux compose
/* eslint-disable no-underscore-dangle */
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
@ -38,23 +38,23 @@ const configureStore = (initialState?: counterStateType) => {
// Options: http://zalmoxisus.github.io/redux-devtools-extension/API/Arguments.html
actionCreators
})
: compose;
: compose
/* eslint-enable no-underscore-dangle */
// Apply Middleware & Compose Enhancers
enhancers.push(applyMiddleware(...middleware, ipc));
const enhancer = composeEnhancers(...enhancers);
enhancers.push(applyMiddleware(...middleware, ipc))
const enhancer = composeEnhancers(...enhancers)
// Create Store
const store = createStore(rootReducer, initialState, enhancer);
const store = createStore(rootReducer, initialState, enhancer)
if (module.hot) {
module.hot.accept('../reducers', () =>
store.replaceReducer(require('../reducers')) // eslint-disable-line global-require
);
)
}
return store;
};
return store
}
export default { configureStore, history };
export default { configureStore, history }

4
app/store/configureStore.js

@ -1,6 +1,6 @@
// @flow
if (process.env.NODE_ENV === 'production') {
module.exports = require('./configureStore.prod'); // eslint-disable-line global-require
module.exports = require('./configureStore.prod') // eslint-disable-line global-require
} else {
module.exports = require('./configureStore.dev'); // eslint-disable-line global-require
module.exports = require('./configureStore.dev') // eslint-disable-line global-require
}

35
app/yarn.lock

@ -190,6 +190,10 @@ delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
detect-libc@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
ecc-jsbn@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
@ -289,15 +293,15 @@ graceful-fs@^4.1.2:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
grpc@^1.6.6:
version "1.6.6"
resolved "https://registry.yarnpkg.com/grpc/-/grpc-1.6.6.tgz#2051784f6bd6134681fa2c4b5e75dc82c6c23ffa"
grpc@^1.7.3:
version "1.7.3"
resolved "https://registry.yarnpkg.com/grpc/-/grpc-1.7.3.tgz#c9d034324e2ec8a06cfaa577a044a116f96c8c90"
dependencies:
arguejs "^0.2.3"
lodash "^4.17.4"
nan "^2.7.0"
node-pre-gyp "^0.6.38"
protobufjs "^5.0.2"
lodash "^4.15.0"
nan "^2.0.0"
node-pre-gyp "^0.6.39"
protobufjs "^5.0.0"
har-schema@^1.0.5:
version "1.0.5"
@ -428,7 +432,7 @@ lcid@^1.0.0:
dependencies:
invert-kv "^1.0.0"
lodash@^4.17.4:
lodash@^4.15.0:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
@ -476,9 +480,9 @@ ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
nan@^2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.7.0.tgz#d95bf721ec877e08db276ed3fc6eb78f9083ad46"
nan@^2.0.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a"
node-fetch@^1.0.1:
version "1.7.2"
@ -487,10 +491,11 @@ node-fetch@^1.0.1:
encoding "^0.1.11"
is-stream "^1.0.1"
node-pre-gyp@^0.6.38:
version "0.6.38"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.38.tgz#e92a20f83416415bb4086f6d1fb78b3da73d113d"
node-pre-gyp@^0.6.39:
version "0.6.39"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649"
dependencies:
detect-libc "^1.0.2"
hawk "3.1.3"
mkdirp "^0.5.1"
nopt "^4.0.1"
@ -585,7 +590,7 @@ prop-types@15.5.8:
dependencies:
fbjs "^0.8.9"
protobufjs@^5.0.2:
protobufjs@^5.0.0:
version "5.0.2"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-5.0.2.tgz#59748d7dcf03d2db22c13da9feb024e16ab80c91"
dependencies:

2
internals/mocks/fileMock.js

@ -1 +1 @@
export default 'test-file-stub';
export default 'test-file-stub'

16
internals/scripts/CheckBuiltsExist.js

@ -1,24 +1,24 @@
// @flow
// Check if the renderer and main bundles are built
import path from 'path';
import chalk from 'chalk';
import fs from 'fs';
import path from 'path'
import chalk from 'chalk'
import fs from 'fs'
function CheckBuildsExist() {
const mainPath = path.join(__dirname, '..', '..', 'app', 'main.prod.js');
const rendererPath = path.join(__dirname, '..', '..', 'app', 'dist', 'renderer.prod.js');
const mainPath = path.join(__dirname, '..', '..', 'app', 'main.prod.js')
const rendererPath = path.join(__dirname, '..', '..', 'app', 'dist', 'renderer.prod.js')
if (!fs.existsSync(mainPath)) {
throw new Error(chalk.whiteBright.bgRed.bold(
'The main process is not built yet. Build it by running "npm run build-main"'
));
))
}
if (!fs.existsSync(rendererPath)) {
throw new Error(chalk.whiteBright.bgRed.bold(
'The renderer process is not built yet. Build it by running "npm run build-renderer"'
));
))
}
}
CheckBuildsExist();
CheckBuildsExist()

8
internals/scripts/CheckNodeEnv.js

@ -1,17 +1,17 @@
// @flow
import chalk from 'chalk';
import chalk from 'chalk'
export default function CheckNodeEnv(expectedEnv: string) {
if (!expectedEnv) {
throw new Error('"expectedEnv" not set');
throw new Error('"expectedEnv" not set')
}
if (process.env.NODE_ENV !== expectedEnv) {
/* eslint-disable */
console.log(chalk.whiteBright.bgRed.bold(
`"process.env.NODE_ENV" must be "${expectedEnv}" to use this webpack config`
));
))
/* eslint-enable */
process.exit(2);
process.exit(2)
}
}

2
package.json

@ -143,7 +143,7 @@
"css-loader": "^0.28.3",
"electron": "^1.6.10",
"electron-builder": "^19.8.0",
"electron-devtools-installer": "^2.2.0",
"electron-devtools-installer": "^2.2.1",
"enzyme": "^2.9.1",
"enzyme-to-json": "^1.5.1",
"eslint": "^4.4.1",

BIN
resources/bin/darwin/lnd

Binary file not shown.

3
test/components/Nav.spec.js

@ -21,9 +21,8 @@ describe('default elements', () => {
it('should render nav links', () => {
expect(el.find(NavLink).at(0).props().to).toBe('/')
expect(el.find(NavLink).at(1).props().to).toBe('/wallet')
expect(el.find(NavLink).at(1).props().to).toBe('/peers')
expect(el.find(NavLink).at(2).props().to).toBe('/channels')
expect(el.find(NavLink).at(3).props().to).toBe('/settings')
})
it('should render buttons', () => {
expect(el.find('.button').at(0).text()).toContain('Pay')

6
test/example.js

@ -1,5 +1,5 @@
describe('description', () => {
it('should have description', () => {
expect(1 + 2).toBe(3);
});
});
expect(1 + 2).toBe(3)
})
})

11
test/reducers/__snapshots__/peers.spec.js.snap

@ -12,6 +12,7 @@ Object {
},
"peers": Array [],
"peersLoading": false,
"searchQuery": "",
}
`;
@ -27,6 +28,7 @@ Object {
},
"peers": Array [],
"peersLoading": false,
"searchQuery": "",
}
`;
@ -44,6 +46,7 @@ Object {
"foo",
],
"peersLoading": false,
"searchQuery": "",
}
`;
@ -59,6 +62,7 @@ Object {
},
"peers": Array [],
"peersLoading": false,
"searchQuery": "",
}
`;
@ -74,6 +78,7 @@ Object {
},
"peers": Array [],
"peersLoading": false,
"searchQuery": "",
}
`;
@ -89,6 +94,7 @@ Object {
},
"peers": Array [],
"peersLoading": false,
"searchQuery": "",
}
`;
@ -104,6 +110,7 @@ Object {
},
"peers": Array [],
"peersLoading": true,
"searchQuery": "",
}
`;
@ -119,6 +126,7 @@ Object {
},
"peers": "foo",
"peersLoading": false,
"searchQuery": "",
}
`;
@ -134,6 +142,7 @@ Object {
},
"peers": Array [],
"peersLoading": false,
"searchQuery": "",
}
`;
@ -152,6 +161,7 @@ Object {
},
"peers": Array [],
"peersLoading": false,
"searchQuery": "",
}
`;
@ -167,5 +177,6 @@ Object {
},
"peers": Array [],
"peersLoading": false,
"searchQuery": "",
}
`;

12
test/runTests.js

@ -1,11 +1,11 @@
const spawn = require('cross-spawn');
const path = require('path');
const spawn = require('cross-spawn')
const path = require('path')
const s = `\\${path.sep}`;
const s = `\\${path.sep}`
const pattern = process.argv[2] === 'e2e'
? `test${s}e2e${s}.+\\.spec\\.js`
: `test${s}(?!e2e${s})[^${s}]+${s}.+\\.spec\\.js$`;
: `test${s}(?!e2e${s})[^${s}]+${s}.+\\.spec\\.js$`
const result = spawn.sync(path.normalize('./node_modules/.bin/jest'), [pattern], { stdio: 'inherit' });
const result = spawn.sync(path.normalize('./node_modules/.bin/jest'), [pattern], { stdio: 'inherit' })
process.exit(result.status);
process.exit(result.status)

6
webpack.config.base.js

@ -2,9 +2,9 @@
* Base webpack config used across other specific configs
*/
import path from 'path';
import webpack from 'webpack';
import { dependencies as externals } from './app/package.json';
import path from 'path'
import webpack from 'webpack'
import { dependencies as externals } from './app/package.json'
export default {
externals: Object.keys(externals || {}),

4
webpack.config.eslint.js

@ -1,3 +1,3 @@
require('babel-register');
require('babel-register')
module.exports = require('./webpack.config.renderer.dev');
module.exports = require('./webpack.config.renderer.dev')

16
webpack.config.main.prod.js

@ -2,14 +2,14 @@
* Webpack config for production electron main process
*/
import webpack from 'webpack';
import merge from 'webpack-merge';
import BabiliPlugin from 'babili-webpack-plugin';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
import baseConfig from './webpack.config.base';
import CheckNodeEnv from './internals/scripts/CheckNodeEnv';
import webpack from 'webpack'
import merge from 'webpack-merge'
import BabiliPlugin from 'babili-webpack-plugin'
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
import baseConfig from './webpack.config.base'
import CheckNodeEnv from './internals/scripts/CheckNodeEnv'
CheckNodeEnv('production');
CheckNodeEnv('production')
export default merge.smart(baseConfig, {
devtool: 'source-map',
@ -59,4 +59,4 @@ export default merge.smart(baseConfig, {
__dirname: false,
__filename: false
}
});
})

18
webpack.config.renderer.dev.dll.js

@ -2,16 +2,16 @@
* Builds the DLL for development electron renderer process
*/
import webpack from 'webpack';
import path from 'path';
import merge from 'webpack-merge';
import baseConfig from './webpack.config.base';
import { dependencies } from './package.json';
import CheckNodeEnv from './internals/scripts/CheckNodeEnv';
import webpack from 'webpack'
import path from 'path'
import merge from 'webpack-merge'
import baseConfig from './webpack.config.base'
import { dependencies } from './package.json'
import CheckNodeEnv from './internals/scripts/CheckNodeEnv'
CheckNodeEnv('development');
CheckNodeEnv('development')
const dist = path.resolve(process.cwd(), 'dll');
const dist = path.resolve(process.cwd(), 'dll')
export default merge.smart(baseConfig, {
context: process.cwd(),
@ -205,4 +205,4 @@ export default merge.smart(baseConfig, {
}
})
]
});
})

20
webpack.config.renderer.prod.js

@ -2,16 +2,16 @@
* Build config for electron renderer process
*/
import path from 'path';
import webpack from 'webpack';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
import merge from 'webpack-merge';
import BabiliPlugin from 'babili-webpack-plugin';
import baseConfig from './webpack.config.base';
import CheckNodeEnv from './internals/scripts/CheckNodeEnv';
import path from 'path'
import webpack from 'webpack'
import ExtractTextPlugin from 'extract-text-webpack-plugin'
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
import merge from 'webpack-merge'
import BabiliPlugin from 'babili-webpack-plugin'
import baseConfig from './webpack.config.base'
import CheckNodeEnv from './internals/scripts/CheckNodeEnv'
CheckNodeEnv('production');
CheckNodeEnv('production')
export default merge.smart(baseConfig, {
devtool: 'source-map',
@ -165,4 +165,4 @@ export default merge.smart(baseConfig, {
openAnalyzer: process.env.OPEN_ANALYZER === 'true'
})
]
});
})

6
yarn.lock

@ -3137,9 +3137,9 @@ electron-debug@^1.2.0:
electron-is-dev "^0.1.0"
electron-localshortcut "^2.0.0"
electron-devtools-installer@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/electron-devtools-installer/-/electron-devtools-installer-2.2.0.tgz#9813e6811afcd69ddca3cae5416db72ea7ecfb6a"
electron-devtools-installer@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/electron-devtools-installer/-/electron-devtools-installer-2.2.1.tgz#0beb73ccbf65cbc4d09e706cebda638f839b8c55"
dependencies:
"7zip" "0.0.6"
cross-unzip "0.0.2"

Loading…
Cancel
Save