FIX: support electrum-desktop QR psbt for multisig

This commit is contained in:
Overtorment 2020-10-09 16:08:39 +01:00
parent 9360567fd0
commit 0e8863ccb1
5 changed files with 49 additions and 1 deletions

14
blue_modules/base43.js Normal file
View file

@ -0,0 +1,14 @@
const base = require('base-x');
const Base43 = {
encode: function () {
throw new Error('not implemented');
},
decode: function (input) {
const x = base('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ$*+-./:');
return x.decode(input).toString('hex');
},
};
module.exports = Base43;

View file

@ -388,6 +388,6 @@
"scan_or_import_file": "Scan or import file",
"export_coordination_setup": "export coordination setup",
"cosign_this_transaction": "Co-sign this transaction?",
"co_sign_transaction": "Co-sign transaction"
"co_sign_transaction": "Co-sign QR-airgapped transaction"
}
}

View file

@ -79,6 +79,7 @@
"@sentry/react-native": "1.8.2",
"amplitude-js": "5.11.0",
"assert": "1.5.0",
"base-x": "3.0.8",
"bc-bech32": "file:blue_modules/bc-bech32",
"bc-ur": "file:blue_modules/bc-ur",
"bech32": "1.1.4",

View file

@ -14,6 +14,8 @@ const LocalQRCode = require('@remobile/react-native-qrcode-local-image');
const createHash = require('create-hash');
const isDesktop = getSystemName() === 'Mac OS X';
const fs = require('../../blue_modules/fs');
const Base43 = require('../../blue_modules/base43');
const bitcoin = require('bitcoinjs-lib');
const styles = StyleSheet.create({
root: {
@ -146,6 +148,18 @@ const ScanQRCode = () => {
return _onReadUniformResource(ret.data);
}
// is it base43? stupid electrum desktop
try {
const hex = Base43.decode(ret.data);
bitcoin.Psbt.fromHex(hex); // if it doesnt throw - all good
if (launchedBy) {
navigation.navigate(launchedBy);
}
onBarScanned({ data: Buffer.from(hex, 'hex').toString('base64') });
return;
} catch (_) {}
if (!isLoading) {
setIsLoading(true);
try {

View file

@ -3,6 +3,7 @@ import assert from 'assert';
import { MultisigHDWallet } from '../../class/';
import { decodeUR } from 'bc-ur/dist';
const bitcoin = require('bitcoinjs-lib');
const Base43 = require('../../blue_modules/base43');
const mnemonicsCobo =
'fossil glove maze chest logic shadow document describe awake card bunker lottery sunset athlete giant among logic capable happy sword ridge beef warfare fire';
@ -1347,6 +1348,24 @@ describe('multisig-wallet (native segwit)', () => {
assert.ok(!w.isLegacy());
});
it('base43 works', () => {
const electrum43TransactionString =
'71OUKK$VH33.J1Y/K8Q8T3-F8X59N/YIO*LXY.7320F/5.KN$EG47LC*I1VP$S7FS2+.KAJR5:8$-MDQTMHA54/QT3R$JVX/WRDLONP/*TJLGIHRB.KNSGZWVUW9TOSOE6G1::..-NLQNJD-R1GNJ.HA7A1M.6CS:-60X9LR9XHHB6B1KLTX4T/EZN3$ZWW+J10-Z9QU-N9HHU$EV865ED$3JD$ZUJ6IA2Z:.WXKXTCK2:BMZFW3F+QI.GS54BN3*Q1T*3C1ESF0QA:ZOX1RLG/I/I1GPL:FPLRKAKH:KO4*U0YAK16-CGI-Z7A3EQAJ8Q484VA05FE7JO$-U.HBFWNFSFD8EGPJR*QV3YJD5SHA3BLWM+FR0*FS7M89S115/PU7:6-XW:EPL4/+7N2RFM/**Z6J*/--97OD2QWSLUE7G5F42ATP0SAV52U1GV+WZAJX$T0R:49QIDYJUKOXWX.$UUTR5596EOVK88E$ALJ-/MEML4883J5572D1-LRSXTRYL:X39U8QQ0XII09I5M3:13$U+B7V3S1+YUQM3:G+A/IH9+$.CHEOGE-3NX:OZ+H1D*N3IFC9+/ZT*S/O45QLRC';
const hexTransactionString =
'0100000001ac01d39c405d31d3d20b00254e84dce9838b9c280f3aa07bf77a1510d8f8779900000000fd4201004830450221009a4065d3b869f20b6e858e0722d9b511213e09dcf1b61072cccbff340c7f424e022034c42927a64fe323d8e8b76d99960322bf0664fdad9994939aedac74a32ca8c701483045022100dda3d5974ae1c06d9742c7aa5e2f789218054c60476f049300c7d4d0395819aa02201f484d7a2b4cc6186b23f54ea4099a728760d71fcc0c7a82bd056c6eaeacf3ab014cad5221020de4d18c5b852a3c1d1f1033a812b019c396b75cab2a248089b09632c7bbdda221024ee8ab3639ea02d7fac7e90078b16c06811573d7046cd06b5d1d8d7e50e0767a21025392159aaf967c2f7e1dca92b68d1b3abaf44a9d3903f7382e76f9f64e7bfa242102df269b98c7ea5bdec1aac268d6107b827163d3a0ca8bd3522279d14c46e1bf1a2103cfbf85d74dddf892b3b6f918fd36dab13cc904d9ba3c9306e9e25fe53ebde08155aeffffffff01131f0000000000001976a914e9cc1b59c97f860f5c629c23d93920da60648d0388ac00000000';
const badString = 'invalid characters';
assert.throws(() => {
Base43.decode(badString);
});
assert.strictEqual(Base43.decode(electrum43TransactionString), hexTransactionString);
assert.ok(
Base43.decode(
'8+065FQS++FH76-QX$/RI8KR6O*V+WR-I0FH.9B49H1+L6I5N1JJ$M+P:3AH:QM2QUFSRR2D1XFX+I2:WTTG3F2HL4P02O2+6JE8VYJNXP:EPJ6KPMHQEJO-I/W.6*ESN:YC6FZ24PJS/QRU0YEAKSZAZM8:$7$HI7UKPG+H:+BNRO20QPOOCI8P45/TNGX-QR.X0P*WP0TAGCHMMO-UGONFLCG2QMMIA$GU6HPNI.9TK2+X99L7GLD0$OHSX2N55/1.X8ZCRH.-06B8L+6A865PIWM8Q.*8BLD2/AY+1E2F-FH6VD+JFZC*-G*IDZQ/U-8G0UOGYV1GA6BC1N.X95R:E12L987Q$TG61X4+SR4SO*IG083GH4L77DF6FL-JAFDX/W5BR4.I*$3S*9CDIW0Z4MXWJE-R9TP-OU3T$L0RHXXV885$GJ$VMOP6DX700GU7CASZGM:-XZQ+QSFXUOE:P/OKNUEIBT.BV8G.V5GRDQ3DT-W5*L4GHD-X2WFV9940YL:4LCTAWQDL..GAD9X6H:ZU064-5MUBKG0O20ZY8FV0RX+O7IL3T3YL0CKGLYZQUYXB+.F2JNN4MV83/V70UWZA6AGSU5SVSJMYXN7RRO02IXX8*QBDCYJU2G*N7+U',
).startsWith('70736274'),
);
});
it('can import from specter-desktop/fullynoded', () => {
// @see https://github.com/Fonta1n3/FullyNoded/blob/master/Docs/Wallets/Wallet-Export-Spec.md
const json = JSON.stringify({