v0.3.2-beta.1 native release, paymentRequest receive fix

This commit is contained in:
minibits-cash
2025-10-17 11:25:59 +02:00
parent d3287c6c52
commit 6613545147
13 changed files with 88 additions and 116 deletions
-1
View File
@@ -1,4 +1,3 @@
api.cache(false)
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: [
+1
View File
@@ -93,6 +93,7 @@ notifee.onBackgroundEvent(async ({ type, detail }) => {
return true
})
globalThis.RNFB_SILENCE_MODULAR_DEPRECATION_WARNINGS = true
messaging().onMessage(NotificationService.onForegroundNotification)
messaging().setBackgroundMessageHandler(NotificationService.onBackgroundNotification)
NotificationService.initNotifications()
+6 -12
View File
@@ -301,7 +301,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = minibits_wallet/minibits_wallet.entitlements;
CURRENT_PROJECT_VERSION = 16;
CURRENT_PROJECT_VERSION = 17;
DEVELOPMENT_TEAM = GR2ZKMCLAM;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = minibits_wallet/Info.plist;
@@ -312,7 +312,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.3.1;
MARKETING_VERSION = 0.3.2;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -337,7 +337,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = minibits_wallet/minibits_wallet.entitlements;
CURRENT_PROJECT_VERSION = 16;
CURRENT_PROJECT_VERSION = 17;
DEVELOPMENT_TEAM = GR2ZKMCLAM;
INFOPLIST_FILE = minibits_wallet/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Minibits;
@@ -347,7 +347,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.3.1;
MARKETING_VERSION = 0.3.2;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -447,10 +447,7 @@
"-DFOLLY_CFG_NO_COROUTINES=1",
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
);
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
OTHER_LDFLAGS = "$(inherited) ";
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
@@ -533,10 +530,7 @@
"-DFOLLY_CFG_NO_COROUTINES=1",
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
);
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
OTHER_LDFLAGS = "$(inherited) ";
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
@@ -31,7 +31,7 @@
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Release"
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
+16 -11
View File
@@ -8,15 +8,13 @@ import {
ViewStyle,
KeyboardAvoidingView,
Platform,
StatusBar,
Modal as RNModal,
} from "react-native"
import { colors, useThemeColor, spacing } from "../theme"
import { Text, TextProps } from "./Text"
import { useSafeAreaInsets } from "react-native-safe-area-context"
import { Header } from "@react-navigation/stack"
import { moderateVerticalScale } from "@gocodingnow/rn-size-matters"
import { KeyboardState, useAnimatedKeyboard } from "react-native-reanimated"
import { log } from "../services"
import { log } from "../services/logService"
interface ModalProps extends ViewProps {
@@ -113,7 +111,7 @@ export function BottomModal(props: ModalProps) {
isVisible = true,
onBackdropPress,
onBackButtonPress,
backdropOpacity = Platform.OS === 'ios' ? 0.25 : 0,
backdropOpacity = Platform.OS === 'ios' ? 0.25 : 0.25,
content,
contentTx,
contentTxOptions,
@@ -165,20 +163,28 @@ export function BottomModal(props: ModalProps) {
// const statusBarOnModalOpen = useThemeColor('statusBarOnModalOpen')
// const keyboard = useAnimatedKeyboard()
//log.trace({keyboard})
// log.trace({isVisible})
return (
<View>
<Modal
isVisible={isVisible}
// statusBarTranslucent={true} // makes the modal hide behind the keyboard if open
statusBarTranslucent={true} // makes the modal hide behind the keyboard if open
avoidKeyboard={true}
// RNModal
// avoidKeyboard={true}
// allowSwipeDismissal
// onRequestClose={onBackButtonPress}
onBackdropPress={onBackdropPress}
onBackButtonPress={onBackButtonPress}
useNativeDriver={true}
hideModalContentWhileAnimating={true}
// useNativeDriverForBackdrop={true} // causes issues with backdropOpacity animation on Android
backdropOpacity={backdropOpacity}
style={[$outerContainerBase, $containerStyleOverride]}
{...otherProps}
>
@@ -244,8 +250,7 @@ const $outerContainerBase: ViewStyle = {
}
const $innerContainerBase: ViewStyle = {
width: '100%',
alignItems: 'center',
width: '100%',
borderTopLeftRadius: spacing.small,
borderTopRightRadius: spacing.small,
padding: spacing.small
+1 -1
View File
@@ -200,7 +200,7 @@ export const WalletProfileStoreModel = types
}),
recoverAddress: flow(function* recover(walletId: string, seedHash: string) {
let profileRecord: WalletProfileRecord = yield MinibitsClient.recoverProfile(
let profileRecord: WalletProfileRecord = yield MinibitsClient.recoverAddress(
walletId, seedHash
)
+1 -2
View File
@@ -239,8 +239,7 @@ export const OwnName = observer(function (props: {pubkey: string}) {
}
const { paid } = await MinibitsClient.checkDonationPaid(
donationInvoice.payment_hash as string,
pubkey as string
donationInvoice.payment_hash as string,
)
if(paid) {
+29 -64
View File
@@ -330,8 +330,9 @@ export const RecoveryOptionsScreen = observer(function RecoveryOptionsScreen(_:
<Card
style={$card}
HeadingComponent={
<ListItem
HeadingComponent={
<>
<ListItem
tx="backupRemoveSpentCoins"
subTx="backupRemoveSpentCoinsDescription"
leftIcon='faRecycle'
@@ -347,33 +348,28 @@ export const RecoveryOptionsScreen = observer(function RecoveryOptionsScreen(_:
</View>
}
style={$item}
/>
/>
<ListItem
tx="increaseRecoveryIndexes"
subTx="increaseRecoveryIndexesDesc"
leftIcon='faArrowUp'
leftIconColor={colors.palette.success300}
leftIconInverse={true}
RightComponent={
<View style={$rightContainer}>
<Button
onPress={increaseCounters}
tx='recoveryScreen_increase'
preset='secondary'
/>
</View>
}
topSeparator={true}
style={$item}
/>
</>
}
/>
<Card
style={$card}
HeadingComponent={
<>
<ListItem
tx="increaseRecoveryIndexes"
subTx="increaseRecoveryIndexesDesc"
leftIcon='faArrowUp'
leftIconColor={colors.palette.success300}
leftIconInverse={true}
RightComponent={
<View style={$rightContainer}>
<Button
onPress={increaseCounters}
tx='recoveryScreen_increase'
preset='secondary'
/>
</View>
}
style={$item}
/>
</>
}
/>
<Card
labelTx='recoveryScreen_experimentalTools'
style={[$card, {marginBottom: spacing.huge * 2}]}
@@ -494,39 +490,7 @@ export const RecoveryOptionsScreen = observer(function RecoveryOptionsScreen(_:
}
onBackButtonPress={toggleMintQuoteModal}
onBackdropPress={toggleMintQuoteModal}
/>
{/* it looks like this modal is a duplicate of the one above? for now not removing, but worth checking later */}
<BottomModal
isVisible={isMintQuoteModalVisible ? true : false}
ContentComponent={
<View style={$quoteContainer}>
<Text tx='recoveryEnterMintQuote' />
<View style={{flexDirection: 'row', alignItems: 'center', marginTop: spacing.small}}>
<TextInput
ref={mintQuoteInputRef}
onChangeText={(quote) => setMintQuote(quote)}
value={mintQuote}
autoCapitalize='none'
keyboardType='default'
maxLength={40}
selectTextOnFocus={true}
style={[$quoteInput, {backgroundColor: inputBg, color: inputText}]}
/>
<Button
tx='commonPaste'
preset='secondary'
style={$pasteButton}
onPress={onPasteMintQuote}
/>
</View>
<View style={[$buttonContainer, {marginTop: spacing.medium}]}>
<Button onPress={onMintEcashFromQuote} tx='recoveryMintEcashButton' />
</View>
</View>
}
onBackButtonPress={toggleMintQuoteModal}
onBackdropPress={toggleMintQuoteModal}
/>
/>
<BottomModal
isVisible={isMintQuoteResultModalVisible ? true : false}
ContentComponent={
@@ -608,7 +572,7 @@ export const RecoveryOptionsScreen = observer(function RecoveryOptionsScreen(_:
)
const $screen: ViewStyle = {
//flex: 1,
// flex: 1,
}
const $headerContainer: TextStyle = {
@@ -625,7 +589,8 @@ const $contentContainer: TextStyle = {
}
const $mintsContainer: TextStyle = {
// flex: 1,
flex: 0,
// alignItems: 'flex-start',
alignSelf: 'stretch',
minHeight: spacing.screenHeight * 0.4,
}
@@ -633,8 +598,8 @@ const $mintsContainer: TextStyle = {
const $quoteContainer: TextStyle = {
// flex: 1,
padding: spacing.small,
alignSelf: 'stretch',
minHeight: spacing.screenHeight * 0.3,
// alignSelf: 'stretch',
maxHeight: spacing.screenHeight * 0.3,
}
const $pasteButton: ViewStyle = {
+5 -4
View File
@@ -351,6 +351,7 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
const toggleSendModal = () => {
log.trace('toggleSendModal')
setIsSendModalVisible(previousState => !previousState)
}
@@ -744,7 +745,7 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
<BottomModal
isVisible={isUpdateModalVisible ? true : false}
style={{alignItems: 'stretch'}}
// style={{alignItems: 'stretch'}}
ContentComponent={
<ListItem
LeftComponent={
@@ -765,7 +766,7 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
/>
<BottomModal
isVisible={isMintsModalVisible ? true : false}
style={{alignItems: 'stretch'}}
// style={{alignItems: 'stretch'}}
ContentComponent={
<MintsByUnitList
mintsByUnit={groupedMints}
@@ -780,7 +781,7 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
/>
<BottomModal
isVisible={isSendModalVisible ? true : false}
style={{alignItems: 'stretch'}}
//style={{alignItems: 'stretch'}}
ContentComponent={
<>
<ListItem
@@ -803,7 +804,7 @@ export const WalletScreen = observer(function WalletScreen({ route }: Props) {
/>
<BottomModal
isVisible={isReceiveModalVisible ? true : false}
style={{alignItems: 'stretch'}}
// style={{alignItems: 'stretch'}}
ContentComponent={
<>
<ListItem
+8 -8
View File
@@ -10,7 +10,7 @@ import { CurrencyCode } from "./wallet/currency"
import { rootStoreInstance } from "../models"
import { JwtTokens } from "./keyChain"
import { AuthChallengeResponse, VerifyChallengeResponse } from "../models/AuthStore"
// refresh // refresh // refresh
// refresh // refresh // refresh // refresh
type MinibitsRequestArgs = {
method: 'POST' | 'PUT' | 'DELETE' | 'GET'
@@ -214,7 +214,7 @@ const recoverProfile = async function (walletId: string, seedHash: string) {
jwtAuthRequired: true
}) as WalletProfileRecord
log.info('[recoverProfile]', `Recovered wallet address`, {seedHash, walletId})
log.info('[recoverProfile]', `Recovered wallet address`, {walletAddress: walletProfile.nip05})
return walletProfile
}
@@ -311,11 +311,11 @@ const createDonation = async function (amount: number, memo: string, pubkey: str
}
const checkDonationPaid = async function (paymentHash: string, pubkey: string) {
const checkDonationPaid = async function (paymentHash: string) {
const url = MINIBITS_SERVER_API_HOST + '/donation'
const method = 'GET'
const donationPaid = await fetchApi(url + `/${paymentHash}/${pubkey}`, {
const donationPaid = await fetchApi(url + `/${paymentHash}`, {
method,
jwtAuthRequired: true
}) as {paid: boolean}
@@ -326,14 +326,13 @@ const checkDonationPaid = async function (paymentHash: string, pubkey: string) {
}
const createClaim = async function (walletId: string, seedHash: string, pubkey: string, batchFrom?: number) {
const createClaim = async function (walletId: string, seedHash: string, batchFrom?: number) {
const url = MINIBITS_SERVER_API_HOST + '/claim'
const method = 'POST'
const body = {
walletId,
seedHash,
pubkey,
seedHash,
batchFrom
}
@@ -458,7 +457,8 @@ export const MinibitsClient = {
updateWalletProfile,
updateWalletProfileNip05,
updateDeviceToken,
recoverProfile,
recoverProfile,
recoverAddress,
getRandomPictures,
getWalletProfileByNip05,
getWalletProfileBySeedHash,
+7 -1
View File
@@ -612,9 +612,15 @@ const getTransactionBy = function (criteria: { paymentId?: string; quote?: strin
const db = getInstance()
const {rows} = db.execute(query, params)
log.trace(rows)
if(!rows || rows.length === 0) {
throw new AppError(Err.DATABASE_ERROR, 'Transaction not found', 'No matching transaction')
}
return normalizeTransactionRecord(rows?.item(0))
} catch (e: any) {
throw new AppError(Err.DATABASE_ERROR, 'Transaction not found', e.message)
throw new AppError(Err.DATABASE_ERROR, 'Transaction getTransactionBy error', e.message)
}
}
+1 -1
View File
@@ -421,7 +421,7 @@ export const receiveByCashuPaymentRequestTask = async function (
}
// Let's find transaction with related payment request
const transaction = transactionsStore.findBy({paymentRequest: paymentRequestId})
const transaction = transactionsStore.findBy({paymentId: paymentRequestId})
if(!transaction) {
throw new AppError(
+12 -10
View File
@@ -858,16 +858,19 @@ const syncStateWithMintTask = async function (
} as TransactionStateUpdate
} else {
// syn just after we've reverted the transaction should not complete it again
if(tx.status !== TransactionStatus.REVERTED) {
completedTransactionIds.push(Number(tId))
completedTransactionIds.push(Number(tId))
return {
tId: Number(tId),
amount: tx.amount,
spentByMintAmount: spentByMintTxAmount as number,
meltQuoteToRecover: tx.type === TransactionType.TRANSFER && tx.quote && tx.quote.length > 0 ? tx.quote : null,
updatedStatus: TransactionStatus.COMPLETED
} as TransactionStateUpdate
return {
tId: Number(tId),
amount: tx.amount,
spentByMintAmount: spentByMintTxAmount as number,
meltQuoteToRecover: tx.type === TransactionType.TRANSFER && tx.quote && tx.quote.length > 0 ? tx.quote : null,
updatedStatus: TransactionStatus.COMPLETED
} as TransactionStateUpdate
}
}
}
@@ -2066,8 +2069,7 @@ const handleClaimQueue = async function (): Promise<void> {
// Based on user setting, ask for batched token if more then 5 payments are waiting to be claimed
const claimedTokens = await MinibitsClient.createClaim(
keys.walletId,
keys.SEED.seedHash,
keys.NOSTR.publicKey,
keys.SEED.seedHash,
isBatchClaimOn ? 5 : undefined
)