mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-23 15:20:55 +01:00
commit
664a6d961b
13 changed files with 714 additions and 684 deletions
|
@ -105,6 +105,14 @@ const WalletsStackNavigator = createStackNavigator(
|
||||||
screen: LightningSettings,
|
screen: LightningSettings,
|
||||||
path: 'LightningSettings',
|
path: 'LightningSettings',
|
||||||
},
|
},
|
||||||
|
LNDViewInvoice: {
|
||||||
|
screen: LNDViewInvoice,
|
||||||
|
swipeEnabled: false,
|
||||||
|
gesturesEnabled: false,
|
||||||
|
},
|
||||||
|
LNDViewAdditionalInvoiceInformation: {
|
||||||
|
screen: LNDViewAdditionalInvoiceInformation,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{ headerBackTitleVisible: false },
|
{ headerBackTitleVisible: false },
|
||||||
);
|
);
|
||||||
|
@ -149,17 +157,6 @@ const ManageFundsStackNavigator = createStackNavigator({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const LNDViewInvoiceStackNavigator = createStackNavigator({
|
|
||||||
LNDViewInvoice: {
|
|
||||||
screen: LNDViewInvoice,
|
|
||||||
swipeEnabled: false,
|
|
||||||
gesturesEnabled: false,
|
|
||||||
},
|
|
||||||
LNDViewAdditionalInvoiceInformation: {
|
|
||||||
screen: LNDViewAdditionalInvoiceInformation,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const LNDCreateInvoiceStackNavigator = createStackNavigator({
|
const LNDCreateInvoiceStackNavigator = createStackNavigator({
|
||||||
LNDCreateInvoice: {
|
LNDCreateInvoice: {
|
||||||
screen: LNDCreateInvoice,
|
screen: LNDCreateInvoice,
|
||||||
|
@ -260,12 +257,6 @@ const MainBottomTabs = createStackNavigator(
|
||||||
header: null,
|
header: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
LNDViewExistingInvoice: {
|
|
||||||
screen: LNDViewInvoiceStackNavigator,
|
|
||||||
navigationOptions: {
|
|
||||||
header: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mode: 'modal',
|
mode: 'modal',
|
||||||
|
|
|
@ -102,8 +102,8 @@ android {
|
||||||
applicationId "io.bluewallet.bluewallet"
|
applicationId "io.bluewallet.bluewallet"
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode 17
|
versionCode 18
|
||||||
versionName "3.5.7"
|
versionName "3.6.0"
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters "armeabi-v7a", "x86"
|
abiFilters "armeabi-v7a", "x86"
|
||||||
}
|
}
|
||||||
|
|
40
loc/jp_JP.js
40
loc/jp_JP.js
|
@ -1,6 +1,6 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
_: {
|
_: {
|
||||||
storage_is_encrypted: 'ストレージが暗号化されています。復号にはパスワードが必要です。',
|
storage_is_encrypted: 'ウォレットは暗号化されています。復号にはパスワードが必要です。',
|
||||||
enter_password: 'パスワードを入力',
|
enter_password: 'パスワードを入力',
|
||||||
bad_password: 'パスワードが間違っています。',
|
bad_password: 'パスワードが間違っています。',
|
||||||
never: 'データなし',
|
never: 'データなし',
|
||||||
|
@ -13,7 +13,7 @@ module.exports = {
|
||||||
createBitcoinWallet:
|
createBitcoinWallet:
|
||||||
'Bitcoin ウォレットを持っていません。Lightning ウォレットへ課金する場合は Bitcoin ウォレットを新規作成するかインポートする必要があります。続行しますか?',
|
'Bitcoin ウォレットを持っていません。Lightning ウォレットへ課金する場合は Bitcoin ウォレットを新規作成するかインポートする必要があります。続行しますか?',
|
||||||
list: {
|
list: {
|
||||||
app_name: 'Blue Wallet',
|
app_name: 'BlueWallet',
|
||||||
title: 'ウォレット',
|
title: 'ウォレット',
|
||||||
header: 'ウォレットは秘密鍵(プライベートキー)とウォレットアドレスのペアで構成されています。' + 'コインを受信するために共有できます。',
|
header: 'ウォレットは秘密鍵(プライベートキー)とウォレットアドレスのペアで構成されています。' + 'コインを受信するために共有できます。',
|
||||||
add: 'ウォレットの追加',
|
add: 'ウォレットの追加',
|
||||||
|
@ -32,7 +32,7 @@ module.exports = {
|
||||||
title: 'ウォレットの追加',
|
title: 'ウォレットの追加',
|
||||||
description:
|
description:
|
||||||
'ペーパーウォレット(WIF 形式- Wallet Import Format)をスキャンするかウォレットを新規作成できます。既定で Segwit ウォレットが作成されます。',
|
'ペーパーウォレット(WIF 形式- Wallet Import Format)をスキャンするかウォレットを新規作成できます。既定で Segwit ウォレットが作成されます。',
|
||||||
scan: 'スキャン',
|
scan: '読取り',
|
||||||
create: '作成',
|
create: '作成',
|
||||||
label_new_segwit: '新規 SegWit',
|
label_new_segwit: '新規 SegWit',
|
||||||
label_new_lightning: '新規 Lightning',
|
label_new_lightning: '新規 Lightning',
|
||||||
|
@ -77,7 +77,7 @@ module.exports = {
|
||||||
error: 'インポートに失敗しました。入力したデータが有効か確認してください。',
|
error: 'インポートに失敗しました。入力したデータが有効か確認してください。',
|
||||||
success: '成功',
|
success: '成功',
|
||||||
do_import: 'インポート',
|
do_import: 'インポート',
|
||||||
scan_qr: '代わりに QR コードをスキャンしますか?',
|
scan_qr: 'QR コードの読み取り',
|
||||||
},
|
},
|
||||||
scanQrWif: {
|
scanQrWif: {
|
||||||
go_back: '戻る',
|
go_back: '戻る',
|
||||||
|
@ -125,7 +125,7 @@ module.exports = {
|
||||||
fee_placeholder: '取引手数料 (BTC)',
|
fee_placeholder: '取引手数料 (BTC)',
|
||||||
note_placeholder: 'ラベル',
|
note_placeholder: 'ラベル',
|
||||||
cancel: '中止',
|
cancel: '中止',
|
||||||
scan: 'スキャン',
|
scan: '読取り',
|
||||||
send: '送金',
|
send: '送金',
|
||||||
create: '作成',
|
create: '作成',
|
||||||
remaining_balance: '残高',
|
remaining_balance: '残高',
|
||||||
|
@ -160,7 +160,7 @@ module.exports = {
|
||||||
share: '共有',
|
share: '共有',
|
||||||
copiedToClipboard: 'クリップボードにコピーしました。',
|
copiedToClipboard: 'クリップボードにコピーしました。',
|
||||||
label: '概要',
|
label: '概要',
|
||||||
create: 'Create',
|
create: '作成',
|
||||||
setAmount: '入金額',
|
setAmount: '入金額',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -172,13 +172,13 @@ module.exports = {
|
||||||
settings: {
|
settings: {
|
||||||
header: '設定',
|
header: '設定',
|
||||||
plausible_deniability: '隠匿設定...',
|
plausible_deniability: '隠匿設定...',
|
||||||
storage_not_encrypted: 'ストレージ: 暗号化されていません',
|
storage_not_encrypted: 'ウォレット: 暗号化されていません',
|
||||||
storage_encrypted: 'ストレージ: 暗号化されています',
|
storage_encrypted: 'ウォレット: 暗号化されています',
|
||||||
password: 'パスワード',
|
password: 'パスワード',
|
||||||
password_explain: 'ストレージの復号に使用するパスワードを作成',
|
password_explain: 'ウォレットの復号に使用するパスワードを作成',
|
||||||
retype_password: 'パスワードの再入力',
|
retype_password: 'パスワードの再入力',
|
||||||
passwords_do_not_match: 'パスワードが一致しません',
|
passwords_do_not_match: 'パスワードが一致しません',
|
||||||
encrypt_storage: 'ストレージの暗号化',
|
encrypt_storage: 'ウォレットの暗号化',
|
||||||
lightning_settings: 'Lightning 設定',
|
lightning_settings: 'Lightning 設定',
|
||||||
lightning_settings_explain:
|
lightning_settings_explain:
|
||||||
'他の LND ノードへ接続するには LndHub をインストール後、' +
|
'他の LND ノードへ接続するには LndHub をインストール後、' +
|
||||||
|
@ -192,18 +192,20 @@ module.exports = {
|
||||||
plausibledeniability: {
|
plausibledeniability: {
|
||||||
title: '隠匿設定',
|
title: '隠匿設定',
|
||||||
help:
|
help:
|
||||||
'このウォレットの復号に必要なパスワードを第三者に強要される場合、' +
|
'BuleWallet のウォレットの復号に必要なパスワードを第三者に強要される場合、' +
|
||||||
'コインを安全に保護するために BlueWallet はメインとは異なるパスワードで' +
|
'コインを安全に保護するためにメインのウォレットとは異なるパスワードで' +
|
||||||
'暗号化されたダミーのストレージを作成します。' +
|
'暗号化されたダミーのウォレットを作成することが可能です。' +
|
||||||
'第三者へこのパスワードを提供することで、第三者が BlueWallet のダミーの' +
|
'第三者へ異なるパスワードを提供すれば、BlueWallet のダミーの' +
|
||||||
'暗号化ストレージを復号することで、メインのストレージを隠匿することが可能となり' +
|
'暗号化ウォレットを復号することとなり、メインのウォレットは隠匿され' +
|
||||||
'コインは安全に保護されます。',
|
'コインは安全に保護されます。',
|
||||||
help2: 'この新規ダミーのストレージは完全に機能します。少額のコインを保管することで' + 'ダミーと疑われないようにすることが可能です。',
|
help2:
|
||||||
create_fake_storage: 'ダミーの暗号化ストレージの作成',
|
'新規のダミーのウォレットはメインと同様に機能します。少額のコインを入金しておくことで' +
|
||||||
|
'ダミーと疑われないようにすることが可能です。',
|
||||||
|
create_fake_storage: 'ダミーの暗号化ウォレットの作成',
|
||||||
go_back: '戻る',
|
go_back: '戻る',
|
||||||
create_password: 'パスワードの作成',
|
create_password: 'パスワードの作成',
|
||||||
create_password_explanation: 'ダミーの暗号化ストレージのパスワードはメインのストレージのパスワードと異なる必要があります。',
|
create_password_explanation: 'ダミーのウォレットのパスワードはメインのウォレットのパスワードと異なる必要があります。',
|
||||||
password_should_not_match: 'ダミーのストレージのパスワードはメインのストレージのパスワードと異なる必要があります。',
|
password_should_not_match: 'ダミーのウォレットのパスワードはメインのウォレットのパスワードと異なる必要があります。',
|
||||||
retype_password: 'パスワードの再入力',
|
retype_password: 'パスワードの再入力',
|
||||||
passwords_do_not_match: 'パスワードが一致しません',
|
passwords_do_not_match: 'パスワードが一致しません',
|
||||||
success: '成功',
|
success: '成功',
|
||||||
|
|
|
@ -9,8 +9,10 @@ export const FiatUnit = Object.freeze({
|
||||||
HRK: { endPointKey: 'HRK', symbol: 'HRK', locale: 'hr-HR' },
|
HRK: { endPointKey: 'HRK', symbol: 'HRK', locale: 'hr-HR' },
|
||||||
INR: { endPointKey: 'INR', symbol: '₹', locale: 'hi-HN' },
|
INR: { endPointKey: 'INR', symbol: '₹', locale: 'hi-HN' },
|
||||||
JPY: { endPointKey: 'JPY', symbol: '¥', locale: 'ja-JP' },
|
JPY: { endPointKey: 'JPY', symbol: '¥', locale: 'ja-JP' },
|
||||||
|
PLN: { endPointKey: 'PLN', symbol: 'zł', locale: 'pl-PL' },
|
||||||
RUB: { endPointKey: 'RUB', symbol: '₽', locale: 'ru-RU' },
|
RUB: { endPointKey: 'RUB', symbol: '₽', locale: 'ru-RU' },
|
||||||
SGD: { endPointKey: 'SGD', symbol: 'S$', locale: 'zh-SG' },
|
SGD: { endPointKey: 'SGD', symbol: 'S$', locale: 'zh-SG' },
|
||||||
|
SEK: { endPointKey: 'SEK', symbol: 'kr', locale: 'sv-SE' },
|
||||||
THB: { endPointKey: 'THB', symbol: '฿', locale: 'th-TH' },
|
THB: { endPointKey: 'THB', symbol: '฿', locale: 'th-TH' },
|
||||||
VEF: { endPointKey: 'VEF', symbol: 'Bs.', locale: 'es-VE' },
|
VEF: { endPointKey: 'VEF', symbol: 'Bs.', locale: 'es-VE' },
|
||||||
ZAR: { endPointKey: 'ZAR', symbol: 'R', locale: 'en-ZA' },
|
ZAR: { endPointKey: 'ZAR', symbol: 'R', locale: 'en-ZA' },
|
||||||
|
|
907
package-lock.json
generated
907
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -43,7 +43,7 @@
|
||||||
"buffer": "^5.2.1",
|
"buffer": "^5.2.1",
|
||||||
"buffer-reverse": "^1.0.1",
|
"buffer-reverse": "^1.0.1",
|
||||||
"crypto-js": "^3.1.9-1",
|
"crypto-js": "^3.1.9-1",
|
||||||
"dayjs": "^1.7.8",
|
"dayjs": "^1.8.0",
|
||||||
"eslint-config-prettier": "^2.10.0",
|
"eslint-config-prettier": "^2.10.0",
|
||||||
"eslint-config-standard": "^12.0.0",
|
"eslint-config-standard": "^12.0.0",
|
||||||
"eslint-config-standard-react": "^7.0.2",
|
"eslint-config-standard-react": "^7.0.2",
|
||||||
|
|
|
@ -1,12 +1,71 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { View, Alert, Dimensions } from 'react-native';
|
import { TouchableOpacity, ActivityIndicator, View, Alert, Dimensions } from 'react-native';
|
||||||
import { WebView } from 'react-native-webview';
|
import { WebView } from 'react-native-webview';
|
||||||
import { BlueNavigationStyle } from '../../BlueComponents';
|
import { BlueNavigationStyle, SafeBlueArea } from '../../BlueComponents';
|
||||||
import { FormInput } from 'react-native-elements';
|
import { FormInput } from 'react-native-elements';
|
||||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
const { width } = Dimensions.get('window');
|
const { width } = Dimensions.get('window');
|
||||||
|
|
||||||
|
let processedInvoices = {};
|
||||||
|
let lastTimeTriedToPay = 0;
|
||||||
|
|
||||||
|
/// ///////////////////////////////////////////////////////////////////////
|
||||||
|
// this code has no use in RN, it gets copypasted in webview injected code
|
||||||
|
//
|
||||||
|
let bluewalletResponses = {};
|
||||||
|
// eslint-disable-next-line
|
||||||
|
var webln = {
|
||||||
|
enable: function() {
|
||||||
|
window.postMessage('enable');
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getInfo: function() {
|
||||||
|
window.postMessage('getInfo');
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
reject(new Error('not implemented'));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
sendPayment: function(paymentRequest) {
|
||||||
|
window.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.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.postMessage('signMessage');
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
reject(new Error('not implemented'));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
verifyMessage: function() {
|
||||||
|
window.postMessage('verifyMessage');
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
reject(new Error('not implemented'));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
// end injected code
|
||||||
|
/// /////////////////
|
||||||
|
/// /////////////////
|
||||||
|
|
||||||
export default class Browser extends Component {
|
export default class Browser extends Component {
|
||||||
static navigationOptions = ({ navigation }) => ({
|
static navigationOptions = ({ navigation }) => ({
|
||||||
...BlueNavigationStyle(navigation, true),
|
...BlueNavigationStyle(navigation, true),
|
||||||
|
@ -17,32 +76,40 @@ export default class Browser extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
if (!props.navigation.getParam('fromSecret')) throw new Error('Invalid param');
|
if (!props.navigation.getParam('fromSecret')) throw new Error('Invalid param');
|
||||||
|
if (!props.navigation.getParam('fromWallet')) throw new Error('Invalid param');
|
||||||
|
|
||||||
this.state = { url: '' };
|
this.state = {
|
||||||
|
url: 'https://bluewallet.io/marketplace/',
|
||||||
|
pageIsLoading: false,
|
||||||
|
fromSecret: props.navigation.getParam('fromSecret'),
|
||||||
|
fromWallet: props.navigation.getParam('fromWallet'),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<SafeBlueArea>
|
||||||
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
||||||
<Ionicons
|
<TouchableOpacity
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
this.webview.goBack();
|
this.webview.goBack();
|
||||||
}}
|
}}
|
||||||
name={'ios-arrow-round-back'}
|
>
|
||||||
size={26}
|
<Ionicons
|
||||||
style={{
|
name={'ios-arrow-round-back'}
|
||||||
color: 'red',
|
size={36}
|
||||||
backgroundColor: 'transparent',
|
style={{
|
||||||
left: 8,
|
color: 'red',
|
||||||
top: 1,
|
backgroundColor: 'transparent',
|
||||||
}}
|
paddingLeft: 10,
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
<FormInput
|
<FormInput
|
||||||
inputStyle={{ color: '#0c2550', fontSize: 16 }}
|
inputStyle={{ color: '#0c2550', maxWidth: width - 150, fontSize: 16 }}
|
||||||
containerStyle={{
|
containerStyle={{
|
||||||
maxWidth: width - 100,
|
maxWidth: width - 150,
|
||||||
borderColor: '#d2d2d2',
|
borderColor: '#d2d2d2',
|
||||||
borderWidth: 0.5,
|
borderWidth: 0.5,
|
||||||
backgroundColor: '#f5f5f5',
|
backgroundColor: '#f5f5f5',
|
||||||
|
@ -50,35 +117,73 @@ export default class Browser extends Component {
|
||||||
value={this.state.url}
|
value={this.state.url}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Ionicons
|
<TouchableOpacity
|
||||||
|
onPress={() => {
|
||||||
|
this.setState({ url: 'https://bluewallet.io/marketplace/' });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name={'ios-home'}
|
||||||
|
size={36}
|
||||||
|
style={{
|
||||||
|
color: 'red',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
this.webview.reload();
|
this.webview.reload();
|
||||||
}}
|
}}
|
||||||
name={'ios-sync'}
|
>
|
||||||
size={26}
|
{(!this.state.pageIsLoading && (
|
||||||
style={{
|
<Ionicons
|
||||||
color: 'red',
|
name={'ios-sync'}
|
||||||
backgroundColor: 'transparent',
|
size={36}
|
||||||
left: 8,
|
style={{
|
||||||
top: 1,
|
color: 'red',
|
||||||
}}
|
backgroundColor: 'transparent',
|
||||||
/>
|
paddingLeft: 15,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)) || (
|
||||||
|
<View style={{ paddingLeft: 20 }}>
|
||||||
|
<ActivityIndicator />
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<WebView
|
<WebView
|
||||||
ref={ref => (this.webview = ref)}
|
ref={ref => (this.webview = ref)}
|
||||||
source={{ uri: 'https://bluewallet.io/marketplace/' }}
|
source={{ uri: this.state.url }}
|
||||||
|
mixedContentMode={'compatibility'}
|
||||||
onMessage={e => {
|
onMessage={e => {
|
||||||
// this is a handler which receives messages sent from within the browser
|
// this is a handler which receives messages sent from within the browser
|
||||||
|
console.log('---- message from the bus:', e.nativeEvent.data);
|
||||||
let json = false;
|
let json = false;
|
||||||
try {
|
try {
|
||||||
json = JSON.parse(e.nativeEvent.data);
|
json = JSON.parse(e.nativeEvent.data);
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
// message from browser has ln invoice
|
// message from browser has ln invoice
|
||||||
if (json && json.pay) {
|
if (json && json.sendPayment) {
|
||||||
|
// checking that we do not trigger alert too often:
|
||||||
|
if (+new Date() - lastTimeTriedToPay < 3000) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastTimeTriedToPay = +new Date();
|
||||||
|
|
||||||
|
// checking that already asked about this invoice:
|
||||||
|
if (processedInvoices[json.sendPayment]) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
processedInvoices[json.sendPayment] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
'Page',
|
'Page',
|
||||||
'This page asks for permission to pay this invoice',
|
'This page asks for permission to pay an invoice',
|
||||||
[
|
[
|
||||||
{ text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel' },
|
{ text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel' },
|
||||||
{
|
{
|
||||||
|
@ -88,7 +193,8 @@ export default class Browser extends Component {
|
||||||
this.props.navigation.navigate({
|
this.props.navigation.navigate({
|
||||||
routeName: 'ScanLndInvoice',
|
routeName: 'ScanLndInvoice',
|
||||||
params: {
|
params: {
|
||||||
uri: json.pay,
|
uri: json.sendPayment,
|
||||||
|
fromSecret: this.state.fromSecret,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -97,75 +203,174 @@ export default class Browser extends Component {
|
||||||
{ cancelable: false },
|
{ cancelable: false },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (json && json.makeInvoice) {
|
||||||
|
let amount = Math.max(+json.makeInvoice.minimumAmount, +json.makeInvoice.maximumAmount, +json.makeInvoice.defaultAmount);
|
||||||
|
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 }));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
{ cancelable: false },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
injectedJavaScript={`
|
||||||
|
|
||||||
|
/* 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.postMessage('enable');
|
||||||
|
return new Promise(function(resolve, reject){
|
||||||
|
resolve(true);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getInfo : function () {
|
||||||
|
window.postMessage('getInfo');
|
||||||
|
return new Promise(function(resolve, reject){
|
||||||
|
reject('not implemented');
|
||||||
|
})
|
||||||
|
},
|
||||||
|
sendPayment: function(paymentRequest) {
|
||||||
|
window.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.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.postMessage('signMessage');
|
||||||
|
return new Promise(function(resolve, reject){
|
||||||
|
reject('not implemented');
|
||||||
|
})
|
||||||
|
},
|
||||||
|
verifyMessage: function () {
|
||||||
|
window.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.postMessage("inside webview, received post message: " + event.data);
|
||||||
|
var json;
|
||||||
|
try {
|
||||||
|
json = JSON.parse(event.data);
|
||||||
|
} 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.postMessage(JSON.stringify({sendPayment:invoice}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for non-webln compatible pages we do it oldschool,
|
||||||
|
searching for all bolt11 manually */
|
||||||
|
|
||||||
|
setInterval(function() {
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
`}
|
||||||
|
onLoadStart={e => {
|
||||||
|
this.setState({ pageIsLoading: true });
|
||||||
}}
|
}}
|
||||||
onLoadEnd={e => {
|
onLoadEnd={e => {
|
||||||
this.setState({ url: e.nativeEvent.url });
|
this.setState({ url: e.nativeEvent.url, pageIsLoading: false });
|
||||||
|
|
||||||
this.webview.injectJavaScript(`
|
|
||||||
|
|
||||||
lastTimeTriedToPay = 0;
|
|
||||||
function tryToPay(invoice) {
|
|
||||||
if (+new Date() - lastTimeTriedToPay >= 3000) {
|
|
||||||
window.postMessage(JSON.stringify({pay:invoice}));
|
|
||||||
lastTimeTriedToPay = +new Date();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setInterval(function(){
|
|
||||||
|
|
||||||
var searchText = "lnbc";
|
|
||||||
|
|
||||||
var aTags = document.getElementsByTagName("span");
|
|
||||||
for (var i = 0; i < aTags.length; i++) {
|
|
||||||
if (aTags[i].textContent.indexOf(searchText) === 0) {
|
|
||||||
tryToPay(aTags[i].textContent);
|
|
||||||
aTags[i].replaceWith('Invoice intercepted by BlueWallet');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
//////////////////////////////////
|
|
||||||
//////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
var aTags = document.getElementsByTagName("input");
|
|
||||||
|
|
||||||
for (var i = 0; i < aTags.length; i++) {
|
|
||||||
if (aTags[i].value.indexOf(searchText) === 0) {
|
|
||||||
tryToPay(aTags[i].value);
|
|
||||||
aTags[i].replaceWith('Invoice intercepted by BlueWallet');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
//////////////////////////////////
|
|
||||||
//////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
var aTags = document.getElementsByTagName("a");
|
|
||||||
var searchText = "lightning:lnbc";
|
|
||||||
|
|
||||||
for (var i = 0; i < aTags.length; i++) {
|
|
||||||
let href = aTags[i].getAttribute('href') + '';
|
|
||||||
if (href.indexOf(searchText) === 0) {
|
|
||||||
tryToPay(href.replace('lightning:', ''));
|
|
||||||
aTags[i].replaceWith('Invoice intercepted by BlueWallet');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}, 1000);
|
|
||||||
`);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</React.Fragment>
|
</SafeBlueArea>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ export default class LNDCreateInvoice extends Component {
|
||||||
this.props.navigation.navigate('LNDViewInvoice', {
|
this.props.navigation.navigate('LNDViewInvoice', {
|
||||||
invoice: invoiceRequest,
|
invoice: invoiceRequest,
|
||||||
fromWallet: this.state.fromWallet,
|
fromWallet: this.state.fromWallet,
|
||||||
|
isModal: true,
|
||||||
});
|
});
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
ReactNativeHapticFeedback.trigger('notificationError', false);
|
ReactNativeHapticFeedback.trigger('notificationError', false);
|
||||||
|
|
|
@ -10,7 +10,7 @@ const loc = require('../../loc');
|
||||||
|
|
||||||
export default class LNDViewAdditionalInvoiceInformation extends Component {
|
export default class LNDViewAdditionalInvoiceInformation extends Component {
|
||||||
static navigationOptions = ({ navigation }) => ({
|
static navigationOptions = ({ navigation }) => ({
|
||||||
...BlueNavigationStyle(navigation, true, () => navigation.dismiss()),
|
...BlueNavigationStyle(),
|
||||||
title: 'Additional Information',
|
title: 'Additional Information',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,14 @@ const QRFast = require('react-native-qrcode');
|
||||||
const { width, height } = Dimensions.get('window');
|
const { width, height } = Dimensions.get('window');
|
||||||
|
|
||||||
export default class LNDViewInvoice extends Component {
|
export default class LNDViewInvoice extends Component {
|
||||||
static navigationOptions = ({ navigation }) => ({
|
static navigationOptions = ({ navigation }) =>
|
||||||
...BlueNavigationStyle(navigation, true, () => navigation.dismiss()),
|
navigation.getParam('isModal') === true
|
||||||
title: 'Lightning Invoice',
|
? {
|
||||||
headerLeft: null,
|
...BlueNavigationStyle(navigation, true, () => navigation.dismiss()),
|
||||||
});
|
title: 'Lightning Invoice',
|
||||||
|
headerLeft: null,
|
||||||
|
}
|
||||||
|
: { ...BlueNavigationStyle(), title: 'Lightning Invoice' };
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -39,6 +39,7 @@ export default class ScanLndInvoice extends React.Component {
|
||||||
const lightningWallets = BlueApp.getWallets().filter(item => item.type === LightningCustodianWallet.type);
|
const lightningWallets = BlueApp.getWallets().filter(item => item.type === LightningCustodianWallet.type);
|
||||||
if (lightningWallets.length > 0) {
|
if (lightningWallets.length > 0) {
|
||||||
fromSecret = lightningWallets[0].getSecret();
|
fromSecret = lightningWallets[0].getSecret();
|
||||||
|
console.warn('warning: using ln wallet index 0');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -430,6 +430,7 @@ export default class WalletsList extends Component {
|
||||||
this.props.navigation.navigate('LNDViewInvoice', {
|
this.props.navigation.navigate('LNDViewInvoice', {
|
||||||
invoice: rowData.item,
|
invoice: rowData.item,
|
||||||
fromWallet: lightningWallet[0],
|
fromWallet: lightningWallet[0],
|
||||||
|
isModal: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -371,7 +371,7 @@ export default class WalletTransactions extends Component {
|
||||||
style={{ alignSelf: 'flex-start', left: 10, top: 15, flexDirection: 'row' }}
|
style={{ alignSelf: 'flex-start', left: 10, top: 15, flexDirection: 'row' }}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
console.log('navigating to LappBrowser');
|
console.log('navigating to LappBrowser');
|
||||||
navigate('LappBrowser', { fromSecret: this.state.wallet.getSecret() });
|
navigate('LappBrowser', { fromSecret: this.state.wallet.getSecret(), fromWallet: this.state.wallet });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<BlueText style={{ fontWeight: '600', fontSize: 16 }}>{'marketplace'}</BlueText>
|
<BlueText style={{ fontWeight: '600', fontSize: 16 }}>{'marketplace'}</BlueText>
|
||||||
|
@ -544,9 +544,10 @@ export default class WalletTransactions extends Component {
|
||||||
rowData.item.type === 'payment_request' ||
|
rowData.item.type === 'payment_request' ||
|
||||||
rowData.item.type === 'paid_invoice'
|
rowData.item.type === 'paid_invoice'
|
||||||
) {
|
) {
|
||||||
this.props.navigation.navigate('LNDViewExistingInvoice', {
|
this.props.navigation.navigate('LNDViewInvoice', {
|
||||||
invoice: rowData.item,
|
invoice: rowData.item,
|
||||||
fromWallet: this.state.wallet,
|
fromWallet: this.state.wallet,
|
||||||
|
isModal: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
Loading…
Add table
Reference in a new issue