Merge branch 'master' into intentd

This commit is contained in:
Marcos Rodriguez Velez 2024-10-26 12:10:42 -04:00
commit 92fb8bf686
52 changed files with 766 additions and 518 deletions

View File

@ -5,7 +5,7 @@ GEM
base64
nkf
rexml
activesupport (7.2.1.1)
activesupport (7.2.1.2)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
@ -24,7 +24,7 @@ GEM
artifactory (3.0.17)
atomos (0.1.3)
aws-eventstream (1.3.0)
aws-partitions (1.992.0)
aws-partitions (1.996.0)
aws-sdk-core (3.211.0)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
@ -220,7 +220,7 @@ GEM
i18n (1.14.6)
concurrent-ruby (~> 1.0)
jmespath (1.6.2)
json (2.7.2)
json (2.7.4)
jwt (2.9.3)
base64
logger (1.6.1)
@ -254,7 +254,7 @@ GEM
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
retriable (3.1.2)
rexml (3.3.8)
rexml (3.3.9)
rouge (2.0.7)
ruby-macho (2.5.1)
ruby2_keywords (0.0.5)

View File

@ -14,4 +14,15 @@
<natures>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>1729710829465</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>

View File

@ -20,4 +20,15 @@
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>1729710829486</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>

View File

@ -109,7 +109,16 @@
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" android:mimeType="application/octet-stream" android:pathPattern=".*\\.psbt" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" android:mimeType="image/jpeg" />
<data android:scheme="file" android:mimeType="image/png" />
<data android:scheme="file" android:mimeType="image/jpg" />
</intent-filter>
<!-- Intent filter for other custom schemes (bitcoin, bluewallet, etc.) -->
<intent-filter tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" />

View File

@ -1,4 +1,3 @@
import LocalQRCode from '@remobile/react-native-qrcode-local-image';
import { Alert, Linking, Platform } from 'react-native';
import DocumentPicker from 'react-native-document-picker';
import RNFS from 'react-native-fs';
@ -9,6 +8,7 @@ import presentAlert from '../components/Alert';
import loc from '../loc';
import { isDesktop } from './environment';
import { readFile } from './react-native-bw-file-access';
import RNQRGenerator from 'rn-qr-generator';
const _sanitizeFileName = (fileName: string) => {
// Remove any path delimiters and non-alphanumeric characters except for -, _, and .
@ -128,14 +128,18 @@ export const showImagePickerAndReadImage = (): Promise<string | undefined> => {
if (!response.didCancel) {
const asset = response.assets?.[0] ?? {};
if (asset.uri) {
const uri = asset.uri.toString().replace('file://', '');
LocalQRCode.decode(uri, (error: any, result: string) => {
if (!error) {
resolve(result);
} else {
RNQRGenerator.detect({
uri: decodeURI(asset.uri.toString()),
})
.then(result => {
if (result) {
resolve(result.values[0]);
}
})
.catch(error => {
console.error(error);
reject(new Error(loc.send.qr_error_no_qrcode));
}
});
});
}
}
},
@ -183,13 +187,19 @@ export const showFilePickerAndReadFile = async function (): Promise<{ data: stri
return;
}
const uri2 = res.fileCopyUri.replace('file://', '');
LocalQRCode.decode(decodeURI(uri2), (error: any, result: string) => {
if (!error) {
resolve({ data: result, uri: fileCopyUri });
} else {
RNQRGenerator.detect({
uri: decodeURI(uri2),
})
.then(result => {
if (result) {
resolve({ data: result.values[0], uri: fileCopyUri });
}
})
.catch(error => {
console.error(error);
resolve({ data: false, uri: false });
}
});
});
});
}

View File

