mirror of
https://github.com/minibits-cash/minibits_wallet.git
synced 2026-08-10 16:43:19 +00:00
Fix lightning paymentRequests handling
This commit is contained in:
@@ -14,7 +14,7 @@ import java.util.concurrent.TimeUnit
|
||||
class CorePlaneOkHttpClientFactory : OkHttpClientFactory {
|
||||
override fun createNewNetworkModuleClient(): OkHttpClient {
|
||||
val okHttpVersion = OkHttp.VERSION
|
||||
Log.d("OkHttpFactory", "Using OkHttp version: $okHttpVersion")
|
||||
// Log.d("OkHttpFactory", "Using OkHttp version: $okHttpVersion")
|
||||
|
||||
return OkHttpClientProvider.createClientBuilder()
|
||||
.dns(CorePlaneOkHttpDNSSelector(CorePlaneOkHttpDNSSelector.IPvMode.IPV4_FIRST))
|
||||
|
||||
@@ -105,8 +105,12 @@ export const LightningPayScreen = function LightningPayScreen({ route }: Props)
|
||||
|
||||
|
||||
const gotoContacts = function () {
|
||||
navigation.navigate('Contacts', {
|
||||
paymentOption: SendOption.LNURL_ADDRESS
|
||||
//@ts-ignore
|
||||
navigation.navigate('ContactsNavigator', {
|
||||
screen: 'Contacts',
|
||||
params: {
|
||||
paymentOption: SendOption.LNURL_ADDRESS
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { validateMnemonic } from '@scure/bip39'
|
||||
import QuickCrypto from 'react-native-quick-crypto'
|
||||
import { wordlist } from '@scure/bip39/wordlists/english'
|
||||
import { mnemonicToSeedSync } from '@scure/bip39'
|
||||
import { spacing, useThemeColor } from '../theme'
|
||||
import { colors, spacing, useThemeColor } from '../theme'
|
||||
import { Icon, ListItem, Screen, Text, Card, Loading, ErrorModal, Button } from '../components'
|
||||
import { useHeader } from '../utils/useHeader'
|
||||
import AppError, { Err } from '../utils/AppError'
|
||||
@@ -166,17 +166,30 @@ export const RecoverWalletAddressScreen = observer(function RecoverWalletAddress
|
||||
onError={handleError}
|
||||
/>
|
||||
{isValidMnemonic && profileToRecover && (
|
||||
<>
|
||||
<Card
|
||||
style={$card}
|
||||
ContentComponent={
|
||||
<ListItem
|
||||
text={profileToRecover.nip05}
|
||||
subText="This is the wallet address linked to the provided seed. If you continue, your current address will reset to this one, but wallet seed phrase will NOT be updated."
|
||||
subText="This is the wallet address linked to the provided seed."
|
||||
LeftComponent={<View style={[$numIcon, { backgroundColor: numIconColor }]}><Text text='2' /></View>}
|
||||
style={$item}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Card
|
||||
style={[$card]}
|
||||
ContentComponent={
|
||||
<ListItem
|
||||
text={'Do not forget!'}
|
||||
subText="Your current address will reset, but current wallet seed phrase will NOT be changed. Make a backup!"
|
||||
LeftComponent={<View style={[$numIcon, { backgroundColor: numIconColor }]}><Text text='3' /></View>}
|
||||
style={$item}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
{isValidMnemonic && (
|
||||
|
||||
@@ -810,6 +810,8 @@ export const SendScreen = observer(function SendScreen({ route }: Props) {
|
||||
setIsNostrDMModalVisible(false)
|
||||
setIsProofSelectorModalVisible(false)
|
||||
setIsLoading(false)
|
||||
setResultModalInfo(undefined)
|
||||
setIsResultModalVisible(false)
|
||||
|
||||
navigation.dispatch(
|
||||
StackActions.popToTop()
|
||||
|
||||
@@ -20,6 +20,7 @@ import { verticalScale } from '@gocodingnow/rn-size-matters'
|
||||
import { translate } from '../i18n'
|
||||
import { MintUnit } from '../services/wallet/currency'
|
||||
import { StaticScreenProps, useNavigation } from '@react-navigation/native'
|
||||
import { SendOption } from './SendScreen'
|
||||
|
||||
type Props = StaticScreenProps<{
|
||||
unit: MintUnit
|
||||
@@ -90,14 +91,21 @@ export const TokenReceiveScreen = function TokenReceiveScreen({ route }: Props)
|
||||
|
||||
const gotoScan = async function () {
|
||||
tokenInputRef.current?.blur()
|
||||
navigation.navigate('Scan', {mintUrl: mint?.mintUrl, unit})
|
||||
navigation.navigate('Scan', {
|
||||
mintUrl: mint?.mintUrl,
|
||||
unit
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/* const gotoContacts = function () {
|
||||
//@ts-ignore
|
||||
navigation.navigate('ContactsNavigator', {
|
||||
screen: 'Contacts',
|
||||
params: {paymentOption: SendOption.LNURL_ADDRESS}})
|
||||
params: {
|
||||
paymentOption: SendOption.LNURL_ADDRESS
|
||||
}
|
||||
})
|
||||
} */
|
||||
|
||||
|
||||
|
||||
@@ -532,7 +532,6 @@ export const TopupScreen = observer(function TopupScreen({ route }: Props) {
|
||||
|
||||
if (updated.length > 1) {
|
||||
updated[1].sentToRelays = relaysToShareTo
|
||||
updated[1].sentEvent = sentEvent
|
||||
|
||||
// status does not change, just add event and relay info to tx.data
|
||||
transaction.setStatus(
|
||||
@@ -549,8 +548,12 @@ export const TopupScreen = observer(function TopupScreen({ route }: Props) {
|
||||
}
|
||||
|
||||
const gotoContacts = function () {
|
||||
navigation.navigate('Contacts', {
|
||||
paymentOption: ReceiveOption.SEND_PAYMENT_REQUEST
|
||||
//@ts-ignore
|
||||
navigation.navigate('ContactsNavigator', {
|
||||
screen: 'Contacts',
|
||||
params: {
|
||||
paymentOption: ReceiveOption.SEND_PAYMENT_REQUEST
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -616,6 +619,8 @@ export const TopupScreen = observer(function TopupScreen({ route }: Props) {
|
||||
setIsWithdrawModalVisible(false)
|
||||
setIsWithdrawRequestSending(false)
|
||||
setPaymentOption(ReceiveOption.SHOW_INVOICE)
|
||||
setResultModalInfo(undefined)
|
||||
setIsResultModalVisible(false)
|
||||
|
||||
navigation.dispatch(
|
||||
StackActions.popToTop()
|
||||
|
||||
@@ -1322,17 +1322,25 @@ const TopupInfoBlock = function (props: {
|
||||
}) {
|
||||
const {transaction, navigation, mint} = props
|
||||
const {mintsStore} = useStores()
|
||||
|
||||
// retrieve pr from NOT COMPLETED transaction as it might have been expired and removed from storage
|
||||
const paymentRequest = getPaymentRequestToRetry(transaction)
|
||||
const isInternetReachable = useIsInternetReachable()
|
||||
|
||||
|
||||
const [paymentRequest, setPaymentRequest] = useState<PaymentRequest | undefined>(undefined)
|
||||
const [isPendingTopupTaskSentToQueue, setIsPendingTopupTaskSentToQueue] = useState<boolean>(false)
|
||||
const [isResultModalVisible, setIsResultModalVisible] = useState<boolean>(false)
|
||||
const [resultModalInfo, setResultModalInfo] = useState<
|
||||
{status: TransactionStatus; message: string} | undefined
|
||||
>()
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
|
||||
useFocusEffect(useCallback(() => {
|
||||
// retrieve pr from NOT COMPLETED transaction as it might have been expired and removed from storage
|
||||
log.trace('[TopupInfoBlock] useFocusEffect start')
|
||||
const pr = getPaymentRequestToRetry(transaction)
|
||||
if(pr) {
|
||||
log.trace('[TopupInfoBlock] found payment request')
|
||||
setPaymentRequest(pr)
|
||||
}
|
||||
}, []))
|
||||
|
||||
useFocusEffect(useCallback(() => {
|
||||
const handlePendingTopupTaskResult = async (result: TransactionTaskResult) => {
|
||||
@@ -1470,6 +1478,16 @@ const TopupInfoBlock = function (props: {
|
||||
</>
|
||||
}
|
||||
/>
|
||||
{transaction.status === TransactionStatus.PENDING && paymentRequest && (
|
||||
<View style={{marginBottom: spacing.small}}>
|
||||
<QRCodeBlock
|
||||
qrCodeData={paymentRequest.encodedInvoice}
|
||||
title={translate("tranDetailScreen.invoice")}
|
||||
type='Bolt11Invoice'
|
||||
size={spacing.screenWidth * 0.8}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
<Card
|
||||
labelTx='tranDetailScreen.topupTo'
|
||||
style={$dataCard}
|
||||
@@ -1484,17 +1502,7 @@ const TopupInfoBlock = function (props: {
|
||||
<Text text={transaction.mint} />
|
||||
)
|
||||
}
|
||||
/>
|
||||
{transaction.status === TransactionStatus.PENDING && paymentRequest && (
|
||||
<View style={{marginBottom: spacing.small}}>
|
||||
<QRCodeBlock
|
||||
qrCodeData={paymentRequest.encodedInvoice}
|
||||
title={translate("tranDetailScreen.invoice")}
|
||||
type='Bolt11Invoice'
|
||||
size={spacing.screenWidth * 0.8}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
<BottomModal
|
||||
isVisible={isResultModalVisible ? true : false}
|
||||
ContentComponent={
|
||||
@@ -1900,6 +1908,7 @@ const getPaymentRequestToRetry = (
|
||||
transaction: Transaction,
|
||||
): PaymentRequest | undefined => {
|
||||
try {
|
||||
log.trace('[getPaymentRequestToRetry] start')
|
||||
if(transaction.type !== (TransactionType.TOPUP)) {
|
||||
return undefined
|
||||
}
|
||||
@@ -1910,14 +1919,20 @@ const getPaymentRequestToRetry = (
|
||||
return undefined
|
||||
}
|
||||
|
||||
const {mintsStore} = useStores()
|
||||
|
||||
/* const {mintsStore} = useStores()
|
||||
|
||||
// skip if mint is still offline
|
||||
const {mint} = transaction
|
||||
const mintInstance = mintsStore.findByUrl(mint)
|
||||
|
||||
log.trace('[getPaymentRequestToRetry] mint', {mint: mintInstance})
|
||||
|
||||
if(!mintInstance || mintInstance.status === MintStatus.OFFLINE) {
|
||||
return undefined
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
const data = JSON.parse(transaction.data)
|
||||
const pendingRecord = data.find(
|
||||
@@ -1926,6 +1941,8 @@ const getPaymentRequestToRetry = (
|
||||
|
||||
const paymentRequest: PaymentRequest = pendingRecord.paymentRequest
|
||||
|
||||
log.trace('[getPaymentRequestToRetry]', {paymentRequest})
|
||||
|
||||
if(!paymentRequest) {return undefined}
|
||||
if(pollerExists(`handlePendingTopupPoller-${paymentRequest.paymentHash}`)) {return undefined}
|
||||
|
||||
|
||||
@@ -649,7 +649,8 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
|
||||
}
|
||||
style={{
|
||||
width: spacing.screenWidth * 0.28,
|
||||
marginRight: spacing.small,
|
||||
marginRight: spacing.small,
|
||||
marginBottom: spacing.extraSmall
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -1510,34 +1510,29 @@ const handlePendingTopupTask = async function (params: {paymentRequest: PaymentR
|
||||
throw new AppError(Err.VALIDATION_ERROR, 'Returned quote is different then the one requested', {mintUrl, quote, mintQuote})
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
/*
|
||||
* UNPAID or ISSUED
|
||||
*/
|
||||
case MintQuoteState.UNPAID:
|
||||
case MintQuoteState.ISSUED:
|
||||
if (isBefore(pr.expiresAt as Date, new Date())) {
|
||||
log.debug('[handlePendingTopupTask]', `Invoice expired, removing: ${pr.paymentHash}`)
|
||||
|
||||
// expire related tx - but only if it has not been completed before this check
|
||||
if(transaction.status !== TransactionStatus.COMPLETED) {
|
||||
const transactionDataUpdate = {
|
||||
status: TransactionStatus.EXPIRED,
|
||||
message: 'Invoice expired',
|
||||
createdAt: new Date(),
|
||||
}
|
||||
|
||||
await transactionsStore.updateStatuses(
|
||||
[transactionId],
|
||||
TransactionStatus.EXPIRED,
|
||||
JSON.stringify(transactionDataUpdate),
|
||||
)
|
||||
}
|
||||
|
||||
stopPolling(`handlePendingTopupPoller-${paymentHash}`)
|
||||
paymentRequestsStore.removePaymentRequest(pr)
|
||||
}
|
||||
// continue
|
||||
if (isBefore(pr.expiresAt as Date, new Date())) {
|
||||
log.debug('[handlePendingTopupTask]', `Invoice expired, removing: ${pr.paymentHash}`)
|
||||
|
||||
// expire related tx - but only if it has not been completed before this check
|
||||
if(transaction.status !== TransactionStatus.COMPLETED) {
|
||||
const transactionDataUpdate = {
|
||||
status: TransactionStatus.EXPIRED,
|
||||
message: 'Invoice expired',
|
||||
createdAt: new Date(),
|
||||
}
|
||||
|
||||
await transactionsStore.updateStatuses(
|
||||
[transactionId],
|
||||
TransactionStatus.EXPIRED,
|
||||
JSON.stringify(transactionDataUpdate),
|
||||
)
|
||||
}
|
||||
|
||||
stopPolling(`handlePendingTopupPoller-${paymentHash}`)
|
||||
paymentRequestsStore.removePaymentRequest(pr)
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case MintQuoteState.UNPAID:
|
||||
log.trace('[handlePendingTopupTask] Quote not paid', {mintUrl, mintQuote})
|
||||
|
||||
@@ -1622,7 +1617,7 @@ const handlePendingTopupTask = async function (params: {paymentRequest: PaymentR
|
||||
)
|
||||
|
||||
transaction.setProfile(
|
||||
JSON.stringify(getSnapshot(pr.contactTo))
|
||||
JSON.stringify(pr.contactTo)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1648,6 +1643,8 @@ const handlePendingTopupTask = async function (params: {paymentRequest: PaymentR
|
||||
case MintQuoteState.ISSUED:
|
||||
log.trace('[handlePendingTopupTask] Quote already issued', {mintUrl, mintQuote})
|
||||
|
||||
paymentRequestsStore.removePaymentRequest(pr)
|
||||
|
||||
return {
|
||||
taskFunction: HANDLE_PENDING_TOPUP_TASK,
|
||||
transaction,
|
||||
@@ -1673,8 +1670,7 @@ const handlePendingTopupTask = async function (params: {paymentRequest: PaymentR
|
||||
} as WalletTaskResult
|
||||
}
|
||||
|
||||
} catch (e: any) {
|
||||
|
||||
} catch (e: any) {
|
||||
return {
|
||||
taskFunction: HANDLE_PENDING_TOPUP_TASK,
|
||||
mintUrl,
|
||||
|
||||
Reference in New Issue
Block a user