mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2024-11-19 09:50:15 +01:00
FIX: scan multisig cosigner in formats: plain Zpub, wallet descriptor
This commit is contained in:
parent
cee135a183
commit
a9aa213b21
@ -1,3 +1,6 @@
|
||||
import b58 from 'bs58check';
|
||||
const HDNode = require('bip32');
|
||||
|
||||
export class MultisigCosigner {
|
||||
constructor(data) {
|
||||
this._data = data;
|
||||
@ -7,6 +10,50 @@ export class MultisigCosigner {
|
||||
this._valid = false;
|
||||
this._cosigners = [];
|
||||
|
||||
// is it plain simple Zpub/Ypub/xpub?
|
||||
if (data.startsWith('Zpub') && MultisigCosigner.isXpubValid(data)) {
|
||||
this._fp = '00000000';
|
||||
this._xpub = data;
|
||||
this._path = "m/48'/0'/0'/2'";
|
||||
this._valid = true;
|
||||
this._cosigners = [true];
|
||||
return;
|
||||
} else if (data.startsWith('Ypub') && MultisigCosigner.isXpubValid(data)) {
|
||||
this._fp = '00000000';
|
||||
this._xpub = data;
|
||||
this._path = "m/48'/0'/0'/1'";
|
||||
this._valid = true;
|
||||
this._cosigners = [true];
|
||||
return;
|
||||
} else if (data.startsWith('xpub') && MultisigCosigner.isXpubValid(data)) {
|
||||
this._fp = '00000000';
|
||||
this._xpub = data;
|
||||
this._path = "m/45'";
|
||||
this._valid = true;
|
||||
this._cosigners = [true];
|
||||
return;
|
||||
}
|
||||
|
||||
// is it wallet descriptor?
|
||||
if (data.startsWith('[')) {
|
||||
const end = data.indexOf(']');
|
||||
const part = data.substr(1, end - 1).replace(/[h]/g, "'");
|
||||
this._fp = part.split('/')[0];
|
||||
const xpub = data.substr(end + 1);
|
||||
|
||||
if (MultisigCosigner.isXpubValid(xpub)) {
|
||||
this._xpub = xpub;
|
||||
this._path = 'm';
|
||||
for (let c = 0; c < part.split('/').length; c++) {
|
||||
if (c === 0) continue;
|
||||
this._path += '/' + part.split('/')[c];
|
||||
}
|
||||
this._cosigners = [true];
|
||||
this._valid = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// is it cobo json?
|
||||
try {
|
||||
const json = JSON.parse(data);
|
||||
@ -47,6 +94,26 @@ export class MultisigCosigner {
|
||||
}
|
||||
}
|
||||
|
||||
static _zpubToXpub(zpub) {
|
||||
let data = b58.decode(zpub);
|
||||
data = data.slice(4);
|
||||
data = Buffer.concat([Buffer.from('0488b21e', 'hex'), data]);
|
||||
|
||||
return b58.encode(data);
|
||||
}
|
||||
|
||||
static isXpubValid(key) {
|
||||
let xpub;
|
||||
|
||||
try {
|
||||
xpub = MultisigCosigner._zpubToXpub(key);
|
||||
HDNode.fromBase58(xpub);
|
||||
return true;
|
||||
} catch (_) {}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static exportToJson(xfp, xpub, path) {
|
||||
return JSON.stringify({
|
||||
xfp: xfp,
|
||||
|
@ -1582,6 +1582,41 @@ describe('multisig-cosigner', () => {
|
||||
assert.strictEqual(cosigner.howManyCosignersWeHave(), 1);
|
||||
});
|
||||
|
||||
it('can parse plain Zpub', () => {
|
||||
const cosigner = new MultisigCosigner(Zpub1);
|
||||
assert.ok(cosigner.isValid());
|
||||
assert.strictEqual(cosigner.getFp(), '00000000');
|
||||
assert.strictEqual(cosigner.getXpub(), Zpub1);
|
||||
assert.strictEqual(cosigner.getPath(), "m/48'/0'/0'/2'");
|
||||
assert.strictEqual(cosigner.howManyCosignersWeHave(), 1);
|
||||
});
|
||||
|
||||
it('can parse wallet descriptor', () => {
|
||||
let cosigner = new MultisigCosigner(
|
||||
'[73c5da0a/48h/0h/0h/2h]Zpub74Jru6aftwwHxCUCWEvP6DgrfFsdA4U6ZRtQ5i8qJpMcC39yZGv3egBhQfV3MS9pZtH5z8iV5qWkJsK6ESs6mSzt4qvGhzJxPeeVS2e1zUG',
|
||||
);
|
||||
assert.ok(cosigner.isValid());
|
||||
assert.strictEqual(cosigner.getFp(), '73c5da0a');
|
||||
assert.strictEqual(
|
||||
cosigner.getXpub(),
|
||||
'Zpub74Jru6aftwwHxCUCWEvP6DgrfFsdA4U6ZRtQ5i8qJpMcC39yZGv3egBhQfV3MS9pZtH5z8iV5qWkJsK6ESs6mSzt4qvGhzJxPeeVS2e1zUG',
|
||||
);
|
||||
assert.strictEqual(cosigner.getPath(), "m/48'/0'/0'/2'");
|
||||
assert.strictEqual(cosigner.howManyCosignersWeHave(), 1);
|
||||
|
||||
cosigner = new MultisigCosigner(
|
||||
'[73c5da0a/48h/0h/0h/2h]xpub6DkFAXWQ2dHxq2vatrt9qyA3bXYU4ToWQwCHbf5XB2mSTexcHZCeKS1VZYcPoBd5X8yVcbXFHJR9R8UCVpt82VX1VhR28mCyxUFL4r6KFrf',
|
||||
);
|
||||
assert.ok(cosigner.isValid());
|
||||
assert.strictEqual(cosigner.getFp(), '73c5da0a');
|
||||
assert.strictEqual(
|
||||
cosigner.getXpub(),
|
||||
'xpub6DkFAXWQ2dHxq2vatrt9qyA3bXYU4ToWQwCHbf5XB2mSTexcHZCeKS1VZYcPoBd5X8yVcbXFHJR9R8UCVpt82VX1VhR28mCyxUFL4r6KFrf',
|
||||
);
|
||||
assert.strictEqual(cosigner.getPath(), "m/48'/0'/0'/2'");
|
||||
assert.strictEqual(cosigner.howManyCosignersWeHave(), 1);
|
||||
});
|
||||
|
||||
it('cant parse bs', () => {
|
||||
const cosigner = new MultisigCosigner('asdfasdgsqwrgqwegq');
|
||||
assert.ok(!cosigner.isValid());
|
||||
|
Loading…
Reference in New Issue
Block a user