mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-22 23:08:07 +01:00
REF: Handoff in-app rather than browser
This commit is contained in:
parent
f1d52e8867
commit
359981ff9b
14 changed files with 108 additions and 49 deletions
31
App.js
31
App.js
|
@ -34,6 +34,7 @@ import Biometric from './class/biometrics';
|
||||||
import WidgetCommunication from './blue_modules/WidgetCommunication';
|
import WidgetCommunication from './blue_modules/WidgetCommunication';
|
||||||
import changeNavigationBarColor from 'react-native-navigation-bar-color';
|
import changeNavigationBarColor from 'react-native-navigation-bar-color';
|
||||||
import ActionSheet from './screen/ActionSheet';
|
import ActionSheet from './screen/ActionSheet';
|
||||||
|
import HandoffComponent from './components/handoff';
|
||||||
const A = require('./blue_modules/analytics');
|
const A = require('./blue_modules/analytics');
|
||||||
const currency = require('./blue_modules/currency');
|
const currency = require('./blue_modules/currency');
|
||||||
|
|
||||||
|
@ -59,6 +60,7 @@ const App = () => {
|
||||||
const colorScheme = useColorScheme();
|
const colorScheme = useColorScheme();
|
||||||
|
|
||||||
const onNotificationReceived = async notification => {
|
const onNotificationReceived = async notification => {
|
||||||
|
console.warn(notification);
|
||||||
const payload = Object.assign({}, notification, notification.data);
|
const payload = Object.assign({}, notification, notification.data);
|
||||||
if (notification.data && notification.data.data) Object.assign(payload, notification.data.data);
|
if (notification.data && notification.data.data) Object.assign(payload, notification.data.data);
|
||||||
payload.foreground = true;
|
payload.foreground = true;
|
||||||
|
@ -77,6 +79,30 @@ const App = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onUserActivityOpen = data => {
|
||||||
|
console.warn(data);
|
||||||
|
switch (data.activityType) {
|
||||||
|
case HandoffComponent.activityTypes.ReceiveOnchain:
|
||||||
|
NavigationService.navigate('ReceiveDetailsRoot', {
|
||||||
|
screen: 'ReceiveDetails',
|
||||||
|
params: {
|
||||||
|
address: data.userInfo.address,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case HandoffComponent.activityTypes.Xpub:
|
||||||
|
NavigationService.navigate('WalletXpubRoot', {
|
||||||
|
screen: 'WalletXpub',
|
||||||
|
params: {
|
||||||
|
xPub: data.userInfo.xpub,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (walletsInitialized) {
|
if (walletsInitialized) {
|
||||||
addListeners();
|
addListeners();
|
||||||
|
@ -90,6 +116,7 @@ const App = () => {
|
||||||
AppState.removeEventListener('change', handleAppStateChange);
|
AppState.removeEventListener('change', handleAppStateChange);
|
||||||
eventEmitter.removeAllListeners('onNotificationReceived');
|
eventEmitter.removeAllListeners('onNotificationReceived');
|
||||||
eventEmitter.removeAllListeners('openSettings');
|
eventEmitter.removeAllListeners('openSettings');
|
||||||
|
eventEmitter.removeAllListeners('onUserActivityOpen');
|
||||||
};
|
};
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
@ -117,9 +144,11 @@ const App = () => {
|
||||||
*/
|
*/
|
||||||
eventEmitter.addListener('onNotificationReceived', onNotificationReceived);
|
eventEmitter.addListener('onNotificationReceived', onNotificationReceived);
|
||||||
eventEmitter.addListener('openSettings', openSettings);
|
eventEmitter.addListener('openSettings', openSettings);
|
||||||
|
eventEmitter.addListener('onUserActivityOpen', onUserActivityOpen);
|
||||||
};
|
};
|
||||||
|
|
||||||
const popInitialAction = async data => {
|
const popInitialAction = async data => {
|
||||||
|
console.warn(data);
|
||||||
if (data) {
|
if (data) {
|
||||||
const wallet = wallets.find(wallet => wallet.getID() === data.userInfo.url.split('wallet/')[1]);
|
const wallet = wallets.find(wallet => wallet.getID() === data.userInfo.url.split('wallet/')[1]);
|
||||||
NavigationService.dispatch(
|
NavigationService.dispatch(
|
||||||
|
@ -134,6 +163,7 @@ const App = () => {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const url = await Linking.getInitialURL();
|
const url = await Linking.getInitialURL();
|
||||||
|
console.warn(url);
|
||||||
if (url) {
|
if (url) {
|
||||||
if (DeeplinkSchemaMatch.hasSchema(url)) {
|
if (DeeplinkSchemaMatch.hasSchema(url)) {
|
||||||
handleOpenURL({ url });
|
handleOpenURL({ url });
|
||||||
|
@ -295,6 +325,7 @@ const App = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOpenURL = event => {
|
const handleOpenURL = event => {
|
||||||
|
console.warn(event);
|
||||||
DeeplinkSchemaMatch.navigationRouteFor(event, value => NavigationService.navigate(...value), { wallets, addWallet, saveToDisk });
|
DeeplinkSchemaMatch.navigationRouteFor(event, value => NavigationService.navigate(...value), { wallets, addWallet, saveToDisk });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
import React, { useContext } from 'react';
|
|
||||||
import Handoff from 'react-native-handoff';
|
|
||||||
import { BlueStorageContext } from '../blue_modules/storage-context';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
const HandoffComponent = props => {
|
|
||||||
const { isHandOffUseEnabled } = useContext(BlueStorageContext);
|
|
||||||
|
|
||||||
return isHandOffUseEnabled && props && props.url ? <Handoff {...props} /> : null;
|
|
||||||
};
|
|
||||||
export default HandoffComponent;
|
|
||||||
|
|
||||||
HandoffComponent.propTypes = {
|
|
||||||
url: PropTypes.string,
|
|
||||||
};
|
|
|
@ -1,5 +1,21 @@
|
||||||
const HandoffComponent = () => {
|
import React, { useContext } from 'react';
|
||||||
return null;
|
import Handoff from 'react-native-handoff';
|
||||||
|
import { BlueStorageContext } from '../blue_modules/storage-context';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
const HandoffComponent = props => {
|
||||||
|
const { isHandOffUseEnabled } = useContext(BlueStorageContext);
|
||||||
|
|
||||||
|
return isHandOffUseEnabled ? <Handoff {...props} /> : null;
|
||||||
|
};
|
||||||
|
export default HandoffComponent;
|
||||||
|
|
||||||
|
HandoffComponent.propTypes = {
|
||||||
|
url: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default HandoffComponent;
|
HandoffComponent.activityTypes = {
|
||||||
|
ReceiveOnchain: 'io.bluewallet.bluewallet.receiveonchain',
|
||||||
|
Xpub: 'io.bluewallet.bluewallet.xpub',
|
||||||
|
ViewInBlockExplorer: 'io.bluewallet.bluewallet.blockexplorer',
|
||||||
|
};
|
||||||
|
|
|
@ -83,6 +83,21 @@ static void InitializeFlipper(UIApplication *application) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
|
||||||
|
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
|
||||||
|
{
|
||||||
|
|
||||||
|
if (userActivity.activityType == NSUserActivityTypeBrowsingWeb) {
|
||||||
|
return [RCTLinkingManager application:application
|
||||||
|
continueUserActivity:userActivity
|
||||||
|
restorationHandler:restorationHandler];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[EventEmitter.sharedInstance sendUserActivity:@{@"activityType": userActivity.activityType, @"userInfo": userActivity.userInfo}];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||||
return [RCTLinkingManager application:app openURL:url options:options];
|
return [RCTLinkingManager application:app openURL:url options:options];
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,11 @@
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>$(PRODUCT_NAME)</string>
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>NSUserActivityTypes</key>
|
||||||
|
<array>
|
||||||
|
<string>io.bluewallet.bluewallet.receiveonchain</string>
|
||||||
|
<string>io.bluewallet.bluewallet.xpub</string>
|
||||||
|
</array>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
|
|
|
@ -14,5 +14,6 @@
|
||||||
+ (EventEmitter *)sharedInstance;
|
+ (EventEmitter *)sharedInstance;
|
||||||
- (void)sendNotification:(NSDictionary *)userInfo;
|
- (void)sendNotification:(NSDictionary *)userInfo;
|
||||||
- (void)openSettings;
|
- (void)openSettings;
|
||||||
|
- (void)sendUserActivity:(NSDictionary *)userInfo;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -29,7 +29,7 @@ RCT_EXPORT_MODULE();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray<NSString *> *)supportedEvents {
|
- (NSArray<NSString *> *)supportedEvents {
|
||||||
return @[@"onNotificationReceived",@"openSettings"];
|
return @[@"onNotificationReceived",@"openSettings",@"onUserActivityOpen"];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)sendNotification:(NSDictionary *)userInfo
|
- (void)sendNotification:(NSDictionary *)userInfo
|
||||||
|
@ -37,6 +37,11 @@ RCT_EXPORT_MODULE();
|
||||||
[sharedInstance sendEventWithName:@"onNotificationReceived" body:userInfo];
|
[sharedInstance sendEventWithName:@"onNotificationReceived" body:userInfo];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)sendUserActivity:(NSDictionary *)userInfo
|
||||||
|
{
|
||||||
|
[sharedInstance sendEventWithName:@"onUserActivityOpen" body:userInfo];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)openSettings
|
- (void)openSettings
|
||||||
{
|
{
|
||||||
|
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -19803,8 +19803,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-native-handoff": {
|
"react-native-handoff": {
|
||||||
"version": "git+https://github.com/marcosrdz/react-native-handoff.git#f5becc63f3e36bf2da1ed1fc60fc690323e73602",
|
"version": "git+https://github.com/BlueWallet/react-native-handoff.git#31d005f93d31099d0e564590a3bbd052b8a02b39",
|
||||||
"from": "git+https://github.com/marcosrdz/react-native-handoff.git#f5becc63f3e36bf2da1ed1fc60fc690323e73602"
|
"from": "git+https://github.com/BlueWallet/react-native-handoff.git#31d005f93d31099d0e564590a3bbd052b8a02b39"
|
||||||
},
|
},
|
||||||
"react-native-haptic-feedback": {
|
"react-native-haptic-feedback": {
|
||||||
"version": "git+https://github.com/junina-de/react-native-haptic-feedback.git#8e4d598ad9be886325316b0e2140df8df624a91f",
|
"version": "git+https://github.com/junina-de/react-native-haptic-feedback.git#8e4d598ad9be886325316b0e2140df8df624a91f",
|
||||||
|
|
|
@ -152,7 +152,7 @@
|
||||||
"react-native-fingerprint-scanner": "https://github.com/BlueWallet/react-native-fingerprint-scanner#ce644673681716335d786727bab998f7e632ab5e",
|
"react-native-fingerprint-scanner": "https://github.com/BlueWallet/react-native-fingerprint-scanner#ce644673681716335d786727bab998f7e632ab5e",
|
||||||
"react-native-fs": "2.18.0",
|
"react-native-fs": "2.18.0",
|
||||||
"react-native-gesture-handler": "1.10.3",
|
"react-native-gesture-handler": "1.10.3",
|
||||||
"react-native-handoff": "https://github.com/marcosrdz/react-native-handoff#f5becc63f3e36bf2da1ed1fc60fc690323e73602",
|
"react-native-handoff": "https://github.com/BlueWallet/react-native-handoff#31d005f93d31099d0e564590a3bbd052b8a02b39",
|
||||||
"react-native-haptic-feedback": "https://github.com/junina-de/react-native-haptic-feedback.git#8e4d598ad9be886325316b0e2140df8df624a91f",
|
"react-native-haptic-feedback": "https://github.com/junina-de/react-native-haptic-feedback.git#8e4d598ad9be886325316b0e2140df8df624a91f",
|
||||||
"react-native-idle-timer": "https://github.com/BlueWallet/react-native-idle-timer#8587876d68ab5920e79619726aeca9e672beaf2b",
|
"react-native-idle-timer": "https://github.com/BlueWallet/react-native-idle-timer#8587876d68ab5920e79619726aeca9e672beaf2b",
|
||||||
"react-native-image-picker": "4.1.1",
|
"react-native-image-picker": "4.1.1",
|
||||||
|
|
|
@ -407,6 +407,8 @@ const ReceiveDetails = () => {
|
||||||
} else {
|
} else {
|
||||||
obtainWalletAddress();
|
obtainWalletAddress();
|
||||||
}
|
}
|
||||||
|
} else if (!wallet && address) {
|
||||||
|
setAddressBIP21Encoded(address);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return () => {
|
return () => {
|
||||||
|
@ -507,9 +509,9 @@ const ReceiveDetails = () => {
|
||||||
<StatusBar barStyle="light-content" />
|
<StatusBar barStyle="light-content" />
|
||||||
{address !== undefined && showAddress && (
|
{address !== undefined && showAddress && (
|
||||||
<HandoffComponent
|
<HandoffComponent
|
||||||
title={`Bitcoin Transaction ${address}`}
|
title={loc.send.details_address}
|
||||||
type="io.bluewallet.bluewallet"
|
type={HandoffComponent.activityTypes.ReceiveOnchain}
|
||||||
url={`https://blockstream.info/address/${address}`}
|
userInfo={{ address: address }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{showConfirmedBalance ? renderConfirmedBalance() : null}
|
{showConfirmedBalance ? renderConfirmedBalance() : null}
|
||||||
|
|
|
@ -129,9 +129,9 @@ const TransactionsDetails = () => {
|
||||||
return (
|
return (
|
||||||
<SafeBlueArea>
|
<SafeBlueArea>
|
||||||
<HandoffComponent
|
<HandoffComponent
|
||||||
title={`Bitcoin Transaction ${tx.hash}`}
|
title={loc.transactions.details_title}
|
||||||
type="io.bluewallet.bluewallet"
|
type={HandoffComponent.activityTypes.ViewInBlockExplorer}
|
||||||
url={`https://blockstream.info/tx/${tx.hash}`}
|
url={`https://mempool.space/tx/${tx.hash}`}
|
||||||
/>
|
/>
|
||||||
<StatusBar barStyle="default" />
|
<StatusBar barStyle="default" />
|
||||||
<ScrollView style={styles.scroll}>
|
<ScrollView style={styles.scroll}>
|
||||||
|
|
|
@ -369,9 +369,9 @@ const TransactionsStatus = () => {
|
||||||
return (
|
return (
|
||||||
<SafeBlueArea>
|
<SafeBlueArea>
|
||||||
<HandoffComponent
|
<HandoffComponent
|
||||||
title={`Bitcoin Transaction ${tx.hash}`}
|
title={loc.transactions.details_title}
|
||||||
type="io.bluewallet.bluewallet"
|
type={HandoffComponent.activityTypes.ViewInBlockExplorer}
|
||||||
url={`https://blockstream.info/tx/${tx.hash}`}
|
url={`https://mempool.space/tx/${tx.hash}`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<StatusBar barStyle="default" />
|
<StatusBar barStyle="default" />
|
||||||
|
|
|
@ -25,7 +25,6 @@ import { BlueAlertWalletExportReminder } from '../../BlueComponents';
|
||||||
import WalletGradient from '../../class/wallet-gradient';
|
import WalletGradient from '../../class/wallet-gradient';
|
||||||
import navigationStyle from '../../components/navigationStyle';
|
import navigationStyle from '../../components/navigationStyle';
|
||||||
import { LightningCustodianWallet, LightningLdkWallet, MultisigHDWallet, WatchOnlyWallet } from '../../class';
|
import { LightningCustodianWallet, LightningLdkWallet, MultisigHDWallet, WatchOnlyWallet } from '../../class';
|
||||||
import HandoffComponent from '../../components/handoff';
|
|
||||||
import ActionSheet from '../ActionSheet';
|
import ActionSheet from '../ActionSheet';
|
||||||
import loc from '../../loc';
|
import loc from '../../loc';
|
||||||
import { FContainer, FButton } from '../../components/FloatButtons';
|
import { FContainer, FButton } from '../../components/FloatButtons';
|
||||||
|
@ -560,13 +559,6 @@ const WalletTransactions = () => {
|
||||||
return (
|
return (
|
||||||
<View style={styles.flex}>
|
<View style={styles.flex}>
|
||||||
<StatusBar barStyle="light-content" backgroundColor={WalletGradient.headerColorFor(wallet.type)} animated />
|
<StatusBar barStyle="light-content" backgroundColor={WalletGradient.headerColorFor(wallet.type)} animated />
|
||||||
{wallet.chain === Chain.ONCHAIN && wallet.type !== MultisigHDWallet.type && (
|
|
||||||
<HandoffComponent
|
|
||||||
title={`Bitcoin Wallet ${wallet.getLabel()}`}
|
|
||||||
type="io.bluewallet.bluewallet"
|
|
||||||
url={`https://blockpath.com/search/addr?q=${wallet.getXpub()}`}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<TransactionsNavigationHeader
|
<TransactionsNavigationHeader
|
||||||
wallet={wallet}
|
wallet={wallet}
|
||||||
onWalletUnitChange={passedWallet =>
|
onWalletUnitChange={passedWallet =>
|
||||||
|
|
|
@ -8,6 +8,7 @@ import Biometric from '../../class/biometrics';
|
||||||
import loc from '../../loc';
|
import loc from '../../loc';
|
||||||
import { BlueStorageContext } from '../../blue_modules/storage-context';
|
import { BlueStorageContext } from '../../blue_modules/storage-context';
|
||||||
import QRCodeComponent from '../../components/QRCodeComponent';
|
import QRCodeComponent from '../../components/QRCodeComponent';
|
||||||
|
import HandoffComponent from '../../components/handoff';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
root: {
|
root: {
|
||||||
|
@ -23,12 +24,11 @@ const styles = StyleSheet.create({
|
||||||
|
|
||||||
const WalletXpub = () => {
|
const WalletXpub = () => {
|
||||||
const { wallets } = useContext(BlueStorageContext);
|
const { wallets } = useContext(BlueStorageContext);
|
||||||
const { walletID } = useRoute().params;
|
const { walletID, xPub } = useRoute().params;
|
||||||
const wallet = wallets.find(w => w.getID() === walletID);
|
const wallet = wallets.find(w => w.getID() === walletID);
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [xPub, setXPub] = useState();
|
|
||||||
const [xPubText, setXPubText] = useState();
|
const [xPubText, setXPubText] = useState();
|
||||||
const { goBack } = useNavigation();
|
const { goBack, setParams } = useNavigation();
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
const [qrCodeSize, setQRCodeSize] = useState(90);
|
const [qrCodeSize, setQRCodeSize] = useState(90);
|
||||||
const stylesHook = StyleSheet.create({ root: { backgroundColor: colors.elevated } });
|
const stylesHook = StyleSheet.create({ root: { backgroundColor: colors.elevated } });
|
||||||
|
@ -45,9 +45,12 @@ const WalletXpub = () => {
|
||||||
return goBack();
|
return goBack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setXPub(wallet.getXpub());
|
setParams({ xPub: wallet.getXpub() });
|
||||||
setXPubText(wallet.getXpub());
|
setXPubText(wallet.getXpub());
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
} else if (xPub) {
|
||||||
|
setXPubText(xPub);
|
||||||
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return () => {
|
return () => {
|
||||||
|
@ -55,7 +58,7 @@ const WalletXpub = () => {
|
||||||
Privacy.disableBlur();
|
Privacy.disableBlur();
|
||||||
};
|
};
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [goBack, walletID]),
|
}, [goBack, walletID, xPub]),
|
||||||
);
|
);
|
||||||
|
|
||||||
const onLayout = e => {
|
const onLayout = e => {
|
||||||
|
@ -71,15 +74,19 @@ const WalletXpub = () => {
|
||||||
<SafeBlueArea style={[styles.root, stylesHook.root]} onLayout={onLayout}>
|
<SafeBlueArea style={[styles.root, stylesHook.root]} onLayout={onLayout}>
|
||||||
<StatusBar barStyle="light-content" />
|
<StatusBar barStyle="light-content" />
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<View>
|
{wallet && (
|
||||||
<BlueText>{wallet.typeReadable}</BlueText>
|
<>
|
||||||
</View>
|
<View>
|
||||||
<BlueSpacing20 />
|
<BlueText>{wallet.typeReadable}</BlueText>
|
||||||
|
</View>
|
||||||
|
<BlueSpacing20 />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<QRCodeComponent value={xPub} size={qrCodeSize} />
|
<QRCodeComponent value={xPub} size={qrCodeSize} />
|
||||||
|
|
||||||
<BlueSpacing20 />
|
<BlueSpacing20 />
|
||||||
<BlueCopyTextToClipboard text={xPubText} />
|
<BlueCopyTextToClipboard text={xPubText} />
|
||||||
|
<HandoffComponent title={loc.wallets.xpub_title} type={HandoffComponent.activityTypes.Xpub} userInfo={{ xpub: xPubText }} />
|
||||||
</View>
|
</View>
|
||||||
</SafeBlueArea>
|
</SafeBlueArea>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Reference in a new issue