DEL: Lapp Browser

This commit is contained in:
Marcos Rodriguez Velez 2024-04-19 18:36:12 -04:00
parent 440e4d407e
commit a651b66c64
No known key found for this signature in database
GPG Key ID: 6030B2F48CCE86D7
8 changed files with 1 additions and 668 deletions

View File

@ -71,7 +71,6 @@ import { isDesktop, isHandset, isTablet } from './blue_modules/environment';
import navigationStyle from './components/navigationStyle';
import { useTheme } from './components/themes';
import loc from './loc';
import LappBrowser from './screen/lnd/browser';
import LdkInfo from './screen/lnd/ldkInfo';
import LdkOpenChannel from './screen/lnd/ldkOpenChannel';
import LNDCreateInvoice from './screen/lnd/lndCreateInvoice';
@ -492,17 +491,6 @@ const WalletExportStackRoot = () => {
);
};
const LappBrowserStack = createNativeStackNavigator();
const LappBrowserStackRoot = () => {
const theme = useTheme();
return (
<LappBrowserStack.Navigator id="LappBrowserRoot" screenOptions={{ headerShadowVisible: false }} initialRouteName="LappBrowser">
<LappBrowserStack.Screen name="LappBrowser" component={LappBrowser} options={LappBrowser.navigationOptions(theme)} />
</LappBrowserStack.Navigator>
);
};
const InitStack = createNativeStackNavigator();
const InitRoot = () => {
const { walletsInitialized } = useContext(BlueStorageContext);
@ -638,7 +626,6 @@ const Navigation = () => {
/>
<RootStack.Screen name="SelectWallet" component={SelectWallet} />
<RootStack.Screen name="ReceiveDetailsRoot" component={ReceiveDetailsStackRoot} options={NavigationDefaultOptions} />
<RootStack.Screen name="LappBrowserRoot" component={LappBrowserStackRoot} options={NavigationDefaultOptions} />
<RootStack.Screen name="LDKOpenChannelRoot" component={LDKOpenChannelRoot} options={NavigationDefaultOptions} />
<RootStack.Screen

View File

@ -1,11 +1,10 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import bip21, { TOptions } from 'bip21';
import * as bitcoin from 'bitcoinjs-lib';
import URL from 'url';
import { readFileOutsideSandbox } from '../blue_modules/fs';
import { Chain } from '../models/bitcoinUnits';
import { BlueApp, LightningCustodianWallet, WatchOnlyWallet } from './';
import { WatchOnlyWallet } from './';
import Azteco from './azteco';
import Lnurl from './lnurl';
import type { TWallet } from './wallets/types';
@ -215,64 +214,6 @@ class DeeplinkSchemaMatch {
(async () => {
if (urlObject.protocol === 'bluewallet:' || urlObject.protocol === 'lapp:' || urlObject.protocol === 'blue:') {
switch (urlObject.host) {
case 'openlappbrowser': {
console.log('opening LAPP', urlObject.query.url);
// searching for LN wallet:
let haveLnWallet = false;
for (const w of context.wallets) {
if (w.type === LightningCustodianWallet.type) {
haveLnWallet = true;
}
}
if (!haveLnWallet) {
// need to create one
const w = new LightningCustodianWallet();
w.setLabel(w.typeReadable);
try {
const lndhub = await AsyncStorage.getItem(BlueApp.LNDHUB);
if (lndhub) {
w.setBaseURI(lndhub);
w.init();
}
await w.createAccount();
await w.authorize();
} catch (Err) {
// giving up, not doing anything
return;
}
context.addWallet(w);
context.saveToDisk();
}
// now, opening lapp browser and navigating it to URL.
// looking for a LN wallet:
let lnWallet;
for (const w of context.wallets) {
if (w.type === LightningCustodianWallet.type) {
lnWallet = w;
break;
}
}
if (!lnWallet) {
// something went wrong
return;
}
completionHandler([
'LappBrowserRoot',
{
screen: 'LappBrowser',
params: {
walletID: lnWallet.getID(),
url: urlObject.query.url,
},
},
]);
break;
}
case 'setelectrumserver':
completionHandler([
'ElectrumSettings',

View File

@ -352,9 +352,6 @@ PODS:
- react-native-tcp-socket (6.0.6):
- CocoaAsyncSocket
- React-Core
- react-native-webview (13.8.6):
- RCT-Folly (= 2021.07.22.00)
- React-Core
- react-native-widget-center (0.0.9):
- React
- React-NativeModulesApple (0.72.12):
@ -563,7 +560,6 @@ DEPENDENCIES:
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- react-native-secure-key-store (from `../node_modules/react-native-secure-key-store`)
- react-native-tcp-socket (from `../node_modules/react-native-tcp-socket`)
- react-native-webview (from `../node_modules/react-native-webview`)
- react-native-widget-center (from `../node_modules/react-native-widget-center`)
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
@ -691,8 +687,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-secure-key-store"
react-native-tcp-socket:
:path: "../node_modules/react-native-tcp-socket"
react-native-webview:
:path: "../node_modules/react-native-webview"
react-native-widget-center:
:path: "../node_modules/react-native-widget-center"
React-NativeModulesApple:
@ -822,7 +816,6 @@ SPEC CHECKSUMS:
react-native-safe-area-context: b97eb6f9e3b7f437806c2ce5983f479f8eb5de4b
react-native-secure-key-store: 910e6df6bc33cb790aba6ee24bc7818df1fe5898
react-native-tcp-socket: e724380c910c2e704816ec817ed28f1342246ff7
react-native-webview: 2ce07db2190ee7b3af77e8fac75ff47abe47089f
react-native-widget-center: 12dfba20a4fa995850b52cf0afecf734397f4b9c
React-NativeModulesApple: 694679e4193a49c09f0a76ee27ec09b2c466d59c
React-perflogger: 63606aeab27683112e1bd4ef25bd099ec1cb03f8

View File

@ -449,7 +449,6 @@
"list_empty_txs2": "Start with your wallet.",
"list_empty_txs2_lightning": "\nTo start using it, tap on Manage Funds and topup your balance.",
"list_latest_transaction": "Latest Transaction",
"list_ln_browser": "LApp Browser",
"list_long_choose": "Choose Photo",
"list_long_clipboard": "Copy from Clipboard",
"list_long_scan": "Scan QR Code",

38
package-lock.json generated
View File

@ -97,7 +97,6 @@
"react-native-tcp-socket": "6.0.6",
"react-native-vector-icons": "10.0.3",
"react-native-watch-connectivity": "1.1.0",
"react-native-webview": "13.8.6",
"react-native-widget-center": "https://github.com/BlueWallet/react-native-widget-center#a128c38",
"readable-stream": "3.6.2",
"realm": "12.7.0",
@ -19827,27 +19826,6 @@
"react-native": ">=0.40"
}
},
"node_modules/react-native-webview": {
"version": "13.8.6",
"resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.8.6.tgz",
"integrity": "sha512-jtZ9OgB2AN6rhDwto6dNL3PtOtl/SI4VN93pZEPbMLvRjqHfxiUrilGllL5fKAXq5Ry5FJyfUi82A4Ii8olZ7A==",
"dependencies": {
"escape-string-regexp": "2.0.0",
"invariant": "2.2.4"
},
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-webview/node_modules/escape-string-regexp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
"engines": {
"node": ">=8"
}
},
"node_modules/react-native-widget-center": {
"version": "0.0.9",
"resolved": "git+ssh://git@github.com/BlueWallet/react-native-widget-center.git#a128c389526d55afdd67937494f2fec224dd0009",
@ -37368,22 +37346,6 @@
"lodash.sortby": "^4.7.0"
}
},
"react-native-webview": {
"version": "13.8.6",
"resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.8.6.tgz",
"integrity": "sha512-jtZ9OgB2AN6rhDwto6dNL3PtOtl/SI4VN93pZEPbMLvRjqHfxiUrilGllL5fKAXq5Ry5FJyfUi82A4Ii8olZ7A==",
"requires": {
"escape-string-regexp": "2.0.0",
"invariant": "2.2.4"
},
"dependencies": {
"escape-string-regexp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="
}
}
},
"react-native-widget-center": {
"version": "git+ssh://git@github.com/BlueWallet/react-native-widget-center.git#a128c389526d55afdd67937494f2fec224dd0009",
"from": "react-native-widget-center@https://github.com/BlueWallet/react-native-widget-center#a128c38"

View File

@ -184,7 +184,6 @@
"react-native-tcp-socket": "6.0.6",
"react-native-vector-icons": "10.0.3",
"react-native-watch-connectivity": "1.1.0",
"react-native-webview": "13.8.6",
"react-native-widget-center": "https://github.com/BlueWallet/react-native-widget-center#a128c38",
"readable-stream": "3.6.2",
"realm": "12.7.0",

View File

@ -1,527 +0,0 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Ionicons from 'react-native-vector-icons/Ionicons';
import { ActivityIndicator, Alert, BackHandler, Keyboard, Platform, StyleSheet, TextInput, TouchableOpacity, View } from 'react-native';
import { WebView } from 'react-native-webview';
import navigationStyle from '../../components/navigationStyle';
import Notifications from '../../blue_modules/notifications';
import loc from '../../loc';
import { Button } from 'react-native-elements';
import { BlueStorageContext } from '../../blue_modules/storage-context';
import SafeArea from '../../components/SafeArea';
let processedInvoices = {};
let lastTimeTriedToPay = 0;
/// ///////////////////////////////////////////////////////////////////////
// this code has no use in RN, it gets copypasted in webview injected code
//
const bluewalletResponses = {};
// eslint-disable-next-line @typescript-eslint/no-unused-vars, no-var
var webln = {
enable: function () {
window.ReactNativeWebView.postMessage(JSON.stringify({ enable: true }));
return new Promise(function (resolve, reject) {
resolve(true);
});
},
getInfo: function () {
window.ReactNativeWebView.postMessage('getInfo');
return new Promise(function (resolve, reject) {
reject(new Error('not implemented'));
});
},
sendPayment: function (paymentRequest) {
window.ReactNativeWebView.postMessage(JSON.stringify({ sendPayment: paymentRequest }));
return new Promise(function (resolve, reject) {
/* nop. intentionally, forever hang promise.
lapp page usually asynchroniously checks payment itself, via ajax,
so atm there's no need to pass payment preimage from RN to webview and fullfill promise.
might change in future */
});
},
makeInvoice: function (RequestInvoiceArgs) {
var id = Math.random(); // eslint-disable-line no-var
window.ReactNativeWebView.postMessage(JSON.stringify({ makeInvoice: RequestInvoiceArgs, id }));
return new Promise(function (resolve, reject) {
// eslint-disable-next-line no-var
var interval = setInterval(function () {
if (bluewalletResponses[id]) {
clearInterval(interval);
resolve(bluewalletResponses[id]);
}
}, 1000);
});
},
signMessage: function () {
window.ReactNativeWebView.postMessage('signMessage');
return new Promise(function (resolve, reject) {
reject(new Error('not implemented'));
});
},
verifyMessage: function () {
window.ReactNativeWebView.postMessage('verifyMessage');
return new Promise(function (resolve, reject) {
reject(new Error('not implemented'));
});
},
};
// end injected code
/// /////////////////
/// /////////////////
let alreadyInjected = false;
const injectedParadise = `
/* rules:
no 'let', only 'var'
no arrow functions
globals without 'var'
should work if compressed to single line
*/
/* this is a storage of responses from OUTER code (react native)
it gets written by message bus handler callback:
webview makes a call through bus to RN, each request with a unique ID.
RN processes the request from the bus, and posts response to the bus, with the same ID.
webview callback handler writes it in this hashmap. Then, some other code that patiently
waits for a response will see that the answer with such ID is present, and will fulfill a promise */
bluewalletResponses = {};
/* this is injected WEBLN provider */
webln = {
enable : function () {
window.ReactNativeWebView.postMessage(JSON.stringify({'enable': true}));
return new Promise(function(resolve, reject){
resolve(true);
})
},
getInfo : function () {
window.ReactNativeWebView.postMessage('getInfo');
return new Promise(function(resolve, reject){
reject('not implemented');
})
},
sendPayment: function(paymentRequest) {
window.ReactNativeWebView.postMessage(JSON.stringify({ sendPayment: paymentRequest }));
return new Promise(function(resolve, reject) {
/* nop. intentionally, forever hang promise.
lapp page usually asynchroniously checks payment itself, via ajax,
so atm there's no need to pass payment preimage from RN to webview and fullfill promise.
might change in future */
});
},
makeInvoice: function (RequestInvoiceArgs) {
var id = Math.random();
window.ReactNativeWebView.postMessage(JSON.stringify({makeInvoice: RequestInvoiceArgs, id: id}));
return new Promise(function(resolve, reject) {
var interval = setInterval(function () {
if (bluewalletResponses[id]) {
clearInterval(interval);
resolve(bluewalletResponses[id]);
}
}, 1000);
});
},
signMessage: function () {
window.ReactNativeWebView.postMessage('signMessage');
return new Promise(function(resolve, reject){
reject('not implemented');
})
},
verifyMessage: function () {
window.ReactNativeWebView.postMessage('verifyMessage');
return new Promise(function(resolve, reject){
reject('not implemented');
})
},
};
/* end WEBLN */
/* listening to events that might come from RN: */
document.addEventListener("message", function(event) {
window.ReactNativeWebView.postMessage("inside webview, received post message: " + event.detail);
var json;
try {
json = JSON.parse(event.detail);
} catch (_) {}
if (json && json.bluewalletResponse) {
/* this is an answer to one of our inside-webview calls.
we store it in answers hashmap for someone who cares about it */
bluewalletResponses[json.id] = json.bluewalletResponse
}
}, false);
function tryToPay(invoice) {
window.ReactNativeWebView.postMessage(JSON.stringify({sendPayment:invoice}));
}
/* for non-webln compatible pages we do it oldschool,
searching for all bolt11 manually */
setInterval(function() {
window.ReactNativeWebView.postMessage('interval');
var searchText = "lnbc";
var aTags = document.getElementsByTagName("span");
var i;
for (i = 0; i < aTags.length; i++) {
if (aTags[i].textContent.indexOf(searchText) === 0) {
tryToPay(aTags[i].textContent);
}
}
/* ------------------------- */
aTags = document.getElementsByTagName("input");
for (i = 0; i < aTags.length; i++) {
if (aTags[i].value.indexOf(searchText) === 0) {
tryToPay(aTags[i].value);
}
}
/* ------------------------- */
aTags = document.getElementsByTagName("a");
searchText = "lightning:lnbc";
for (i = 0; i < aTags.length; i++) {
var href = aTags[i].getAttribute('href') + '';
if (href.indexOf(searchText) === 0) {
tryToPay(href.replace('lightning:', ''));
}
}
}, 1000);
`;
const styles = StyleSheet.create({
safeRoot: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
minHeight: 44,
},
safeURL: {
flex: 1,
marginHorizontal: 8,
alignItems: 'center',
justifyContent: 'center',
},
safeURLTextWrap: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
alignItems: 'center',
marginVertical: 8,
borderRadius: 4,
},
safeURLText: {
flex: 1,
marginLeft: 4,
minHeight: 33,
color: '#81868e',
},
safeURLHome: {
alignContent: 'flex-end',
height: 44,
flexDirection: 'row',
marginHorizontal: 8,
},
sync: {
color: 'red',
backgroundColor: 'transparent',
paddingLeft: 15,
},
activity: {
flex: 1,
justifyContent: 'center',
paddingLeft: 20,
alignContent: 'center',
},
goBack: {
backgroundColor: 'transparent',
paddingLeft: 10,
},
colorRed: {
color: 'red',
},
// eslint-disable-next-line react-native/no-unused-styles
colorGray: {
color: 'gray',
},
transparent: {
backgroundColor: 'transparent',
},
colorGreen: {
color: 'green',
},
});
export default class Browser extends Component {
webView = React.createRef();
constructor(props, context) {
super(props);
if (!props.route.params.walletID) throw new Error('Missing walletID param');
let url;
if (props.route.params.url) url = props.route.params.url;
this.state = {
url: url || 'https://www.duckduckgo.com/',
fromWallet: context.wallets.find(w => w.getID() === props.route.params.walletID),
canGoBack: false,
pageIsLoading: false,
stateURL: url || 'https://www.duckduckgo.com/',
};
BackHandler.addEventListener('hardwareBackPress', this.handleBackButton.bind(this));
}
componentWillUnmount = () => {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton.bind(this));
};
handleBackButton() {
this.state.canGoBack ? this.webView.current?.goBack() : this.props.navigation.goBack(null);
return true;
}
_onNavigationStateChange = webViewState => {
this.setState({ canGoBack: webViewState.canGoBack, stateURL: webViewState.url });
};
renderWebView = () => {
return (
<WebView
onNavigationStateChange={this._onNavigationStateChange}
ref={this.webView}
source={{ uri: this.state.url }}
onMessage={e => {
// this is a handler which receives messages sent from within the browser
console.log('---- message from the bus:', e.nativeEvent.data);
let json = false;
try {
json = JSON.parse(e.nativeEvent.data);
} catch (_) {}
// message from browser has ln invoice
if (json && json.sendPayment) {
// checking that already asked about this invoice:
if (processedInvoices[json.sendPayment]) {
return;
} else {
// checking that we do not trigger alert too often:
if (+new Date() - lastTimeTriedToPay < 3000) {
return;
}
lastTimeTriedToPay = +new Date();
//
processedInvoices[json.sendPayment] = 1;
}
Alert.alert(
'Page',
'This page asks for permission to pay an invoice',
[
{ text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel' },
{
text: 'Pay',
onPress: () => {
console.log('OK Pressed');
this.props.navigation.navigate('ScanLndInvoiceRoot', {
screen: 'ScanLndInvoice',
params: {
uri: json.sendPayment,
walletID: this.state.fromWallet.getID(),
},
});
},
},
],
{ cancelable: false },
);
}
if (json && json.makeInvoice) {
const amount = Math.max(
json.makeInvoice.minimumAmount || 0,
json.makeInvoice.maximumAmount || 0,
json.makeInvoice.defaultAmount || 0,
json.makeInvoice.amount || 0,
);
Alert.alert(
'Page',
'This page wants to pay you ' + amount + ' sats (' + json.makeInvoice.defaultMemo + ')',
[
{ text: 'No thanks', onPress: () => console.log('Cancel Pressed'), style: 'cancel' },
{
text: 'Accept',
onPress: async () => {
/** @type {LightningCustodianWallet} */
const fromWallet = this.state.fromWallet;
const payreq = await fromWallet.addInvoice(amount, json.makeInvoice.defaultMemo || ' ');
// this.webView.postMessage(JSON.stringify({ bluewalletResponse: { paymentRequest: payreq }, id: json.id }));
// Since webview.postMessage is removed from webview, we inject javascript that will manually triger document
// event; note how data is passed in 'detail', not 'data'
const jsonstr = JSON.stringify({ bluewalletResponse: { paymentRequest: payreq }, id: json.id });
this.webView.current?.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], []);
},
},
],
{ cancelable: false },
);
}
if (json && json.enable) {
console.log('webln enabled');
this.setState({ weblnEnabled: true });
}
}}
onLoadStart={e => {
alreadyInjected = false;
console.log('load start');
this.setState({ pageIsLoading: true, weblnEnabled: false });
}}
onLoadEnd={e => {
console.log('load end');
this.setState({ url: e.nativeEvent.url, pageIsLoading: false });
}}
onLoadProgress={e => {
console.log('progress:', e.nativeEvent.progress);
if (!alreadyInjected && e.nativeEvent.progress > 0.5) {
this.webView.current?.injectJavaScript(injectedParadise);
alreadyInjected = true;
console.log('injected');
}
}}
/>
);
};
render() {
return (
<SafeArea>
<View style={styles.safeRoot}>
<Button
icon={{
type: 'ionicon',
name: 'arrow-back-outline',
size: 36,
color: this.state.canGoBack ? styles.colorRed.color : styles.colorGray.color,
}}
type="clear"
disabled={!this.state.canGoBack}
style={styles.goBack}
onPress={() => this.webView.current?.goBack()}
/>
<View style={styles.safeURL}>
<View style={styles.safeURLTextWrap}>
<TextInput
onChangeText={text => this.setState({ stateURL: text })}
value={this.state.stateURL}
numberOfLines={1}
placeholderTextColor="#81868e"
style={styles.safeURLText}
editable
textContentType="URL"
keyboardType="url"
autoCorrect={false}
autoCapitalize="none"
onSubmitEditing={() => {
Keyboard.dismiss();
let url = this.state.stateURL;
if (!url.toLowerCase().startsWith('http://') && !url.toLowerCase().startsWith('https://')) {
url = 'https://' + url;
}
this.setState({ url });
}}
/>
</View>
</View>
<View style={styles.safeURLHome}>
{Platform.OS !== 'ios' && ( // on iOS lappbrowser opens blank page, thus, no HOME button
<TouchableOpacity
accessibilityRole="button"
onPress={() => {
processedInvoices = {};
this.setState({ url: 'https://www.duckduckgo.com/' });
}}
>
<Ionicons
name="ios-home"
size={36}
style={[styles.transparent, this.state.weblnEnabled ? styles.colorGreen : styles.colorRed]}
/>
</TouchableOpacity>
)}
<TouchableOpacity
accessibilityRole="button"
onPress={() => {
this.webView.current?.reload();
}}
>
{!this.state.pageIsLoading ? (
<Ionicons name="ios-sync" size={36} style={styles.sync} />
) : (
<View style={styles.activity}>
<ActivityIndicator />
</View>
)}
</TouchableOpacity>
</View>
</View>
{this.renderWebView()}
</SafeArea>
);
}
}
Browser.propTypes = {
navigation: PropTypes.shape({
navigate: PropTypes.func,
goBack: PropTypes.func,
}),
route: PropTypes.shape({
params: PropTypes.object,
}),
};
Browser.contextType = BlueStorageContext;
Browser.navigationOptions = navigationStyle(
{
headerBackVisible: false,
closeButton: true,
statusBarStyle: 'auto',
},
opts => ({ ...opts, title: loc.wallets.list_ln_browser }),
);

View File

@ -277,7 +277,6 @@ const WalletTransactions = ({ navigation }) => {
return (
<View style={styles.flex}>
<View style={styles.listHeader}>{wallet.chain === Chain.OFFCHAIN && renderLappBrowserButton()}</View>
{wallet.type === LightningLdkWallet.type && (lnNodeInfo.canSend > 0 || lnNodeInfo.canReceive > 0) && (
<View style={[styles.marginHorizontal18, styles.marginBottom18]}>
<LNNodeBar canSend={lnNodeInfo.canSend} canReceive={lnNodeInfo.canReceive} itemPriceUnit={itemPriceUnit} />
@ -290,26 +289,6 @@ const WalletTransactions = ({ navigation }) => {
);
};
const renderLappBrowserButton = () => {
return (
<TouchableOpacity
accessibilityRole="button"
onPress={() => {
navigate('LappBrowserRoot', {
screen: 'LappBrowser',
params: {
walletID,
url: 'https://duckduckgo.com',
},
});
}}
style={[styles.browserButton2, stylesHook.browserButton2]}
>
<Text style={[styles.marketpalceText1, stylesHook.marketpalceText1]}>{loc.wallets.list_ln_browser}</Text>
</TouchableOpacity>
);
};
const onWalletSelect = async selectedWallet => {
if (selectedWallet) {
navigate('WalletTransactions', {