ADD: push notifications

This commit is contained in:
Overtorment 2020-07-18 20:33:43 +01:00 committed by GitHub
parent f58653bdb7
commit 545c8891f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 399 additions and 13 deletions

1
App.js
View File

@ -30,6 +30,7 @@ const lightningModalString = 'Lightning Invoice';
const loc = require('./loc');
const BlueApp = require('./BlueApp');
const EV = require('./blue_modules/events');
const notifications = require('./blue_modules/notifications'); // eslint-disable-line no-unused-vars
export default class App extends React.Component {
state = {

View File

@ -2,6 +2,8 @@ import * as Watch from 'react-native-watch-connectivity';
import { InteractionManager } from 'react-native';
import { Chain } from './models/bitcoinUnits';
const loc = require('./loc');
const notifications = require('./blue_modules/notifications');
export default class WatchConnectivity {
isAppInstalled = false;
static shared = new WatchConnectivity();
@ -50,6 +52,11 @@ export default class WatchConnectivity {
if (wallet.allowReceive() && amount > 0 && description.trim().length > 0) {
try {
const invoiceRequest = await wallet.addInvoice(amount, description);
// lets decode payreq and subscribe groundcontrol so we can receive push notification when our invoice is paid
const decoded = await wallet.decodeInvoice(invoiceRequest);
await notifications.tryToObtainPermissions();
notifications.majorTomToGroundControl([], [decoded.payment_hash]);
return invoiceRequest;
} catch (error) {
return error;

View File

@ -219,4 +219,5 @@ task copyDownloadableDepsToLibs(type: Copy) {
into 'libs'
}
apply plugin: 'com.google.gms.google-services' // Google Services plugin
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

View File

@ -0,0 +1,40 @@
{
"project_info": {
"project_number": "993804676679",
"firebase_url": "https://bluewallet-d7cd5.firebaseio.com",
"project_id": "bluewallet-d7cd5",
"storage_bucket": "bluewallet-d7cd5.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:993804676679:android:3e611cf30d58bac8b5cb62",
"android_client_info": {
"package_name": "io.bluewallet.bluewallet"
}
},
"oauth_client": [
{
"client_id": "993804676679-cntmqmnbkrm9c89lcr1cq6rhaq8tfi0u.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyCzJxNtavou1G10ZLIjzC-b2mX6TrVF3Ew"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "993804676679-cntmqmnbkrm9c89lcr1cq6rhaq8tfi0u.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}

View File

@ -13,6 +13,38 @@
android:allowBackup="false"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme">
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name"
android:value="BlueWallet notifications"/> <!-- YOUR NOTIFICATION CHANNEL NAME -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_description"
android:value="Notifications about incoming payments"/> <!-- YOUR NOTIFICATION CHANNEL DESCRIPTION -->
<!-- Change the value to true to enable pop-up for in foreground (remote-only, for local use ignoreInForeground) -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground"
android:value="true"/>
<!-- Change the value to false if you don't want the creation of the default channel -->
<meta-data android:name="com.dieam.reactnativepushnotification.channel_create_default"
android:value="true"/>
<!-- Change the resource name to your App's accent color - or any other color you want -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color"
android:resource="@color/white"/> <!-- or @android:color/{name} to use a standard color -->
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<activity
android:name=".MainActivity"
android:label="@string/app_name"

View File

@ -0,0 +1,3 @@
<resources>
<color name="white">#FFF</color>
</resources>

View File

@ -9,6 +9,7 @@ buildscript {
supportLibVersion = "28.0.0"
googlePlayServicesVersion = "16.+"
firebaseVersion = "17.3.4"
firebaseMessagingVersion = "20.2.1"
}
repositories {
google()
@ -18,6 +19,8 @@ buildscript {
dependencies {
classpath('com.android.tools.build:gradle:3.6.3')
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath 'com.google.gms:google-services:4.3.3' // Google Services plugin
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files

View File

@ -0,0 +1,5 @@
/**
* Let's keep config vars, constants and definitions here
*/
export const groundControlUri = 'https://groundcontrol-bluewallet.herokuapp.com/';

View File

@ -0,0 +1,180 @@
import PushNotificationIOS from '@react-native-community/push-notification-ios';
import { Alert } from 'react-native';
import Frisbee from 'frisbee';
import AsyncStorage from '@react-native-community/async-storage';
const PushNotification = require('react-native-push-notification');
const constants = require('./constants');
const PUSH_TOKEN = 'PUSH_TOKEN';
const loc = require('../loc');
let alreadyConfigured = false;
async function _setPushToken(token) {
token = JSON.stringify(token);
return AsyncStorage.setItem(PUSH_TOKEN, token);
}
async function _getPushToken() {
try {
let token = await AsyncStorage.getItem(PUSH_TOKEN);
token = JSON.parse(token);
return token;
} catch (_) {}
return false;
}
/**
* Calls `configure`, which tries to obtain push token, save it, and registers all associated with
* notifications callbacks
*
* @returns {Promise<boolean>} TRUE if acquired token, FALSE if not
*/
const configureNotifications = async function () {
return new Promise(function (resolve) {
PushNotification.configure({
// (optional) Called when Token is generated (iOS and Android)
onRegister: async function (token) {
console.log('TOKEN:', token);
alreadyConfigured = true;
await _setPushToken(token);
resolve(true);
},
// (required) Called when a remote is received or opened, or local notification is opened
onNotification: function (notification) {
console.log('NOTIFICATION:', notification);
// process the notification
PushNotification.setApplicationIconBadgeNumber(0); // always reset badges to zero
// (required) Called when a remote is received or opened, or local notification is opened
notification.finish(PushNotificationIOS.FetchResult.NoData);
},
// (optional) Called when Registered Action is pressed and invokeApp is false, if true onNotification will be called (Android)
onAction: function (notification) {
console.log('ACTION:', notification.action);
console.log('NOTIFICATION:', notification);
// process the action
},
// (optional) Called when the user fails to register for remote notifications. Typically occurs when APNS is having issues, or the device is a simulator. (iOS)
onRegistrationError: function (err) {
console.error(err.message, err);
resolve(false);
},
// IOS ONLY (optional): default: all - Permissions to register.
permissions: {
alert: true,
badge: true,
sound: true,
},
// Should the initial notification be popped automatically
// default: true
popInitialNotification: true,
/**
* (optional) default: true
* - Specified if permissions (ios) and token (android and ios) will requested or not,
* - if not, you must call PushNotificationsHandler.requestPermissions() later
* - if you are not using remote notification or do not have Firebase installed, use this:
* requestPermissions: Platform.OS === 'ios'
*/
requestPermissions: true,
});
});
};
/**
* Should be called when user is most interested in receiving push notifications.
* If we dont have a token it will show alert asking whether
* user wants to receive notifications, and if yes - will configure push notifications.
* FYI, on Android permissions are acquired when app is installed, so basically we dont need to ask,
* we can just call `configure`. On iOS its different, and calling `configure` triggers system's dialog box.
*
* @returns {Promise<boolean>} TRUE if permissions were obtained, FALSE otherwise
*/
const tryToObtainPermissions = async function () {
if (await _getPushToken()) {
// we already have a token, no sense asking again, just configure pushes to register callbacks and we are done
if (!alreadyConfigured) configureNotifications(); // no await so it executes in background while we return TRUE and use token
return true;
}
return new Promise(function (resolve) {
Alert.alert(
'Would you like to receive notifications when you get incoming payments?',
'',
[
{
text: 'Ask Me Later',
onPress: () => {
resolve(false);
},
style: 'cancel',
},
{
text: loc._.ok,
onPress: async () => {
resolve(await configureNotifications());
},
style: 'default',
},
],
{ cancelable: false },
);
});
};
function _getHeaders() {
return {
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
};
}
/**
* Submits onchain bitcoin addresses and ln invoice preimage hashes to GroundControl server, so later we could
* be notified if they were paid
*
* @param addresses {string[]}
* @param hashes {string[]}
* @returns {Promise<object>} Response object from API rest call
*/
const majorTomToGroundControl = async function (addresses, hashes) {
if (!Array.isArray(addresses) || !Array.isArray(hashes)) throw new Error('no addresses or hashes provided');
const pushToken = await _getPushToken();
if (!pushToken || !pushToken.token || !pushToken.os) return;
const api = new Frisbee({ baseURI: constants.groundControlUri });
return await api.post(
'/majorTomToGroundControl',
Object.assign({}, _getHeaders(), {
body: {
addresses,
hashes,
token: pushToken.token,
os: pushToken.os,
},
}),
);
};
// on app launch (load module):
(async () => {
if (!(await _getPushToken())) return;
// if we previously had token that means we already acquired permission from the user and it is safe to call
// `configure` to register callbacks etc
await configureNotifications();
})();
// every launch should clear badges:
PushNotification.setApplicationIconBadgeNumber(0);
module.exports.tryToObtainPermissions = tryToObtainPermissions;
module.exports.majorTomToGroundControl = majorTomToGroundControl;

View File

@ -1,5 +0,0 @@
/**
* Let's keep config vars, constants and definitions here
*/
export const useBlockcypherTokens = false;

View File

@ -1,6 +1,5 @@
export * from './wallets/abstract-wallet';
export * from './app-storage';
export * from './constants';
export * from './wallets/legacy-wallet';
export * from './wallets/segwit-bech32-wallet';
export * from './wallets/segwit-p2sh-wallet';

View File

@ -5,9 +5,10 @@
* LICENSE file in the root directory of this source tree.
*/
#import <UserNotifications/UNUserNotificationCenter.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate>
@property (nonatomic, strong) UIWindow *window;

View File

@ -11,6 +11,8 @@
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import "RNQuickActionManager.h"
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>
#if DEBUG
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
@ -18,6 +20,7 @@
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
static void InitializeFlipper(UIApplication *application) {
FlipperClient *client = [FlipperClient sharedClient];
SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
@ -57,6 +60,11 @@ static void InitializeFlipper(UIApplication *application) {
UIView* launchScreenView = [[UIStoryboard storyboardWithName:@"LaunchScreen" bundle:nil] instantiateInitialViewController].view;
launchScreenView.frame = self.window.bounds;
rootView.loadingView = launchScreenView;
// Define UNUserNotificationCenter
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
return YES;
}
@ -82,4 +90,69 @@ static void InitializeFlipper(UIApplication *application) {
[RNQuickActionManager onQuickActionPress:shortcutItem completionHandler:completionHandler];
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
[RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings];
}
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event. You must call the completion handler after handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
// IOS 10+ Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler
{
[RNCPushNotificationIOS didReceiveNotificationResponse:response];
completionHandler();
}
// IOS 4-10 Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
[RNCPushNotificationIOS didReceiveLocalNotification:notification];
}
@end

View File

@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.security.application-groups</key>
<array>
<string>group.io.bluewallet.bluewallet</string>

View File

@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.icloud-container-identifiers</key>
<array/>
<key>com.apple.developer.icloud-services</key>

View File

@ -339,6 +339,8 @@ PODS:
- React
- RNCMaskedView (0.1.10):
- React
- RNCPushNotificationIOS (1.3.0):
- React
- RNDefaultPreference (1.4.3):
- React
- RNDeviceInfo (5.6.1):
@ -372,9 +374,9 @@ PODS:
- React
- RNWatch (0.5.0):
- React
- Sentry (5.1.6):
- Sentry/Core (= 5.1.6)
- Sentry/Core (5.1.6)
- Sentry (5.1.9):
- Sentry/Core (= 5.1.9)
- Sentry/Core (5.1.9)
- swift_qrcodejs (1.1.2)
- ToolTipMenu (5.2.0):
- React
@ -449,6 +451,7 @@ DEPENDENCIES:
- "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)"
- "RNCClipboard (from `../node_modules/@react-native-community/clipboard`)"
- "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)"
- "RNCPushNotificationIOS (from `../node_modules/@react-native-community/push-notification-ios`)"
- RNDefaultPreference (from `../node_modules/react-native-default-preference`)
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
- RNFS (from `../node_modules/react-native-fs`)
@ -573,6 +576,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/@react-native-community/clipboard"
RNCMaskedView:
:path: "../node_modules/@react-native-community/masked-view"
RNCPushNotificationIOS:
:path: "../node_modules/@react-native-community/push-notification-ios"
RNDefaultPreference:
:path: "../node_modules/react-native-default-preference"
RNDeviceInfo:
@ -666,6 +671,7 @@ SPEC CHECKSUMS:
RNCAsyncStorage: db711e29e5e0500d9bd21aa0c2e397efa45302b1
RNCClipboard: a254f6e568bc713b7ef49646e216661369882030
RNCMaskedView: f5c7d14d6847b7b44853f7acb6284c1da30a3459
RNCPushNotificationIOS: 23c5b5fdae79f105c63236de5ca306a70c00c444
RNDefaultPreference: 21816c0a6f61a2829ccc0cef034392e9b509ee5f
RNDeviceInfo: ab2ab4ca9e7f2bc4f35d62ab6ce2b66f2cbf1e7a
RNFS: 2bd9eb49dc82fa9676382f0585b992c424cd59df
@ -682,7 +688,7 @@ SPEC CHECKSUMS:
RNSVG: ce9d996113475209013317e48b05c21ee988d42e
RNVectorIcons: 0bb4def82230be1333ddaeee9fcba45f0b288ed4
RNWatch: 4de37878bbf071847e438b089c01d4ad8d4eddae
Sentry: e5796ec31a481474d2f94553213278470f9e302d
Sentry: 81f7f2bd3cb041137ea7efcde3aa5ad0d5a67632
swift_qrcodejs: 4d024fc98b0778b804ec6a5c810880fd092aec9d
ToolTipMenu: 4d89d95ddffd7539230bdbe02ee51bbde362e37e
Yoga: 3ebccbdd559724312790e7742142d062476b698e

16
package-lock.json generated
View File

@ -4650,6 +4650,14 @@
"resolved": "https://registry.npmjs.org/@react-native-community/masked-view/-/masked-view-0.1.10.tgz",
"integrity": "sha512-rk4sWFsmtOw8oyx8SD3KSvawwaK7gRBSEIy2TAwURyGt+3TizssXP1r8nx3zY+R7v2vYYHXZ+k2/GULAT/bcaQ=="
},
"@react-native-community/push-notification-ios": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@react-native-community/push-notification-ios/-/push-notification-ios-1.3.0.tgz",
"integrity": "sha512-fXLtDYsDv8CZIF/1pnrLyKv68X1VVgsWQTVdxA4UeYPAGP9OU4XdShD1TsPFWIF5VgabNrnmKl1uEDLw3X+6jA==",
"requires": {
"invariant": "^2.2.4"
}
},
"@react-native-community/slider": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@react-native-community/slider/-/slider-3.0.0.tgz",
@ -14968,6 +14976,14 @@
"version": "git+https://github.com/BlueWallet/react-native-prompt-android.git#2073b07f64bf5dc95807f64d79f37bdb111e6951",
"from": "git+https://github.com/BlueWallet/react-native-prompt-android.git#2073b07f64bf5dc95807f64d79f37bdb111e6951"
},
"react-native-push-notification": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/react-native-push-notification/-/react-native-push-notification-4.0.0.tgz",
"integrity": "sha512-PwFxGupwlAKc8qz8nMhX9U+/En/kiEH/1cyuKvUQdMa+tx96xZ/t81RTyOkkehkx4lbsI+Tv2F+D+fJV9IQb+A==",
"requires": {
"@react-native-community/push-notification-ios": "^1.2.2"
}
},
"react-native-qrcode-svg": {
"version": "6.0.6",
"resolved": "https://registry.npmjs.org/react-native-qrcode-svg/-/react-native-qrcode-svg-6.0.6.tgz",

View File

@ -42,7 +42,7 @@
"e2e:debug": "(test -f android/app/build/outputs/apk/debug/app-debug.apk && test -f android/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk) || npm run e2e:debug-build; npm run e2e:debug-test",
"e2e:release-build": "npx detox build -c android.emu.release",
"e2e:release-test": "detox test -c android.emu.release --record-videos all --take-screenshots all --headless",
"lint": "eslint *.js screen/**/*.js blue_modules/crypto.js class/**/*.js models/ loc/ tests/**/*.js",
"lint": "eslint *.js screen/**/*.js blue_modules/*.js class/**/*.js models/ loc/ tests/**/*.js",
"lint:fix": "npm run lint -- --fix",
"lint:quickfix": "git status --porcelain | grep -v '\\.json' | grep '\\.js' --color=never | awk '{print $2}' | xargs eslint --fix; exit 0",
"unit": "jest tests/unit/*"
@ -65,6 +65,7 @@
"@react-native-community/blur": "3.6.0",
"@react-native-community/clipboard": "1.2.2",
"@react-native-community/masked-view": "0.1.10",
"@react-native-community/push-notification-ios": "1.3.0",
"@react-native-community/slider": "3.0.0",
"@react-navigation/native": "5.6.1",
"@react-navigation/stack": "5.6.2",
@ -128,6 +129,7 @@
"react-native-popup-menu-android": "1.0.3",
"react-native-privacy-snapshot": "git+https://github.com/BlueWallet/react-native-privacy-snapshot.git",
"react-native-prompt-android": "git+https://github.com/BlueWallet/react-native-prompt-android.git#2073b07f64bf5dc95807f64d79f37bdb111e6951",
"react-native-push-notification": "4.0.0",
"react-native-qrcode-svg": "6.0.6",
"react-native-quick-actions": "0.3.13",
"react-native-randombytes": "3.5.3",

View File

@ -15,6 +15,7 @@ import { WebView } from 'react-native-webview';
import { BlueNavigationStyle, SafeBlueArea } from '../../BlueComponents';
import Ionicons from 'react-native-vector-icons/Ionicons';
import PropTypes from 'prop-types';
const notifications = require('../../blue_modules/notifications');
let processedInvoices = {};
let lastTimeTriedToPay = 0;
@ -392,6 +393,11 @@ export default class Browser extends Component {
// event; note how data is passed in 'detail', not 'data'
const jsonstr = JSON.stringify({ bluewalletResponse: { paymentRequest: payreq }, id: json.id });
this.webview.injectJavaScript("document.dispatchEvent( new CustomEvent('message', { detail: '" + jsonstr + "' }) );");
// lets decode payreq and subscribe groundcontrol so we can receive push notification when our invoice is paid
const decoded = await fromWallet.decodeInvoice(payreq);
await notifications.tryToObtainPermissions();
notifications.majorTomToGroundControl([], [decoded.payment_hash]);
},
},
],

View File

@ -32,6 +32,7 @@ const currency = require('../../blue_modules/currency');
const BlueApp = require('../../BlueApp');
const EV = require('../../blue_modules/events');
const loc = require('../../loc');
const notifications = require('../../blue_modules/notifications');
const styles = StyleSheet.create({
createButton: {
@ -222,6 +223,13 @@ export default class LNDCreateInvoice extends Component {
EV(EV.enum.TRANSACTIONS_COUNT_CHANGED);
ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
// lets decode payreq and subscribe groundcontrol so we can receive push notification when our invoice is paid
/** @type LightningCustodianWallet */
const fromWallet = this.state.fromWallet;
const decoded = await fromWallet.decodeInvoice(invoiceRequest);
await notifications.tryToObtainPermissions();
notifications.majorTomToGroundControl([], [decoded.payment_hash]);
// send to lnurl-withdraw callback url if that exists
if (this.state.lnurlParams) {
const { callback, k1 } = this.state.lnurlParams;

View File

@ -37,6 +37,7 @@ import { BlueCurrentTheme } from '../../components/themes';
const BlueApp = require('../../BlueApp');
const loc = require('../../loc');
const currency = require('../../blue_modules/currency');
const notifications = require('../../blue_modules/notifications');
const ReceiveDetails = () => {
const { secret } = useRoute().params;
@ -151,7 +152,6 @@ const ReceiveDetails = () => {
} else {
BlueApp.saveToDisk(); // caching whatever getAddressAsync() generated internally
}
setAddress(address);
} else if (wallet.chain === Chain.OFFCHAIN) {
try {
await Promise.race([wallet.getAddressAsync(), BlueApp.sleep(1000)]);
@ -166,8 +166,12 @@ const ReceiveDetails = () => {
}
}
setAddress(address);
await notifications.tryToObtainPermissions();
notifications.majorTomToGroundControl([address], []);
} else if (wallet.getAddress) {
setAddress(wallet.getAddress());
await notifications.tryToObtainPermissions();
notifications.majorTomToGroundControl([wallet.getAddress()], []);
}
InteractionManager.runAfterInteractions(async () => {
const bip21encoded = DeeplinkSchemaMatch.bip21encode(address);