From 11789181ef37cae3da4d3a2fb533cb4f7cf808b3 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Sun, 9 Feb 2020 18:55:11 +0100 Subject: [PATCH 01/16] feat: update lnd to v0.9.0-beta-2-gba4483f6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aeb8d8a1742..e71c63dae66 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ }, "config": { "lnd-binary": { - "binaryVersion": "0.8.0-beta-2-gb95a0a0f", + "binaryVersion": "0.9.0-beta-2-gba4483f6", "binarySite": "https://github.com/LN-Zap/lnd/releases/download" } }, From 2779a18bf762b9682ee905cb5569093de2b0f3d6 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Tue, 3 Mar 2020 09:36:07 +0100 Subject: [PATCH 02/16] chore: add additional lnd tags to release script --- scripts/lnd-release/.goreleaser.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/lnd-release/.goreleaser.yml b/scripts/lnd-release/.goreleaser.yml index 9442f1b0d7e..3f083c0cf63 100644 --- a/scripts/lnd-release/.goreleaser.yml +++ b/scripts/lnd-release/.goreleaser.yml @@ -11,7 +11,7 @@ builds: ldflags: - -X github.com/lightningnetwork/lnd/build.Commit={{.Tag}} flags: - - -tags=experimental autopilotrpc signrpc walletrpc chainrpc invoicesrpc routerrpc + - -tags=experimental monitoring autopilotrpc chainrpc invoicesrpc routerrpc signrpc walletrpc watchtowerrpc wtclientrpc - id: lncli goos: - linux @@ -24,7 +24,7 @@ builds: ldflags: - -X github.com/lightningnetwork/lnd/build.Commit={{.Tag}} flags: - - -tags=experimental autopilotrpc signrpc walletrpc chainrpc invoicesrpc routerrpc + - -tags=experimental monitoring autopilotrpc chainrpc invoicesrpc routerrpc signrpc walletrpc watchtowerrpc wtclientrpc archives: - name_template: '{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}{{ .Arm }}-v{{ .Version }}' format: tar.gz From f58de7302a5179a97009ae350f7cdeebe947a52e Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Tue, 3 Mar 2020 09:46:46 +0100 Subject: [PATCH 03/16] feat: update lnd to v0.9.1-beta-2-g64bd2e59 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e71c63dae66..9ee51224c3a 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ }, "config": { "lnd-binary": { - "binaryVersion": "0.9.0-beta-2-gba4483f6", + "binaryVersion": "0.9.1-beta-2-g64bd2e59", "binarySite": "https://github.com/LN-Zap/lnd/releases/download" } }, From 8621eb68cae14ef53dfea8047f1033c4c860f52f Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Wed, 4 Mar 2020 15:37:13 +0100 Subject: [PATCH 04/16] feat(wallet): basic keysend support fix #3333 fix #3338 --- .../components/Form/LightningInvoiceInput.js | 10 +-- renderer/components/Pay/Pay.js | 67 +++++++++++------ renderer/components/Pay/PayAddressField.js | 10 +-- renderer/components/Pay/PayPanelBody.js | 10 ++- renderer/components/Pay/PayPanelFooter.js | 25 +++++-- renderer/components/Pay/PayPanelHeader.js | 7 +- renderer/components/Pay/PaySummary.js | 12 +++- .../components/Pay/PaySummaryLightning.js | 37 +++++++--- renderer/components/Request/RequestSummary.js | 2 +- renderer/reducers/payment.js | 71 +++++++++++++------ services/grpc/lightning.methods.js | 1 + .../components/Pay/PayAddressField.spec.js | 6 +- .../components/Pay/PayPanelHeader.spec.js | 2 +- .../PayAddressField.spec.js.snap | 12 ++-- .../PaySummaryLightning.spec.js.snap | 2 +- test/unit/utils/crypto.spec.js | 12 ++-- utils/crypto.js | 18 ++++- 17 files changed, 207 insertions(+), 97 deletions(-) diff --git a/renderer/components/Form/LightningInvoiceInput.js b/renderer/components/Form/LightningInvoiceInput.js index 1ad4b7aa49e..e989520c7c3 100644 --- a/renderer/components/Form/LightningInvoiceInput.js +++ b/renderer/components/Form/LightningInvoiceInput.js @@ -2,7 +2,7 @@ import React, { useCallback } from 'react' import PropTypes from 'prop-types' import { FormattedMessage, useIntl } from 'react-intl' import { useFieldState } from 'informed' -import { isOnchain, isLn, decodePayReq } from '@zap/utils/crypto' +import { isOnchain, isBolt11, isPubkey, decodePayReq } from '@zap/utils/crypto' import { Message } from 'components/UI' import TextArea from './TextArea' import messages from './messages' @@ -20,7 +20,7 @@ const validate = (intl, network, chain, value) => { { chain: chainName } ) // If we have a LN invoice, ensure the invoice has an amount. - if (isLn(value, chain, network)) { + if (isBolt11(value, chain, network)) { try { const invoice = decodePayReq(value) if (!invoice) { @@ -33,7 +33,7 @@ const validate = (intl, network, chain, value) => { } catch (e) { return invalidRequestMessage } - } else if (!isOnchain(value, chain, network)) { + } else if (!isOnchain(value, chain, network) && !isPubkey(value)) { return invalidRequestMessage } } @@ -45,7 +45,7 @@ const LightningInvoiceInput = props => { const intl = useIntl() const fieldState = useFieldState(field) const { value } = fieldState - let chainName = isLn(value, chain, network) ? 'lightning' : chain + let chainName = isBolt11(value, chain, network) || isPubkey(value) ? 'lightning' : chain if (network !== 'mainnet') { chainName += ` (${network})` } @@ -62,7 +62,7 @@ const LightningInvoiceInput = props => { {value && !fieldState.error && ( { - const { isLn, isOnchain, invoice } = this.state + const { isBolt11, isPubkey, isOnchain, invoice } = this.state let steps = [PAY_FORM_STEPS.address] - if (isLn) { + if (isBolt11) { // If we have an invoice and the invoice has an amount, this is a 2 step form. if (invoice && (invoice.satoshis || invoice.millisatoshis)) { steps.push(PAY_FORM_STEPS.summary) @@ -270,7 +284,7 @@ class Pay extends React.Component { else { steps = [PAY_FORM_STEPS.address, PAY_FORM_STEPS.amount, PAY_FORM_STEPS.summary] } - } else if (isOnchain) { + } else if (isOnchain || isPubkey) { steps = [PAY_FORM_STEPS.address, PAY_FORM_STEPS.amount, PAY_FORM_STEPS.summary] } return steps @@ -301,7 +315,7 @@ class Pay extends React.Component { } /** - * handlePayReqChange - Set isLn/isOnchain state based on payReq value. + * handlePayReqChange - Set isBolt11/isOnchain/isPubkey state based on payReq value. * * @param {string} payReq Payment request */ @@ -309,20 +323,21 @@ class Pay extends React.Component { const { chain, network } = this.props const state = { currentStep: PAY_FORM_STEPS.address, - isLn: null, + isBolt11: null, + isPubkey: null, isOnchain: null, invoice: null, } // See if the user has entered a valid lightning payment request. - if (isLn(payReq, chain, network)) { + if (isBolt11(payReq, chain, network)) { try { const invoice = decodePayReq(payReq) state.invoice = invoice } catch (e) { return } - state.isLn = true + state.isBolt11 = true } // Otherwise, see if we have a valid onchain address. @@ -330,12 +345,17 @@ class Pay extends React.Component { state.isOnchain = true } + // Or a valid pubkey. + else if (isPubkey(payReq)) { + state.isPubkey = true + } + // Update the state with our findings. this.setState(state) } render() { - const { currentStep, invoice, isLn, isOnchain, previousStep } = this.state + const { currentStep, invoice, isBolt11, isOnchain, isPubkey, previousStep } = this.state const { chain, chainName, @@ -374,8 +394,9 @@ class Pay extends React.Component { @@ -393,8 +414,9 @@ class Pay extends React.Component { initialAmountFiat={initialAmountFiat} intl={intl} invoice={invoice} - isLn={isLn} + isBolt11={isBolt11} isOnchain={isOnchain} + isPubkey={isPubkey} isQueryingFees={isQueryingFees} lndTargetConfirmations={lndTargetConfirmations} network={network} @@ -415,9 +437,10 @@ class Pay extends React.Component { currentStep={currentStep} formState={formState} invoice={invoice} - isLn={isLn} + isBolt11={isBolt11} isOnchain={isOnchain} isProcessing={isProcessing} + isPubkey={isPubkey} maxOneTimeSend={maxOneTimeSend} previousStep={this.goToPreviousStep} walletBalanceConfirmed={walletBalanceConfirmed} diff --git a/renderer/components/Pay/PayAddressField.js b/renderer/components/Pay/PayAddressField.js index 884473681b5..d35281006b2 100644 --- a/renderer/components/Pay/PayAddressField.js +++ b/renderer/components/Pay/PayAddressField.js @@ -27,7 +27,7 @@ class PayAddressField extends React.Component { formState: PropTypes.object, handlePayReqChange: PropTypes.func.isRequired, intl: intlShape.isRequired, - isLn: PropTypes.bool, + isBolt11: PropTypes.bool, network: PropTypes.string.isRequired, redirectPayReq: PropTypes.object, } @@ -48,11 +48,11 @@ class PayAddressField extends React.Component { } getPaymentRequestLabel = () => { - const { currentStep, isLn } = this.props + const { currentStep, isBolt11 } = this.props let payReqLabel = 'request_label_onchain' if (currentStep === PAY_FORM_STEPS.address) { payReqLabel = 'request_label_combined' - } else if (isLn) { + } else if (isBolt11) { payReqLabel = 'request_label_offchain' } @@ -66,11 +66,11 @@ class PayAddressField extends React.Component { currentStep, formState, handlePayReqChange, - isLn, + isBolt11, network, redirectPayReq, } = this.props - const addressFieldState = currentStep === PAY_FORM_STEPS.address || isLn ? 'big' : 'small' + const addressFieldState = currentStep === PAY_FORM_STEPS.address || isBolt11 ? 'big' : 'small' const { payReq } = formState.values const { submits } = formState diff --git a/renderer/components/Pay/PayPanelBody.js b/renderer/components/Pay/PayPanelBody.js index de806c82a88..0297c3fda9a 100644 --- a/renderer/components/Pay/PayPanelBody.js +++ b/renderer/components/Pay/PayPanelBody.js @@ -21,8 +21,9 @@ const PayPanelBody = props => { initialAmountFiat, intl, invoice, - isLn, + isBolt11, isOnchain, + isPubkey, isQueryingFees, lndTargetConfirmations, network, @@ -49,7 +50,7 @@ const PayPanelBody = props => { formApi={formState} handlePayReqChange={handlePayReqChange} intl={intl} - isLn={isLn} + isBolt11={isBolt11} network={network} redirectPayReq={redirectPayReq} /> @@ -62,6 +63,7 @@ const PayPanelBody = props => { intl={intl} invoice={invoice} isOnchain={isOnchain} + isPubkey={isPubkey} isQueryingFees={isQueryingFees} lndTargetConfirmations={lndTargetConfirmations} onchainFees={onchainFees} @@ -73,6 +75,7 @@ const PayPanelBody = props => { currentStep={currentStep} formApi={formApi} isOnchain={isOnchain} + isPubkey={isPubkey} lndTargetConfirmations={lndTargetConfirmations} onchainFees={onchainFees} routes={routes} @@ -95,8 +98,9 @@ PayPanelBody.propTypes = { initialAmountFiat: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), intl: intlShape.isRequired, invoice: PropTypes.object, - isLn: PropTypes.bool, + isBolt11: PropTypes.bool, isOnchain: PropTypes.bool, + isPubkey: PropTypes.bool, isQueryingFees: PropTypes.bool, lndTargetConfirmations: PropTypes.shape({ fast: PropTypes.number.isRequired, diff --git a/renderer/components/Pay/PayPanelFooter.js b/renderer/components/Pay/PayPanelFooter.js index fde951009d6..9f15fdb375e 100644 --- a/renderer/components/Pay/PayPanelFooter.js +++ b/renderer/components/Pay/PayPanelFooter.js @@ -12,11 +12,19 @@ import { PAY_FORM_STEPS } from './constants' const isEnoughFunds = props => { // convert entered amount to satoshis - const { amountInSats, channelBalance, invoice, isLn, isOnchain, walletBalanceConfirmed } = props + const { + amountInSats, + channelBalance, + invoice, + isBolt11, + isOnchain, + isPubkey, + walletBalanceConfirmed, + } = props // Determine whether we have enough funds available. let hasEnoughFunds = true - if (isLn && invoice) { + if ((isBolt11 && invoice) || isPubkey) { hasEnoughFunds = amountInSats <= channelBalance } else if (isOnchain) { hasEnoughFunds = amountInSats <= walletBalanceConfirmed @@ -58,8 +66,9 @@ const PayPanelFooter = props => { cryptoUnitName, currentStep, formState, - isLn, + isBolt11, isOnchain, + isPubkey, isProcessing, previousStep, walletBalanceConfirmed, @@ -67,14 +76,14 @@ const PayPanelFooter = props => { } = props const renderLiquidityWarning = props => { - const { currentStep, maxOneTimeSend, cryptoUnit, isLn, amountInSats } = props + const { currentStep, maxOneTimeSend, cryptoUnit, isBolt11, isPubkey, amountInSats } = props if (currentStep !== PAY_FORM_STEPS.summary) { return null } const isNotEnoughFunds = !isEnoughFunds(props) - const isAboveMax = isLn && amountInSats > maxOneTimeSend + const isAboveMax = (isBolt11 || isPubkey) && amountInSats > maxOneTimeSend const formattedMax = intl.formatNumber(convert('sats', cryptoUnit, maxOneTimeSend), { maximumFractionDigits: 8, }) @@ -100,7 +109,8 @@ const PayPanelFooter = props => { // Determine which buttons should be visible. const hasBackButton = currentStep !== PAY_FORM_STEPS.address - const hasSubmitButton = currentStep !== PAY_FORM_STEPS.address || isOnchain || isLn + const hasSubmitButton = + currentStep !== PAY_FORM_STEPS.address || isOnchain || isBolt11 || isPubkey return ( @@ -157,9 +167,10 @@ PayPanelFooter.propTypes = { formState: PropTypes.object.isRequired, intl: intlShape.isRequired, invoice: PropTypes.object, - isLn: PropTypes.bool, + isBolt11: PropTypes.bool, isOnchain: PropTypes.bool, isProcessing: PropTypes.bool, + isPubkey: PropTypes.bool, maxOneTimeSend: PropTypes.string.isRequired, previousStep: PropTypes.func.isRequired, walletBalanceConfirmed: PropTypes.string.isRequired, diff --git a/renderer/components/Pay/PayPanelHeader.js b/renderer/components/Pay/PayPanelHeader.js index 140feb265b5..207fdcde064 100644 --- a/renderer/components/Pay/PayPanelHeader.js +++ b/renderer/components/Pay/PayPanelHeader.js @@ -7,9 +7,9 @@ import messages from './messages' import { PAY_HEADER_TYPES } from './constants' const PayPanelHeader = props => { - const { chainName, cryptoUnitName, isLn, isOnchain } = props + const { chainName, cryptoUnitName, isBolt11, isOnchain, isPubkey } = props let headerType = null - if (isLn) { + if (isBolt11 || isPubkey) { headerType = PAY_HEADER_TYPES.offchain } else if (isOnchain) { headerType = PAY_HEADER_TYPES.onchain @@ -33,8 +33,9 @@ const PayPanelHeader = props => { PayPanelHeader.propTypes = { chainName: PropTypes.string.isRequired, cryptoUnitName: PropTypes.string.isRequired, - isLn: PropTypes.bool, + isBolt11: PropTypes.bool, isOnchain: PropTypes.bool, + isPubkey: PropTypes.bool, } export default PayPanelHeader diff --git a/renderer/components/Pay/PaySummary.js b/renderer/components/Pay/PaySummary.js index 7ca72240dfa..0727d3f8584 100644 --- a/renderer/components/Pay/PaySummary.js +++ b/renderer/components/Pay/PaySummary.js @@ -8,7 +8,15 @@ import { PAY_FORM_STEPS } from './constants' import { getFeeRate } from './utils' const PaySummary = props => { - const { amountInSats, formApi, isOnchain, lndTargetConfirmations, onchainFees, routes } = props + const { + amountInSats, + formApi, + isOnchain, + isPubkey, + lndTargetConfirmations, + onchainFees, + routes, + } = props const formState = formApi.getState() const { speed, payReq, isCoinSweep } = formState.values @@ -29,6 +37,7 @@ const PaySummary = props => { return ( = 0 && maxFee < 1) { + if (CoinBig(maxFee).gte(0) && CoinBig(maxFee).lt(1)) { feeMessage = messages.fee_less_than_1 } // Otherwise, if we have both a min and max fee that are different, present the fee range. @@ -87,6 +98,10 @@ class PaySummaryLightning extends React.Component { feeMessage = messages.fee_upto } + const totalAmountInSatoshis = hasMaxFee + ? CoinBig.sum(amountInSatoshis, maxFee).toString() + : amountInSatoshis + return ( @@ -140,7 +155,7 @@ class PaySummaryLightning extends React.Component { right={ - + } /> diff --git a/renderer/components/Request/RequestSummary.js b/renderer/components/Request/RequestSummary.js index b53a6d12a9c..dc184bc0d72 100644 --- a/renderer/components/Request/RequestSummary.js +++ b/renderer/components/Request/RequestSummary.js @@ -12,7 +12,7 @@ import { intlShape } from '@zap/i18n' import messages from './messages' const RequestSummary = ({ invoice = {}, payReq, intl, showNotification, ...rest }) => { - const decodedInvoice = useMemo(() => decodePayReq(payReq), [payReq]) + const decodedInvoice = useMemo(() => (payReq ? decodePayReq(payReq) : {}), [payReq]) const [isExpired, setIsExpired] = useState(false) const [expiryDelta, setExpiryDelta] = useState( decodedInvoice.timeExpireDate - getUnixTime() / 1000 diff --git a/renderer/reducers/payment.js b/renderer/reducers/payment.js index b9a4eba1777..25de79e58cd 100644 --- a/renderer/reducers/payment.js +++ b/renderer/reducers/payment.js @@ -1,11 +1,12 @@ import config from 'config' +import { randomBytes, createHash } from 'crypto' import { createSelector } from 'reselect' import uniqBy from 'lodash/uniqBy' import find from 'lodash/find' import createReducer from '@zap/utils/createReducer' import errorToUserFriendly from '@zap/utils/userFriendlyErrors' import { getIntl } from '@zap/i18n' -import { decodePayReq, getNodeAlias, getTag } from '@zap/utils/crypto' +import { decodePayReq, getNodeAlias, getTag, isPubkey } from '@zap/utils/crypto' import { convert } from '@zap/utils/btc' import delay from '@zap/utils/delay' import genId from '@zap/utils/genId' @@ -115,10 +116,7 @@ export function getPayments() { * @returns {Function} Thunk */ export const sendPayment = data => dispatch => { - const invoice = decodePayReq(data.paymentRequest) - const paymentHash = getTag(invoice, 'payment_hash') - - if (!paymentHash) { + if (!data.paymentHash) { dispatch(showError(getIntl().formatMessage(messages.payment_send_error))) return } @@ -128,7 +126,7 @@ export const sendPayment = data => dispatch => { status: PAYMENT_STATUS_SENDING, isSending: true, creation_date: Math.round(new Date() / 1000), - payment_hash: paymentHash, + payment_hash: data.paymentHash, } dispatch({ @@ -188,38 +186,71 @@ export const payInvoice = ({ retries = 0, originalPaymentId, }) => async dispatch => { - let paymentId = originalPaymentId + let paymentHash + const paymentId = originalPaymentId || genId() + const isKeysend = isPubkey(payReq) + + let payload = { + paymentId, + amt, + fee_limit: { fixed: feeLimit }, + allow_self_payment: true, + } - // If we already have an id then this is a retry. Decrease the retry count. - if (originalPaymentId) { - dispatch(decPaymentRetry(originalPaymentId)) + // Keysend payment. + if (isKeysend) { + const defaultCltvDelta = 43 + const keySendPreimageType = '5482373484' + const preimageByteLength = 32 + const preimage = randomBytes(preimageByteLength) + const secret = preimage.toString('hex') + paymentHash = createHash('sha256') + .update(preimage) + .digest() + + payload = { + ...payload, + payment_hash: paymentHash, + final_cltv_delta: defaultCltvDelta, + dest: Buffer.from(payReq, 'hex'), + dest_custom_records: { + [keySendPreimageType]: Buffer.from(secret, 'hex'), + }, + } } - // Otherwise, add to paymentsSending in the state. + // Bolt11 invoice payent. else { - // Generate a unique id for the payment that we will use to track the payment across retry attempts. - paymentId = genId() + const invoice = decodePayReq(payReq) + paymentHash = getTag(invoice, 'payment_hash') + payload = { + ...payload, + payment_request: payReq, + } + } + + // If we already have an id then this is a retry. Decrease the retry count. + // Otherwise, add to paymentsSending in the state. + if (originalPaymentId) { + dispatch(decPaymentRetry(originalPaymentId)) + } else { dispatch( sendPayment({ paymentId, - paymentRequest: payReq, + paymentHash, feeLimit, value: amt, remainingRetries: retries, maxRetries: retries, + isKeysend, }) ) } // Submit the payment to LND. try { - const data = await grpc.services.Lightning.sendPayment({ - paymentId, - payment_request: payReq, - amt, - fee_limit: { fixed: feeLimit }, - }) + const data = await grpc.services.Lightning.sendPayment(payload) dispatch(paymentSuccessful(data)) } catch (e) { const { details: data, message: error } = e diff --git a/services/grpc/lightning.methods.js b/services/grpc/lightning.methods.js index 035229ba6eb..33b89fb1fe3 100644 --- a/services/grpc/lightning.methods.js +++ b/services/grpc/lightning.methods.js @@ -268,6 +268,7 @@ async function sendPayment(payload = {}) { return new Promise((resolve, reject) => { try { + logGrpcCmd('Lightning.sendPayment', payload) const call = this.service.sendPayment(payload) call.on('data', data => { diff --git a/test/unit/components/Pay/PayAddressField.spec.js b/test/unit/components/Pay/PayAddressField.spec.js index 6af3d1fa49f..5098f8b1bef 100644 --- a/test/unit/components/Pay/PayAddressField.spec.js +++ b/test/unit/components/Pay/PayAddressField.spec.js @@ -8,7 +8,7 @@ const props = { chain: 'Bitcoin', handlePayReqChange: () => {}, intl: {}, - isLn: null, + isBolt11: null, network: 'testnet', redirectPayReq: {}, formState: { values: {}, submits: 0 }, @@ -26,7 +26,7 @@ describe('component.Pay.PayAddressField', () => { describe('and it is an LN transaction', () => { it('should render correctly', () => { const wrapper = shallow( - + ) expect(toJSON(wrapper)).toMatchSnapshot() }) @@ -35,7 +35,7 @@ describe('component.Pay.PayAddressField', () => { describe('and it is an on-chain transaction', () => { it('should render correctly', () => { const wrapper = shallow( - + ) expect(toJSON(wrapper)).toMatchSnapshot() }) diff --git a/test/unit/components/Pay/PayPanelHeader.spec.js b/test/unit/components/Pay/PayPanelHeader.spec.js index b41cfd9081b..b17247c12ab 100644 --- a/test/unit/components/Pay/PayPanelHeader.spec.js +++ b/test/unit/components/Pay/PayPanelHeader.spec.js @@ -11,7 +11,7 @@ const props = { describe('component.Pay.PayPanelHeader', () => { describe('is an LN transaction', () => { it('should render correctly', () => { - const wrapper = shallow() + const wrapper = shallow() expect(toJSON(wrapper)).toMatchSnapshot() }) }) diff --git a/test/unit/components/Pay/__snapshots__/PayAddressField.spec.js.snap b/test/unit/components/Pay/__snapshots__/PayAddressField.spec.js.snap index e656d9acfb0..8ba7f4eba53 100644 --- a/test/unit/components/Pay/__snapshots__/PayAddressField.spec.js.snap +++ b/test/unit/components/Pay/__snapshots__/PayAddressField.spec.js.snap @@ -22,7 +22,7 @@ exports[`component.Pay.PayAddressField current step is "address" should render c }, "handlePayReqChange": [Function], "intl": Object {}, - "isLn": null, + "isBolt11": null, "network": "testnet", "redirectPayReq": Object {}, }, @@ -61,7 +61,7 @@ exports[`component.Pay.PayAddressField current step is "address" should render c } handlePayReqChange={[Function]} intl={Object {}} - isLn={null} + isBolt11={null} network="testnet" redirectPayReq={Object {}} />, @@ -118,7 +118,7 @@ exports[`component.Pay.PayAddressField current step is "summary" and it is an LN }, "handlePayReqChange": [Function], "intl": Object {}, - "isLn": true, + "isBolt11": true, "network": "testnet", "redirectPayReq": Object {}, }, @@ -157,7 +157,7 @@ exports[`component.Pay.PayAddressField current step is "summary" and it is an LN } handlePayReqChange={[Function]} intl={Object {}} - isLn={true} + isBolt11={true} network="testnet" redirectPayReq={Object {}} />, @@ -214,7 +214,7 @@ exports[`component.Pay.PayAddressField current step is "summary" and it is an on }, "handlePayReqChange": [Function], "intl": Object {}, - "isLn": false, + "isBolt11": false, "network": "testnet", "redirectPayReq": Object {}, }, @@ -253,7 +253,7 @@ exports[`component.Pay.PayAddressField current step is "summary" and it is an on } handlePayReqChange={[Function]} intl={Object {}} - isLn={false} + isBolt11={false} network="testnet" redirectPayReq={Object {}} />, diff --git a/test/unit/components/Pay/__snapshots__/PaySummaryLightning.spec.js.snap b/test/unit/components/Pay/__snapshots__/PaySummaryLightning.spec.js.snap index 5622abeeda8..f0757142e6b 100644 --- a/test/unit/components/Pay/__snapshots__/PaySummaryLightning.spec.js.snap +++ b/test/unit/components/Pay/__snapshots__/PaySummaryLightning.spec.js.snap @@ -138,7 +138,7 @@ exports[`component.Form.PaySummaryLightning should render correctly 1`] = ` mr={2} /> } diff --git a/test/unit/utils/crypto.spec.js b/test/unit/utils/crypto.spec.js index 080da04eb81..3af55e46137 100644 --- a/test/unit/utils/crypto.spec.js +++ b/test/unit/utils/crypto.spec.js @@ -1,7 +1,7 @@ /* eslint-disable max-len */ import { formatValue, - isLn, + isBolt11, isOnchain, getMinFee, getMaxFee, @@ -13,22 +13,22 @@ const VALID_BITCOIN_MAINNET_LN = const VALID_BITCOIN_TESTNET_LN = 'lntb10u1pdue0gxpp5uljstna5aenp3yku3ft4wn8y63qfqdgqfh4cqqxz8z58undqp8hqdqqcqzysxqyz5vqqwaeuuh0fy52tqx6rrq6kya4lwm6v523wyqe9nesd5a3mszcq7j4e9mv8rd2vhmp7ycxswtktvs8gqq8lu5awjwfevnvfc4rzp8fmacpp4h27e' -describe('Crypto.isLn', () => { +describe('Crypto.isBolt11', () => { describe('Bitcoin', () => { describe('Mainnet', () => { it('should pass with a valid invoice ', () => { - expect(isLn(VALID_BITCOIN_MAINNET_LN, 'bitcoin', 'mainnet')).toBeTruthy() + expect(isBolt11(VALID_BITCOIN_MAINNET_LN, 'bitcoin', 'mainnet')).toBeTruthy() }) it('should fail with an invalid invoice ', () => { - expect(isLn(VALID_BITCOIN_TESTNET_LN, 'bitcoin', 'mainnet')).toBeFalsy() + expect(isBolt11(VALID_BITCOIN_TESTNET_LN, 'bitcoin', 'mainnet')).toBeFalsy() }) }) describe('Testnet', () => { it('should pass with a valid invoice', () => { - expect(isLn(VALID_BITCOIN_TESTNET_LN, 'bitcoin', 'testnet')).toBeTruthy() + expect(isBolt11(VALID_BITCOIN_TESTNET_LN, 'bitcoin', 'testnet')).toBeTruthy() }) it('should fail with an invalid invoice ', () => { - expect(isLn(VALID_BITCOIN_MAINNET_LN, 'bitcoin', 'testnet')).toBeFalsy() + expect(isBolt11(VALID_BITCOIN_MAINNET_LN, 'bitcoin', 'testnet')).toBeFalsy() }) }) }) diff --git a/utils/crypto.js b/utils/crypto.js index 3d713eb62a7..aa09455d0ea 100644 --- a/utils/crypto.js +++ b/utils/crypto.js @@ -142,14 +142,14 @@ export const isOnchain = (input, chain, network) => { } /** - * isLn - Test to see if a string is a valid lightning address. + * isBolt11 - Test to see if a string is a valid lightning address. * * @param {string} input Value to check * @param {string} chain Chain name * @param {string} network Network name * @returns {boolean} Boolean indicating whether the address is a lightning address */ -export const isLn = (input, chain = 'bitcoin', network = 'mainnet') => { +export const isBolt11 = (input, chain = 'bitcoin', network = 'mainnet') => { if (!input || typeof input !== 'string') { return false } @@ -164,6 +164,20 @@ export const isLn = (input, chain = 'bitcoin', network = 'mainnet') => { } } +/** + * isPubkey - Test to see if a string is a valid pubkey. + * + * @param {string} input Value to check + * @returns {boolean} Boolean indicating whether the address is a pubkey + */ +export const isPubkey = input => { + if (!input || typeof input !== 'string') { + return false + } + const isHex = /^[0-9a-fA-F]+$/.test(input) + return isHex && input.length === 66 +} + /** * getNodeAlias - Get a nodes alias. * From fa894ba4e0e4f9a700089b256b6088149b84ec97 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Fri, 20 Mar 2020 10:14:19 +0100 Subject: [PATCH 05/16] fix(wallet): handle amounts as bignumber --- renderer/components/Pay/PayPanelFooter.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/renderer/components/Pay/PayPanelFooter.js b/renderer/components/Pay/PayPanelFooter.js index 9f15fdb375e..8bd1fe0120c 100644 --- a/renderer/components/Pay/PayPanelFooter.js +++ b/renderer/components/Pay/PayPanelFooter.js @@ -2,6 +2,7 @@ import React from 'react' import PropTypes from 'prop-types' import { Flex } from 'rebass/styled-components' import { FormattedMessage, injectIntl } from 'react-intl' +import { CoinBig } from '@zap/utils/coin' import { intlShape } from '@zap/i18n' import { convert } from '@zap/utils/btc' import { CryptoValue } from 'containers/UI' @@ -25,9 +26,9 @@ const isEnoughFunds = props => { // Determine whether we have enough funds available. let hasEnoughFunds = true if ((isBolt11 && invoice) || isPubkey) { - hasEnoughFunds = amountInSats <= channelBalance + hasEnoughFunds = CoinBig(amountInSats).lte(CoinBig(channelBalance)) } else if (isOnchain) { - hasEnoughFunds = amountInSats <= walletBalanceConfirmed + hasEnoughFunds = CoinBig(amountInSats).lte(CoinBig(walletBalanceConfirmed)) } return hasEnoughFunds @@ -83,7 +84,7 @@ const PayPanelFooter = props => { } const isNotEnoughFunds = !isEnoughFunds(props) - const isAboveMax = (isBolt11 || isPubkey) && amountInSats > maxOneTimeSend + const isAboveMax = (isBolt11 || isPubkey) && CoinBig(amountInSats).gt(CoinBig(maxOneTimeSend)) const formattedMax = intl.formatNumber(convert('sats', cryptoUnit, maxOneTimeSend), { maximumFractionDigits: 8, }) From 557204897a6fe1ecc66abdaad0e496023812b0c5 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Sun, 22 Mar 2020 10:29:22 +0100 Subject: [PATCH 06/16] fix(ui): display destination when sending keysend payments --- renderer/reducers/payment.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/renderer/reducers/payment.js b/renderer/reducers/payment.js index 25de79e58cd..712be6061a7 100644 --- a/renderer/reducers/payment.js +++ b/renderer/reducers/payment.js @@ -186,9 +186,10 @@ export const payInvoice = ({ retries = 0, originalPaymentId, }) => async dispatch => { - let paymentHash const paymentId = originalPaymentId || genId() const isKeysend = isPubkey(payReq) + let pubkey + let paymentHash let payload = { paymentId, @@ -202,11 +203,12 @@ export const payInvoice = ({ const defaultCltvDelta = 43 const keySendPreimageType = '5482373484' const preimageByteLength = 32 + const preimage = randomBytes(preimageByteLength) - const secret = preimage.toString('hex') paymentHash = createHash('sha256') .update(preimage) .digest() + pubkey = payReq payload = { ...payload, @@ -214,7 +216,7 @@ export const payInvoice = ({ final_cltv_delta: defaultCltvDelta, dest: Buffer.from(payReq, 'hex'), dest_custom_records: { - [keySendPreimageType]: Buffer.from(secret, 'hex'), + [keySendPreimageType]: preimage, }, } } @@ -223,10 +225,11 @@ export const payInvoice = ({ else { const invoice = decodePayReq(payReq) paymentHash = getTag(invoice, 'payment_hash') + pubkey = invoice.payeeNodeKey payload = { ...payload, - payment_request: payReq, + payment_request: invoice.payeeNodeKey, } } @@ -237,8 +240,9 @@ export const payInvoice = ({ } else { dispatch( sendPayment({ - paymentId, + path: [pubkey], paymentHash, + paymentId, feeLimit, value: amt, remainingRetries: retries, From 21306101cfef1c1ac891257c8febc1009969294a Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Sun, 22 Mar 2020 17:06:36 +0100 Subject: [PATCH 07/16] fix(ui): improve keysend receive message --- renderer/reducers/invoice.js | 4 +++- renderer/reducers/messages/messages.js | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/renderer/reducers/invoice.js b/renderer/reducers/invoice.js index 08c628d51ce..26217ebc1b2 100644 --- a/renderer/reducers/invoice.js +++ b/renderer/reducers/invoice.js @@ -229,7 +229,9 @@ export const receiveInvoiceData = invoice => dispatch => { const intl = getIntl() // HTML 5 desktop notification for the invoice update const notifTitle = intl.formatMessage(messages.invoice_receive_title) - const notifBody = intl.formatMessage(messages.invoice_receive_body) + const notifBody = intl.formatMessage( + invoice.is_keysend ? messages.keysend_receive_body : messages.invoice_receive_body + ) showSystemNotification(notifTitle, { body: notifBody }) } diff --git a/renderer/reducers/messages/messages.js b/renderer/reducers/messages/messages.js index 234f1818340..ae1c1a77a6c 100644 --- a/renderer/reducers/messages/messages.js +++ b/renderer/reducers/messages/messages.js @@ -16,6 +16,7 @@ export default defineMessages({ channels_open_warning: 'Channel opening initiated', invoice_receive_title: `You've been Zapped`, invoice_receive_body: 'Congrats, someone just paid an invoice of yours', + keysend_receive_body: 'Congrats, someone just paid you', app_init_db_error: 'Unable to initialize database: {error}', transaction_received_title: 'On-chain Transaction Received!', transaction_received_body: `Lucky you, you just received a new on-chain transaction. I'm jealous.`, From c2982f382764719126c4072afe40350ba25771e4 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Sun, 22 Mar 2020 17:07:02 +0100 Subject: [PATCH 08/16] chore(i18n): extract new translation strings --- translations/af-ZA.json | 1 + translations/ar-SA.json | 1 + translations/bg-BG.json | 1 + translations/ca-ES.json | 1 + translations/cs-CZ.json | 1 + translations/da-DK.json | 1 + translations/de-DE.json | 1 + translations/el-GR.json | 1 + translations/en.json | 1 + translations/es-ES.json | 1 + translations/fi-FI.json | 1 + translations/fr-FR.json | 1 + translations/ga-IE.json | 1 + translations/he-IL.json | 1 + translations/hi-IN.json | 1 + translations/hr-HR.json | 1 + translations/hu-HU.json | 1 + translations/it-IT.json | 1 + translations/ja-JP.json | 1 + translations/ko-KR.json | 1 + translations/nl-NL.json | 1 + translations/no-NO.json | 1 + translations/pl-PL.json | 1 + translations/pt-BR.json | 1 + translations/pt-PT.json | 1 + translations/ro-RO.json | 1 + translations/ru-RU.json | 1 + translations/sr-SP.json | 1 + translations/sv-SE.json | 1 + translations/tr-TR.json | 1 + translations/uk-UA.json | 1 + translations/vi-VN.json | 1 + translations/zh-CN.json | 1 + translations/zh-TW.json | 1 + 34 files changed, 34 insertions(+) diff --git a/translations/af-ZA.json b/translations/af-ZA.json index 4371406c081..4d6db43c01f 100644 --- a/translations/af-ZA.json +++ b/translations/af-ZA.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/ar-SA.json b/translations/ar-SA.json index d9f85e66c1e..50b02bd7cc2 100644 --- a/translations/ar-SA.json +++ b/translations/ar-SA.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/bg-BG.json b/translations/bg-BG.json index 443e6e4594c..58b60949603 100644 --- a/translations/bg-BG.json +++ b/translations/bg-BG.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/ca-ES.json b/translations/ca-ES.json index 4371406c081..4d6db43c01f 100644 --- a/translations/ca-ES.json +++ b/translations/ca-ES.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/cs-CZ.json b/translations/cs-CZ.json index 75cb8c796df..536e98607c8 100644 --- a/translations/cs-CZ.json +++ b/translations/cs-CZ.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "Otevření kanálu bylo zahájeno", "reducers.messages.invoice_receive_body": "Gratulujeme, někdo právě zaplatil vaši fakturu", "reducers.messages.invoice_receive_title": "Byl jsi Zappován", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "Visa kdo? Jste nyní svým vlastním zpracovatelem plateb!", "reducers.messages.neutrtino_synced_title": "Lightning uzel synchronizován", "reducers.messages.pay_lnurl_withdraw_error": "Nelze zpracovat žádost o výběr z {service}: {reason}", diff --git a/translations/da-DK.json b/translations/da-DK.json index c97b80d4778..7d4dcb5f52f 100644 --- a/translations/da-DK.json +++ b/translations/da-DK.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/de-DE.json b/translations/de-DE.json index 96f7158be1c..b2dd9b4908c 100644 --- a/translations/de-DE.json +++ b/translations/de-DE.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "Kanalöffnung gestartet", "reducers.messages.invoice_receive_body": "Gratuliere, jemand hat eine deiner Zahlungsanfragen bezahlt", "reducers.messages.invoice_receive_title": "Du wurdest geZappt", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "Visa wer? Du bist jetzt dein eigener Zahlungsabwickler!", "reducers.messages.neutrtino_synced_title": "Lightning Node synchronisiert", "reducers.messages.pay_lnurl_withdraw_error": "Abhebungsanfrage von {service} konnte nicht verarbeitet werden: {reason}", diff --git a/translations/el-GR.json b/translations/el-GR.json index 0ef71129601..861d065c8ab 100644 --- a/translations/el-GR.json +++ b/translations/el-GR.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/en.json b/translations/en.json index 45f35533850..63747ac0e0f 100644 --- a/translations/en.json +++ b/translations/en.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "Channel opening initiated", "reducers.messages.invoice_receive_body": "Congrats, someone just paid an invoice of yours", "reducers.messages.invoice_receive_title": "You've been Zapped", + "reducers.messages.keysend_receive_body": "Congrats, someone just paid you", "reducers.messages.neutrtino_synced_body": "Visa who? You're your own payment processor now!", "reducers.messages.neutrtino_synced_title": "Lightning Node Synced", "reducers.messages.pay_lnurl_withdraw_error": "Unable to process withdraw request from {service}: {reason}", diff --git a/translations/es-ES.json b/translations/es-ES.json index 395f29e13d3..27e35590e83 100644 --- a/translations/es-ES.json +++ b/translations/es-ES.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "Iniciando apertura de canal", "reducers.messages.invoice_receive_body": "Felicidades, alguien acaba de pagar una de tus facturas", "reducers.messages.invoice_receive_title": "Has sido Zapeado", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "Visa ni que Visa? Ahora tu mismo eres tu propio procesador de pago!", "reducers.messages.neutrtino_synced_title": "Nodo de Lightning Sincronizado", "reducers.messages.pay_lnurl_withdraw_error": "No se puede procesar la solicitud de retiro de {service}: {reason}", diff --git a/translations/fi-FI.json b/translations/fi-FI.json index 4371406c081..4d6db43c01f 100644 --- a/translations/fi-FI.json +++ b/translations/fi-FI.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/fr-FR.json b/translations/fr-FR.json index 832d33e85fd..0638aa89bfb 100644 --- a/translations/fr-FR.json +++ b/translations/fr-FR.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "Ouverture du canal initiée", "reducers.messages.invoice_receive_body": "Félicitations ! Quelqu'un vient de payer votre demande", "reducers.messages.invoice_receive_title": "Zap ! Vous avez été foudroyé", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "Visa, vous dites ? Vous êtes désormais votre propre système de paiement !", "reducers.messages.neutrtino_synced_title": "Nœud Lightning synchronisé", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/ga-IE.json b/translations/ga-IE.json index dba4cd7f758..507b93941f9 100644 --- a/translations/ga-IE.json +++ b/translations/ga-IE.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/he-IL.json b/translations/he-IL.json index 02b82fda58c..2d3c88ed5fd 100644 --- a/translations/he-IL.json +++ b/translations/he-IL.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/hi-IN.json b/translations/hi-IN.json index 98fdc6f1a90..164e1eef931 100644 --- a/translations/hi-IN.json +++ b/translations/hi-IN.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/hr-HR.json b/translations/hr-HR.json index 68dba9e7ecd..2b495ea1ef8 100644 --- a/translations/hr-HR.json +++ b/translations/hr-HR.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/hu-HU.json b/translations/hu-HU.json index 4371406c081..4d6db43c01f 100644 --- a/translations/hu-HU.json +++ b/translations/hu-HU.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/it-IT.json b/translations/it-IT.json index c38c72ae598..15a9535f3e9 100644 --- a/translations/it-IT.json +++ b/translations/it-IT.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/ja-JP.json b/translations/ja-JP.json index b4ce40baeaf..e9755974d61 100644 --- a/translations/ja-JP.json +++ b/translations/ja-JP.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/ko-KR.json b/translations/ko-KR.json index 4371406c081..4d6db43c01f 100644 --- a/translations/ko-KR.json +++ b/translations/ko-KR.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/nl-NL.json b/translations/nl-NL.json index 5135f61a7fd..3e6f249bf70 100644 --- a/translations/nl-NL.json +++ b/translations/nl-NL.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/no-NO.json b/translations/no-NO.json index caed34b3140..9c1dde35d92 100644 --- a/translations/no-NO.json +++ b/translations/no-NO.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/pl-PL.json b/translations/pl-PL.json index 1ea14ebc928..d07b5b90998 100644 --- a/translations/pl-PL.json +++ b/translations/pl-PL.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/pt-BR.json b/translations/pt-BR.json index 64876b5b9b2..c3af4fe5a1f 100644 --- a/translations/pt-BR.json +++ b/translations/pt-BR.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/pt-PT.json b/translations/pt-PT.json index c0d919a8983..9c44969e6f1 100644 --- a/translations/pt-PT.json +++ b/translations/pt-PT.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/ro-RO.json b/translations/ro-RO.json index c24431b0242..0784ad6e24c 100644 --- a/translations/ro-RO.json +++ b/translations/ro-RO.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/ru-RU.json b/translations/ru-RU.json index 1d63573adac..38c65eae384 100644 --- a/translations/ru-RU.json +++ b/translations/ru-RU.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/sr-SP.json b/translations/sr-SP.json index 4371406c081..4d6db43c01f 100644 --- a/translations/sr-SP.json +++ b/translations/sr-SP.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/sv-SE.json b/translations/sv-SE.json index 45b0cdf383e..95eb701aa3b 100644 --- a/translations/sv-SE.json +++ b/translations/sv-SE.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/tr-TR.json b/translations/tr-TR.json index 5d66362c04c..b7b96614f8c 100644 --- a/translations/tr-TR.json +++ b/translations/tr-TR.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/uk-UA.json b/translations/uk-UA.json index ad72f135d32..5551b1482db 100644 --- a/translations/uk-UA.json +++ b/translations/uk-UA.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/vi-VN.json b/translations/vi-VN.json index 4371406c081..4d6db43c01f 100644 --- a/translations/vi-VN.json +++ b/translations/vi-VN.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/zh-CN.json b/translations/zh-CN.json index 84273ae46fc..3b8b37ef347 100644 --- a/translations/zh-CN.json +++ b/translations/zh-CN.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", diff --git a/translations/zh-TW.json b/translations/zh-TW.json index dc75334fdf4..0d938f81ab0 100644 --- a/translations/zh-TW.json +++ b/translations/zh-TW.json @@ -660,6 +660,7 @@ "reducers.messages.channels_open_warning": "", "reducers.messages.invoice_receive_body": "", "reducers.messages.invoice_receive_title": "", + "reducers.messages.keysend_receive_body": "", "reducers.messages.neutrtino_synced_body": "", "reducers.messages.neutrtino_synced_title": "", "reducers.messages.pay_lnurl_withdraw_error": "", From 954b77c4f7c85d3bd53d7d12fce142c2b053e552 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Sun, 22 Mar 2020 18:12:05 +0100 Subject: [PATCH 09/16] feat(lnd): enable keysend for neutrino clients --- services/neutrino/neutrino.js | 1 + 1 file changed, 1 insertion(+) diff --git a/services/neutrino/neutrino.js b/services/neutrino/neutrino.js index 6c05a8812bb..d16246fb111 100644 --- a/services/neutrino/neutrino.js +++ b/services/neutrino/neutrino.js @@ -299,6 +299,7 @@ class Neutrino extends EventEmitter { `--rpclisten=${this.lndConfig.host}`, `--listen=${listen}`, `--restlisten=${restlisten}`, + '--accept-keysend', `${this.lndConfig.assumechanvalid ? '--routing.assumechanvalid' : ''}`, `${this.lndConfig.alias ? `--alias=${this.lndConfig.alias}` : ''}`, ...autopilotArgs, From 2e11bc53e2285e6b91f6e876fc1aea60147118ff Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Tue, 24 Mar 2020 10:52:01 +0100 Subject: [PATCH 10/16] fix(ui): do not show qr code for keysend payments --- renderer/components/Request/RequestSummary.js | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/renderer/components/Request/RequestSummary.js b/renderer/components/Request/RequestSummary.js index dc184bc0d72..42d6f6f3490 100644 --- a/renderer/components/Request/RequestSummary.js +++ b/renderer/components/Request/RequestSummary.js @@ -92,31 +92,33 @@ const RequestSummary = ({ invoice = {}, payReq, intl, showNotification, ...rest - - - - + {payReq && ( + + + + + + + + } + right={ + + - - - } - right={ - - - - } - /> + } + /> + )} @@ -162,8 +164,8 @@ const RequestSummary = ({ invoice = {}, payReq, intl, showNotification, ...rest RequestSummary.propTypes = { intl: intlShape.isRequired, - invoice: PropTypes.object, - payReq: PropTypes.string.isRequired, + invoice: PropTypes.object.isRequired, + payReq: PropTypes.string, showNotification: PropTypes.func.isRequired, } From 1690f91816b25ddc3673d0faedb85e408cc1227f Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Tue, 24 Mar 2020 10:59:12 +0100 Subject: [PATCH 11/16] feat(ui): add note to request summary for keysend payments --- renderer/components/Request/RequestSummary.js | 58 ++++++++++--------- renderer/components/Request/messages.js | 1 + 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/renderer/components/Request/RequestSummary.js b/renderer/components/Request/RequestSummary.js index 42d6f6f3490..83335b6d887 100644 --- a/renderer/components/Request/RequestSummary.js +++ b/renderer/components/Request/RequestSummary.js @@ -92,33 +92,39 @@ const RequestSummary = ({ invoice = {}, payReq, intl, showNotification, ...rest - {payReq && ( - - - - - - - - } - right={ - + + + {payReq && ( + <> + + + + + + )} + + } + right={ + + {payReq ? ( - - } - /> - )} + ) : ( + + )} + + } + /> diff --git a/renderer/components/Request/messages.js b/renderer/components/Request/messages.js index d3a7e978785..6502f4ed855 100644 --- a/renderer/components/Request/messages.js +++ b/renderer/components/Request/messages.js @@ -10,6 +10,7 @@ export default defineMessages({ address_copied_notification_title: 'Address copied', address_copied_notification_description: 'Payment request has been copied to your clipboard', payment_request: 'Payment request', + payment_request_keysend: 'Received via pubkey (keysend)', total: 'Total', memo: 'Memo', fallback_address: 'Fallback address', From 8d356c5dffecb5075a48e7598fe607a99ad7f5fe Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Tue, 24 Mar 2020 11:14:27 +0100 Subject: [PATCH 12/16] feat(ui): add node pubkey into send address field label --- renderer/components/Pay/PayAddressField.js | 11 ++++++++--- renderer/components/Pay/PayPanelBody.js | 2 ++ renderer/components/Pay/messages.js | 3 ++- translations/en.json | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/renderer/components/Pay/PayAddressField.js b/renderer/components/Pay/PayAddressField.js index d35281006b2..1b65bbe8e93 100644 --- a/renderer/components/Pay/PayAddressField.js +++ b/renderer/components/Pay/PayAddressField.js @@ -28,6 +28,7 @@ class PayAddressField extends React.Component { handlePayReqChange: PropTypes.func.isRequired, intl: intlShape.isRequired, isBolt11: PropTypes.bool, + isPubkey: PropTypes.bool, network: PropTypes.string.isRequired, redirectPayReq: PropTypes.object, } @@ -48,16 +49,20 @@ class PayAddressField extends React.Component { } getPaymentRequestLabel = () => { - const { currentStep, isBolt11 } = this.props - let payReqLabel = 'request_label_onchain' + const { currentStep, isPubkey, isBolt11 } = this.props + let payReqLabel if (currentStep === PAY_FORM_STEPS.address) { payReqLabel = 'request_label_combined' + } else if (isPubkey) { + payReqLabel = 'request_label_pubkey' } else if (isBolt11) { payReqLabel = 'request_label_offchain' + } else { + payReqLabel = 'request_label_onchain' } const { intl } = this.props - return intl.formatMessage({ ...messages[payReqLabel] }) + return payReqLabel && intl.formatMessage({ ...messages[payReqLabel] }) } render() { diff --git a/renderer/components/Pay/PayPanelBody.js b/renderer/components/Pay/PayPanelBody.js index 0297c3fda9a..2645480faed 100644 --- a/renderer/components/Pay/PayPanelBody.js +++ b/renderer/components/Pay/PayPanelBody.js @@ -51,6 +51,8 @@ const PayPanelBody = props => { handlePayReqChange={handlePayReqChange} intl={intl} isBolt11={isBolt11} + isOnchain={isOnchain} + isPubkey={isPubkey} network={network} redirectPayReq={redirectPayReq} /> diff --git a/renderer/components/Pay/messages.js b/renderer/components/Pay/messages.js index a38a2d1c86d..bc3c0c51f96 100644 --- a/renderer/components/Pay/messages.js +++ b/renderer/components/Pay/messages.js @@ -5,9 +5,10 @@ export default defineMessages({ calculating: 'calculating…', current_balance: 'Your current confirmed balance:', error_not_enough_funds: 'You do not have enough funds available to make this payment.', - request_label_combined: 'Payment Request or Address', + request_label_combined: 'Payment Request, Address, or Node Pubkey', request_label_offchain: 'Payment Request', request_label_onchain: 'Address', + request_label_pubkey: 'Node Pubkey', searching_routes: 'searching for routes…', subtitle_onchain: 'On-Chain Payment', subtitle_offchain: 'Lightning Payment', diff --git a/translations/en.json b/translations/en.json index 63747ac0e0f..1e4c9aad315 100644 --- a/translations/en.json +++ b/translations/en.json @@ -449,7 +449,7 @@ "components.Pay.next": "Next", "components.Pay.next_block_confirmation": "next block confirmation", "components.Pay.onchain_balance": "{amount} {cryptoUnitName} (onchain)", - "components.Pay.request_label_combined": "Payment Request or Address", + "components.Pay.request_label_combined": "Payment Request, Address, or Node Pubkey", "components.Pay.request_label_offchain": "Payment Request", "components.Pay.request_label_onchain": "Address", "components.Pay.searching_routes": "searching for routes…", From 72ead23ac92733ca356a5b0bd0f73f25bc34b8ee Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Tue, 24 Mar 2020 10:59:31 +0100 Subject: [PATCH 13/16] chore(i18n): extract new translation strings --- translations/af-ZA.json | 2 ++ translations/ar-SA.json | 2 ++ translations/bg-BG.json | 2 ++ translations/ca-ES.json | 2 ++ translations/cs-CZ.json | 2 ++ translations/da-DK.json | 2 ++ translations/de-DE.json | 2 ++ translations/el-GR.json | 2 ++ translations/en.json | 2 ++ translations/es-ES.json | 2 ++ translations/fi-FI.json | 2 ++ translations/fr-FR.json | 2 ++ translations/ga-IE.json | 2 ++ translations/he-IL.json | 2 ++ translations/hi-IN.json | 2 ++ translations/hr-HR.json | 2 ++ translations/hu-HU.json | 2 ++ translations/it-IT.json | 2 ++ translations/ja-JP.json | 2 ++ translations/ko-KR.json | 2 ++ translations/nl-NL.json | 2 ++ translations/no-NO.json | 2 ++ translations/pl-PL.json | 2 ++ translations/pt-BR.json | 2 ++ translations/pt-PT.json | 2 ++ translations/ro-RO.json | 2 ++ translations/ru-RU.json | 2 ++ translations/sr-SP.json | 2 ++ translations/sv-SE.json | 2 ++ translations/tr-TR.json | 2 ++ translations/uk-UA.json | 2 ++ translations/vi-VN.json | 2 ++ translations/zh-CN.json | 2 ++ translations/zh-TW.json | 2 ++ 34 files changed, 68 insertions(+) diff --git a/translations/af-ZA.json b/translations/af-ZA.json index 4d6db43c01f..0422f611691 100644 --- a/translations/af-ZA.json +++ b/translations/af-ZA.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "", "components.Request.paid": "", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/ar-SA.json b/translations/ar-SA.json index 50b02bd7cc2..a8302325389 100644 --- a/translations/ar-SA.json +++ b/translations/ar-SA.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "", "components.Request.paid": "", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/bg-BG.json b/translations/bg-BG.json index 58b60949603..5e1ab3c651c 100644 --- a/translations/bg-BG.json +++ b/translations/bg-BG.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "Не платени", "components.Request.paid": "Платени", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/ca-ES.json b/translations/ca-ES.json index 4d6db43c01f..0422f611691 100644 --- a/translations/ca-ES.json +++ b/translations/ca-ES.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "", "components.Request.paid": "", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/cs-CZ.json b/translations/cs-CZ.json index 536e98607c8..76e4c403170 100644 --- a/translations/cs-CZ.json +++ b/translations/cs-CZ.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "Žádost o platbu nebo adresa", "components.Pay.request_label_offchain": "Žádost o platbu", "components.Pay.request_label_onchain": "Adresa", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "hledání tras…", "components.Pay.send": "Odeslat", "components.Pay.send_all": "Poslat vše", @@ -530,6 +531,7 @@ "components.Request.not_paid": "Nezaplaceno", "components.Request.paid": "Zaplaceno", "components.Request.payment_request": "Žádost o platbu", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "QR-kód", "components.Request.routing_hints_label": "Zahrnout pokyny pro směrování", "components.Request.routing_hints_tooltip": "Zda by tato faktura měla obsahovat pokyny pro směrování soukromých kanálů.", diff --git a/translations/da-DK.json b/translations/da-DK.json index 7d4dcb5f52f..a8f12e9e70f 100644 --- a/translations/da-DK.json +++ b/translations/da-DK.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "Betalings Anmodning eller Adresse", "components.Pay.request_label_offchain": "Betalings Anmodning", "components.Pay.request_label_onchain": "Adresse", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "søger efter ruter", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "ikke betalt", "components.Request.paid": "betalt", "components.Request.payment_request": "Betalings Anmodning", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "QR-Kode", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/de-DE.json b/translations/de-DE.json index b2dd9b4908c..479cc71b471 100644 --- a/translations/de-DE.json +++ b/translations/de-DE.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "Zahlungsanforderung oder Adresse", "components.Pay.request_label_offchain": "Zahlungsanfrage", "components.Pay.request_label_onchain": "Adresse", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "Suche nach Routen…", "components.Pay.send": "Senden", "components.Pay.send_all": "Alles senden", @@ -530,6 +531,7 @@ "components.Request.not_paid": "nicht bezahlt", "components.Request.paid": "bezahlt", "components.Request.payment_request": "Zahlungsanfrage", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "QR-Code", "components.Request.routing_hints_label": "Routenplanungen einschließen", "components.Request.routing_hints_tooltip": "Ob diese Rechnung Routenplanungen für private Kanäle beinhalten sollte.", diff --git a/translations/el-GR.json b/translations/el-GR.json index 861d065c8ab..6409b5c088a 100644 --- a/translations/el-GR.json +++ b/translations/el-GR.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "Δεν καταβάλλεται", "components.Request.paid": "Καταβάλλεται", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/en.json b/translations/en.json index 1e4c9aad315..4a52f9335ca 100644 --- a/translations/en.json +++ b/translations/en.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "Payment Request, Address, or Node Pubkey", "components.Pay.request_label_offchain": "Payment Request", "components.Pay.request_label_onchain": "Address", + "components.Pay.request_label_pubkey": "Node Pubkey", "components.Pay.searching_routes": "searching for routes…", "components.Pay.send": "Send", "components.Pay.send_all": "Send all", @@ -530,6 +531,7 @@ "components.Request.not_paid": "not paid", "components.Request.paid": "paid", "components.Request.payment_request": "Payment request", + "components.Request.payment_request_keysend": "Received via pubkey (keysend)", "components.Request.qrcode": "QR-Code", "components.Request.routing_hints_label": "Include routing hints", "components.Request.routing_hints_tooltip": "Whether this invoice should include routing hints for private channels.", diff --git a/translations/es-ES.json b/translations/es-ES.json index 27e35590e83..a9ef32122c2 100644 --- a/translations/es-ES.json +++ b/translations/es-ES.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "Solicitud de Pago o Dirección", "components.Pay.request_label_offchain": "Solicitud de Pago", "components.Pay.request_label_onchain": "Dirección", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "buscando rutas…", "components.Pay.send": "Enviar", "components.Pay.send_all": "Enviar todo", @@ -530,6 +531,7 @@ "components.Request.not_paid": "no pagado", "components.Request.paid": "pagado", "components.Request.payment_request": "Solicitud de Pago", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "Código QR", "components.Request.routing_hints_label": "Incluir pistas de ruta", "components.Request.routing_hints_tooltip": "Si esta factura debe incluir pistas de enrutamiento para canales privados.", diff --git a/translations/fi-FI.json b/translations/fi-FI.json index 4d6db43c01f..0422f611691 100644 --- a/translations/fi-FI.json +++ b/translations/fi-FI.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "", "components.Request.paid": "", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/fr-FR.json b/translations/fr-FR.json index 0638aa89bfb..707354ebae0 100644 --- a/translations/fr-FR.json +++ b/translations/fr-FR.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "Demande de paiement ou adresse", "components.Pay.request_label_offchain": "Demande de paiement", "components.Pay.request_label_onchain": "Adresse", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "recherche de routes…", "components.Pay.send": "Envoyer", "components.Pay.send_all": "Tout envoyer", @@ -530,6 +531,7 @@ "components.Request.not_paid": "non payé", "components.Request.paid": "payé", "components.Request.payment_request": "Demande de paiement", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "QR Code", "components.Request.routing_hints_label": "Inclure des indications de routage", "components.Request.routing_hints_tooltip": "Est-ce que cette demande doit inclure des indications de routage pour les canaux privés ?", diff --git a/translations/ga-IE.json b/translations/ga-IE.json index 507b93941f9..21b2ce41a63 100644 --- a/translations/ga-IE.json +++ b/translations/ga-IE.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "Seol gach ceann", @@ -530,6 +531,7 @@ "components.Request.not_paid": "Gan Íoctha", "components.Request.paid": "Íoctha", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "Cuir leideanna ródála san áireamh", "components.Request.routing_hints_tooltip": "Dá cheart go mbeadh leideanna ródála le haghaidh bealaí príobháideacha san áireamh sa sonrasc seo.", diff --git a/translations/he-IL.json b/translations/he-IL.json index 2d3c88ed5fd..71587039984 100644 --- a/translations/he-IL.json +++ b/translations/he-IL.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "", "components.Request.paid": "", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/hi-IN.json b/translations/hi-IN.json index 164e1eef931..d31a7357daf 100644 --- a/translations/hi-IN.json +++ b/translations/hi-IN.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "", "components.Request.paid": "भुगतान किया", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/hr-HR.json b/translations/hr-HR.json index 2b495ea1ef8..e275d1ef7d7 100644 --- a/translations/hr-HR.json +++ b/translations/hr-HR.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "Zahtjev za plaćanjem ili adresa", "components.Pay.request_label_offchain": "Zahtjev za plaćanjem", "components.Pay.request_label_onchain": "Adresa", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "traženje rute plaćanja", "components.Pay.send": "Slanje", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "Nije plaćeno", "components.Request.paid": "Plaćeno", "components.Request.payment_request": "Zahtjev za plaćanje", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "QR-kod", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/hu-HU.json b/translations/hu-HU.json index 4d6db43c01f..0422f611691 100644 --- a/translations/hu-HU.json +++ b/translations/hu-HU.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "", "components.Request.paid": "", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/it-IT.json b/translations/it-IT.json index 15a9535f3e9..d63de5dfdc8 100644 --- a/translations/it-IT.json +++ b/translations/it-IT.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "", "components.Request.paid": "", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/ja-JP.json b/translations/ja-JP.json index e9755974d61..b6dc10dad6e 100644 --- a/translations/ja-JP.json +++ b/translations/ja-JP.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "支払われていません。", "components.Request.paid": "支払った", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/ko-KR.json b/translations/ko-KR.json index 4d6db43c01f..0422f611691 100644 --- a/translations/ko-KR.json +++ b/translations/ko-KR.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "", "components.Request.paid": "", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/nl-NL.json b/translations/nl-NL.json index 3e6f249bf70..54738fb75e7 100644 --- a/translations/nl-NL.json +++ b/translations/nl-NL.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "Niet betaald", "components.Request.paid": "Betaald", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/no-NO.json b/translations/no-NO.json index 9c1dde35d92..80c9dc7b5dd 100644 --- a/translations/no-NO.json +++ b/translations/no-NO.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "Betalingsforespørsel", "components.Pay.request_label_onchain": "Adresse", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "Send", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "ikke betalt", "components.Request.paid": "betalt", "components.Request.payment_request": "Betalingsforespørsel", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "QR-kode", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/pl-PL.json b/translations/pl-PL.json index d07b5b90998..73c7d844610 100644 --- a/translations/pl-PL.json +++ b/translations/pl-PL.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "", "components.Request.paid": "", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/pt-BR.json b/translations/pt-BR.json index c3af4fe5a1f..87a66065f05 100644 --- a/translations/pt-BR.json +++ b/translations/pt-BR.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "Não pago", "components.Request.paid": "Pago", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/pt-PT.json b/translations/pt-PT.json index 9c44969e6f1..94a7b3805ea 100644 --- a/translations/pt-PT.json +++ b/translations/pt-PT.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "", "components.Request.paid": "", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/ro-RO.json b/translations/ro-RO.json index 0784ad6e24c..9d63a374e61 100644 --- a/translations/ro-RO.json +++ b/translations/ro-RO.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "Neachitat", "components.Request.paid": "Plătit", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/ru-RU.json b/translations/ru-RU.json index 38c65eae384..79e4c2c3ca2 100644 --- a/translations/ru-RU.json +++ b/translations/ru-RU.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "Запрос платежа", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "Отправить", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "Не Оплачено", "components.Request.paid": "Oплаченный", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "QR-код", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/sr-SP.json b/translations/sr-SP.json index 4d6db43c01f..0422f611691 100644 --- a/translations/sr-SP.json +++ b/translations/sr-SP.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "", "components.Request.paid": "", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/sv-SE.json b/translations/sv-SE.json index 95eb701aa3b..d6490bea1aa 100644 --- a/translations/sv-SE.json +++ b/translations/sv-SE.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "Inte betalad", "components.Request.paid": "Betald", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/tr-TR.json b/translations/tr-TR.json index b7b96614f8c..6d933a587be 100644 --- a/translations/tr-TR.json +++ b/translations/tr-TR.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "Ödenmeyen", "components.Request.paid": "Ödenen", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/uk-UA.json b/translations/uk-UA.json index 5551b1482db..73e72989651 100644 --- a/translations/uk-UA.json +++ b/translations/uk-UA.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "Не сплачені", "components.Request.paid": "Сплачені", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/vi-VN.json b/translations/vi-VN.json index 4d6db43c01f..0422f611691 100644 --- a/translations/vi-VN.json +++ b/translations/vi-VN.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "", "components.Request.paid": "", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/zh-CN.json b/translations/zh-CN.json index 3b8b37ef347..14d46b6ea66 100644 --- a/translations/zh-CN.json +++ b/translations/zh-CN.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "未支付", "components.Request.paid": "已支付", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", diff --git a/translations/zh-TW.json b/translations/zh-TW.json index 0d938f81ab0..c50c1860b5d 100644 --- a/translations/zh-TW.json +++ b/translations/zh-TW.json @@ -452,6 +452,7 @@ "components.Pay.request_label_combined": "", "components.Pay.request_label_offchain": "", "components.Pay.request_label_onchain": "", + "components.Pay.request_label_pubkey": "", "components.Pay.searching_routes": "", "components.Pay.send": "", "components.Pay.send_all": "", @@ -530,6 +531,7 @@ "components.Request.not_paid": "未支付", "components.Request.paid": "已支付", "components.Request.payment_request": "", + "components.Request.payment_request_keysend": "", "components.Request.qrcode": "", "components.Request.routing_hints_label": "", "components.Request.routing_hints_tooltip": "", From d8e4b8729a544557cd48901b6e01b0b62a5ff176 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Tue, 24 Mar 2020 11:53:33 +0100 Subject: [PATCH 14/16] refactor: check length before hex regex --- utils/crypto.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/utils/crypto.js b/utils/crypto.js index aa09455d0ea..809dfa00448 100644 --- a/utils/crypto.js +++ b/utils/crypto.js @@ -174,8 +174,7 @@ export const isPubkey = input => { if (!input || typeof input !== 'string') { return false } - const isHex = /^[0-9a-fA-F]+$/.test(input) - return isHex && input.length === 66 + return input.length === 66 && /^[0-9a-fA-F]+$/.test(input) } /** From 5e83698b889f351c121ed20de2ea5f3f984af691 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Tue, 24 Mar 2020 11:54:11 +0100 Subject: [PATCH 15/16] refactor: dont silence lint warnings --- renderer/components/Pay/Pay.js | 2 +- renderer/components/Pay/PaySummaryLightning.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/renderer/components/Pay/Pay.js b/renderer/components/Pay/Pay.js index 15dcc7c950c..1bdb8c3b0f3 100644 --- a/renderer/components/Pay/Pay.js +++ b/renderer/components/Pay/Pay.js @@ -132,7 +132,7 @@ class Pay extends React.Component { if (isNowSummary) { let payeeNodeKey if (invoice) { - payeeNodeKey = invoice.payeeNodeKey // eslint-disable-line prefer-destructuring + ;({ payeeNodeKey } = invoice) } else if (isPubkey) { const { values: { payReq }, diff --git a/renderer/components/Pay/PaySummaryLightning.js b/renderer/components/Pay/PaySummaryLightning.js index 7b12ba87781..9c1a6af516a 100644 --- a/renderer/components/Pay/PaySummaryLightning.js +++ b/renderer/components/Pay/PaySummaryLightning.js @@ -71,7 +71,7 @@ class PaySummaryLightning extends React.Component { } catch (e) { return null } - payeeNodeKey = invoice.payeeNodeKey // eslint-disable-line prefer-destructuring + ;({ payeeNodeKey } = invoice) memo = getTag(invoice, 'description') const { satoshis, millisatoshis } = invoice amountInSatoshis = satoshis || convert('msats', 'sats', millisatoshis) || amount From 120c74bbc7a2898c3d5e2d19ada453d662bf0ac9 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Tue, 24 Mar 2020 11:54:36 +0100 Subject: [PATCH 16/16] refactor: dont double init CoinBig --- renderer/components/Pay/PayPanelFooter.js | 6 +++--- renderer/reducers/payment.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/renderer/components/Pay/PayPanelFooter.js b/renderer/components/Pay/PayPanelFooter.js index 8bd1fe0120c..50d502a9a6b 100644 --- a/renderer/components/Pay/PayPanelFooter.js +++ b/renderer/components/Pay/PayPanelFooter.js @@ -26,9 +26,9 @@ const isEnoughFunds = props => { // Determine whether we have enough funds available. let hasEnoughFunds = true if ((isBolt11 && invoice) || isPubkey) { - hasEnoughFunds = CoinBig(amountInSats).lte(CoinBig(channelBalance)) + hasEnoughFunds = CoinBig(amountInSats).lte(channelBalance) } else if (isOnchain) { - hasEnoughFunds = CoinBig(amountInSats).lte(CoinBig(walletBalanceConfirmed)) + hasEnoughFunds = CoinBig(amountInSats).lte(walletBalanceConfirmed) } return hasEnoughFunds @@ -84,7 +84,7 @@ const PayPanelFooter = props => { } const isNotEnoughFunds = !isEnoughFunds(props) - const isAboveMax = (isBolt11 || isPubkey) && CoinBig(amountInSats).gt(CoinBig(maxOneTimeSend)) + const isAboveMax = (isBolt11 || isPubkey) && CoinBig(amountInSats).gt(maxOneTimeSend) const formattedMax = intl.formatNumber(convert('sats', cryptoUnit, maxOneTimeSend), { maximumFractionDigits: 8, }) diff --git a/renderer/reducers/payment.js b/renderer/reducers/payment.js index 712be6061a7..48a1799e4a0 100644 --- a/renderer/reducers/payment.js +++ b/renderer/reducers/payment.js @@ -221,7 +221,7 @@ export const payInvoice = ({ } } - // Bolt11 invoice payent. + // Bolt11 invoice payment. else { const invoice = decodePayReq(payReq) paymentHash = getTag(invoice, 'payment_hash')