FIX: Scan of descriptor QR from Sparrow Wallet not working (closes #5539)

This commit is contained in:
overtorment 2023-06-28 22:56:12 +01:00
parent f2f5a437e2
commit d9c2edc3d3
5 changed files with 79 additions and 10 deletions

View File

@ -282,6 +282,11 @@ class BlueURDecoder extends URDecoder {
return JSON.stringify(results);
}
if (decoded.type === 'crypto-output') {
const output = CryptoOutput.fromCBOR(decoded.cbor);
return output.toString();
}
throw new Error('unsupported data format');
}
}

View File

@ -601,6 +601,31 @@ export class MultisigHDWallet extends AbstractHDElectrumWallet {
this.addCosigner(xpub, hexFingerprint.toUpperCase(), path);
}
}
if (this.getN() === 0) {
// handling a case when smth went wrong and we didnt parse any cosigners, probably because
// string is a bit non-standard, deesnt have chars like '['
for (let c = 1; c < s3.length; c++) {
const hexFingerprint = s3[c].split('/')[0];
let indexOfXpub = s3[c].indexOf('xpub');
if (indexOfXpub === -1) {
// just for any case
indexOfXpub = s3[c].indexOf('ypub');
}
if (indexOfXpub === -1) {
// just for any case
indexOfXpub = s3[c].indexOf('zpub');
}
if (indexOfXpub === -1) {
throw new Error('Could not parse cosigner in a descriptor');
}
const xpub = s3[c].substring(indexOfXpub).replaceAll(')', '');
const path = 'm' + s3[c].substring(hexFingerprint.length, indexOfXpub);
this.addCosigner(xpub, hexFingerprint.toUpperCase(), path);
}
}
}
// is it caravan?

16
package-lock.json generated
View File