@ -190,24 +190,54 @@ function Notifications(props) {
* @returns {Promise<object>} Response object from API rest call
*/
Notifications.majorTomToGroundControl = async function (addresses, hashes, txids) {
if (!Array.isArray(addresses) || !Array.isArray(hashes) || !Array.isArray(txids))
throw new Error('no addresses or hashes or txids provided');
const pushToken = await Notifications.getPushToken();
if (!pushToken || !pushToken.token || !pushToken.os) return;
try {
if (!Array.isArray(addresses) || !Array.isArray(hashes) || !Array.isArray(txids)) {
throw new Error('No addresses, hashes, or txids provided');
}
const response = await fetch(`${baseURI}/majorTomToGroundControl`, {
method: 'POST',
headers: _getHeaders(),
body: JSON.stringify({
const pushToken = await Notifications.getPushToken();
if (!pushToken || !pushToken.token || !pushToken.os) {
return;
}
const requestBody = JSON.stringify({
addresses,
hashes,
txids,
token: pushToken.token,
os: pushToken.os,
}),
});
});
return response.json();
let response;
try {
response = await fetch(`${baseURI}/majorTomToGroundControl`, {
method: 'POST',
headers: _getHeaders(),
body: requestBody,
});
} catch (networkError) {
console.error('Network request failed:', networkError);
throw networkError;
}
if (!response.ok) {
return;
}
const responseText = await response.text();
if (responseText) {
try {
return JSON.parse(responseText);
} catch (jsonError) {
console.error('Error parsing response JSON:', jsonError);
throw jsonError;
}
} else {
return {}; // Return an empty object if there is no response body
}
} catch (error) {
console.error('Error in majorTomToGroundControl:', error);
}
};
/**

View File

@ -5,6 +5,11 @@ import { scanQrHelper } from '../helpers/scan-qr';
import loc from '../loc';
import presentAlert from './Alert';
import ToolTipMenu from './TooltipMenu';
import { CommonToolTipActions } from '../typings/CommonToolTipActions';
import Clipboard from '@react-native-clipboard/clipboard';
import RNQRGenerator from 'rn-qr-generator';
import { showFilePickerAndReadFile, showImagePickerAndReadImage } from '../blue_modules/fs';
import { useTheme } from './themes';
interface AddressInputProps {
isLoading?: boolean;
@ -73,7 +78,7 @@ const AddressInput = ({
}, [launchedBy, onBarScanned, scanButtonTapped]);
const onMenuItemPressed = useCallback(
(action: string) => {
async (action: string) => {
if (onBarScanned === undefined) throw new Error('onBarScanned is required');
switch (action) {
case actionKeys.ScanQR:
@ -87,12 +92,42 @@ const AddressInput = ({
}
break;
case actionKeys.CopyFromClipboard:
Clipboard.getString()
.then(onChangeText)
.catch(error => {
presentAlert({ message: error.message });
});
case CommonToolTipActions.PasteFromClipboard.id:
try {
let getImage: string | null = null;
if (Platform.OS === 'android') {
getImage = await Clipboard.getImage();
} else {
const hasImage = await Clipboard.hasImage();
if (hasImage) {
getImage = await Clipboard.getImageJPG();
}
}
if (getImage) {
try {
const base64Data = getImage.replace(/^data:image\/jpeg;base64,/, '');
const values = await RNQRGenerator.detect({
base64: base64Data,
});
if (values && values.values.length > 0) {
onChangeText(values.values[0]);
} else {
presentAlert({ message: loc.send.qr_error_no_qrcode });
}
} catch (error) {
presentAlert({ message: (error as Error).message });
}
} else {
const clipboardText = await Clipboard.getString();
onChangeText(clipboardText);
}
} catch (error) {
presentAlert({ message: (error as Error).message });
}
break;
case actionKeys.ChoosePhoto:
showImagePickerAndReadImage()
@ -199,7 +234,7 @@ const styles = StyleSheet.create({
const actionKeys = {
ScanQR: 'scan_qr',
CopyFromClipboard: 'copy_from_clipboard',
PasteFromClipboard: 'copy_from_clipboard',
ChoosePhoto: 'choose_photo',
ImportFile: 'import_file',
};
@ -226,8 +261,8 @@ const actions = [
icon: actionIcons.ScanQR,
},
{
id: actionKeys.CopyFromClipboard,
text: loc.wallets.list_long_clipboard,
id: actionKeys.PasteFromClipboard,
text: loc.wallets.paste_from_clipboard,
icon: actionIcons.Clipboard,
},
{

View File

@ -16,6 +16,8 @@ import { Chain } from '../models/bitcoinUnits';
import { navigationRef } from '../NavigationService';
import ActionSheet from '../screen/ActionSheet';
import { useStorage } from '../hooks/context/useStorage';
import RNQRGenerator from 'rn-qr-generator';
import presentAlert from './Alert';
const MenuElements = lazy(() => import('../components/MenuElements'));
const DeviceQuickActions = lazy(() => import('../components/DeviceQuickActions'));
@ -104,17 +106,51 @@ const CompanionDelegates = () => {
}, [fetchAndSaveWalletTransactions, refreshAllWalletTransactions, wallets]);
const handleOpenURL = useCallback(
(event: { url: string }) => {
DeeplinkSchemaMatch.navigationRouteFor(event, value => navigationRef.navigate(...value), {
wallets,
addWallet,
saveToDisk,
setSharedCosigner,
});
},
[addWallet, saveToDisk, setSharedCosigner, wallets],
);
async (event: { url: string }): Promise<void> => {
const { url } = event;
if (url) {
const decodedUrl = decodeURIComponent(url);
const fileName = decodedUrl.split('/').pop()?.toLowerCase();
if (fileName && /\.(jpe?g|png)$/i.test(fileName)) {
try {
const values = await RNQRGenerator.detect({
uri: decodedUrl,
});
if (values && values.values.length > 0) {
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
DeeplinkSchemaMatch.navigationRouteFor(
{ url: values.values[0] },
(value: [string, any]) => navigationRef.navigate(...value),
{
wallets,
addWallet,
saveToDisk,
setSharedCosigner,
},
);
} else {
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
presentAlert({ message: loc.send.qr_error_no_qrcode });
}
} catch (error) {
console.error('Error detecting QR code:', error);
}
}
} else {
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
DeeplinkSchemaMatch.navigationRouteFor(event, (value: [string, any]) => navigationRef.navigate(...value), {
wallets,
addWallet,
saveToDisk,
setSharedCosigner,
});
}
},
[wallets, addWallet, saveToDisk, setSharedCosigner],
);
const showClipboardAlert = useCallback(
({ contentType }: { contentType: undefined | string }) => {
triggerHapticFeedback(HapticFeedbackTypes.ImpactLight);

View File

@ -2,310 +2,216 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LSMinimumSystemVersion</key>
<string>11</string>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>io.bluewallet.bluewallet.fetchTxsForWallet</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>BlueWallet</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>PSBT</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>io.bluewallet.psbt</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>TXN</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>io.bluewallet.psbt.txn</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>ELECTRUMBACKUP</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>io.bluewallet.backup</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>BW COSIGNER</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>io.bluewallet.bwcosigner</string>
</array>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>bitcoin</string>
<string>lightning</string>
<string>bluewallet</string>
<string>lapp</string>
<string>blue</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationCategoryType</key>
<string>public.app-category.finance</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>https</string>
<string>http</string>
</array>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSAllowsLocalNetworking</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
<key>onion</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>tailscale.net</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>ts.net</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
<key>NSCameraUsageDescription</key>
<string>In order to quickly scan the recipient&apos;s address, we need your permission to use the camera to scan their QR Code.</string>
<key>NSFaceIDUsageDescription</key>
<string>In order to use FaceID please confirm your permission.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Your authorization is required to save this image.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>In order to import an image for scanning, we need your permission to access your photo library.</string>
<key>NSUserActivityTypes</key>
<array>
<string>io.bluewallet.bluewallet.receiveonchain</string>
<string>io.bluewallet.bluewallet.xpub</string>
</array>
<key>UIAppFonts</key>
<array>
<string>Entypo.ttf</string>
<string>FontAwesome.ttf</string>
<string>FontAwesome5_Brands.ttf</string>
<string>FontAwesome5_Regular.ttf</string>
<string>FontAwesome5_Solid.ttf</string>
<string>Ionicons.ttf</string>
<string>MaterialIcons.ttf</string>
<string>Octicons.ttf</string>
</array>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>processing</string>
<string>remote-notification</string>
</array>
<key>UIFileSharingEnabled</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>Partially Signed Bitcoin Transaction</string>
<key>UTTypeIdentifier</key>
<string>io.bluewallet.psbt</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>psbt</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeDescription</key>
<string>BW COSIGNER</string>
<key>UTTypeIdentifier</key>
<string>io.bluewallet.bwcosigner</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>bwcosigner</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>Bitcoin Transaction</string>
<key>UTTypeIdentifier</key>
<string>io.bluewallet.psbt.txn</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>txn</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>Electrum Backup</string>
<key>UTTypeIdentifier</key>
<string>io.bluewallet.backup</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>backup</string>
</array>
</dict>
</dict>
</array>
<key>UTImportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.text</string>
</array>
<key>UTTypeDescription</key>
<string>JSON File</string>
<key>UTTypeIdentifier</key>
<string>public.json</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>json</string>
</array>
<key>public.mime-type</key>
<array>
<string>application/json</string>
</array>
</dict>
</dict>
</array>
<key>bugsnag</key>
<dict>
<key>apiKey</key>
<string>17ba9059f676f1cc4f45d98182388b01</string>
</dict>
<key>FIREBASE_ANALYTICS_COLLECTION_ENABLED</key>
<false/>
<key>FIREBASE_MESSAGING_AUTO_INIT_ENABLED</key>
<false/>
<key>NSAppIntents</key>
<key>LSMinimumSystemVersion</key>
<string>11</string>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>io.bluewallet.bluewallet.fetchTxsForWallet</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>BlueWallet</string>
<key>CFBundleDocumentTypes</key>
<array>
<!-- PSBT file type -->
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>PSBT</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>io.bluewallet.psbt</string>
</array>
</dict>
<!-- Image file types -->
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>Image</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSItemContentTypes</key>
<array>
<string>public.jpeg</string>
<string>public.image</string>
</array>
</dict>
<!-- TXN file type -->
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>TXN</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>io.bluewallet.psbt.txn</string>
</array>
</dict>
<!-- Electrum Backup file type -->
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>ELECTRUMBACKUP</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>io.bluewallet.backup</string>
</array>
</dict>
<!-- BW COSIGNER file type -->
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>BW COSIGNER</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>io.bluewallet.bwcosigner</string>
</array>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>bitcoin</string>
<string>lightning</string>
<string>bluewallet</string>
<string>lapp</string>
<string>blue</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationCategoryType</key>
<string>public.app-category.finance</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>https</string>
<string>http</string>
</array>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSAllowsLocalNetworking</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
<key>onion</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>tailscale.net</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>ts.net</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
<key>NSCameraUsageDescription</key>
<string>In order to quickly scan the recipient's address, we need your permission to use the camera to scan their QR Code.</string>
<key>NSFaceIDUsageDescription</key>
<string>In order to use FaceID please confirm your permission.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Your authorization is required to save this image.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>In order to import an image for scanning, we need your permission to access your photo library.</string>
<key>NSUserActivityTypes</key>
<array>
<string>io.bluewallet.bluewallet.receiveonchain</string>
<string>io.bluewallet.bluewallet.xpub</string>
</array>
<key>UIAppFonts</key>
<array>
<string>Entypo.ttf</string>
<string>FontAwesome.ttf</string>
<string>FontAwesome5_Brands.ttf</string>
<string>FontAwesome5_Regular.ttf</string>
<string>FontAwesome5_Solid.ttf</string>
<string>Ionicons.ttf</string>
<string>MaterialIcons.ttf</string>
<string>Octicons.ttf</string>
</array>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>processing</string>
<string>remote-notification</string>
</array>
<key>UIFileSharingEnabled</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>NSAppIntents</key>
<array>
<dict>
<key>INIntentClassName</key>
@ -324,5 +230,131 @@
<string>Generates a QR code for a Bitcoin address from your wallet and exports it as an image.</string>
</dict>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
<!-- Define exported types (UTIs) for file types -->
<key>UTExportedTypeDeclarations</key>
<array>
<!-- PSBT -->
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>Partially Signed Bitcoin Transaction</string>
<key>UTTypeIdentifier</key>
<string>io.bluewallet.psbt</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>psbt</string>
</array>
</dict>
</dict>
<!-- BW Cosigner -->
<dict>
<key>UTTypeDescription</key>
<string>BW COSIGNER</string>
<key>UTTypeIdentifier</key>
<string>io.bluewallet.bwcosigner</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>bwcosigner</string>
</array>
</dict>
</dict>
<!-- TXN -->
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>Bitcoin Transaction</string>
<key>UTTypeIdentifier</key>
<string>io.bluewallet.psbt.txn</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>txn</string>
</array>
</dict>
</dict>
<!-- Electrum Backup -->
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>Electrum Backup</string>
<key>UTTypeIdentifier</key>
<string>io.bluewallet.backup</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>backup</string>
</array>
</dict>
</dict>
</array>
<!-- Define imported types for other files -->
<key>UTImportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.text</string>
</array>
<key>UTTypeDescription</key>
<string>JSON File</string>
<key>UTTypeIdentifier</key>
<string>public.json</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>json</string>
</array>
<key>public.mime-type</key>
<array>
<string>application/json</string>
</array>
</dict>
<key>LSHandlerRank</key>
<string>Alternate</string>
</dict>
</array>
<key>bugsnag</key>
<dict>
<key>apiKey</key>
<string>17ba9059f676f1cc4f45d98182388b01</string>
</dict>
<key>FIREBASE_ANALYTICS_COLLECTION_ENABLED</key>
<false/>
<key>FIREBASE_MESSAGING_AUTO_INIT_ENABLED</key>
<false/>
</dict>
</plist>
</plist>

View File

@ -1,6 +1,6 @@
PODS:
- boost (1.84.0)
- BugsnagReactNative (8.0.0):
- BugsnagReactNative (8.1.1):
- React-Core
- BVLinearGradient (2.8.3):
- React-Core
@ -1317,8 +1317,6 @@ PODS:
- React-Core
- react-native-menu (1.1.3):
- React
- react-native-qrcode-local-image (1.0.4):
- React
- react-native-randombytes (3.6.1):
- React-Core
- react-native-safe-area-context (4.11.1):
@ -1592,7 +1590,7 @@ PODS:
- React-utils (= 0.75.4)
- ReactNativeCameraKit (13.0.0):
- React-Core
- RealmJS (12.13.1):
- RealmJS (20.0.0):
- React
- RNCAsyncStorage (1.24.0):
- React-Core
@ -1635,6 +1633,9 @@ PODS:
- React-Core
- RNPermissions (4.1.5):
- React-Core
- RNQrGenerator (1.4.2):
- React
- ZXingObjC
- RNQuickAction (0.3.13):
- React
- RNRate (1.2.12):
@ -1819,6 +1820,9 @@ PODS:
- ReactCommon/turbomodule/core
- Yoga
- Yoga (0.0.0)
- ZXingObjC (3.6.9):
- ZXingObjC/All (= 3.6.9)
- ZXingObjC/All (3.6.9)
DEPENDENCIES:
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
@ -1868,7 +1872,6 @@ DEPENDENCIES:
- react-native-image-picker (from `../node_modules/react-native-image-picker`)
- react-native-ios-context-menu (from `../node_modules/react-native-ios-context-menu`)
- "react-native-menu (from `../node_modules/@react-native-menu/menu`)"
- "react-native-qrcode-local-image (from `../node_modules/@remobile/react-native-qrcode-local-image`)"
- react-native-randombytes (from `../node_modules/react-native-randombytes`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- react-native-screen-capture (from `../node_modules/react-native-screen-capture`)
@ -1913,6 +1916,7 @@ DEPENDENCIES:
- RNKeychain (from `../node_modules/react-native-keychain`)
- RNLocalize (from `../node_modules/react-native-localize`)
- RNPermissions (from `../node_modules/react-native-permissions`)
- RNQrGenerator (from `../node_modules/rn-qr-generator`)
- RNQuickAction (from `../node_modules/react-native-quick-actions`)
- RNRate (from `../node_modules/react-native-rate`)
- RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`)
@ -1930,6 +1934,7 @@ SPEC REPOS:
- CocoaAsyncSocket
- lottie-ios
- SocketRocket
- ZXingObjC
EXTERNAL SOURCES:
boost:
@ -2023,8 +2028,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-ios-context-menu"
react-native-menu:
:path: "../node_modules/@react-native-menu/menu"
react-native-qrcode-local-image:
:path: "../node_modules/@remobile/react-native-qrcode-local-image"
react-native-randombytes:
:path: "../node_modules/react-native-randombytes"
react-native-safe-area-context:
@ -2113,6 +2116,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-localize"
RNPermissions:
:path: "../node_modules/react-native-permissions"
RNQrGenerator:
:path: "../node_modules/rn-qr-generator"
RNQuickAction:
:path: "../node_modules/react-native-quick-actions"
RNRate:
@ -2138,7 +2143,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
boost: 4cb898d0bf20404aab1850c656dcea009429d6c1
BugsnagReactNative: c712dfc4b0b1cce9f195d5476c0ea05c2cbb7b23
BugsnagReactNative: c8b6afecdf4dc127246de7ebef082bc71d96ac51
BVLinearGradient: 880f91a7854faff2df62518f0281afb1c60d49a3
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5
@ -2184,7 +2189,6 @@ SPEC CHECKSUMS:
react-native-image-picker: 2fbbafdae7a7c6db9d25df2f2b1db4442d2ca2ad
react-native-ios-context-menu: e529171ba760a1af7f2ef0729f5a7f4d226171c5
react-native-menu: c30eb7a85d7b04d51945f61ea8a8986ed366ac5c
react-native-qrcode-local-image: 35ccb306e4265bc5545f813e54cc830b5d75bcfc
react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846
react-native-safe-area-context: 5141f11858b033636f1788b14f32eaba92cee810
react-native-screen-capture: 75db9b051c41fea47fa68665506e9257d4b1dadc
@ -2217,7 +2221,7 @@ SPEC CHECKSUMS:
ReactCodegen: 4bcb34e6b5ebf6eef5cee34f55aa39991ea1c1f1
ReactCommon: 6a952e50c2a4b694731d7682aaa6c79bc156e4ad
ReactNativeCameraKit: 9d46a5d7dd544ca64aa9c03c150d2348faf437eb
RealmJS: 325a7b621587dd9945306d4cbfd6b641bc20e2dd
RealmJS: 6946b520bada5568b7e92a5242e138d3a19aa69f
RNCAsyncStorage: ec53e44dc3e75b44aa2a9f37618a49c3bc080a7a
RNCClipboard: 5e503962f0719ace8f7fdfe9c60282b526305c85
RNCPushNotificationIOS: 64218f3c776c03d7408284a819b2abfda1834bc8
@ -2229,6 +2233,7 @@ SPEC CHECKSUMS:
RNKeychain: bfe3d12bf4620fe488771c414530bf16e88f3678
RNLocalize: 4f22418187ecd5ca693231093ff1d912d1b3c9bc
RNPermissions: 9fa74223844f437bc309e112994859dc47194829
RNQrGenerator: 5c12ab86443a07e923735800679da7b6fcaaeb31
RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93
RNRate: ef3bcff84f39bb1d1e41c5593d3eea4aab2bd73a
RNReactNativeHapticFeedback: 0d591ea1e150f36cb96d868d4e8d77272243d78a
@ -2241,6 +2246,7 @@ SPEC CHECKSUMS:
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
TrueSheet: 49bf7af5d5a29f018f02879c26a1afe595c85829
Yoga: 055f92ad73f8c8600a93f0e25ac0b2344c3b07e6
ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5
PODFILE CHECKSUM: 95cd28e70ae47c36e1e0b30f60bba0bd6ffa77d8

View File

@ -380,7 +380,7 @@
"list_empty_txs2_lightning": "\nللبدء في استخدامها، اضغط على \"إدارة الأموال\" واشحن رصيدك.",
"list_latest_transaction": "آخر عملية",
"list_long_choose": "اختيار صورة",
"list_long_clipboard": "النسخ من الحافظة",
"paste_from_clipboard": "النسخ من الحافظة",
"import_file": "استيراد ملف",
"list_long_scan": "مسح رمز الاستجابة (QR) ضوئيًا",
"list_title": "المحافظ",

View File

@ -460,7 +460,7 @@
"list_empty_txs2_lightning": "\nChcete-li ji začít používat, klepněte na „Správa prostředků“ a doplňte zůstatek.",
"list_latest_transaction": "Poslední transakce",
"list_long_choose": "Vybrat fotku",
"list_long_clipboard": "Kopírovat ze schránky",
"paste_from_clipboard": "Kopírovat ze schránky",
"import_file": "Importovat soubor",
"list_long_scan": "Naskenovat QR kód",
"list_title": "Peněženky",

View File

@ -183,7 +183,7 @@
"list_empty_txs2": "Dechrau efo dy waled",
"list_latest_transaction": "Trafodyn Diweddaraf",
"list_long_choose": "Dewis Llun",
"list_long_clipboard": "Copio o'r Clipfwrdd",
"paste_from_clipboard": "Copio o'r Clipfwrdd",
"import_file": "Mewnforio ffeil",
"list_title": "Waledi",
"list_tryagain": "Trio eto",

View File

@ -455,7 +455,7 @@
"list_empty_txs2_lightning": "\nDrücke zum Starten «Beträge verwalten», um das Wallet aufzuladen.",
"list_latest_transaction": "Letzte Transaktion",
"list_long_choose": "Foto auswählen",
"list_long_clipboard": "Aus der Zwischenablage kopieren",
"paste_from_clipboard": "Aus der Zwischenablage kopieren",
"import_file": "Datei importieren",
"list_long_scan": "QR Code scannen",
"list_title": "Wallets",

View File

@ -282,7 +282,7 @@
"list_empty_txs1": "Οι συναλλαγές θα εμφανιστούν εδώ,",
"list_latest_transaction": "Τελευταία συναλλαγή",
"list_long_choose": "Επιλογή φωτογραφίας",
"list_long_clipboard": "Αντιγραφή από το πρόχειρο",
"paste_from_clipboard": "Αντιγραφή από το πρόχειρο",
"list_long_scan": "Σάρωση QR Code",
"list_title": "Πορτοφόλια",
"list_tryagain": "Προσπαθήστε ξανά",

View File

@ -466,7 +466,7 @@
"list_empty_txs2_lightning": "\nTo start using it, tap on Manage Funds and topup your balance.",
"list_latest_transaction": "Latest Transaction",
"list_long_choose": "Choose Photo",
"list_long_clipboard": "Copy from Clipboard",
"paste_from_clipboard": "Paste from Clipboard",
"import_file": "Import File",
"list_long_scan": "Scan QR Code",
"list_title": "Wallets",

View File

@ -368,7 +368,7 @@
"list_empty_txs2_lightning": "\nPara comenzar a usarlo, toca en \"administrar fondos\" y añade algo de saldo.",
"list_latest_transaction": "Última transacción",
"list_long_choose": "Elegir foto",
"list_long_clipboard": "Copiar del portapapeles",
"paste_from_clipboard": "Copiar del portapapeles",
"import_file": "Importar archivo",
"list_long_scan": "Escanear código QR",
"list_title": "Carteras",

View File

@ -460,7 +460,7 @@
"list_empty_txs2_lightning": "\nPara comenzar a usarla, toca Administrar Fondos y recarga tu saldo.",
"list_latest_transaction": "Última Transacción",
"list_long_choose": "Elige una Foto",
"list_long_clipboard": "Copiar desde el Portapapeles",
"paste_from_clipboard": "Copiar desde el Portapapeles",
"import_file": "Importar Archivo",
"list_long_scan": "Escanear Código QR",
"list_title": "Billeteras",

View File

@ -386,7 +386,7 @@
"list_empty_txs2_lightning": "\nبرای شروع استفاده، روی «مدیریت دارایی» بزنید و موجودی خود را شارژ کنید.",
"list_latest_transaction": "آخرین تراکنش",
"list_long_choose": "انتخاب عکس",
"list_long_clipboard": "کپی از کلیپ‌بورد",
"paste_from_clipboard": "کپی از کلیپ‌بورد",
"import_file": "واردکردن فایل",
"list_long_scan": "اسکن کد QR",
"list_title": "کیف پول‌ها",

View File

@ -409,7 +409,7 @@
"list_empty_txs2_lightning": "Aloita lompakon käyttäminen napsauttamalla \"hallinnoi varoja\" ja lisää saldoasi.\n",
"list_latest_transaction": "Viimeisin Siirtotapahtuma",
"list_long_choose": "Valitse Kuva",
"list_long_clipboard": "Kopioi Leikepöydältä",
"paste_from_clipboard": "Kopioi Leikepöydältä",
"import_file": "Tuo tiedosto",
"list_long_scan": "Skannaa QR-koodi",
"list_title": "lompakot",

View File

@ -389,7 +389,7 @@
"list_empty_txs2_lightning": "\nPour commencer à l'utiliser taper sur \"Gérer les fonds\" et alimentez votre solde.",
"list_latest_transaction": "dernière transaction",
"list_long_choose": "Choisir une photo",
"list_long_clipboard": "Copier depuis le presse-papier",
"paste_from_clipboard": "Copier depuis le presse-papier",
"import_file": "Importer le fichier",
"list_long_scan": "Scanner le QR Code",
"list_title": "portefeuilles",

View File

@ -433,7 +433,7 @@
"list_empty_txs2_lightning": "\nלהתחלת שימוש לחצו על \"ניהול כספים\" ומלאו את היתרה שלכם.",
"list_latest_transaction": "פעולה אחרונה",
"list_long_choose": "בחר תמונה",
"list_long_clipboard": "העתקה מלוח",
"paste_from_clipboard": "העתקה מלוח",
"import_file": "יבוא קובץ",
"list_long_scan": "סריקת קוד QR",
"list_title": "ארנקים",

View File

@ -382,7 +382,7 @@
"list_empty_txs2_lightning": "\nA kezdéshez kattints a \"Kezelés\"-re, és töltsd fel az egyenleged.",
"list_latest_transaction": "utolsó tranzakció",
"list_long_choose": "Válassz fényképet",
"list_long_clipboard": "Másolás vágólapról",
"paste_from_clipboard": "Másolás vágólapról",
"import_file": "fájl importálása",
"list_long_scan": "QR kód szkennelése",
"list_title": "tárcák",

View File

@ -377,7 +377,7 @@
"list_empty_txs2_lightning": "\nPer iniziare ad usarlo, seleziona Gestisci Fondi e ricarica il tuo saldo.",
"list_latest_transaction": "Transazioni recenti",
"list_long_choose": "Scegli foto",
"list_long_clipboard": "Copia dagli appunti",
"paste_from_clipboard": "Copia dagli appunti",
"list_long_scan": "Scansiona un codice QR",
"list_title": "Portafogli",
"list_tryagain": "Riprova",

View File

@ -455,7 +455,7 @@
"list_empty_txs2_lightning": "\n利用を開始するには\"資金の管理\"をタップしてウォレットへ送金してください。",
"list_latest_transaction": "最新の取引",
"list_long_choose": "写真選択",
"list_long_clipboard": "クリップボードからコピー",
"paste_from_clipboard": "クリップボードからコピー",
"import_file": "インポートファイル",
"list_long_scan": "QRコードをスキャン",
"list_title": "ウォレット",

View File

@ -359,7 +359,7 @@
"list_empty_txs2_lightning": "\n사용하시려면 기금관리를 탭하신다음 잔고를 더해 주세요.",
"list_latest_transaction": "최근 트랜잭션",
"list_long_choose": "사진 선택하기",
"list_long_clipboard": "클립보드에서 복사",
"paste_from_clipboard": "클립보드에서 복사",
"import_file": "화일 들여오기",
"list_long_scan": "QR 코드 스캔",
"list_title": "지갑",

View File

@ -331,7 +331,7 @@
"list_empty_txs2_lightning": "\nUntuk mula menggunakan, ketik pada Uruskan Wang dan tambah nilai pada baki anda.",
"list_latest_transaction": "Urus Niaga Terkini",
"list_long_choose": "Pilih Gambar",
"list_long_clipboard": "Salin dari Papan Sepit",
"paste_from_clipboard": "Salin dari Papan Sepit",
"import_file": "Pindah Masuk Fail",
"list_long_scan": "Imbas Kod QR",
"list_title": "Dompet",

View File

@ -362,7 +362,7 @@
"list_empty_txs2_lightning": "\nFor å begynne å bruke den, trykk på Administrer Midler og fyll på saldoen.",
"list_latest_transaction": "Siste Transaksjon",
"list_long_choose": "Velg Bilde",
"list_long_clipboard": "Kopier fra utklippstavlen",
"paste_from_clipboard": "Kopier fra utklippstavlen",
"import_file": "Importer Fil",
"list_long_scan": "Skann QR-kode",
"list_title": "Lommebøker",

View File

@ -364,7 +364,7 @@
"list_empty_txs2_lightning": "\nOm het te gebruiken, tikt u op \"tegoeden beheren\" en laadt u uw saldo op.",
"list_latest_transaction": "Laatste transactie",
"list_long_choose": "Kies foto",
"list_long_clipboard": "Kopiëren van klembord",
"paste_from_clipboard": "Kopiëren van klembord",
"import_file": "Importeer bestand",
"list_long_scan": "Scan QR-code",
"list_title": "Wallets",

View File

@ -449,7 +449,7 @@
"list_empty_txs2_lightning": "\nAby zacząć używać, dotknij Zarządzaj Środkami i doładuj swoje saldo.",
"list_latest_transaction": "Ostatnia transakcja",
"list_long_choose": "Wybierz zdjęcie",
"list_long_clipboard": "Kopiuj ze schowka",
"paste_from_clipboard": "Kopiuj ze schowka",
"import_file": "Importuj plik",
"list_long_scan": "Zeskanuj kod QR",
"list_title": "Portfele",

View File

@ -449,7 +449,7 @@
"list_empty_txs2_lightning": "\nPara começar a usar clique em \"administrar fundos\" e recarregue o seu saldo.",
"list_latest_transaction": "Transação mais recente",
"list_long_choose": "Escolher foto",
"list_long_clipboard": "Copiar da área de transferência",
"paste_from_clipboard": "Colar da área de transferência",
"import_file": "Importar arquivo",
"list_long_scan": "Leia o código QR",
"list_title": "Carteiras",

View File

@ -318,7 +318,7 @@
"list_empty_txs2_lightning": "\nPara começar a usar toque em \"gerir fundos\" e recarregue o seu saldo.",
"list_latest_transaction": "últimas transacções",
"list_long_choose": "Escolher Foto",
"list_long_clipboard": "Copiar da área de transferência",
"paste_from_clipboard": "Copiar da área de transferência",
"import_file": "Importar ficheiro",
"list_long_scan": "Leia o código QR",
"list_title": "carteiras",

View File

@ -340,7 +340,7 @@
"list_empty_txs2_lightning": "\nPentru a începe să utilizezi, apasă pe Administrează Fonduri și încarcă balanța.",
"list_latest_transaction": "Ultima tranzacție",
"list_long_choose": "Alege foto",
"list_long_clipboard": "Copiază din clipboard",
"paste_from_clipboard": "Copiază din clipboard",
"import_file": "Importă fișier",
"list_long_scan": "Scaneză cod QR",
"list_title": "Portofele",

View File

@ -460,7 +460,7 @@
"list_empty_txs2_lightning": "\nДля начала использования нажмите на 'Управление средствами' и пополните баланс.",
"list_latest_transaction": "Последняя транзакция",
"list_long_choose": "Выбрать фото",
"list_long_clipboard": "Вставить из буфера обмена",
"paste_from_clipboard": "Вставить из буфера обмена",
"import_file": "Импортировать файл",
"list_long_scan": "Сканировать QR-код",
"list_title": "Кошельки",

View File

@ -357,7 +357,7 @@
"list_empty_txs2_lightning": "\nඑය භාවිතා කිරීම ආරම්භ කිරීම සඳහා කළමනාකරණය කළමනාකරණය කර ඔබේ ශේෂය ඉහළ නැංවීමට තට්ටු කරන්න.",
"list_latest_transaction": "නවතම ගනුදෙනුව",
"list_long_choose": "ඡායාරූපය තෝරන්න",
"list_long_clipboard": "පසුරු පුවරුවෙන් පිටපත් කරන්න",
"paste_from_clipboard": "පසුරු පුවරුවෙන් පිටපත් කරන්න",
"import_file": "ආයාත ගොනුව",
"list_long_scan": "QR කේතය පරිලෝකනය කරන්න",
"list_title": "පසුම්බි",

View File

@ -209,7 +209,7 @@
"list_empty_txs2_lightning": "\nKliknite na \"spravovať zostatok\" a naplňte si peňaženku.",
"list_latest_transaction": "posledná transakcia",
"list_long_choose": "Vyberte fotku",
"list_long_clipboard": "Skopírovať zo schránky",
"paste_from_clipboard": "Skopírovať zo schránky",
"list_long_scan": "Skenovať QR kód",
"list_title": "peňaženky",
"list_tryagain": "Skúste znovu",

View File

@ -367,7 +367,7 @@
"list_empty_txs2_lightning": "\nČe želite začeti z uporabo, tapnite na \"uredi sredstva\" in napolnite denarnico.",
"list_latest_transaction": "Zadnja transakcija",
"list_long_choose": "Izberite fotografijo",
"list_long_clipboard": "Kopiraj iz odložišča",
"paste_from_clipboard": "Kopiraj iz odložišča",
"import_file": "Uvozi datoteko",
"list_long_scan": "Skeniraj QR kodo",
"list_title": "Denarnice",

View File

@ -378,7 +378,7 @@
"list_empty_txs2_lightning": "\nFör att komma igång klicka på \"sätt in / ta ut\" ovan och sätt in dina första bitcoin.",
"list_latest_transaction": "Senaste transaktion",
"list_long_choose": "Välj Foto",
"list_long_clipboard": "Kopiera från Urklipp",
"paste_from_clipboard": "Kopiera från Urklipp",
"import_file": "Importera fil",
"list_long_scan": "Skanna QR kod",
"list_title": "Plånböcker",

View File

@ -254,7 +254,7 @@
"list_empty_txs2_lightning": "\nแตะที่ \"จัดการเงิน\" เพื่อเริ่มใช้งาน และเติมเงิน",
"list_latest_transaction": "ธุรกรรมล่าสุด",
"list_long_choose": "เลือกรูปภาพ",
"list_long_clipboard": "คัดลอกจากคลิปบอร์ด",
"paste_from_clipboard": "คัดลอกจากคลิปบอร์ด",
"import_file": "นำเข้าไฟล์",
"list_long_scan": "สแกนคิวอาร์โค้ด",
"list_title": "กระเป๋าสตางค์",

View File

@ -372,7 +372,7 @@
"list_empty_txs2_lightning": "\nĐể bắt đầu sử dụng nó, chạm vào Quản lý tiền, và nạp tiền vào số dư của bạn. ",
"list_latest_transaction": "Giao dịch mới nhất",
"list_long_choose": "Chọn hình",
"list_long_clipboard": "Sao chép từ bảng tạm",
"paste_from_clipboard": "Sao chép từ bảng tạm",
"list_long_scan": "Quét mã QR",
"list_title": "Các ví",
"list_tryagain": "Thử lại",

View File

@ -311,7 +311,7 @@
"list_empty_txs2_lightning": "\n要开始使用它请点击“管理资金”并充值。",
"list_latest_transaction": "最近的交易",
"list_long_choose": "选择图片",
"list_long_clipboard": "从剪贴板复制",
"paste_from_clipboard": "从剪贴板复制",
"import_file": "导入文件",
"list_long_scan": "扫描二维码",
"list_title": "钱包",

View File

@ -307,7 +307,7 @@
"list_empty_txs2_lightning": "\n要開始使用它請點擊“管理資金”並增值。",
"list_latest_transaction": "最近的交易",
"list_long_choose": "選擇圖片",
"list_long_clipboard": "從剪貼簿複製",
"paste_from_clipboard": "從剪貼簿複製",
"import_file": "匯入檔案",
"list_long_scan": "掃描二維碼",
"list_title": "錢包",

196
package-lock.json generated
View File

@ -11,7 +11,7 @@
"license": "MIT",
"dependencies": {
"@babel/preset-env": "7.25.8",
"@bugsnag/react-native": "8.0.0",
"@bugsnag/react-native": "8.1.2",
"@bugsnag/source-maps": "2.3.3",
"@keystonehq/bc-ur-registry": "0.7.0",
"@lodev09/react-native-true-sheet": "github:BlueWallet/react-native-true-sheet#839f2966cee77c0ad99d09609dadb61a338e7f54",
@ -26,7 +26,6 @@
"@react-navigation/drawer": "6.7.2",
"@react-navigation/native": "6.1.18",
"@react-navigation/native-stack": "6.11.0",
"@remobile/react-native-qrcode-local-image": "github:BlueWallet/react-native-qrcode-local-image#31b0113110fbafcf5a5f3ca4183a563550f5c352",
"@rneui/base": "4.0.0-rc.8",
"@rneui/themed": "4.0.0-rc.8",
"@spsina/bip47": "github:BlueWallet/bip47#df82345",
@ -97,8 +96,9 @@
"react-native-vector-icons": "10.2.0",
"react-native-watch-connectivity": "1.1.0",
"readable-stream": "3.6.2",
"realm": "12.13.1",
"realm": "20.0.0",
"rn-nodeify": "10.3.0",
"rn-qr-generator": "https://github.com/BlueWallet/rn-qr-generator.git#eacee6d6546eb5b43bfd257255d0a7aa3bd90165",
"scryptsy": "2.1.0",
"silent-payments": "github:BlueWallet/SilentPayments#7ac4d17",
"slip39": "https://github.com/BlueWallet/slip39-js#d316ee6",
@ -111,7 +111,7 @@
"@babel/runtime": "^7.20.0",
"@jest/reporters": "^27.5.1",
"@react-native/babel-preset": "^0.75.4",
"@react-native/eslint-config": "^0.75.4",
"@react-native/eslint-config": "^0.76.0",
"@react-native/js-polyfills": "^0.75.4",
"@react-native/metro-babel-transformer": "^0.75.4",
"@react-native/typescript-config": "^0.75.4",
@ -2164,15 +2164,15 @@
"license": "MIT"
},
"node_modules/@bugsnag/core": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@bugsnag/core/-/core-8.0.0.tgz",
"integrity": "sha512-AcDMjd4RZ+G8M/n6TFzL5P/1due+aNvTIu+26mu9TW2Tt4d/86lKVFQSy0H2Ju1HIaBdqtUUNCTXOIeNXJVkHQ==",
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@bugsnag/core/-/core-8.1.1.tgz",
"integrity": "sha512-ytOWqwm4H2h8rADqYPR+tQpDHsBav3NEZ5E2VSCCxPbT2R89Q0/t0PZTbQVlOS+TRutajO29VxTV9qsAREfpSw==",
"license": "MIT",
"dependencies": {
"@bugsnag/cuid": "^3.0.0",
"@bugsnag/safe-json-stringify": "^6.0.0",
"error-stack-parser": "^2.0.3",
"iserror": "0.0.2",
"iserror": "^0.0.2",
"stack-generator": "^2.0.3"
}
},
@ -2183,39 +2183,39 @@
"license": "MIT"
},
"node_modules/@bugsnag/delivery-react-native": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@bugsnag/delivery-react-native/-/delivery-react-native-8.0.0.tgz",
"integrity": "sha512-WUdKcWSDnHNfqkI40HdU0ZXPrpnwWoZf+trZVGu2xGQFIhRduHkBy773NhSz94U3G2up5MiXQpjD6ic1ulhHJQ==",
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@bugsnag/delivery-react-native/-/delivery-react-native-8.1.1.tgz",
"integrity": "sha512-fK2yez573INVYYJCfJPWqW3gxMBEa7Bw2Lm/K0Gj1mtKu0hFAvResTMeT3E61P/BKK+x5QJzG9VpK4fZk+e5JA==",
"license": "MIT",
"peerDependencies": {
"@bugsnag/core": "^8.0.0-alpha.1"
"@bugsnag/core": "^8.0.0"
}
},
"node_modules/@bugsnag/plugin-console-breadcrumbs": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-console-breadcrumbs/-/plugin-console-breadcrumbs-8.0.0.tgz",
"integrity": "sha512-sehh8KRdGNArWdGOLo2cguBjkmovjCNX6aq/ysNUOJ//ElMRHNATkW9RO5fu4bvU+Bx5G6VsT0uIfodEZLraCw==",
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-console-breadcrumbs/-/plugin-console-breadcrumbs-8.1.1.tgz",
"integrity": "sha512-D0nk5Qy3Ht6rRMoNRu77aGQvm58Iyc0JJHt5uvXIX+/3J+43jrsceTaHICrYI/i4PI+/iYhlzTdolGD64pvxXQ==",
"license": "MIT",
"peerDependencies": {
"@bugsnag/core": "^8.0.0-alpha.1"
"@bugsnag/core": "^8.0.0"
}
},
"node_modules/@bugsnag/plugin-network-breadcrumbs": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-network-breadcrumbs/-/plugin-network-breadcrumbs-8.0.0.tgz",
"integrity": "sha512-kd2U71/4yyrV8MztS6kQGNxH1HPEw93XtO1awJ4L3iPH5swJ3mnBxxmwXeeoaA56lImik7Q07mUM+TfSZbNGrg==",
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-network-breadcrumbs/-/plugin-network-breadcrumbs-8.1.1.tgz",
"integrity": "sha512-Tr6eNWdS3Fc3Ns6LFV/GudxO+L4cCVySja+Sb5yQFIKtRf7MIKyndcJNmkSz5jB8QDNZq0GwCV6A9GkAQHQb4Q==",
"license": "MIT",
"peerDependencies": {
"@bugsnag/core": "^8.0.0-alpha.1"
"@bugsnag/core": "^8.0.0"
}
},
"node_modules/@bugsnag/plugin-react": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react/-/plugin-react-8.0.0.tgz",
"integrity": "sha512-hzLRt0sw6PSups+yd/XKJPMOv8yp8x5yaOzITii7PjXND++0tStGnQQEWTbS5DCW1685mGqP/G4gye8s9LP5og==",
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react/-/plugin-react-8.1.1.tgz",
"integrity": "sha512-G21+YMDSsdco/CjD6BkfQH73t92mJB9/REU2bYCvDvU9yqKiRQyhTr5D2Ak/ON4KmbKAqexBh/pXGkzOGSP7xQ==",
"license": "MIT",
"peerDependencies": {
"@bugsnag/core": "^8.0.0-alpha.1"
"@bugsnag/core": "^8.0.0"
},
"peerDependenciesMeta": {
"@bugsnag/core": {
@ -2224,76 +2224,76 @@
}
},
"node_modules/@bugsnag/plugin-react-native-client-sync": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react-native-client-sync/-/plugin-react-native-client-sync-8.0.0.tgz",
"integrity": "sha512-l0ze2D1eTMQ+7ot7ppf1DqU8o3vQ/go8Ds8FNm7IovmHvjdpIXd8tGGDirYpqgf0eyh/YCYG7EVw9/bafkYFHg==",
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react-native-client-sync/-/plugin-react-native-client-sync-8.1.1.tgz",
"integrity": "sha512-8VYqpNvJLu+ZZVDjahw8R/cbcdI+imwZMbR96TCCvwRcG3HLKf+ZOTn8b0pY7l+tVdHePGFoQhrHBZ6ZchyTgg==",
"license": "MIT",
"peerDependencies": {
"@bugsnag/core": "^8.0.0-alpha.1"
"@bugsnag/core": "^8.0.0"
}
},
"node_modules/@bugsnag/plugin-react-native-event-sync": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react-native-event-sync/-/plugin-react-native-event-sync-8.0.0.tgz",
"integrity": "sha512-zFevMYZWVqm+Qx7TQIX4CgqYD6wRsvVMAljElFp+b2F9vly/iMFqRu9xuj3fqS/RS8a1g0ClsC7e5QmzaMoHJw==",
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react-native-event-sync/-/plugin-react-native-event-sync-8.1.1.tgz",
"integrity": "sha512-XhtRZVmYVvfOh0Hjszeeg3k0ajGh/BJVZ/wCmuLQMpgUAoVVWF1wJt+WX7P+oVQ862hbf7bUAGbcI5sS6rMS2Q==",
"license": "MIT",
"peerDependencies": {
"@bugsnag/core": "^8.0.0-alpha.1"
"@bugsnag/core": "^8.0.0"
}
},
"node_modules/@bugsnag/plugin-react-native-global-error-handler": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react-native-global-error-handler/-/plugin-react-native-global-error-handler-8.0.0.tgz",
"integrity": "sha512-6lE8KHwg302VO3xZS1vgo9KPckQvzwdQIKTtmx/arVtYNms6u0fTdsXUawoap7ox48dK8/c7GpamH6YGGn1wrg==",
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react-native-global-error-handler/-/plugin-react-native-global-error-handler-8.1.1.tgz",
"integrity": "sha512-TgbddOyzHwJTmJbSHZdznZIJw2BwgLx4QOWLc8tSOJFl6lmfeoCPS2+OKd43tsd76OcyNBwfEnvcAzD66Shlrg==",
"license": "MIT",
"peerDependencies": {
"@bugsnag/core": "^8.0.0-alpha.1"
"@bugsnag/core": "^8.0.0"
}
},
"node_modules/@bugsnag/plugin-react-native-hermes": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react-native-hermes/-/plugin-react-native-hermes-8.0.0.tgz",
"integrity": "sha512-J8Jva4iFR8WnEIoArEITbIk9WPoyg7Hp4Uuho7pKKFdt8RLk91yFravLBMUHbevwLiaQ7KgwxmE53/RqR6Kadw==",
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react-native-hermes/-/plugin-react-native-hermes-8.1.1.tgz",
"integrity": "sha512-tXuZFc1WF8OfI6OyOrEOS9MYUvay40aWouRkLPOVjMnNkHTXD6sbQWn1xkFhG6oFohxUJ3cCBNK1YxRXXz0fmA==",
"license": "MIT",
"peerDependencies": {
"@bugsnag/core": "^8.0.0-alpha.1"
"@bugsnag/core": "^8.0.0"
}
},
"node_modules/@bugsnag/plugin-react-native-session": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react-native-session/-/plugin-react-native-session-8.0.0.tgz",
"integrity": "sha512-YfxTZdxTObBaymeUKQGa9JyvFecqy+SEHZ7AiSkdY/SCguQFgrDS/XCzIj+MOxF5Tf7XAu3QVVEvP0xmsmb1aQ==",
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react-native-session/-/plugin-react-native-session-8.1.1.tgz",
"integrity": "sha512-ZKn7cbAbRr+LxZ1QFz+h9jm7LlQHJXoyyEg8ut3SwrkGtA30sbUZHhkZ92NCUHSq/SCBkZbTsVME4kEJ1hy3Yg==",
"license": "MIT",
"peerDependencies": {
"@bugsnag/core": "^8.0.0-alpha.1"
"@bugsnag/core": "^8.0.0"
}
},
"node_modules/@bugsnag/plugin-react-native-unhandled-rejection": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react-native-unhandled-rejection/-/plugin-react-native-unhandled-rejection-8.0.0.tgz",
"integrity": "sha512-Nu773KAbpSasW18hjsODB5tSNX6B7/dWWAubfSNCQW/B92EAqxpOKhekGPqQ71u8cs7SIG4FBUfilfZrnJCP+Q==",
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@bugsnag/plugin-react-native-unhandled-rejection/-/plugin-react-native-unhandled-rejection-8.1.1.tgz",
"integrity": "sha512-tCnH5w/0gYJPcR9xvMc7fAEfo2zJghgar1QRYx9mrJCng2/sdNOcjJn35uLwj/tPBd/9pz7OVtsxm/GpsQUK3g==",
"license": "MIT",
"peerDependencies": {
"@bugsnag/core": "^8.0.0-alpha.1"
"@bugsnag/core": "^8.0.0"
}
},
"node_modules/@bugsnag/react-native": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@bugsnag/react-native/-/react-native-8.0.0.tgz",
"integrity": "sha512-rKjMBjGLBaZ6zYa6I3hoXPlWT9ysndmhlTd56X6MsAaN4aEyHde67YjaWEl6as1LKAu3l39oarPu6/tdyu8oOQ==",
"version": "8.1.2",
"resolved": "https://registry.npmjs.org/@bugsnag/react-native/-/react-native-8.1.2.tgz",
"integrity": "sha512-3JorQfeDZjVP1krHPAw8Oegq/PVY+MQ+uQ+wsYx+lUbLOS1qr60FV6GJn8jJEpTnnINWPGsgUBBspUB+kPoEsw==",
"license": "MIT",
"dependencies": {
"@bugsnag/core": "^8.0.0",
"@bugsnag/delivery-react-native": "^8.0.0",
"@bugsnag/plugin-console-breadcrumbs": "^8.0.0",
"@bugsnag/plugin-network-breadcrumbs": "^8.0.0",
"@bugsnag/plugin-react": "^8.0.0",
"@bugsnag/plugin-react-native-client-sync": "^8.0.0",
"@bugsnag/plugin-react-native-event-sync": "^8.0.0",
"@bugsnag/plugin-react-native-global-error-handler": "^8.0.0",
"@bugsnag/plugin-react-native-hermes": "^8.0.0",
"@bugsnag/plugin-react-native-session": "^8.0.0",
"@bugsnag/plugin-react-native-unhandled-rejection": "^8.0.0",
"@bugsnag/core": "^8.1.1",
"@bugsnag/delivery-react-native": "^8.1.1",
"@bugsnag/plugin-console-breadcrumbs": "^8.1.1",
"@bugsnag/plugin-network-breadcrumbs": "^8.1.1",
"@bugsnag/plugin-react": "^8.1.1",
"@bugsnag/plugin-react-native-client-sync": "^8.1.1",
"@bugsnag/plugin-react-native-event-sync": "^8.1.1",
"@bugsnag/plugin-react-native-global-error-handler": "^8.1.1",
"@bugsnag/plugin-react-native-hermes": "^8.1.1",
"@bugsnag/plugin-react-native-session": "^8.1.1",
"@bugsnag/plugin-react-native-unhandled-rejection": "^8.1.1",
"iserror": "^0.0.2"
}
},
@ -5840,15 +5840,15 @@
}
},
"node_modules/@react-native/eslint-config": {
"version": "0.75.4",
"resolved": "https://registry.npmjs.org/@react-native/eslint-config/-/eslint-config-0.75.4.tgz",
"integrity": "sha512-3KBHYwp4HnBdaCFx9KDPvQY+sGrv5fHX2qDkXGKmN3uYBz+zfnMQXTiht6OuBbWULUF0y0o8m+uH1yYAn/V9mw==",
"version": "0.76.0",
"resolved": "https://registry.npmjs.org/@react-native/eslint-config/-/eslint-config-0.76.0.tgz",
"integrity": "sha512-YY/YkW6FO00pdPDf1pCzF5yIslOU8YBZ+2Hd+ICNg3pPOuHvtPq9bWXJpZyi1vnWyVrDbCGHXkVPAFMi5sii6A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/core": "^7.20.0",
"@babel/eslint-parser": "^7.20.0",
"@react-native/eslint-plugin": "0.75.4",
"@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.25.1",
"@react-native/eslint-plugin": "0.76.0",
"@typescript-eslint/eslint-plugin": "^7.1.1",
"@typescript-eslint/parser": "^7.1.1",
"eslint-config-prettier": "^8.5.0",
@ -5857,7 +5857,8 @@
"eslint-plugin-jest": "^27.9.0",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-native": "^4.0.0"
"eslint-plugin-react-native": "^4.0.0",
"hermes-eslint": "^0.23.1"
},
"engines": {
"node": ">=18"
@ -6038,9 +6039,9 @@
}
},
"node_modules/@react-native/eslint-plugin": {
"version": "0.75.4",
"resolved": "https://registry.npmjs.org/@react-native/eslint-plugin/-/eslint-plugin-0.75.4.tgz",
"integrity": "sha512-1kEZzC8UKi3baHnH7tBVCNpF4aoAmT7g7hEa5/rtZ+Z7vcpaxeY6wjNYt3j02Z9n310yX0NKDJox30CqvzEvsg==",
"version": "0.76.0",
"resolved": "https://registry.npmjs.org/@react-native/eslint-plugin/-/eslint-plugin-0.76.0.tgz",
"integrity": "sha512-TsQUN10MvmYsbWAuWp0nyGo+t+/FnuiBOZxNc9VS4eg2oni1Sb9p0DSqLL3Y8EDiAyLCaBNyoY+pkMF87jzILw==",
"dev": true,
"license": "MIT",
"engines": {
@ -6233,12 +6234,6 @@
"node": ">=18"
}
},
"node_modules/@remobile/react-native-qrcode-local-image": {
"version": "1.0.4",
"resolved": "git+ssh://git@github.com/BlueWallet/react-native-qrcode-local-image.git#31b0113110fbafcf5a5f3ca4183a563550f5c352",
"integrity": "sha512-ooA3KFI5wUUx4++U5llEIUs2ADGop7oAOeHsZgisu/4A8Hsw27wJj26d74OonVGYgeZkWXwx6KQDe1dxRa/2WQ==",
"license": "MIT"
},
"node_modules/@rneui/base": {
"version": "4.0.0-rc.8",
"resolved": "https://registry.npmjs.org/@rneui/base/-/base-4.0.0-rc.8.tgz",
@ -12739,6 +12734,35 @@
"node": ">= 0.4"
}
},
"node_modules/hermes-eslint": {
"version": "0.23.1",
"resolved": "https://registry.npmjs.org/hermes-eslint/-/hermes-eslint-0.23.1.tgz",
"integrity": "sha512-DaEpbJobK1KwpTSXrPIKkHs2h+B+RTw2F1g9S70tjtJ14a3zM+2gPVUtc8xyffQqRJ6tPfs+/zRKwV17lwDvqA==",
"dev": true,
"license": "MIT",
"dependencies": {
"esrecurse": "^4.3.0",
"hermes-estree": "0.23.1",
"hermes-parser": "0.23.1"
}
},
"node_modules/hermes-eslint/node_modules/hermes-estree": {
"version": "0.23.1",
"resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.23.1.tgz",
"integrity": "sha512-eT5MU3f5aVhTqsfIReZ6n41X5sYn4IdQL0nvz6yO+MMlPxw49aSARHLg/MSehQftyjnrE8X6bYregzSumqc6cg==",
"dev": true,
"license": "MIT"
},
"node_modules/hermes-eslint/node_modules/hermes-parser": {
"version": "0.23.1",
"resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.23.1.tgz",
"integrity": "sha512-oxl5h2DkFW83hT4DAUJorpah8ou4yvmweUzLJmmr6YV2cezduCdlil1AvU/a/xSsAFo4WUcNA4GoV5Bvq6JffA==",
"dev": true,
"license": "MIT",
"dependencies": {
"hermes-estree": "0.23.1"
}
},
"node_modules/hermes-estree": {
"version": "0.22.0",
"resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.22.0.tgz",
@ -21293,10 +21317,9 @@
"license": "BSD"
},
"node_modules/realm": {
"version": "12.13.1",
"resolved": "https://registry.npmjs.org/realm/-/realm-12.13.1.tgz",
"integrity": "sha512-fAs70ZCBf1P7htVhOTrDMFHD6SzoGXVsALy6DpOPR6t0LXoK635cKxBMECX3bYdCgI7+riSfdoWXLA/7g5yTSQ==",
"deprecated": "This version uses Atlas Device Sync, please install `realm@community` and read https://github.com/realm/realm-js/blob/main/DEPRECATION.md for more information.",
"version": "20.0.0",
"resolved": "https://registry.npmjs.org/realm/-/realm-20.0.0.tgz",
"integrity": "sha512-kkUFoDZiUD3KJct22apHCkUISXeV4TZM5DBa4Qxw1XncjU9GpuPCTkZo481++coDoy7wcBja9iPSNx57pzSZ3A==",
"hasInstallScript": true,
"license": "apache-2.0",
"dependencies": {
@ -21654,6 +21677,15 @@
"semver": "bin/semver"
}
},
"node_modules/rn-qr-generator": {
"version": "1.4.2",
"resolved": "git+ssh://git@github.com/BlueWallet/rn-qr-generator.git#eacee6d6546eb5b43bfd257255d0a7aa3bd90165",
"integrity": "sha512-dTGlzCUuPfaSsBeeVCGDEvzFhw3rWSz+4Fxc98ImJO+Ld/7J7gg4u1LFWhmsfrqsL34Ylm8Lr9cffVzxx3WzwA==",
"license": "MIT",
"peerDependencies": {
"react-native": ">=0.55"
}
},
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",

View File

@ -11,7 +11,7 @@
"@babel/runtime": "^7.20.0",
"@jest/reporters": "^27.5.1",
"@react-native/babel-preset": "^0.75.4",
"@react-native/eslint-config": "^0.75.4",
"@react-native/eslint-config": "^0.76.0",
"@react-native/js-polyfills": "^0.75.4",
"@react-native/metro-babel-transformer": "^0.75.4",
"@react-native/typescript-config": "^0.75.4",
@ -75,7 +75,7 @@
},
"dependencies": {
"@babel/preset-env": "7.25.8",
"@bugsnag/react-native": "8.0.0",
"@bugsnag/react-native": "8.1.2",
"@bugsnag/source-maps": "2.3.3",
"@keystonehq/bc-ur-registry": "0.7.0",
"@lodev09/react-native-true-sheet": "github:BlueWallet/react-native-true-sheet#839f2966cee77c0ad99d09609dadb61a338e7f54",
@ -90,7 +90,6 @@
"@react-navigation/drawer": "6.7.2",
"@react-navigation/native": "6.1.18",
"@react-navigation/native-stack": "6.11.0",
"@remobile/react-native-qrcode-local-image": "github:BlueWallet/react-native-qrcode-local-image#31b0113110fbafcf5a5f3ca4183a563550f5c352",
"@rneui/base": "4.0.0-rc.8",
"@rneui/themed": "4.0.0-rc.8",
"@spsina/bip47": "github:BlueWallet/bip47#df82345",
@ -161,8 +160,9 @@
"react-native-vector-icons": "10.2.0",
"react-native-watch-connectivity": "1.1.0",
"readable-stream": "3.6.2",
"realm": "12.13.1",
"realm": "20.0.0",
"rn-nodeify": "10.3.0",
"rn-qr-generator": "https://github.com/BlueWallet/rn-qr-generator.git#eacee6d6546eb5b43bfd257255d0a7aa3bd90165",
"scryptsy": "2.1.0",
"silent-payments": "github:BlueWallet/SilentPayments#7ac4d17",
"slip39": "https://github.com/BlueWallet/slip39-js#d316ee6",

View File

@ -107,15 +107,20 @@ const ReceiveDetails = () => {
let newAddress;
if (address) {
setAddressBIP21Encoded(address);
await Notifications.tryToObtainPermissions(receiveAddressButton);
Notifications.majorTomToGroundControl([address], [], []);
try {
await Notifications.tryToObtainPermissions(receiveAddressButton);
Notifications.majorTomToGroundControl([address], [], []);
} catch (error) {
console.error('Error obtaining notifications permissions:', error);
}
} else {
if (wallet.chain === Chain.ONCHAIN) {
try {
if (!isElectrumDisabled) newAddress = await Promise.race([wallet.getAddressAsync(), sleep(1000)]);
} catch (_) {}
} catch (error) {
console.warn('Error fetching wallet address (ONCHAIN):', error);
}
if (newAddress === undefined) {
// either sleep expired or getAddressAsync threw an exception
console.warn('either sleep expired or getAddressAsync threw an exception');
newAddress = wallet._getExternalAddressByIndex(wallet.getNextFreeAddressIndex());
} else {
@ -125,9 +130,10 @@ const ReceiveDetails = () => {
try {
await Promise.race([wallet.getAddressAsync(), sleep(1000)]);
newAddress = wallet.getAddress();
} catch (_) {}
} catch (error) {
console.warn('Error fetching wallet address (OFFCHAIN):', error);
}
if (newAddress === undefined) {
// either sleep expired or getAddressAsync threw an exception
console.warn('either sleep expired or getAddressAsync threw an exception');
newAddress = wallet.getAddress();
} else {
@ -135,8 +141,12 @@ const ReceiveDetails = () => {
}
}
setAddressBIP21Encoded(newAddress);
await Notifications.tryToObtainPermissions(receiveAddressButton);
Notifications.majorTomToGroundControl([newAddress], [], []);
try {
await Notifications.tryToObtainPermissions(receiveAddressButton);
Notifications.majorTomToGroundControl([newAddress], [], []);
} catch (error) {
console.error('Error obtaining notifications permissions:', error);
}
}
}, [wallet, saveToDisk, address, setAddressBIP21Encoded, isElectrumDisabled, sleep]);
@ -167,7 +177,6 @@ const ReceiveDetails = () => {
const HeaderRight = useMemo(
() => <HeaderMenuButton actions={toolTipActions} onPressMenuItem={onPressMenuItem} />,
[onPressMenuItem, toolTipActions],
);
@ -271,7 +280,7 @@ const ReceiveDetails = () => {
}
}
} catch (error) {
console.debug(error);
console.debug('Error checking balance:', error);
}
}, intervalMs);
@ -363,10 +372,14 @@ const ReceiveDetails = () => {
useFocusEffect(
useCallback(() => {
const task = InteractionManager.runAfterInteractions(async () => {
if (wallet) {
obtainWalletAddress();
} else if (!wallet && address) {
setAddressBIP21Encoded(address);
try {
if (wallet) {
await obtainWalletAddress();
} else if (!wallet && address) {
setAddressBIP21Encoded(address);
}
} catch (error) {
console.error('Error during focus effect:', error);
}
});
return () => {
@ -423,7 +436,7 @@ const ReceiveDetails = () => {
const handleShareButtonPressed = () => {
Share.open({ message: currentTab === loc.wallets.details_address ? bip21encoded : wallet.getBIP47PaymentCode() }).catch(error =>
console.debug(error),
console.debug('Error sharing:', error),
);
};

View File

@ -340,7 +340,11 @@ const Confirm: React.FC = () => {
{state.isLoading ? (
<ActivityIndicator />
) : (
<Button disabled={isElectrumDisabled || state.isButtonDisabled} onPress={handleSendTransaction} title={loc.send.confirm_sendNow} />
<Button
disabled={isElectrumDisabled || state.isButtonDisabled}
onPress={handleSendTransaction}
title={loc.send.confirm_sendNow}
/>
)}
</BlueCard>
</View>
@ -444,4 +448,4 @@ const styles = StyleSheet.create({
fontSize: 15,
fontWeight: 'bold',
},
});
});

View File

@ -1,5 +1,4 @@
import { useFocusEffect, useIsFocused, useNavigation, useRoute } from '@react-navigation/native';
import LocalQRCode from '@remobile/react-native-qrcode-local-image';
import * as bitcoin from 'bitcoinjs-lib';
import createHash from 'create-hash';
import React, { useCallback, useEffect, useState } from 'react';
@ -19,6 +18,7 @@ import { useTheme } from '../../components/themes';
import { isCameraAuthorizationStatusGranted } from '../../helpers/scan-qr';
import loc from '../../loc';
import { useSettings } from '../../hooks/context/useSettings';
import RNQRGenerator from 'rn-qr-generator';
let decoder = false;
@ -312,15 +312,21 @@ const ScanQRCode = () => {
} else {
const asset = response.assets[0];
if (asset.uri) {
const uri = asset.uri.toString().replace('file://', '');
LocalQRCode.decode(uri, (error, result) => {
if (!error) {
onBarCodeRead({ data: result });
} else {
RNQRGenerator.detect({
uri: decodeURI(asset.uri.toString()),
})
.then(result => {
if (result) {
onBarCodeRead({ data: result.values[0] });
}
})
.catch(error => {
console.error(error);
presentAlert({ message: loc.send.qr_error_no_qrcode });
})
.finally(() => {
setIsLoading(false);
}
});
});
} else {
setIsLoading(false);
}

View File

@ -288,7 +288,7 @@ const WalletTransactions: React.FC<WalletTransactionsProps> = ({ route }) => {
const _keyExtractor = (_item: any, index: number) => index.toString();
const copyFromClipboard = async () => {
const pasteFromClipboard = async () => {
onBarCodeRead({ data: await BlueClipboard().getClipboardContent() });
};
@ -326,7 +326,7 @@ const WalletTransactions: React.FC<WalletTransactionsProps> = ({ route }) => {
const cancelButtonIndex = 0;
if (!isClipboardEmpty) {
options.push(loc.wallets.list_long_clipboard);
options.push(loc.wallets.paste_from_clipboard);
}
ActionSheet.showActionSheetWithOptions(
@ -353,7 +353,7 @@ const WalletTransactions: React.FC<WalletTransactionsProps> = ({ route }) => {
}
case 3:
if (!isClipboardEmpty) {
copyFromClipboard();
pasteFromClipboard();
}
break;
}

View File

@ -365,7 +365,7 @@ const WalletsList: React.FC = () => {
[navigate],
);
const copyFromClipboard = useCallback(async () => {
const pasteFromClipboard = useCallback(async () => {
onBarScanned(await BlueClipboard().getClipboardContent());
}, [onBarScanned]);
@ -374,7 +374,7 @@ const WalletsList: React.FC = () => {
const options = [loc._.cancel, loc.wallets.list_long_choose, loc.wallets.list_long_scan];
if (!isClipboardEmpty) {
options.push(loc.wallets.list_long_clipboard);
options.push(loc.wallets.paste_from_clipboard);
}
const props = { title: loc.send.header, options, cancelButtonIndex: 0 };
@ -402,12 +402,12 @@ const WalletsList: React.FC = () => {
break;
case 3:
if (!isClipboardEmpty) {
copyFromClipboard();
pasteFromClipboard();
}
break;
}
});
}, [copyFromClipboard, onBarScanned, routeName]);
}, [pasteFromClipboard, onBarScanned, routeName]);
const onRefresh = useCallback(() => {
console.debug('WalletsList onRefresh');

View File

@ -163,6 +163,15 @@ jest.mock('react-native-ios-context-menu', () => {
return {};
});
jest.mock('rn-qr-generator', () => ({
detect: jest.fn((uri) => {
if (uri === 'invalid-image') {
return Promise.reject(new Error('Failed to decode QR code'));
}
return Promise.resolve({ values: ['mocked-qr-code'] });
}),
}));
jest.mock('react-native-haptic-feedback', () => {
return {
trigger: jest.fn(),

View File

@ -22,6 +22,7 @@ const keys = {
RemoveAllRecipients: 'RemoveAllRecipients',
AddRecipient: 'AddRecipient',
RemoveRecipient: 'RemoveRecipient',
PasteFromClipboard: 'pasteFromClipboard',
};
const icons = {
@ -73,6 +74,7 @@ const icons = {
RemoveAllRecipients: { iconValue: 'person.2.slash' },
AddRecipient: { iconValue: 'person.badge.plus' },
RemoveRecipient: { iconValue: 'person.badge.minus' },
PasteFromClipboard: { iconValue: 'document.on.clipboard' },
};
export const CommonToolTipActions = {
@ -185,4 +187,9 @@ export const CommonToolTipActions = {
icon: icons.PaymentsCode,
menuState: false,
},
PasteFromClipboard: {
id: keys.PasteFromClipboard,
text: loc.transactions.details_copy_amount,
icon: icons.PasteFromClipboard,
},
};

View File

@ -1,3 +0,0 @@
declare module '@remobile/react-native-qrcode-local-image' {
export function decode(uri: string, callback: (error: any, result: string) => void): void;
}