ADD: Import private keys in hex or base64 formats
This commit is contained in:
parent
151dbbbc67
commit
1da0414474
@ -319,6 +319,7 @@ const startImport = (
|
||||
}
|
||||
|
||||
yield { progress: 'wif' };
|
||||
|
||||
const segwitWallet = new SegwitP2SHWallet();
|
||||
segwitWallet.setSecret(text);
|
||||
if (segwitWallet.getAddress()) {
|
||||
@ -382,6 +383,89 @@ const startImport = (
|
||||
yield { wallet: legacyWallet };
|
||||
}
|
||||
|
||||
yield { progress: 'Private key in hex/base64' };
|
||||
|
||||
// check if text is in hex or base64 format
|
||||
const isHexKey = /^[0-9a-fA-F]{64}$/.test(text);
|
||||
const isBase64Key = /^[A-Za-z0-9+/=]{43,44}$/.test(text);
|
||||
|
||||
let rawKeyBuffer;
|
||||
let privateKey;
|
||||
|
||||
if (isHexKey) {
|
||||
rawKeyBuffer = Buffer.from(text, 'hex');
|
||||
} else if (isBase64Key) {
|
||||
rawKeyBuffer = Buffer.from(text, 'base64');
|
||||
}
|
||||
|
||||
if (rawKeyBuffer && rawKeyBuffer.length === 32) {
|
||||
let walletFound = false;
|
||||
|
||||
// convert the bytes to Wallet import format, 0x80 for mainnet,
|
||||
// start with uncompressed p2pkh
|
||||
privateKey = wif.encode(0x80, rawKeyBuffer, false);
|
||||
|
||||
yield { progress: 'p2pkh uncompressed' };
|
||||
const legacyWalletUncompressed = new LegacyWallet('Legacy (P2PKH) - Uncompressed');
|
||||
legacyWalletUncompressed.setSecret(privateKey);
|
||||
|
||||
if (await wasUsed(legacyWalletUncompressed)) {
|
||||
await fetch(legacyWalletUncompressed, true);
|
||||
walletFound = true;
|
||||
yield { wallet: legacyWalletUncompressed };
|
||||
}
|
||||
|
||||
// compressed is true for other wallet types
|
||||
privateKey = wif.encode(0x80, rawKeyBuffer, true);
|
||||
|
||||
yield { progress: 'p2wpkh' };
|
||||
const segwitBech32Wallet = new SegwitBech32Wallet();
|
||||
segwitBech32Wallet.setSecret(privateKey);
|
||||
|
||||
if (await wasUsed(segwitBech32Wallet)) {
|
||||
await fetch(segwitBech32Wallet, true);
|
||||
walletFound = true;
|
||||
yield { wallet: segwitBech32Wallet };
|
||||
}
|
||||
|
||||
yield { progress: 'p2tr' };
|
||||
const taprootWallet = new TaprootWallet();
|
||||
|
||||
taprootWallet.setSecret(privateKey);
|
||||
if (await wasUsed(taprootWallet)) {
|
||||
await fetch(taprootWallet, true);
|
||||
walletFound = true;
|
||||
yield { wallet: taprootWallet };
|
||||
}
|
||||
|
||||
yield { progress: 'p2wpkh-p2sh' };
|
||||
|
||||
segwitWallet.setSecret(privateKey);
|
||||
if (await wasUsed(segwitWallet)) {
|
||||
await fetch(segwitWallet, true);
|
||||
walletFound = true;
|
||||
yield { wallet: segwitWallet };
|
||||
}
|
||||
|
||||
yield { progress: 'p2pkh compressed' };
|
||||
const legacyWalletCompressed = new LegacyWallet('Legacy (P2PKH) - Compressed');
|
||||
legacyWalletCompressed.setSecret(privateKey);
|
||||
|
||||
if (await wasUsed(legacyWalletCompressed)) {
|
||||
await fetch(legacyWalletCompressed, true);
|
||||
walletFound = true;
|
||||
yield { wallet: legacyWalletCompressed };
|
||||
}
|
||||
|
||||
if (!walletFound) {
|
||||
yield { wallet: segwitBech32Wallet };
|
||||
yield { wallet: segwitWallet };
|
||||
yield { wallet: legacyWalletCompressed };
|
||||
yield { wallet: taprootWallet };
|
||||
yield { wallet: legacyWalletUncompressed };
|
||||
}
|
||||
}
|
||||
|
||||
// maybe its a watch-only address?
|
||||
yield { progress: 'watch only' };
|
||||
const wo1 = new WatchOnlyWallet();
|
||||
|
||||
@ -21,15 +21,21 @@ bitcoin.initEccLib(ecc);
|
||||
*/
|
||||
export class LegacyWallet extends AbstractWallet {
|
||||
static readonly type = 'legacy';
|
||||
static readonly typeReadable = 'Legacy (P2PKH)';
|
||||
static readonly defaultTypeReadable = 'Legacy (P2PKH)';
|
||||
// @ts-ignore: override
|
||||
public readonly type = LegacyWallet.type;
|
||||
// @ts-ignore: override
|
||||
public readonly typeReadable = LegacyWallet.typeReadable;
|
||||
public readonly typeReadable: string;
|
||||
|
||||
_txs_by_external_index: Transaction[] = [];
|
||||
_txs_by_internal_index: Transaction[] = [];
|
||||
|
||||
constructor(typeReadable?: string) {
|
||||
super();
|
||||
|
||||
this.typeReadable = typeReadable ?? LegacyWallet.defaultTypeReadable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple function which says that we havent tried to fetch balance
|
||||
* for a long time
|
||||
|
||||
@ -18,6 +18,7 @@ import { SLIP39SegwitBech32Wallet, SLIP39SegwitP2SHWallet } from '../../class/wa
|
||||
import { WatchOnlyWallet } from '../../class/wallets/watch-only-wallet';
|
||||
import startImport from '../../class/wallet-import';
|
||||
import { TWallet } from '../../class/wallets/types';
|
||||
import { TaprootWallet } from '../../class/wallets/taproot-wallet';
|
||||
|
||||
jest.setTimeout(90 * 1000);
|
||||
|
||||
@ -710,4 +711,60 @@ describe('import procedure', () => {
|
||||
'arkade://abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
|
||||
);
|
||||
});
|
||||
|
||||
it('can import private key in hex format', async () => {
|
||||
const store = createStore();
|
||||
const { promise } = startImport(
|
||||
'D556170609D43CAAC751EB81D5400425E029A86C2718CD33EC4D7D43CE1BB306',
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
...store.callbacks,
|
||||
);
|
||||
await promise;
|
||||
assert.strictEqual(store.state.wallets.length > 3, true);
|
||||
|
||||
assert.strictEqual(store.state.wallets[0].type, SegwitBech32Wallet.type);
|
||||
assert.strictEqual(store.state.wallets[1].type, SegwitP2SHWallet.type);
|
||||
assert.strictEqual(store.state.wallets[2].type, LegacyWallet.type);
|
||||
assert.strictEqual(store.state.wallets[3].type, TaprootWallet.type);
|
||||
assert.strictEqual(store.state.wallets[4].type, LegacyWallet.type);
|
||||
|
||||
assert.strictEqual(store.state.wallets[0].getSecret(), 'L4NQfHXE9xQ11neMH9MMjRX5fwiT2nsQYz96LxbMJpk3UU8yUyEC');
|
||||
assert.strictEqual(store.state.wallets[1].getSecret(), 'L4NQfHXE9xQ11neMH9MMjRX5fwiT2nsQYz96LxbMJpk3UU8yUyEC');
|
||||
assert.strictEqual(store.state.wallets[2].getSecret(), 'L4NQfHXE9xQ11neMH9MMjRX5fwiT2nsQYz96LxbMJpk3UU8yUyEC');
|
||||
assert.strictEqual(store.state.wallets[3].getSecret(), 'L4NQfHXE9xQ11neMH9MMjRX5fwiT2nsQYz96LxbMJpk3UU8yUyEC');
|
||||
assert.strictEqual(store.state.wallets[4].getSecret(), '5KSEyFcrCYakxTev5Zhs1YqW9pjvUbQexjQ8ZARYnj5mWqVmQRk');
|
||||
|
||||
assert.strictEqual(store.state.wallets[0].getAddress(), 'bc1qxscvu3w04nj9k2eukx30897xldfygzqqkmtdav');
|
||||
assert.strictEqual(store.state.wallets[1].getAddress(), '38z3svUJKMFj4G3rGrRzcARp2N4vdqV8NK');
|
||||
assert.strictEqual(store.state.wallets[2].getAddress(), '15kxc4PEBR8yXqpgEkb83YijfjSkd2xrKV');
|
||||
assert.strictEqual(store.state.wallets[3].getAddress(), 'bc1pxnmhjaug5jqm3xqz5fekme8f8dax869z96ufqyllgz5g3wpw2gpqvqxqqy');
|
||||
assert.strictEqual(store.state.wallets[4].getAddress(), '1AynZS85C27HqxGEyQphhkoWedYF1bdBnY');
|
||||
});
|
||||
|
||||
it('can import private key in base64 format', async () => {
|
||||
const store = createStore();
|
||||
const { promise } = startImport('1VYXBgnUPKrHUeuB1UAEJeApqGwnGM0z7E19Q84bswY=', false, true, false, ...store.callbacks);
|
||||
await promise;
|
||||
assert.strictEqual(store.state.wallets.length > 3, true);
|
||||
|
||||
assert.strictEqual(store.state.wallets[0].type, SegwitBech32Wallet.type);
|
||||
assert.strictEqual(store.state.wallets[1].type, SegwitP2SHWallet.type);
|
||||
assert.strictEqual(store.state.wallets[2].type, LegacyWallet.type);
|
||||
assert.strictEqual(store.state.wallets[3].type, TaprootWallet.type);
|
||||
assert.strictEqual(store.state.wallets[4].type, LegacyWallet.type);
|
||||
|
||||
assert.strictEqual(store.state.wallets[0].getSecret(), 'L4NQfHXE9xQ11neMH9MMjRX5fwiT2nsQYz96LxbMJpk3UU8yUyEC');
|
||||
assert.strictEqual(store.state.wallets[1].getSecret(), 'L4NQfHXE9xQ11neMH9MMjRX5fwiT2nsQYz96LxbMJpk3UU8yUyEC');
|
||||
assert.strictEqual(store.state.wallets[2].getSecret(), 'L4NQfHXE9xQ11neMH9MMjRX5fwiT2nsQYz96LxbMJpk3UU8yUyEC');
|
||||
assert.strictEqual(store.state.wallets[3].getSecret(), 'L4NQfHXE9xQ11neMH9MMjRX5fwiT2nsQYz96LxbMJpk3UU8yUyEC');
|
||||
assert.strictEqual(store.state.wallets[4].getSecret(), '5KSEyFcrCYakxTev5Zhs1YqW9pjvUbQexjQ8ZARYnj5mWqVmQRk');
|
||||
|
||||
assert.strictEqual(store.state.wallets[0].getAddress(), 'bc1qxscvu3w04nj9k2eukx30897xldfygzqqkmtdav');
|
||||
assert.strictEqual(store.state.wallets[1].getAddress(), '38z3svUJKMFj4G3rGrRzcARp2N4vdqV8NK');
|
||||
assert.strictEqual(store.state.wallets[2].getAddress(), '15kxc4PEBR8yXqpgEkb83YijfjSkd2xrKV');
|
||||
assert.strictEqual(store.state.wallets[3].getAddress(), 'bc1pxnmhjaug5jqm3xqz5fekme8f8dax869z96ufqyllgz5g3wpw2gpqvqxqqy');
|
||||
assert.strictEqual(store.state.wallets[4].getAddress(), '1AynZS85C27HqxGEyQphhkoWedYF1bdBnY');
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user