2020-12-11 04:56:01 +01:00
|
|
|
import React, { useCallback, useContext, useEffect, useState } from 'react';
|
2020-06-11 05:54:47 +02:00
|
|
|
import {
|
|
|
|
Text,
|
|
|
|
ActivityIndicator,
|
|
|
|
KeyboardAvoidingView,
|
|
|
|
View,
|
|
|
|
TouchableOpacity,
|
|
|
|
Keyboard,
|
|
|
|
ScrollView,
|
|
|
|
StyleSheet,
|
2021-03-19 16:12:17 +01:00
|
|
|
I18nManager,
|
2020-06-11 05:54:47 +02:00
|
|
|
} from 'react-native';
|
2020-12-25 17:09:53 +01:00
|
|
|
import { Icon } from 'react-native-elements';
|
2023-10-24 03:28:44 +02:00
|
|
|
import { useFocusEffect, useNavigation, useRoute } from '@react-navigation/native';
|
2020-12-25 17:09:53 +01:00
|
|
|
|
2023-11-15 09:40:22 +01:00
|
|
|
import { BlueCard, BlueDismissKeyboardInputAccessory, BlueLoading, SafeBlueArea } from '../../BlueComponents';
|
2020-12-25 17:09:53 +01:00
|
|
|
import navigationStyle from '../../components/navigationStyle';
|
2021-02-25 17:13:34 +01:00
|
|
|
import AddressInput from '../../components/AddressInput';
|
|
|
|
import AmountInput from '../../components/AmountInput';
|
2020-07-23 20:06:13 +02:00
|
|
|
import Lnurl from '../../class/lnurl';
|
2019-02-26 02:33:29 +01:00
|
|
|
import { BitcoinUnit, Chain } from '../../models/bitcoinUnits';
|
2019-09-25 05:42:21 +02:00
|
|
|
import Biometric from '../../class/biometrics';
|
2020-07-20 15:38:46 +02:00
|
|
|
import loc, { formatBalanceWithoutSuffix } from '../../loc';
|
2020-10-24 19:20:59 +02:00
|
|
|
import { BlueStorageContext } from '../../blue_modules/storage-context';
|
2021-10-04 08:02:33 +02:00
|
|
|
import alert from '../../components/Alert';
|
2023-10-24 03:28:44 +02:00
|
|
|
import { useTheme } from '../../components/themes';
|
2023-11-15 09:40:22 +01:00
|
|
|
import Button from '../../components/Button';
|
2023-12-29 12:52:12 +01:00
|
|
|
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
|
2020-06-09 16:08:18 +02:00
|
|
|
const currency = require('../../blue_modules/currency');
|
2018-09-01 01:28:19 +02:00
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
const ScanLndInvoice = () => {
|
|
|
|
const { wallets, fetchAndSaveWalletTransactions } = useContext(BlueStorageContext);
|
|
|
|
const { colors } = useTheme();
|
|
|
|
const { walletID, uri, invoice } = useRoute().params;
|
|
|
|
const name = useRoute().name;
|
|
|
|
/** @type {LightningCustodianWallet} */
|
2020-12-07 16:58:28 +01:00
|
|
|
const [wallet, setWallet] = useState(
|
2021-09-09 13:00:11 +02:00
|
|
|
wallets.find(item => item.getID() === walletID) || wallets.find(item => item.chain === Chain.OFFCHAIN),
|
2020-12-05 06:28:36 +01:00
|
|
|
);
|
2020-12-11 04:56:01 +01:00
|
|
|
const { navigate, setParams, goBack, pop } = useNavigation();
|
2020-12-05 06:17:51 +01:00
|
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
|
|
const [renderWalletSelectionButtonHidden, setRenderWalletSelectionButtonHidden] = useState(false);
|
|
|
|
const [destination, setDestination] = useState('');
|
2020-12-18 17:08:02 +01:00
|
|
|
const [unit, setUnit] = useState(BitcoinUnit.SATS);
|
2020-12-05 06:17:51 +01:00
|
|
|
const [decoded, setDecoded] = useState();
|
|
|
|
const [amount, setAmount] = useState();
|
|
|
|
const [isAmountInitiallyEmpty, setIsAmountInitiallyEmpty] = useState();
|
|
|
|
const [expiresIn, setExpiresIn] = useState();
|
|
|
|
const stylesHook = StyleSheet.create({
|
|
|
|
walletWrapLabel: {
|
|
|
|
color: colors.buttonAlternativeTextColor,
|
|
|
|
},
|
|
|
|
walletWrapBalance: {
|
|
|
|
color: colors.buttonAlternativeTextColor,
|
|
|
|
},
|
|
|
|
walletWrapSats: {
|
|
|
|
color: colors.buttonAlternativeTextColor,
|
|
|
|
},
|
|
|
|
root: {
|
|
|
|
backgroundColor: colors.elevated,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
console.log('scanLndInvoice useEffect');
|
|
|
|
Keyboard.addListener('keyboardDidShow', _keyboardDidShow);
|
|
|
|
Keyboard.addListener('keyboardDidHide', _keyboardDidHide);
|
|
|
|
return () => {
|
2022-02-11 12:47:06 +01:00
|
|
|
Keyboard.removeAllListeners('keyboardDidShow');
|
|
|
|
Keyboard.removeAllListeners('keyboardDidHide');
|
2020-12-05 06:17:51 +01:00
|
|
|
};
|
|
|
|
}, []);
|
|
|
|
|
2020-12-05 06:28:36 +01:00
|
|
|
useEffect(() => {
|
2020-12-11 04:56:01 +01:00
|
|
|
if (walletID && wallet?.getID() !== walletID) {
|
2020-12-07 16:58:28 +01:00
|
|
|
setWallet(wallets.find(w => w.getID() === walletID));
|
2020-12-05 06:28:36 +01:00
|
|
|
}
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
}, [walletID]);
|
|
|
|
|
2020-12-11 04:56:01 +01:00
|
|
|
useFocusEffect(
|
|
|
|
useCallback(() => {
|
|
|
|
if (!wallet) {
|
2023-12-29 12:52:12 +01:00
|
|
|
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
|
2020-12-11 04:56:01 +01:00
|
|
|
goBack();
|
2021-01-11 09:52:58 +01:00
|
|
|
setTimeout(() => alert(loc.wallets.no_ln_wallet_error), 500);
|
2020-12-11 04:56:01 +01:00
|
|
|
}
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
}, [wallet]),
|
|
|
|
);
|
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
useEffect(() => {
|
2020-12-11 04:56:01 +01:00
|
|
|
if (wallet && uri) {
|
2021-08-30 19:15:22 +02:00
|
|
|
if (Lnurl.isLnurl(uri)) return processLnurlPay(uri);
|
|
|
|
if (Lnurl.isLightningAddress(uri)) return processLnurlPay(uri);
|
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
let data = uri;
|
2019-01-19 22:18:19 +01:00
|
|
|
// handling BIP21 w/BOLT11 support
|
2020-06-01 14:54:23 +02:00
|
|
|
const ind = data.indexOf('lightning=');
|
2019-01-19 22:18:19 +01:00
|
|
|
if (ind !== -1) {
|
|
|
|
data = data.substring(ind + 10).split('&')[0];
|
|
|
|
}
|
|
|
|
|
2019-01-06 21:21:04 +01:00
|
|
|
data = data.replace('LIGHTNING:', '').replace('lightning:', '');
|
|
|
|
console.log(data);
|
|
|
|
|
2023-07-25 15:50:04 +02:00
|
|
|
let newDecoded;
|
2019-01-06 21:21:04 +01:00
|
|
|
try {
|
2023-07-25 15:50:04 +02:00
|
|
|
newDecoded = wallet.decodeInvoice(data);
|
2018-09-01 01:28:19 +02:00
|
|
|
|
2023-07-25 15:50:04 +02:00
|
|
|
let newExpiresIn = (newDecoded.timestamp * 1 + newDecoded.expiry * 1) * 1000; // ms
|
|
|
|
if (+new Date() > newExpiresIn) {
|
|
|
|
newExpiresIn = loc.lnd.expired;
|
2019-01-06 21:21:04 +01:00
|
|
|
} else {
|
2023-07-25 15:50:04 +02:00
|
|
|
const time = Math.round((newExpiresIn - +new Date()) / (60 * 1000));
|
|
|
|
newExpiresIn = loc.formatString(loc.lnd.expiresIn, { time });
|
2019-01-06 21:21:04 +01:00
|
|
|
}
|
|
|
|
Keyboard.dismiss();
|
2020-12-05 06:17:51 +01:00
|
|
|
setParams({ uri: undefined, invoice: data });
|
2023-07-25 15:50:04 +02:00
|
|
|
setIsAmountInitiallyEmpty(newDecoded.num_satoshis === '0');
|
2020-12-05 06:17:51 +01:00
|
|
|
setDestination(data);
|
|
|
|
setIsLoading(false);
|
2023-07-25 15:50:04 +02:00
|
|
|
setAmount(newDecoded.num_satoshis);
|
|
|
|
setExpiresIn(newExpiresIn);
|
|
|
|
setDecoded(newDecoded);
|
2019-01-06 21:21:04 +01:00
|
|
|
} catch (Err) {
|
2023-12-29 12:52:12 +01:00
|
|
|
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
|
2020-01-20 04:33:17 +01:00
|
|
|
Keyboard.dismiss();
|
2020-12-05 06:17:51 +01:00
|
|
|
setParams({ uri: undefined });
|
2020-01-20 04:33:17 +01:00
|
|
|
setTimeout(() => alert(Err.message), 10);
|
2020-12-05 06:17:51 +01:00
|
|
|
setIsLoading(false);
|
2021-09-04 21:04:58 +02:00
|
|
|
setAmount();
|
2021-09-02 20:18:58 +02:00
|
|
|
setDestination();
|
|
|
|
setExpiresIn();
|
|
|
|
setDecoded();
|
2018-09-01 01:28:19 +02:00
|
|
|
}
|
2020-01-20 04:33:17 +01:00
|
|
|
}
|
2020-12-05 06:17:51 +01:00
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
}, [uri]);
|
2020-01-20 04:33:17 +01:00
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
const _keyboardDidShow = () => {
|
|
|
|
setRenderWalletSelectionButtonHidden(true);
|
2020-01-20 04:33:17 +01:00
|
|
|
};
|
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
const _keyboardDidHide = () => {
|
|
|
|
setRenderWalletSelectionButtonHidden(false);
|
2020-01-20 04:33:17 +01:00
|
|
|
};
|
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
const processInvoice = data => {
|
|
|
|
if (Lnurl.isLnurl(data)) return processLnurlPay(data);
|
2021-08-30 19:15:22 +02:00
|
|
|
if (Lnurl.isLightningAddress(data)) return processLnurlPay(data);
|
2020-12-05 06:17:51 +01:00
|
|
|
setParams({ uri: data });
|
2019-01-24 08:36:01 +01:00
|
|
|
};
|
2018-09-01 01:28:19 +02:00
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
const processLnurlPay = data => {
|
|
|
|
navigate('ScanLndInvoiceRoot', {
|
2020-07-23 20:06:13 +02:00
|
|
|
screen: 'LnurlPay',
|
|
|
|
params: {
|
|
|
|
lnurl: data,
|
2021-08-25 07:55:22 +02:00
|
|
|
walletID: walletID || wallet.getID(),
|
2020-07-23 20:06:13 +02:00
|
|
|
},
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
const pay = async () => {
|
|
|
|
if (!decoded) {
|
2018-10-23 00:51:30 +02:00
|
|
|
return null;
|
|
|
|
}
|
2018-09-01 01:28:19 +02:00
|
|
|
|
2019-09-25 05:42:21 +02:00
|
|
|
const isBiometricsEnabled = await Biometric.isBiometricUseCapableAndEnabled();
|
|
|
|
|
|
|
|
if (isBiometricsEnabled) {
|
|
|
|
if (!(await Biometric.unlockWithBiometrics())) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
let amountSats = amount;
|
|
|
|
switch (unit) {
|
2020-06-09 16:08:18 +02:00
|
|
|
case BitcoinUnit.SATS:
|
2023-07-25 15:50:04 +02:00
|
|
|
amountSats = parseInt(amountSats, 10); // nop
|
2020-06-09 16:08:18 +02:00
|
|
|
break;
|
|
|
|
case BitcoinUnit.BTC:
|
|
|
|
amountSats = currency.btcToSatoshi(amountSats);
|
|
|
|
break;
|
|
|
|
case BitcoinUnit.LOCAL_CURRENCY:
|
|
|
|
amountSats = currency.btcToSatoshi(currency.fiatToBTC(amountSats));
|
|
|
|
break;
|
|
|
|
}
|
2020-12-05 06:17:51 +01:00
|
|
|
setIsLoading(true);
|
2020-06-09 16:08:18 +02:00
|
|
|
|
2023-07-25 15:50:04 +02:00
|
|
|
const newExpiresIn = (decoded.timestamp * 1 + decoded.expiry * 1) * 1000; // ms
|
|
|
|
if (+new Date() > newExpiresIn) {
|
2020-12-05 06:17:51 +01:00
|
|
|
setIsLoading(false);
|
2023-12-29 12:52:12 +01:00
|
|
|
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
|
2020-12-05 06:17:51 +01:00
|
|
|
return alert(loc.lnd.errorInvoiceExpired);
|
|
|
|
}
|
2018-09-01 01:28:19 +02:00
|
|
|
|
2020-12-14 16:49:36 +01:00
|
|
|
const currentUserInvoices = wallet.user_invoices_raw; // not fetching invoices, as we assume they were loaded previously
|
2023-07-25 15:50:04 +02:00
|
|
|
if (currentUserInvoices.some(i => i.payment_hash === decoded.payment_hash)) {
|
2020-12-05 06:17:51 +01:00
|
|
|
setIsLoading(false);
|
2023-12-29 12:52:12 +01:00
|
|
|
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
|
2020-12-05 06:17:51 +01:00
|
|
|
return alert(loc.lnd.sameWalletAsInvoiceError);
|
|
|
|
}
|
2019-01-05 01:10:59 +01:00
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
try {
|
2020-12-07 16:58:28 +01:00
|
|
|
await wallet.payInvoice(invoice, amountSats);
|
2020-12-05 06:17:51 +01:00
|
|
|
} catch (Err) {
|
|
|
|
console.log(Err.message);
|
|
|
|
setIsLoading(false);
|
2023-12-29 12:52:12 +01:00
|
|
|
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
|
2020-12-05 06:17:51 +01:00
|
|
|
return alert(Err.message);
|
|
|
|
}
|
2018-09-01 01:28:19 +02:00
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
navigate('Success', {
|
2020-12-18 17:08:02 +01:00
|
|
|
amount: amountSats,
|
2020-12-05 06:17:51 +01:00
|
|
|
amountUnit: BitcoinUnit.SATS,
|
|
|
|
invoiceDescription: decoded.description,
|
|
|
|
});
|
2021-11-09 10:48:27 +01:00
|
|
|
fetchAndSaveWalletTransactions(wallet.getID());
|
2020-12-05 06:17:51 +01:00
|
|
|
};
|
2018-09-01 01:28:19 +02:00
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
const processTextForInvoice = text => {
|
2021-08-30 19:15:22 +02:00
|
|
|
if (
|
|
|
|
text.toLowerCase().startsWith('lnb') ||
|
|
|
|
text.toLowerCase().startsWith('lightning:lnb') ||
|
|
|
|
Lnurl.isLnurl(text) ||
|
|
|
|
Lnurl.isLightningAddress(text)
|
|
|
|
) {
|
2020-12-05 06:17:51 +01:00
|
|
|
processInvoice(text);
|
2018-12-24 16:29:33 +01:00
|
|
|
} else {
|
2020-12-05 06:17:51 +01:00
|
|
|
setDecoded(undefined);
|
|
|
|
setExpiresIn(undefined);
|
|
|
|
setDestination(text);
|
2018-12-24 16:29:33 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
const shouldDisablePayButton = () => {
|
|
|
|
if (!decoded) {
|
2019-01-06 08:28:23 +01:00
|
|
|
return true;
|
|
|
|
} else {
|
2020-12-05 06:17:51 +01:00
|
|
|
if (!amount) {
|
2019-01-06 08:28:23 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2020-12-05 06:17:51 +01:00
|
|
|
return !(amount > 0);
|
|
|
|
// return decoded.num_satoshis <= 0 || isLoading || isNaN(decoded.num_satoshis);
|
2019-01-06 08:28:23 +01:00
|
|
|
};
|
|
|
|
|
2020-12-07 16:12:49 +01:00
|
|
|
const naviageToSelectWallet = () => {
|
|
|
|
navigate('SelectWallet', { onWalletSelect, chainType: Chain.OFFCHAIN });
|
|
|
|
};
|
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
const renderWalletSelectionButton = () => {
|
|
|
|
if (renderWalletSelectionButtonHidden) return;
|
2020-12-07 16:58:28 +01:00
|
|
|
const walletLabel = wallet.getLabel();
|
2019-02-26 02:33:29 +01:00
|
|
|
return (
|
2020-05-24 11:17:26 +02:00
|
|
|
<View style={styles.walletSelectRoot}>
|
2020-12-05 06:17:51 +01:00
|
|
|
{!isLoading && (
|
2021-06-24 14:50:57 +02:00
|
|
|
<TouchableOpacity accessibilityRole="button" style={styles.walletSelectTouch} onPress={naviageToSelectWallet}>
|
2020-05-24 11:17:26 +02:00
|
|
|
<Text style={styles.walletSelectText}>{loc.wallets.select_wallet.toLowerCase()}</Text>
|
2021-03-19 16:12:17 +01:00
|
|
|
<Icon name={I18nManager.isRTL ? 'angle-left' : 'angle-right'} size={18} type="font-awesome" color="#9aa0aa" />
|
2019-02-26 02:33:29 +01:00
|
|
|
</TouchableOpacity>
|
|
|
|
)}
|
2020-05-24 11:17:26 +02:00
|
|
|
<View style={styles.walletWrap}>
|
2021-10-26 22:47:09 +02:00
|
|
|
<TouchableOpacity accessibilityRole="button" disabled={isLoading} style={styles.walletWrapTouch} onPress={naviageToSelectWallet}>
|
2020-12-07 16:58:28 +01:00
|
|
|
<Text style={[styles.walletWrapLabel, stylesHook.walletWrapLabel]}>{walletLabel}</Text>
|
2020-12-05 06:17:51 +01:00
|
|
|
<Text style={[styles.walletWrapBalance, stylesHook.walletWrapBalance]}>
|
2020-12-07 16:58:28 +01:00
|
|
|
{formatBalanceWithoutSuffix(wallet.getBalance(), BitcoinUnit.SATS, false)}
|
2019-09-17 21:39:21 +02:00
|
|
|
</Text>
|
2020-12-05 06:17:51 +01:00
|
|
|
<Text style={[styles.walletWrapSats, stylesHook.walletWrapSats]}>{BitcoinUnit.SATS}</Text>
|
2019-09-17 21:39:21 +02:00
|
|
|
</TouchableOpacity>
|
2019-02-26 02:33:29 +01:00
|
|
|
</View>
|
|
|
|
</View>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
const getFees = () => {
|
|
|
|
const min = Math.floor(decoded.num_satoshis * 0.003);
|
|
|
|
const max = Math.floor(decoded.num_satoshis * 0.01) + 1;
|
2021-09-02 22:22:43 +02:00
|
|
|
return `${min} ${BitcoinUnit.SATS} - ${max} ${BitcoinUnit.SATS}`;
|
2020-12-05 06:17:51 +01:00
|
|
|
};
|
2020-06-04 15:07:33 +02:00
|
|
|
|
2021-09-02 20:18:58 +02:00
|
|
|
const onBlur = () => {
|
|
|
|
processTextForInvoice(destination);
|
|
|
|
};
|
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
const onWalletSelect = selectedWallet => {
|
|
|
|
setParams({ walletID: selectedWallet.getID() });
|
|
|
|
pop();
|
2019-02-26 02:33:29 +01:00
|
|
|
};
|
|
|
|
|
2020-12-07 17:06:45 +01:00
|
|
|
if (wallet === undefined || !wallet) {
|
2020-12-11 04:56:01 +01:00
|
|
|
return (
|
|
|
|
<View style={[styles.loadingIndicator, stylesHook.root]}>
|
|
|
|
<BlueLoading />
|
|
|
|
</View>
|
|
|
|
);
|
2020-06-09 16:08:18 +02:00
|
|
|
}
|
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
return (
|
2021-03-22 12:54:17 +01:00
|
|
|
<SafeBlueArea style={stylesHook.root}>
|
2020-12-05 06:17:51 +01:00
|
|
|
<View style={[styles.root, stylesHook.root]}>
|
2021-05-08 01:09:24 +02:00
|
|
|
<ScrollView contentContainerStyle={styles.scroll} keyboardShouldPersistTaps="handled">
|
2020-12-05 06:17:51 +01:00
|
|
|
<KeyboardAvoidingView enabled behavior="position" keyboardVerticalOffset={20}>
|
|
|
|
<View style={styles.scrollMargin}>
|
2021-02-25 17:13:34 +01:00
|
|
|
<AmountInput
|
2020-12-05 06:17:51 +01:00
|
|
|
pointerEvents={isAmountInitiallyEmpty ? 'auto' : 'none'}
|
|
|
|
isLoading={isLoading}
|
|
|
|
amount={amount}
|
|
|
|
onAmountUnitChange={setUnit}
|
|
|
|
onChangeText={setAmount}
|
2020-12-07 16:15:33 +01:00
|
|
|
disabled={!decoded || isLoading || decoded.num_satoshis > 0}
|
2021-05-08 01:09:24 +02:00
|
|
|
unit={unit}
|
2020-12-05 06:17:51 +01:00
|
|
|
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
|
|
|
|
/>
|
|
|
|
</View>
|
|
|
|
|
|
|
|
<BlueCard>
|
2021-02-25 17:13:34 +01:00
|
|
|
<AddressInput
|
2020-12-05 06:17:51 +01:00
|
|
|
onChangeText={text => {
|
|
|
|
text = text.trim();
|
2021-09-02 20:18:58 +02:00
|
|
|
setDestination(text);
|
2020-12-05 06:17:51 +01:00
|
|
|
}}
|
|
|
|
onBarScanned={processInvoice}
|
|
|
|
address={destination}
|
|
|
|
isLoading={isLoading}
|
|
|
|
placeholder={loc.lnd.placeholder}
|
|
|
|
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
|
|
|
|
launchedBy={name}
|
2021-09-02 20:18:58 +02:00
|
|
|
onBlur={onBlur}
|
2021-10-15 16:52:25 +02:00
|
|
|
keyboardType="email-address"
|
2020-12-05 06:17:51 +01:00
|
|
|
/>
|
|
|
|
<View style={styles.description}>
|
|
|
|
<Text numberOfLines={0} style={styles.descriptionText}>
|
|
|
|
{decoded !== undefined ? decoded.description : ''}
|
|
|
|
</Text>
|
2019-09-17 23:26:19 +02:00
|
|
|
</View>
|
2020-12-05 06:17:51 +01:00
|
|
|
{expiresIn !== undefined && (
|
|
|
|
<View>
|
2021-09-06 10:28:16 +02:00
|
|
|
<Text style={styles.expiresIn}>{expiresIn}</Text>
|
2020-12-05 06:17:51 +01:00
|
|
|
{decoded && decoded.num_satoshis > 0 && (
|
|
|
|
<Text style={styles.expiresIn}>{loc.formatString(loc.lnd.potentialFee, { fee: getFees() })}</Text>
|
|
|
|
)}
|
2019-02-26 02:33:29 +01:00
|
|
|
</View>
|
2020-12-05 06:17:51 +01:00
|
|
|
)}
|
|
|
|
<BlueCard>
|
|
|
|
{isLoading ? (
|
|
|
|
<View>
|
|
|
|
<ActivityIndicator />
|
|
|
|
</View>
|
|
|
|
) : (
|
2020-06-03 22:40:16 +02:00
|
|
|
<View>
|
2023-11-15 09:40:22 +01:00
|
|
|
<Button title={loc.lnd.payButton} onPress={pay} disabled={shouldDisablePayButton()} />
|
2020-06-04 15:07:33 +02:00
|
|
|
</View>
|
|
|
|
)}
|
2019-02-26 02:33:29 +01:00
|
|
|
</BlueCard>
|
2020-12-05 06:17:51 +01:00
|
|
|
</BlueCard>
|
|
|
|
</KeyboardAvoidingView>
|
|
|
|
{renderWalletSelectionButton()}
|
|
|
|
</ScrollView>
|
|
|
|
</View>
|
|
|
|
<BlueDismissKeyboardInputAccessory />
|
|
|
|
</SafeBlueArea>
|
|
|
|
);
|
2020-04-17 17:23:18 +02:00
|
|
|
};
|
2020-07-15 19:32:59 +02:00
|
|
|
|
2020-12-05 06:17:51 +01:00
|
|
|
export default ScanLndInvoice;
|
2021-02-15 09:03:54 +01:00
|
|
|
ScanLndInvoice.navigationOptions = navigationStyle(
|
|
|
|
{
|
|
|
|
closeButton: true,
|
2023-11-11 12:33:50 +01:00
|
|
|
headerBackVisible: false,
|
2021-02-15 09:03:54 +01:00
|
|
|
},
|
2023-10-20 17:10:50 +02:00
|
|
|
opts => ({ ...opts, title: loc.send.header, statusBarStyle: 'light' }),
|
2021-02-15 09:03:54 +01:00
|
|
|
);
|
2020-12-05 06:17:51 +01:00
|
|
|
|
|
|
|
const styles = StyleSheet.create({
|
|
|
|
walletSelectRoot: {
|
|
|
|
marginBottom: 16,
|
|
|
|
alignItems: 'center',
|
|
|
|
justifyContent: 'flex-end',
|
|
|
|
},
|
2020-12-11 04:56:01 +01:00
|
|
|
loadingIndicator: {
|
|
|
|
flex: 1,
|
|
|
|
justifyContent: 'center',
|
|
|
|
},
|
2020-12-05 06:17:51 +01:00
|
|
|
walletSelectTouch: {
|
|
|
|
flexDirection: 'row',
|
|
|
|
alignItems: 'center',
|
|
|
|
},
|
|
|
|
walletSelectText: {
|
|
|
|
color: '#9aa0aa',
|
|
|
|
fontSize: 14,
|
|
|
|
marginRight: 8,
|
|
|
|
},
|
|
|
|
walletWrap: {
|
|
|
|
flexDirection: 'row',
|
|
|
|
alignItems: 'center',
|
|
|
|
marginVertical: 4,
|
|
|
|
},
|
|
|
|
walletWrapTouch: {
|
|
|
|
flexDirection: 'row',
|
|
|
|
alignItems: 'center',
|
|
|
|
},
|
|
|
|
walletWrapLabel: {
|
|
|
|
fontSize: 14,
|
|
|
|
},
|
|
|
|
walletWrapBalance: {
|
|
|
|
fontSize: 14,
|
|
|
|
fontWeight: '600',
|
|
|
|
marginLeft: 4,
|
|
|
|
marginRight: 4,
|
|
|
|
},
|
|
|
|
walletWrapSats: {
|
|
|
|
fontSize: 11,
|
|
|
|
fontWeight: '600',
|
|
|
|
textAlignVertical: 'bottom',
|
|
|
|
marginTop: 2,
|
|
|
|
},
|
|
|
|
root: {
|
|
|
|
flex: 1,
|
|
|
|
},
|
|
|
|
scroll: {
|
|
|
|
flex: 1,
|
|
|
|
justifyContent: 'space-between',
|
|
|
|
},
|
|
|
|
scrollMargin: {
|
|
|
|
marginTop: 60,
|
|
|
|
},
|
|
|
|
description: {
|
|
|
|
flexDirection: 'row',
|
|
|
|
marginHorizontal: 20,
|
|
|
|
alignItems: 'center',
|
|
|
|
marginVertical: 0,
|
|
|
|
borderRadius: 4,
|
|
|
|
},
|
|
|
|
descriptionText: {
|
|
|
|
color: '#81868e',
|
|
|
|
fontWeight: '500',
|
|
|
|
fontSize: 14,
|
|
|
|
},
|
|
|
|
expiresIn: {
|
2021-08-26 20:00:23 +02:00
|
|
|
writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr',
|
2020-12-05 06:17:51 +01:00
|
|
|
color: '#81868e',
|
|
|
|
fontSize: 12,
|
|
|
|
left: 20,
|
|
|
|
top: 10,
|
|
|
|
},
|
|
|
|
});
|