@ -13,7 +13,7 @@
"@babel/preset-env": "^7.20.0",
"@bugsnag/react-native": "7.20.2",
"@bugsnag/source-maps": "2.3.1",
"@keystonehq/bc-ur-registry": "0.5.5",
"@keystonehq/bc-ur-registry": "0.6.3",
"@ngraveio/bc-ur": "1.1.6",
"@noble/secp256k1": "1.6.3",
"@react-native-async-storage/async-storage": "1.18.2",
@ -3713,9 +3713,9 @@
}
},
"node_modules/@keystonehq/bc-ur-registry": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/@keystonehq/bc-ur-registry/-/bc-ur-registry-0.5.5.tgz",
"integrity": "sha512-PoclPHf0OhpIKLfLwzymsu+CjkWf5ZKvaVjpkq3HUalcI4KW8wLk0m8qI2kBVv6F0BQ0ERPqW8OfjLTVqIgWLA==",
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/@keystonehq/bc-ur-registry/-/bc-ur-registry-0.6.3.tgz",
"integrity": "sha512-xwOYrRgqfV5wANpHjmO1ilB2bloY2kMxf8xiZ4CG0U5Zkfwa/9wUaqN60xFaG862w/6wnMOHvLDxDm47xNSDlw==",
"dependencies": {
"@ngraveio/bc-ur": "^1.1.5",
"bs58check": "^2.1.2",
@ -25670,9 +25670,9 @@
}
},
"@keystonehq/bc-ur-registry": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/@keystonehq/bc-ur-registry/-/bc-ur-registry-0.5.5.tgz",
"integrity": "sha512-PoclPHf0OhpIKLfLwzymsu+CjkWf5ZKvaVjpkq3HUalcI4KW8wLk0m8qI2kBVv6F0BQ0ERPqW8OfjLTVqIgWLA==",
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/@keystonehq/bc-ur-registry/-/bc-ur-registry-0.6.3.tgz",
"integrity": "sha512-xwOYrRgqfV5wANpHjmO1ilB2bloY2kMxf8xiZ4CG0U5Zkfwa/9wUaqN60xFaG862w/6wnMOHvLDxDm47xNSDlw==",
"requires": {
"@ngraveio/bc-ur": "^1.1.5",
"bs58check": "^2.1.2",
@ -37439,7 +37439,7 @@
},
"react-native-draggable-flatlist": {
"version": "git+ssh://git@github.com/BlueWallet/react-native-draggable-flatlist.git#ebfddc4877e8f65d5391a748db61b9cd030430ba",
"from": "react-native-draggable-flatlist@https://github.com/BlueWallet/react-native-draggable-flatlist#ebfddc4",
"from": "react-native-draggable-flatlist@github:BlueWallet/react-native-draggable-flatlist#ebfddc4",
"requires": {
"@babel/preset-typescript": "^7.17.12"
}

View File

@ -102,7 +102,7 @@
"@babel/preset-env": "^7.20.0",
"@bugsnag/react-native": "7.20.2",
"@bugsnag/source-maps": "2.3.1",
"@keystonehq/bc-ur-registry": "0.5.5",
"@keystonehq/bc-ur-registry": "0.6.3",
"@ngraveio/bc-ur": "1.1.6",
"@noble/secp256k1": "1.6.3",
"@react-native-async-storage/async-storage": "1.18.2",

View File

@ -1,6 +1,6 @@
import assert from 'assert';
import { MultisigHDWallet } from '../../class/';
import { decodeUR, encodeUR } from '../../blue_modules/ur';
import { BlueURDecoder, decodeUR, encodeUR } from '../../blue_modules/ur';
import { MultisigCosigner } from '../../class/multisig-cosigner';
const bitcoin = require('bitcoinjs-lib');
const Base43 = require('../../blue_modules/base43');
@ -1982,6 +1982,45 @@ describe('multisig-wallet (native segwit)', () => {
assert.strictEqual(w.getPassphrase(2), w2.getPassphrase(2));
assert.strictEqual(w.getPassphrase(3), w2.getPassphrase(3));
});
it('can import descriptor from Sparrow', () => {
const payload =
'UR:CRYPTO-OUTPUT/TAADMETAADMSOEADAOAOLSTAADDLOLAOWKAXHDCLAOCEBDFLNNTKJTIOJSFSURBNFXRPEEHKDLGYRTEMRPYTGYZOCASWENCYMKPAVWJKHYAAHDCXJEFTGSZOIMFEYNDYHYZEJTBAMSJEHLDSRDDIYLSRFYTSZTKNRNYLRNDPAMTLDPZCAHTAADEHOEADAEAOAEAMTAADDYOTADLOCSDYYKAEYKAEYKAOYKAOCYUOHFJPKOAXAAAYCYCSYASAVDTAADDLOLAOWKAXHDCLAXMSZTWZDIGERYDKFSFWTYDPFNDKLNAYSWTTMUHYZTOXHSETPEWSFXPEAYWLJSDEMTAAHDCXSPLTSTDPNTLESANSUTTLPRPFHNVSPFCNMHESOYGASTLRPYVAATNNDKFYHLQZPKLEAHTAADEHOEADAEAOAEAMTAADDYOTADLOCSDYYKAEYKAEYKAOYKAOCYWZFEPLETAXAAAYCYCPCKRENBTAADDLOLAOWKAXHDCLAOLSFWYKYLKTFHJLPYEMGLCEDPFNSNRDDSRFASEOZTGWIALFLUIYDNFXHGVESFEMMEAAHDCXHTZETLJNKPHHAYLSCXWPNDSWPSTPGTEOJKKGHDAELSKPNNBKBSYAWZJTFWNNBDKTAHTAADEHOEADAEAOAEAMTAADDYOTADLOCSDYYKAEYKAEYKAOYKAOCYSKTPJPMSAXAAAYCYCEBKWLAMTDWZGRZE\n';
const decoder = new BlueURDecoder();
decoder.receivePart(payload);
console.log(decoder.isComplete());
const data = decoder.toString();
const w = new MultisigHDWallet();
w.setSecret(data);
assert.strictEqual(w.getM(), 2);
assert.strictEqual(w.getN(), 3);
assert.strictEqual(w.getFingerprint(1), 'DC567276');
assert.strictEqual(w.getFingerprint(2), 'F245AE38');
assert.strictEqual(w.getFingerprint(3), 'C5D87297');
assert.strictEqual(w.isNativeSegwit(), true);
assert.strictEqual(w.getCustomDerivationPathForCosigner(1), "m/48'/0'/0'/2'");
assert.strictEqual(w.getCustomDerivationPathForCosigner(2), "m/48'/0'/0'/2'");
assert.strictEqual(w.getCustomDerivationPathForCosigner(3), "m/48'/0'/0'/2'");
assert.strictEqual(w.getFormat(), 'p2wsh');
assert.strictEqual(
w.getCosigner(1),
'xpub6DiYrfRwNnjeX4vHsWMajJVFKrbEEnu8gAW9vDuQzgTWEsEHE16sGWeXXUV1LBWQE1yCTmeprSNcqZ3W74hqVdgDbtYHUv3eM4W2TEUhpan',
);
assert.strictEqual(
w.getCosigner(2),
'xpub6DnT4E1fT8VxuAZW29avMjr5i99aYTHBp9d7fiLnpL5t4JEprQqPMbTw7k7rh5tZZ2F5g8PJpssqrZoebzBChaiJrmEvWwUTEMAbHsY39Ge',
);
assert.strictEqual(
w.getCosigner(3),
'xpub6DjrnfAyuonMaboEb3ZQZzhQ2ZEgaKV2r64BFmqymZqJqviLTe1JzMr2X2RfQF892RH7MyYUbcy77R7pPu1P71xoj8cDUMNhAMGYzKR4noZ',
);
assert.strictEqual(w._getExternalAddressByIndex(0), 'bc1q4taqq6q6l8fvguva6ftvrz3qgdjy6p3w2s0ds0nl6qrjw7t0hfhqgrqcwd');
});
});
describe('multisig-cosigner', () => {