mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-23 23:27:26 +01:00
Merge branch 'master' into actionmenu
This commit is contained in:
commit
0066612f8a
21 changed files with 538 additions and 861 deletions
|
@ -137,10 +137,12 @@ const showImagePickerAndReadImage = () => {
|
|||
takePhotoButtonTitle: null,
|
||||
maxHeight: 800,
|
||||
maxWidth: 600,
|
||||
selectionLimit: 1,
|
||||
},
|
||||
response => {
|
||||
if (response.uri) {
|
||||
const uri = response.uri.toString().replace('file://', '');
|
||||
const asset = response.assets[0];
|
||||
if (asset.uri) {
|
||||
const uri = asset.uri.toString().replace('file://', '');
|
||||
LocalQRCode.decode(uri, (error, result) => {
|
||||
if (!error) {
|
||||
resolve(result);
|
||||
|
|
|
@ -97,9 +97,9 @@ export default class Lnurl {
|
|||
if (!this._lnurlPayServicePayload.callback) throw new Error('this._lnurlPayServicePayload.callback is not set');
|
||||
if (amountSat < this._lnurlPayServicePayload.min || amountSat > this._lnurlPayServicePayload.max)
|
||||
throw new Error(
|
||||
'amount is not right, ' +
|
||||
'The specified amount is invalid, ' +
|
||||
amountSat +
|
||||
' should be between ' +
|
||||
' it should be between ' +
|
||||
this._lnurlPayServicePayload.min +
|
||||
' and ' +
|
||||
this._lnurlPayServicePayload.max,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import b58 from 'bs58check';
|
||||
import { MultisigHDWallet } from './wallets/multisig-hd-wallet';
|
||||
const HDNode = require('bip32');
|
||||
|
||||
export class MultisigCosigner {
|
||||
|
@ -63,6 +64,19 @@ export class MultisigCosigner {
|
|||
this._path = json.path;
|
||||
this._cosigners = [true];
|
||||
this._valid = true;
|
||||
|
||||
// a bit more logic here: according to the formal BIP48 spec, this xpub field _can_ start with 'xpub', but
|
||||
// the actual type of segwit can be inferred from the path
|
||||
if (
|
||||
this._xpub.startsWith('xpub') &&
|
||||
[MultisigHDWallet.PATH_NATIVE_SEGWIT, MultisigHDWallet.PATH_WRAPPED_SEGWIT].includes(this._path)
|
||||
) {
|
||||
const w = new MultisigHDWallet();
|
||||
w.addCosigner(this._xpub, '00000000', this._path);
|
||||
w.setDerivationPath(this._path);
|
||||
this._xpub = w.convertXpubToMultisignatureXpub(this._xpub);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
} catch (_) {
|
||||
|
|
|
@ -897,6 +897,10 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet {
|
|||
return true;
|
||||
}
|
||||
|
||||
allowSignVerifyMessage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
async fetchUtxo() {
|
||||
await super.fetchUtxo();
|
||||
// now we need to fetch txhash for each input as required by PSBT
|
||||
|
|
|
@ -1304,7 +1304,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = BlueWallet/BlueWallet.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 611;
|
||||
CURRENT_PROJECT_VERSION = 615;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
ENABLE_BITCODE = NO;
|
||||
|
@ -1354,7 +1354,7 @@
|
|||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 611;
|
||||
CURRENT_PROJECT_VERSION = 615;
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
ENABLE_BITCODE = NO;
|
||||
"ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES;
|
||||
|
@ -1399,7 +1399,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = "TodayExtension/BlueWallet - Bitcoin Price.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 611;
|
||||
CURRENT_PROJECT_VERSION = 615;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
@ -1438,7 +1438,7 @@
|
|||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 611;
|
||||
CURRENT_PROJECT_VERSION = 615;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
@ -1475,7 +1475,7 @@
|
|||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 611;
|
||||
CURRENT_PROJECT_VERSION = 615;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
@ -1507,7 +1507,7 @@
|
|||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 611;
|
||||
CURRENT_PROJECT_VERSION = 615;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
@ -1540,7 +1540,7 @@
|
|||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 611;
|
||||
CURRENT_PROJECT_VERSION = 615;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
@ -1585,7 +1585,7 @@
|
|||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 611;
|
||||
CURRENT_PROJECT_VERSION = 615;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = A7W54YZ4WU;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
@ -1731,7 +1731,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = "BlueWalletWatch Extension/BlueWalletWatch Extension.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 611;
|
||||
CURRENT_PROJECT_VERSION = 615;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
@ -1771,7 +1771,7 @@
|
|||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 611;
|
||||
CURRENT_PROJECT_VERSION = 615;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
@ -1811,7 +1811,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = BlueWalletWatch/BlueWalletWatch.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 611;
|
||||
CURRENT_PROJECT_VERSION = 615;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
@ -1850,7 +1850,7 @@
|
|||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 611;
|
||||
CURRENT_PROJECT_VERSION = 615;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
|
|
@ -269,13 +269,13 @@ PODS:
|
|||
- React
|
||||
- react-native-blur (0.8.0):
|
||||
- React
|
||||
- react-native-camera (4.0.3):
|
||||
- react-native-camera (4.1.0):
|
||||
- React-Core
|
||||
- react-native-camera/RCT (= 4.0.3)
|
||||
- react-native-camera/RN (= 4.0.3)
|
||||
- react-native-camera/RCT (4.0.3):
|
||||
- react-native-camera/RCT (= 4.1.0)
|
||||
- react-native-camera/RN (= 4.1.0)
|
||||
- react-native-camera/RCT (4.1.0):
|
||||
- React-Core
|
||||
- react-native-camera/RN (4.0.3):
|
||||
- react-native-camera/RN (4.1.0):
|
||||
- React-Core
|
||||
- react-native-document-picker (3.5.4):
|
||||
- React
|
||||
|
@ -428,7 +428,7 @@ PODS:
|
|||
- React-RCTVibration
|
||||
- ReactCommon/turbomodule/core
|
||||
- Yoga
|
||||
- RNScreens (3.6.0):
|
||||
- RNScreens (3.5.0):
|
||||
- React-Core
|
||||
- React-RCTImage
|
||||
- RNSecureKeyStore (1.0.0):
|
||||
|
@ -744,7 +744,7 @@ SPEC CHECKSUMS:
|
|||
React-jsinspector: cc614ec18a9ca96fd275100c16d74d62ee11f0ae
|
||||
react-native-blue-crypto: 23f1558ad3d38d7a2edb7e2f6ed1bc520ed93e56
|
||||
react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c
|
||||
react-native-camera: 4f6b1e1cf2066b3a5b0d8bc062c55881c97325b6
|
||||
react-native-camera: 87f9f4e0ae5bc7eaf867c891866bf1e830dc5277
|
||||
react-native-document-picker: c5752781fbc0c126c627c1549b037c139444a4cf
|
||||
react-native-fingerprint-scanner: c68136ca57e3704d7bdf5faa554ea535ce15b1d0
|
||||
react-native-idle-timer: 97b8283237d45146a7a5c25bdebe9e1e85f3687b
|
||||
|
@ -786,7 +786,7 @@ SPEC CHECKSUMS:
|
|||
RNRate: e0af7e724e5fcf89578dbd22ab6395c85402ef29
|
||||
RNReactNativeHapticFeedback: 653a8c126a0f5e88ce15ffe280b3ff37e1fbb285
|
||||
RNReanimated: 9c13c86454bfd54dab7505c1a054470bfecd2563
|
||||
RNScreens: eb0dfb2d6b21d2d7f980ad46b14eb306d2f1062e
|
||||
RNScreens: 01ab149b5dd5c27f5ff26741b1d2bdf2cee1af35
|
||||
RNSecureKeyStore: f1ad870e53806453039f650720d2845c678d89c8
|
||||
RNShare: 00e7409201e3cab13e0febc41fd4465a83ae8225
|
||||
RNSVG: 551acb6562324b1d52a4e0758f7ca0ec234e278f
|
||||
|
|
|
@ -119,6 +119,7 @@
|
|||
"lightning_invoice": "Lightning Invoice",
|
||||
"has_been_paid": "This invoice has been paid.",
|
||||
"open_direct_channel": "Open direct channel with this node:",
|
||||
"please_pay_between_and": "Please pay between {min} and {max}",
|
||||
"please_pay": "Please pay",
|
||||
"preimage": "Preimage",
|
||||
"sats": "sats.",
|
||||
|
@ -262,6 +263,7 @@
|
|||
"default_wallets": "View All Wallets",
|
||||
"electrum_connected": "Connected",
|
||||
"electrum_connected_not": "Not Connected",
|
||||
"electrum_connnected_not_description": "An active Electrum connection is required to import a wallet. You can verify if a connection is established by going to the Network screeen in Settings.",
|
||||
"electrum_error_connect": "Can’t connect to the provided Electrum server",
|
||||
"electrum_host": "E.g. {example}",
|
||||
"electrum_offline_mode": "Offline Mode",
|
||||
|
@ -285,6 +287,7 @@
|
|||
"electrum_reset_to_default": "Are you sure to want to reset your Electrum settings to default?",
|
||||
"electrum_clear": "Clear",
|
||||
"tor_supported": "Tor supported",
|
||||
"tor_unsupported": "Tor connections are not supported.",
|
||||
"encrypt_decrypt": "Decrypt Storage",
|
||||
"encrypt_decrypt_q": "Are you sure you want to decrypt your storage? This will allow your wallets to be accessed without a password.",
|
||||
"encrypt_del_uninstall": "Delete if BlueWallet is uninstalled",
|
||||
|
|
907
package-lock.json
generated
907
package-lock.json
generated
File diff suppressed because it is too large
Load diff
10
package.json
10
package.json
|
@ -61,7 +61,7 @@
|
|||
"e2e:debug-test": "detox test -c android.emu.debug -l fatal",
|
||||
"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": "detox build -c android.emu.release",
|
||||
"e2e:release-test": "detox test -c android.emu.release --record-videos all --take-screenshots all --headless --loglevel trace",
|
||||
"e2e:release-test": "detox test -c android.emu.release --record-videos all --take-screenshots all --headless -d 60000 --loglevel info",
|
||||
"tslint": "tsc",
|
||||
"lint": "eslint --ext .js,.ts,.tsx '*.@(js|ts|tsx)' screen 'blue_modules/*.@(js|ts|tsx)' class models loc tests components",
|
||||
"lint:fix": "npm run lint -- --fix",
|
||||
|
@ -99,7 +99,7 @@
|
|||
"@bugsnag/source-maps": "2.3.0",
|
||||
"@keystonehq/bc-ur-registry": "https://github.com/BlueWallet/ur-registry",
|
||||
"@ngraveio/bc-ur": "https://github.com/BlueWallet/bc-ur",
|
||||
"@react-native-async-storage/async-storage": "1.15.7",
|
||||
"@react-native-async-storage/async-storage": "1.15.5",
|
||||
"@react-native-clipboard/clipboard": "1.8.4",
|
||||
"@react-native-community/blur": "3.6.0",
|
||||
"@react-native-community/masked-view": "0.1.11",
|
||||
|
@ -176,10 +176,10 @@
|
|||
"react-native-rate": "1.2.6",
|
||||
"react-native-reanimated": "2.2.0",
|
||||
"react-native-safe-area-context": "3.3.0",
|
||||
"react-native-screens": "3.6.0",
|
||||
"react-native-screens": "3.5.0",
|
||||
"react-native-secure-key-store": "https://github.com/BlueWallet/react-native-secure-key-store#63ab38c9d382a819844a086a69cc204c46aa93f9",
|
||||
"react-native-share": "7.0.0",
|
||||
"react-native-sortable-list": "https://github.com/BlueWallet/react-native-sortable-list.git#46e39a30ae0c4328e7c06c30b72b1af0b69e1aeb",
|
||||
"react-native-sortable-list": "https://github.com/BlueWallet/react-native-sortable-list.git#e4e44a01a90ee2dcb9c57182262595abf36bfdf7",
|
||||
"react-native-svg": "12.1.1",
|
||||
"react-native-tcp-socket": "5.2.1",
|
||||
"react-native-tor": "0.1.7",
|
||||
|
@ -187,7 +187,7 @@
|
|||
"react-native-watch-connectivity": "1.0.4",
|
||||
"react-native-webview": "11.13.0",
|
||||
"react-native-widget-center": "https://github.com/BlueWallet/react-native-widget-center#b1382bbe1ed631b50a8aa03390f64c50775bc9ff",
|
||||
"react-native-windows": "0.65.0",
|
||||
"react-native-windows": "0.64.14",
|
||||
"react-test-render": "1.1.2",
|
||||
"readable-stream": "3.6.0",
|
||||
"realm": "10.6.1",
|
||||
|
|
|
@ -254,7 +254,7 @@ const LNDCreateInvoice = () => {
|
|||
screen: 'LnurlPay',
|
||||
params: {
|
||||
lnurl: data,
|
||||
fromWalletID: wallet.current.getID(),
|
||||
walletID: walletID ?? wallet.current.getID(),
|
||||
},
|
||||
});
|
||||
return;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* global alert */
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { useState, useEffect, useContext } from 'react';
|
||||
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { I18nManager, Image, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||
|
@ -17,59 +16,70 @@ import {
|
|||
} from '../../BlueComponents';
|
||||
import navigationStyle from '../../components/navigationStyle';
|
||||
import AmountInput from '../../components/AmountInput';
|
||||
import { BlueCurrentTheme } from '../../components/themes';
|
||||
import Lnurl from '../../class/lnurl';
|
||||
import { BitcoinUnit, Chain } from '../../models/bitcoinUnits';
|
||||
import loc, { formatBalanceWithoutSuffix } from '../../loc';
|
||||
import loc, { formatBalanceWithoutSuffix, formatBalance } from '../../loc';
|
||||
import Biometric from '../../class/biometrics';
|
||||
import { BlueStorageContext } from '../../blue_modules/storage-context';
|
||||
import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
|
||||
const prompt = require('../../blue_modules/prompt');
|
||||
const currency = require('../../blue_modules/currency');
|
||||
|
||||
export default class LnurlPay extends Component {
|
||||
static contextType = BlueStorageContext;
|
||||
const LnurlPay = () => {
|
||||
const { wallets } = useContext(BlueStorageContext);
|
||||
const { walletID, lnurl } = useRoute().params;
|
||||
const wallet = wallets.find(w => w.getID() === walletID);
|
||||
const [unit, setUnit] = useState(wallet.getPreferredBalanceUnit());
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [LN, setLN] = useState();
|
||||
const [payButtonDisabled, setPayButtonDisabled] = useState(true);
|
||||
const [payload, setPayload] = useState();
|
||||
const { setParams, pop, navigate } = useNavigation();
|
||||
const [amount, setAmount] = useState();
|
||||
const { colors } = useTheme();
|
||||
const stylesHook = StyleSheet.create({
|
||||
root: {
|
||||
backgroundColor: colors.background,
|
||||
},
|
||||
|
||||
constructor(props, context) {
|
||||
super(props);
|
||||
const fromWalletID = props.route.params.fromWalletID;
|
||||
const lnurl = props.route.params.lnurl;
|
||||
walletWrapLabel: {
|
||||
color: colors.buttonAlternativeTextColor,
|
||||
},
|
||||
walletWrapBalance: {
|
||||
color: colors.buttonAlternativeTextColor,
|
||||
},
|
||||
walletWrapSats: {
|
||||
color: colors.buttonAlternativeTextColor,
|
||||
},
|
||||
});
|
||||
|
||||
const fromWallet = context.wallets.find(w => w.getID() === fromWalletID);
|
||||
useEffect(() => {
|
||||
if (lnurl) {
|
||||
const ln = new Lnurl(lnurl, AsyncStorage);
|
||||
ln.callLnurlPayService().then(setPayload);
|
||||
setLN(ln);
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [lnurl]);
|
||||
|
||||
this.state = {
|
||||
isLoading: true,
|
||||
fromWalletID,
|
||||
fromWallet,
|
||||
lnurl,
|
||||
payButtonDisabled: false,
|
||||
unit: fromWallet.getPreferredBalanceUnit(),
|
||||
};
|
||||
}
|
||||
useEffect(() => {
|
||||
setPayButtonDisabled(isLoading);
|
||||
}, [isLoading]);
|
||||
|
||||
async componentDidMount() {
|
||||
const LN = new Lnurl(this.state.lnurl, AsyncStorage);
|
||||
const payload = await LN.callLnurlPayService();
|
||||
useEffect(() => {
|
||||
if (payload) {
|
||||
setAmount(payload.min);
|
||||
}
|
||||
}, [payload]);
|
||||
|
||||
this.setState({
|
||||
payload,
|
||||
amount: payload.min,
|
||||
isLoading: false,
|
||||
LN,
|
||||
});
|
||||
}
|
||||
|
||||
onWalletSelect = wallet => {
|
||||
this.setState({ fromWallet: wallet, fromWalletID: wallet.getID() }, () => {
|
||||
this.props.navigation.pop();
|
||||
});
|
||||
const onWalletSelect = wallet => {
|
||||
setParams({ walletID: wallet.getID() });
|
||||
pop();
|
||||
};
|
||||
|
||||
pay = async () => {
|
||||
this.setState({
|
||||
payButtonDisabled: true,
|
||||
});
|
||||
const pay = async () => {
|
||||
setPayButtonDisabled(true);
|
||||
/** @type {Lnurl} */
|
||||
const LN = this.state.LN;
|
||||
|
||||
const isBiometricsEnabled = await Biometric.isBiometricUseCapableAndEnabled();
|
||||
if (isBiometricsEnabled) {
|
||||
|
@ -78,8 +88,8 @@ export default class LnurlPay extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
let amountSats = this.state.amount;
|
||||
switch (this.state.unit) {
|
||||
let amountSats = amount;
|
||||
switch (unit) {
|
||||
case BitcoinUnit.SATS:
|
||||
amountSats = parseInt(amountSats); // nop
|
||||
break;
|
||||
|
@ -92,7 +102,6 @@ export default class LnurlPay extends Component {
|
|||
}
|
||||
|
||||
/** @type {LightningCustodianWallet} */
|
||||
const fromWallet = this.state.fromWallet;
|
||||
|
||||
let bolt11payload;
|
||||
try {
|
||||
|
@ -102,129 +111,106 @@ export default class LnurlPay extends Component {
|
|||
}
|
||||
|
||||
bolt11payload = await LN.requestBolt11FromLnurlPayService(amountSats, comment);
|
||||
await fromWallet.payInvoice(bolt11payload.pr);
|
||||
const decoded = fromWallet.decodeInvoice(bolt11payload.pr);
|
||||
this.setState({ payButtonDisabled: false });
|
||||
await wallet.payInvoice(bolt11payload.pr);
|
||||
const decoded = wallet.decodeInvoice(bolt11payload.pr);
|
||||
setPayButtonDisabled(false);
|
||||
|
||||
// success, probably
|
||||
ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
|
||||
if (fromWallet.last_paid_invoice_result && fromWallet.last_paid_invoice_result.payment_preimage) {
|
||||
await LN.storeSuccess(decoded.payment_hash, fromWallet.last_paid_invoice_result.payment_preimage);
|
||||
if (wallet.last_paid_invoice_result && wallet.last_paid_invoice_result.payment_preimage) {
|
||||
await LN.storeSuccess(decoded.payment_hash, wallet.last_paid_invoice_result.payment_preimage);
|
||||
}
|
||||
|
||||
this.props.navigation.navigate('ScanLndInvoiceRoot', {
|
||||
navigate('ScanLndInvoiceRoot', {
|
||||
screen: 'LnurlPaySuccess',
|
||||
params: {
|
||||
paymentHash: decoded.payment_hash,
|
||||
justPaid: true,
|
||||
fromWalletID: this.state.fromWalletID,
|
||||
fromWalletID: walletID,
|
||||
},
|
||||
});
|
||||
} catch (Err) {
|
||||
console.log(Err.message);
|
||||
this.setState({ isLoading: false, payButtonDisabled: false });
|
||||
setIsLoading(false);
|
||||
setPayButtonDisabled(false);
|
||||
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
|
||||
return alert(Err.message);
|
||||
}
|
||||
};
|
||||
|
||||
renderWalletSelectionButton = () => {
|
||||
if (this.state.renderWalletSelectionButtonHidden) return;
|
||||
return (
|
||||
<View style={styles.walletSelectRoot}>
|
||||
{!this.state.isLoading && (
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
style={styles.walletSelectTouch}
|
||||
onPress={() =>
|
||||
this.props.navigation.navigate('SelectWallet', { onWalletSelect: this.onWalletSelect, chainType: Chain.OFFCHAIN })
|
||||
}
|
||||
>
|
||||
<Text style={styles.walletSelectText}>{loc.wallets.select_wallet.toLowerCase()}</Text>
|
||||
<Icon name={I18nManager.isRTL ? 'angle-left' : 'angle-right'} size={18} type="font-awesome" color="#9aa0aa" />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
<View style={styles.walletWrap}>
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
style={styles.walletWrapTouch}
|
||||
onPress={() =>
|
||||
this.props.navigation.navigate('SelectWallet', { onWalletSelect: this.onWalletSelect, chainType: Chain.OFFCHAIN })
|
||||
}
|
||||
>
|
||||
<Text style={styles.walletWrapLabel}>{this.state.fromWallet.getLabel()}</Text>
|
||||
<Text style={styles.walletWrapBalance}>
|
||||
{formatBalanceWithoutSuffix(this.state.fromWallet.getBalance(), BitcoinUnit.SATS, false)}
|
||||
</Text>
|
||||
<Text style={styles.walletWrapSats}>{BitcoinUnit.SATS}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
const renderWalletSelectionButton = (
|
||||
<View style={styles.walletSelectRoot}>
|
||||
{!isLoading && (
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
style={styles.walletSelectTouch}
|
||||
onPress={() => navigate('SelectWallet', { onWalletSelect, chainType: Chain.OFFCHAIN })}
|
||||
>
|
||||
<Text style={styles.walletSelectText}>{loc.wallets.select_wallet.toLowerCase()}</Text>
|
||||
<Icon name={I18nManager.isRTL ? 'angle-left' : 'angle-right'} size={18} type="font-awesome" color="#9aa0aa" />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
<View style={styles.walletWrap}>
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
style={styles.walletWrapTouch}
|
||||
onPress={() => navigate('SelectWallet', { onWalletSelect, chainType: Chain.OFFCHAIN })}
|
||||
>
|
||||
<Text style={[styles.walletWrapLabel, stylesHook.walletWrapLabel]}>{wallet.getLabel()}</Text>
|
||||
<Text style={[styles.walletWrapBalance, stylesHook.walletWrapBalance]}>
|
||||
{formatBalanceWithoutSuffix(wallet.getBalance(), BitcoinUnit.SATS, false)}
|
||||
</Text>
|
||||
<Text style={[styles.walletWrapSats, stylesHook.walletWrapSats]}>{BitcoinUnit.SATS}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
</View>
|
||||
);
|
||||
|
||||
renderGotPayload() {
|
||||
const renderGotPayload = () => {
|
||||
return (
|
||||
<SafeBlueArea>
|
||||
<ScrollView>
|
||||
<ScrollView contentContainertyle={{ justifyContent: 'space-around' }}>
|
||||
<BlueCard>
|
||||
<AmountInput
|
||||
isLoading={this.state.isLoading}
|
||||
amount={this.state.amount.toString()}
|
||||
onAmountUnitChange={unit => {
|
||||
this.setState({ unit });
|
||||
}}
|
||||
onChangeText={text => {
|
||||
this.setState({ amount: text });
|
||||
}}
|
||||
disabled={this.state.payload && this.state.payload.fixed}
|
||||
unit={this.state.unit}
|
||||
isLoading={isLoading}
|
||||
amount={amount && amount.toString()}
|
||||
onAmountUnitChange={setUnit}
|
||||
onChangeText={setAmount}
|
||||
disabled={payload && payload.fixed}
|
||||
unit={unit}
|
||||
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
|
||||
/>
|
||||
<BlueText style={styles.alignSelfCenter}>
|
||||
please pay between {this.state.payload.min} and {this.state.payload.max} sat
|
||||
{loc.formatString(loc.lndViewInvoice.please_pay_between_and, {
|
||||
min: formatBalance(payload?.min, wallet.getPreferredBalanceUnit()),
|
||||
max: formatBalance(payload?.max, wallet.getPreferredBalanceUnit()),
|
||||
})}
|
||||
</BlueText>
|
||||
<BlueSpacing20 />
|
||||
{this.state.payload.image && <Image style={styles.img} source={{ uri: this.state.payload.image }} />}
|
||||
<BlueText style={styles.alignSelfCenter}>{this.state.payload.description}</BlueText>
|
||||
<BlueText style={styles.alignSelfCenter}>{this.state.payload.domain}</BlueText>
|
||||
{payload?.image && <Image style={styles.img} source={{ uri: payload?.image }} />}
|
||||
<BlueText style={styles.alignSelfCenter}>{payload?.description}</BlueText>
|
||||
<BlueText style={styles.alignSelfCenter}>{payload?.domain}</BlueText>
|
||||
<BlueSpacing20 />
|
||||
<BlueButton title={loc.lnd.payButton} onPress={this.pay} disabled={this.state.payButtonDisabled} />
|
||||
<BlueButton title={loc.lnd.payButton} onPress={pay} disabled={payButtonDisabled} />
|
||||
<BlueSpacing20 />
|
||||
{this.renderWalletSelectionButton()}
|
||||
</BlueCard>
|
||||
</ScrollView>
|
||||
{renderWalletSelectionButton}
|
||||
</SafeBlueArea>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
if (this.state.isLoading) {
|
||||
return (
|
||||
<View style={styles.root}>
|
||||
<BlueLoading />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return this.renderGotPayload();
|
||||
}
|
||||
}
|
||||
|
||||
LnurlPay.propTypes = {
|
||||
route: PropTypes.shape({
|
||||
params: PropTypes.shape({
|
||||
fromWalletID: PropTypes.string.isRequired,
|
||||
lnurl: PropTypes.string.isRequired,
|
||||
}),
|
||||
}),
|
||||
navigation: PropTypes.shape({
|
||||
navigate: PropTypes.func,
|
||||
pop: PropTypes.func,
|
||||
dangerouslyGetParent: PropTypes.func,
|
||||
}),
|
||||
return isLoading || wallet === undefined || amount === undefined ? (
|
||||
<View style={[styles.root, stylesHook.root]}>
|
||||
<BlueLoading />
|
||||
</View>
|
||||
) : (
|
||||
renderGotPayload()
|
||||
);
|
||||
};
|
||||
|
||||
export default LnurlPay;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
img: { width: 200, height: 200, alignSelf: 'center' },
|
||||
alignSelfCenter: {
|
||||
|
@ -232,10 +218,9 @@ const styles = StyleSheet.create({
|
|||
},
|
||||
root: {
|
||||
flex: 1,
|
||||
backgroundColor: BlueCurrentTheme.colors.background,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
walletSelectRoot: {
|
||||
marginBottom: 16,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
|
@ -258,18 +243,15 @@ const styles = StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
},
|
||||
walletWrapLabel: {
|
||||
color: BlueCurrentTheme.colors.buttonAlternativeTextColor,
|
||||
fontSize: 14,
|
||||
},
|
||||
walletWrapBalance: {
|
||||
color: BlueCurrentTheme.colors.buttonAlternativeTextColor,
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
marginLeft: 4,
|
||||
marginRight: 4,
|
||||
},
|
||||
walletWrapSats: {
|
||||
color: BlueCurrentTheme.colors.buttonAlternativeTextColor,
|
||||
fontSize: 11,
|
||||
fontWeight: '600',
|
||||
textAlignVertical: 'bottom',
|
||||
|
|
|
@ -119,7 +119,7 @@ export default class LnurlPaySuccess extends Component {
|
|||
screen: 'LnurlPay',
|
||||
params: {
|
||||
lnurl: lnurl,
|
||||
fromWalletID: this.state.fromWalletID,
|
||||
walletID: this.state.fromWalletID,
|
||||
},
|
||||
});
|
||||
}}
|
||||
|
|
|
@ -152,7 +152,7 @@ const ScanLndInvoice = () => {
|
|||
screen: 'LnurlPay',
|
||||
params: {
|
||||
lnurl: data,
|
||||
fromWalletID: walletID || wallet.getID(),
|
||||
walletID: walletID || wallet.getID(),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
@ -254,13 +254,15 @@ const ScanQRCode = () => {
|
|||
takePhotoButtonTitle: null,
|
||||
maxHeight: 800,
|
||||
maxWidth: 600,
|
||||
selectionLimit: 1,
|
||||
},
|
||||
response => {
|
||||
if (response.didCancel) {
|
||||
setIsLoading(false);
|
||||
} else {
|
||||
if (response.uri) {
|
||||
const uri = response.uri.toString().replace('file://', '');
|
||||
const asset = response.assets[0];
|
||||
if (asset.uri) {
|
||||
const uri = asset.uri.toString().replace('file://', '');
|
||||
LocalQRCode.decode(uri, (error, result) => {
|
||||
if (!error) {
|
||||
onBarCodeRead({ data: result });
|
||||
|
|
|
@ -162,6 +162,10 @@ export default class ElectrumSettings extends Component {
|
|||
const sslPort = this.state.sslPort ? this.state.sslPort : '';
|
||||
const serverHistory = this.state.serverHistory || [];
|
||||
|
||||
if (host.endsWith('.onion') && !isTorCapable) {
|
||||
return alert(loc.settings.tor_unsupported);
|
||||
}
|
||||
|
||||
this.setState({ isLoading: true }, async () => {
|
||||
try {
|
||||
if (!host && !port && !sslPort) {
|
||||
|
|
|
@ -96,6 +96,10 @@ const LightningSettings: React.FC & { navigationOptions: NavigationOptionsGetter
|
|||
setIsLoading(true);
|
||||
try {
|
||||
if (URI) {
|
||||
if (URI.endsWith('.onion') && !isTorCapable) {
|
||||
setIsLoading(false);
|
||||
return alert(loc.settings.tor_unsupported);
|
||||
}
|
||||
await LightningCustodianWallet.isValidNodeAddress(URI);
|
||||
// validating only if its not empty. empty means use default
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* global alert */
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { Platform, View, Keyboard, StatusBar, StyleSheet, Alert } from 'react-native';
|
||||
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
|
||||
|
@ -19,11 +20,12 @@ import { isDesktop, isMacCatalina } from '../../blue_modules/environment';
|
|||
import { BlueStorageContext } from '../../blue_modules/storage-context';
|
||||
|
||||
const fs = require('../../blue_modules/fs');
|
||||
const BlueElectrum = require('../../blue_modules/BlueElectrum');
|
||||
|
||||
const WalletsImport = () => {
|
||||
const [isToolbarVisibleForAndroid, setIsToolbarVisibleForAndroid] = useState(false);
|
||||
const route = useRoute();
|
||||
const { isImportingWallet } = useContext(BlueStorageContext);
|
||||
const { isImportingWallet, isElectrumDisabled } = useContext(BlueStorageContext);
|
||||
const label = (route.params && route.params.label) || '';
|
||||
const triggerImport = (route.params && route.params.triggerImport) || false;
|
||||
const [importText, setImportText] = useState(label);
|
||||
|
@ -69,6 +71,13 @@ const WalletsImport = () => {
|
|||
* @param importText
|
||||
*/
|
||||
const importMnemonic = async importText => {
|
||||
if (!importText.trim().startsWith('lndhub://')) {
|
||||
const config = await BlueElectrum.getConfig();
|
||||
if (config.connected !== 1) {
|
||||
return alert(loc.settings.electrum_connnected_not_description);
|
||||
}
|
||||
}
|
||||
|
||||
if (isImportingWallet && isImportingWallet.isFailure === false) {
|
||||
return;
|
||||
}
|
||||
|
@ -141,6 +150,21 @@ const WalletsImport = () => {
|
|||
}
|
||||
};
|
||||
|
||||
const isImportDisabled = () => {
|
||||
let disabled = false;
|
||||
const seed = importText.trim();
|
||||
|
||||
if (seed.length === 0) {
|
||||
disabled = true;
|
||||
}
|
||||
|
||||
if (!seed.startsWith('lndhub://') && isElectrumDisabled) {
|
||||
disabled = true;
|
||||
}
|
||||
|
||||
return disabled;
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeBlueArea style={styles.root}>
|
||||
<StatusBar barStyle="light-content" />
|
||||
|
@ -158,12 +182,7 @@ const WalletsImport = () => {
|
|||
<BlueSpacing20 />
|
||||
<View style={styles.center}>
|
||||
<>
|
||||
<BlueButton
|
||||
testID="DoImport"
|
||||
disabled={importText.trim().length === 0}
|
||||
title={loc.wallets.import_do_import}
|
||||
onPress={importButtonPressed}
|
||||
/>
|
||||
<BlueButton testID="DoImport" disabled={isImportDisabled()} title={loc.wallets.import_do_import} onPress={importButtonPressed} />
|
||||
<BlueSpacing20 />
|
||||
<BlueButtonLink title={loc.wallets.import_scan_qr} onPress={importScan} testID="ScanImport" />
|
||||
</>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useEffect, useState, useRef, useContext } from 'react';
|
||||
import { View, ActivityIndicator, Image, Text, StyleSheet, StatusBar, ScrollView, I18nManager } from 'react-native';
|
||||
import { View, ActivityIndicator, Image, Text, StyleSheet, StatusBar, I18nManager } from 'react-native';
|
||||
import { BluePrivateBalance } from '../../BlueComponents';
|
||||
import SortableList from 'react-native-sortable-list';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
|
@ -23,7 +23,6 @@ const styles = StyleSheet.create({
|
|||
itemRoot: {
|
||||
backgroundColor: 'transparent',
|
||||
padding: 10,
|
||||
marginVertical: 17,
|
||||
},
|
||||
gradient: {
|
||||
padding: 15,
|
||||
|
@ -73,7 +72,6 @@ const ReorderWallets = () => {
|
|||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [data, setData] = useState([]);
|
||||
const [hasMovedARow, setHasMovedARow] = useState(false);
|
||||
const [scrollEnabled, setScrollEnabled] = useState(true);
|
||||
const sortableList = useRef();
|
||||
const { colors } = useTheme();
|
||||
const { wallets, setWalletsWithNewOrder } = useContext(BlueStorageContext);
|
||||
|
@ -163,12 +161,10 @@ const ReorderWallets = () => {
|
|||
|
||||
const onActivateRow = () => {
|
||||
ReactNativeHapticFeedback.trigger('selection', { ignoreAndroidSystemSettings: false });
|
||||
setScrollEnabled(false);
|
||||
};
|
||||
|
||||
const onReleaseRow = () => {
|
||||
ReactNativeHapticFeedback.trigger('impactLight', { ignoreAndroidSystemSettings: false });
|
||||
setScrollEnabled(true);
|
||||
};
|
||||
|
||||
return isLoading ? (
|
||||
|
@ -178,17 +174,15 @@ const ReorderWallets = () => {
|
|||
) : (
|
||||
<View style={[styles.root, stylesHook.root]}>
|
||||
<StatusBar barStyle="light-content" />
|
||||
<ScrollView scrollEnabled={scrollEnabled}>
|
||||
<SortableList
|
||||
ref={sortableList}
|
||||
data={data}
|
||||
renderRow={renderItem}
|
||||
scrollEnabled={false}
|
||||
onChangeOrder={onChangeOrder}
|
||||
onActivateRow={onActivateRow}
|
||||
onReleaseRow={onReleaseRow}
|
||||
/>
|
||||
</ScrollView>
|
||||
<SortableList
|
||||
ref={sortableList}
|
||||
data={data}
|
||||
renderRow={renderItem}
|
||||
onChangeOrder={onChangeOrder}
|
||||
onActivateRow={onActivateRow}
|
||||
onReleaseRow={onReleaseRow}
|
||||
style={styles.root}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
Alert,
|
||||
Keyboard,
|
||||
KeyboardAvoidingView,
|
||||
LayoutAnimation,
|
||||
Platform,
|
||||
StyleSheet,
|
||||
TextInput,
|
||||
|
@ -12,6 +13,8 @@ import {
|
|||
} from 'react-native';
|
||||
import { useRoute, useTheme, useNavigation } from '@react-navigation/native';
|
||||
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import Share from 'react-native-share';
|
||||
|
||||
import AOPP from '../../class/aopp';
|
||||
import { BlueDoneAndDismissKeyboardInputAccessory, BlueFormLabel, BlueSpacing10, BlueSpacing20, SafeBlueArea } from '../../BlueComponents';
|
||||
|
@ -20,8 +23,6 @@ import { FContainer, FButton } from '../../components/FloatButtons';
|
|||
import { BlueStorageContext } from '../../blue_modules/storage-context';
|
||||
import loc from '../../loc';
|
||||
import confirm from '../../helpers/confirm';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import Share from 'react-native-share';
|
||||
|
||||
const SignVerify = () => {
|
||||
const { colors } = useTheme();
|
||||
|
@ -129,6 +130,11 @@ const SignVerify = () => {
|
|||
setLoading(false);
|
||||
};
|
||||
|
||||
const handleFocus = value => {
|
||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
||||
setMessageHasFocus(value);
|
||||
};
|
||||
|
||||
if (loading)
|
||||
return (
|
||||
<View style={[stylesHooks.root, styles.loading]}>
|
||||
|
@ -195,8 +201,8 @@ const SignVerify = () => {
|
|||
autoCapitalize="none"
|
||||
spellCheck={false}
|
||||
editable={!loading}
|
||||
onFocus={() => setMessageHasFocus(true)}
|
||||
onBlur={() => setMessageHasFocus(false)}
|
||||
onFocus={() => handleFocus(true)}
|
||||
onBlur={() => handleFocus(false)}
|
||||
/>
|
||||
<BlueSpacing10 />
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ import {
|
|||
View,
|
||||
I18nManager,
|
||||
} from 'react-native';
|
||||
import { launchImageLibrary } from 'react-native-image-picker';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import { useRoute, useNavigation, useTheme, useFocusEffect } from '@react-navigation/native';
|
||||
import { Chain } from '../../models/bitcoinUnits';
|
||||
|
@ -42,7 +41,6 @@ import { TransactionListItem } from '../../components/TransactionListItem';
|
|||
|
||||
const fs = require('../../blue_modules/fs');
|
||||
const BlueElectrum = require('../../blue_modules/BlueElectrum');
|
||||
const LocalQRCode = require('@remobile/react-native-qrcode-local-image');
|
||||
|
||||
const buttonFontSize =
|
||||
PixelRatio.roundToNearestPixel(Dimensions.get('window').width / 26) > 22
|
||||
|
@ -473,27 +471,7 @@ const WalletTransactions = () => {
|
|||
};
|
||||
|
||||
const choosePhoto = () => {
|
||||
launchImageLibrary(
|
||||
{
|
||||
title: null,
|
||||
mediaType: 'photo',
|
||||
takePhotoButtonTitle: null,
|
||||
maxHeight: 800,
|
||||
maxWidth: 600,
|
||||
},
|
||||
response => {
|
||||
if (response.uri) {
|
||||
const uri = response.uri.toString().replace('file://', '');
|
||||
LocalQRCode.decode(uri, (error, result) => {
|
||||
if (!error) {
|
||||
onBarCodeRead({ data: result });
|
||||
} else {
|
||||
alert(loc.send.qr_error_no_qrcode);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
fs.showImagePickerAndReadImage().then(onBarCodeRead);
|
||||
};
|
||||
|
||||
const copyFromClipboard = async () => {
|
||||
|
|
|
@ -1788,6 +1788,52 @@ describe('multisig-cosigner', () => {
|
|||
assert.strictEqual(cosigner.getXpub(), Zpub1);
|
||||
assert.strictEqual(cosigner.getPath(), "m/48'/0'/0'/2'");
|
||||
assert.strictEqual(cosigner.howManyCosignersWeHave(), 1);
|
||||
assert.ok(cosigner.isNativeSegwit());
|
||||
assert.ok(!cosigner.isLegacy());
|
||||
assert.ok(!cosigner.isWrappedSegwit());
|
||||
});
|
||||
|
||||
it('can parse cobo json, if xpub is plain xpub (not Zpub or Ypub)', () => {
|
||||
let xpub = MultisigCosigner._zpubToXpub(Zpub1);
|
||||
assert.ok(xpub.startsWith('xpub'));
|
||||
let cosigner = new MultisigCosigner(`{"xfp":"${fp1cobo}","xpub":"${xpub}","path":"${MultisigHDWallet.PATH_NATIVE_SEGWIT}"}`);
|
||||
assert.ok(cosigner.isValid());
|
||||
assert.strictEqual(cosigner.getFp(), fp1cobo);
|
||||
assert.strictEqual(cosigner.getXpub(), Zpub1);
|
||||
assert.strictEqual(cosigner.getPath(), MultisigHDWallet.PATH_NATIVE_SEGWIT);
|
||||
assert.strictEqual(cosigner.howManyCosignersWeHave(), 1);
|
||||
assert.ok(cosigner.isNativeSegwit());
|
||||
assert.ok(!cosigner.isLegacy());
|
||||
assert.ok(!cosigner.isWrappedSegwit());
|
||||
|
||||
//
|
||||
|
||||
const Ypub1 = 'Ypub6jtUX12KGcqFosZWP4YcHc9qbKRTvgBpb8aE58hsYqby3SQVTr5KGfMmdMg38ekmQ9iLhCdgbAbjih7AWSkA7pgRhiLfah3zT6u1PFvVEbc';
|
||||
xpub = MultisigCosigner._zpubToXpub(Ypub1);
|
||||
assert.ok(xpub.startsWith('xpub'));
|
||||
cosigner = new MultisigCosigner(`{"xfp":"${fp1cobo}","xpub":"${xpub}","path":"${MultisigHDWallet.PATH_WRAPPED_SEGWIT}"}`);
|
||||
assert.ok(cosigner.isValid());
|
||||
assert.strictEqual(cosigner.getFp(), fp1cobo);
|
||||
assert.strictEqual(cosigner.getXpub(), Ypub1);
|
||||
assert.strictEqual(cosigner.getPath(), MultisigHDWallet.PATH_WRAPPED_SEGWIT);
|
||||
assert.strictEqual(cosigner.howManyCosignersWeHave(), 1);
|
||||
assert.ok(!cosigner.isNativeSegwit());
|
||||
assert.ok(!cosigner.isLegacy());
|
||||
assert.ok(cosigner.isWrappedSegwit());
|
||||
|
||||
//
|
||||
|
||||
xpub = MultisigCosigner._zpubToXpub(Ypub1);
|
||||
assert.ok(xpub.startsWith('xpub'));
|
||||
cosigner = new MultisigCosigner(`{"xfp":"${fp1cobo}","xpub":"${xpub}","path":"${MultisigHDWallet.PATH_LEGACY}"}`);
|
||||
assert.ok(cosigner.isValid());
|
||||
assert.strictEqual(cosigner.getFp(), fp1cobo);
|
||||
assert.strictEqual(cosigner.getXpub(), xpub);
|
||||
assert.strictEqual(cosigner.getPath(), MultisigHDWallet.PATH_LEGACY);
|
||||
assert.strictEqual(cosigner.howManyCosignersWeHave(), 1);
|
||||
assert.ok(!cosigner.isNativeSegwit());
|
||||
assert.ok(cosigner.isLegacy());
|
||||
assert.ok(!cosigner.isWrappedSegwit());
|
||||
});
|
||||
|
||||
it('can parse cobo URv2 account', () => {
|
||||
|
|
Loading…
Add table
Reference in a new issue