mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2024-11-19 18:00:17 +01:00
Merge pull request #2822 from BlueWallet/fix-2817
ADD: main view SCAN button can now import watch-only wallets (closes …
This commit is contained in:
commit
d337d4ecc9
@ -1,4 +1,4 @@
|
||||
import { AppStorage, LightningCustodianWallet } from './';
|
||||
import { AppStorage, LightningCustodianWallet, WatchOnlyWallet } from './';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import RNFS from 'react-native-fs';
|
||||
import url from 'url';
|
||||
@ -178,6 +178,17 @@ class DeeplinkSchemaMatch {
|
||||
params: Azteco.getParamsFromUrl(event.url),
|
||||
},
|
||||
]);
|
||||
} else if (new WatchOnlyWallet().setSecret(event.url).init().valid()) {
|
||||
completionHandler([
|
||||
'AddWalletRoot',
|
||||
{
|
||||
screen: 'ImportWallet',
|
||||
params: {
|
||||
triggerImport: true,
|
||||
label: event.url,
|
||||
},
|
||||
},
|
||||
]);
|
||||
} else {
|
||||
const urlObject = url.parse(event.url, true); // eslint-disable-line node/no-deprecated-api
|
||||
(async () => {
|
||||
|
@ -56,13 +56,15 @@ export class WatchOnlyWallet extends LegacyWallet {
|
||||
* this method creates appropriate HD wallet class, depending on whether we have xpub, ypub or zpub
|
||||
* as a property of `this`, and in case such property exists - it recreates it and copies data from old one.
|
||||
* this is needed after serialization/save/load/deserialization procedure.
|
||||
*
|
||||
* @return {WatchOnlyWallet} this
|
||||
*/
|
||||
init() {
|
||||
let hdWalletInstance;
|
||||
if (this.secret.startsWith('xpub')) hdWalletInstance = new HDLegacyP2PKHWallet();
|
||||
else if (this.secret.startsWith('ypub')) hdWalletInstance = new HDSegwitP2SHWallet();
|
||||
else if (this.secret.startsWith('zpub')) hdWalletInstance = new HDSegwitBech32Wallet();
|
||||
else return;
|
||||
else return this;
|
||||
hdWalletInstance._xpub = this.secret;
|
||||
if (this._hdWalletInstance) {
|
||||
// now, porting all properties from old object to new one
|
||||
@ -75,6 +77,8 @@ export class WatchOnlyWallet extends LegacyWallet {
|
||||
delete hdWalletInstance._node0;
|
||||
}
|
||||
this._hdWalletInstance = hdWalletInstance;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
prepareForSerialization() {
|
||||
|
@ -4,13 +4,14 @@
|
||||
*
|
||||
* @param navigateFunc {function}
|
||||
* @param currentScreenName {string}
|
||||
* @param showFileImportButton {boolean}
|
||||
*
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
module.exports = function (navigateFunc, currentScreenName) {
|
||||
module.exports = function scanQrHelper(navigateFunc, currentScreenName, showFileImportButton = true) {
|
||||
return new Promise(resolve => {
|
||||
const params = {};
|
||||
params.showFileImportButton = true;
|
||||
params.showFileImportButton = !!showFileImportButton;
|
||||
|
||||
params.onBarScanned = function (data) {
|
||||
setTimeout(() => resolve(data.data || data), 1);
|
||||
|
@ -315,17 +315,9 @@ const ScanQRCode = () => {
|
||||
testID="scanQrBackdoorOkButton"
|
||||
onPress={() => {
|
||||
setBackdoorVisible(false);
|
||||
let data;
|
||||
try {
|
||||
data = JSON.parse(backdoorText);
|
||||
// this might be a json string (for convenience - in case there are "\n" in there)
|
||||
} catch (_) {
|
||||
data = backdoorText;
|
||||
} finally {
|
||||
setBackdoorText('');
|
||||
}
|
||||
setBackdoorText('');
|
||||
|
||||
if (data) onBarCodeRead({ data });
|
||||
if (backdoorText) onBarCodeRead({ data: backdoorText });
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
|
@ -23,6 +23,7 @@ const WalletsImport = () => {
|
||||
const [isToolbarVisibleForAndroid, setIsToolbarVisibleForAndroid] = useState(false);
|
||||
const route = useRoute();
|
||||
const label = (route.params && route.params.label) || '';
|
||||
const triggerImport = (route.params && route.params.triggerImport) || false;
|
||||
const [importText, setImportText] = useState(label);
|
||||
const navigation = useNavigation();
|
||||
const { colors } = useTheme();
|
||||
@ -50,6 +51,11 @@ const WalletsImport = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (triggerImport) importButtonPressed();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const importButtonPressed = () => {
|
||||
if (importText.trim().length === 0) {
|
||||
return;
|
||||
|
@ -31,6 +31,7 @@ import { isCatalyst, isMacCatalina, isTablet } from '../../blue_modules/environm
|
||||
import BlueClipboard from '../../blue_modules/clipboard';
|
||||
import navigationStyle from '../../components/navigationStyle';
|
||||
|
||||
const scanqrHelper = require('../../helpers/scan-qr');
|
||||
const A = require('../../blue_modules/analytics');
|
||||
const fs = require('../../blue_modules/fs');
|
||||
const WalletsListSections = { CAROUSEL: 'CAROUSEL', LOCALTRADER: 'LOCALTRADER', TRANSACTIONS: 'TRANSACTIONS' };
|
||||
@ -343,18 +344,12 @@ const WalletsList = () => {
|
||||
if (isMacCatalina) {
|
||||
fs.showActionSheet({ anchor: walletActionButtonsRef.current }).then(onBarScanned);
|
||||
} else {
|
||||
navigate('ScanQRCodeRoot', {
|
||||
screen: 'ScanQRCode',
|
||||
params: {
|
||||
launchedBy: routeName,
|
||||
onBarScanned,
|
||||
showFileImportButton: false,
|
||||
},
|
||||
});
|
||||
scanqrHelper(navigate, routeName, false).then(onBarScanned);
|
||||
}
|
||||
};
|
||||
|
||||
const onBarScanned = value => {
|
||||
if (!value) return;
|
||||
DeeplinkSchemaMatch.navigationRouteFor({ url: value }, completionValue => {
|
||||
ReactNativeHapticFeedback.trigger('impactLight', { ignoreAndroidSystemSettings: false });
|
||||
navigate(...completionValue);
|
||||
@ -381,14 +376,7 @@ const WalletsList = () => {
|
||||
if (buttonIndex === 1) {
|
||||
fs.showImagePickerAndReadImage().then(onBarScanned);
|
||||
} else if (buttonIndex === 2) {
|
||||
navigate('ScanQRCodeRoot', {
|
||||
screen: 'ScanQRCode',
|
||||
params: {
|
||||
launchedBy: routeName,
|
||||
onBarScanned,
|
||||
showFileImportButton: false,
|
||||
},
|
||||
});
|
||||
scanqrHelper(navigate, routeName, false).then(onBarScanned);
|
||||
} else if (buttonIndex === 3) {
|
||||
copyFromClipboard();
|
||||
}
|
||||
@ -408,15 +396,7 @@ const WalletsList = () => {
|
||||
},
|
||||
{
|
||||
text: loc.wallets.list_long_scan,
|
||||
onPress: () =>
|
||||
navigate('ScanQRCodeRoot', {
|
||||
screen: 'ScanQRCode',
|
||||
params: {
|
||||
launchedBy: routeName,
|
||||
onBarScanned,
|
||||
showFileImportButton: false,
|
||||
},
|
||||
}),
|
||||
onPress: () => scanqrHelper(navigate, routeName, false).then(onBarScanned),
|
||||
},
|
||||
];
|
||||
if (!isClipboardEmpty) {
|
||||
|
@ -202,6 +202,81 @@ describe('unit - DeepLinkSchemaMatch', function () {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
argument: {
|
||||
url: require('fs').readFileSync('./tests/unit/fixtures/skeleton-cobo.txt', 'ascii'),
|
||||
},
|
||||
expected: [
|
||||
'AddWalletRoot',
|
||||
{
|
||||
screen: 'ImportWallet',
|
||||
params: {
|
||||
triggerImport: true,
|
||||
label: require('fs').readFileSync('./tests/unit/fixtures/skeleton-cobo.txt', 'ascii'),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
argument: {
|
||||
url: require('fs').readFileSync('./tests/unit/fixtures/skeleton-coldcard.txt', 'ascii'),
|
||||
},
|
||||
expected: [
|
||||
'AddWalletRoot',
|
||||
{
|
||||
screen: 'ImportWallet',
|
||||
params: {
|
||||
triggerImport: true,
|
||||
label: require('fs').readFileSync('./tests/unit/fixtures/skeleton-coldcard.txt', 'ascii'),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
argument: {
|
||||
url: require('fs').readFileSync('./tests/unit/fixtures/skeleton-electrum.txt', 'ascii'),
|
||||
},
|
||||
expected: [
|
||||
'AddWalletRoot',
|
||||
{
|
||||
screen: 'ImportWallet',
|
||||
params: {
|
||||
triggerImport: true,
|
||||
label: require('fs').readFileSync('./tests/unit/fixtures/skeleton-electrum.txt', 'ascii'),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
argument: {
|
||||
url: require('fs').readFileSync('./tests/unit/fixtures/skeleton-walletdescriptor.txt', 'ascii'),
|
||||
},
|
||||
expected: [
|
||||
'AddWalletRoot',
|
||||
{
|
||||
screen: 'ImportWallet',
|
||||
params: {
|
||||
triggerImport: true,
|
||||
label: require('fs').readFileSync('./tests/unit/fixtures/skeleton-walletdescriptor.txt', 'ascii'),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
argument: {
|
||||
url: 'zpub6rFDtF1nuXZ9PUL4XzKURh3vJBW6Kj6TUrYL4qPtFNtDXtcTVfiqjQDyrZNwjwzt5HS14qdqo3Co2282Lv3Re6Y5wFZxAVuMEpeygnnDwfx',
|
||||
},
|
||||
expected: [
|
||||
'AddWalletRoot',
|
||||
{
|
||||
screen: 'ImportWallet',
|
||||
params: {
|
||||
triggerImport: true,
|
||||
label: 'zpub6rFDtF1nuXZ9PUL4XzKURh3vJBW6Kj6TUrYL4qPtFNtDXtcTVfiqjQDyrZNwjwzt5HS14qdqo3Co2282Lv3Re6Y5wFZxAVuMEpeygnnDwfx',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const asyncNavigationRouteFor = async function (event) {
|
||||
|
1
tests/unit/fixtures/skeleton-cobo.txt
Normal file
1
tests/unit/fixtures/skeleton-cobo.txt
Normal file
@ -0,0 +1 @@
|
||||
{"ExtPubKey":"zpub6rcabYFcdr41zyUNRWRyHYs2Sm86E5XV8RjjRzTFYsiCngteeZnkwaF2xuhjmM6kpHjuNpFW42BMhzPmFwXt48e1FhddMB7xidZzN4SF24K","MasterFingerprint":"5271c071","CoboVaultFirmwareVersion":"1.2.4(BTC-Only)"}
|
1
tests/unit/fixtures/skeleton-coldcard.txt
Normal file
1
tests/unit/fixtures/skeleton-coldcard.txt
Normal file
@ -0,0 +1 @@
|
||||
{"keystore": {"ckcc_xpub": "xpub661MyMwAqRbcGmUDQVKxmhEESB5xTk8hbsdTSV3Pmhm3HE9Fj3s45R9Y8LwyaQWjXXPytZjuhTKSyCBPeNrB1VVWQq1HCvjbEZ27k44oNmg", "xpub": "zpub6rFDtF1nuXZ9PUL4XzKURh3vJBW6Kj6TUrYL4qPtFNtDXtcTVfiqjQDyrZNwjwzt5HS14qdqo3Co2282Lv3Re6Y5wFZxAVuMEpeygnnDwfx", "label": "Coldcard Import 168DD603", "ckcc_xfp": 64392470, "type": "hardware", "hw_type": "coldcard", "derivation": "m/84'/0'/0'"}, "wallet_type": "standard", "use_encryption": false, "seed_version": 17}
|
1
tests/unit/fixtures/skeleton-electrum.txt
Normal file
1
tests/unit/fixtures/skeleton-electrum.txt
Normal file
File diff suppressed because one or more lines are too long
1
tests/unit/fixtures/skeleton-walletdescriptor.txt
Normal file
1
tests/unit/fixtures/skeleton-walletdescriptor.txt
Normal file
@ -0,0 +1 @@
|
||||
[8cce63f8/84h/0h/0h]zpub6s2RJ9qAEBW8Abhojs6LyDzF7gttcDr6EsR3Umu2aptZBb45e734rGtt4KqsCMmNyR1EEzUU2ugdVYez2VywQvAbBjUSKn8ho4Zk2c5otkk
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user