|
@ -38,7 +38,7 @@ import traceback |
|
|
from functools import partial |
|
|
from functools import partial |
|
|
from numbers import Number |
|
|
from numbers import Number |
|
|
from decimal import Decimal |
|
|
from decimal import Decimal |
|
|
from typing import TYPE_CHECKING |
|
|
from typing import TYPE_CHECKING, List, Optional, Tuple |
|
|
|
|
|
|
|
|
from .i18n import _ |
|
|
from .i18n import _ |
|
|
from .util import (NotEnoughFunds, PrintError, UserCancelled, profiler, |
|
|
from .util import (NotEnoughFunds, PrintError, UserCancelled, profiler, |
|
@ -1227,16 +1227,29 @@ class Imported_Wallet(Simple_Wallet): |
|
|
def get_change_addresses(self): |
|
|
def get_change_addresses(self): |
|
|
return [] |
|
|
return [] |
|
|
|
|
|
|
|
|
def import_address(self, address): |
|
|
def import_addresses(self, addresses: List[str]) -> Tuple[List[str], List[Tuple[str, str]]]: |
|
|
if not bitcoin.is_address(address): |
|
|
good_addr = [] # type: List[str] |
|
|
return '' |
|
|
bad_addr = [] # type: List[Tuple[str, str]] |
|
|
if address in self.addresses: |
|
|
for address in addresses: |
|
|
return '' |
|
|
if not bitcoin.is_address(address): |
|
|
self.addresses[address] = {} |
|
|
bad_addr.append((address, _('invalid address'))) |
|
|
self.add_address(address) |
|
|
continue |
|
|
|
|
|
if address in self.addresses: |
|
|
|
|
|
bad_addr.append((address, _('address already in wallet'))) |
|
|
|
|
|
continue |
|
|
|
|
|
good_addr.append(address) |
|
|
|
|
|
self.addresses[address] = {} |
|
|
|
|
|
self.add_address(address) |
|
|
self.save_addresses() |
|
|
self.save_addresses() |
|
|
self.save_transactions(write=True) |
|
|
self.save_transactions(write=True) |
|
|
return address |
|
|
return good_addr, bad_addr |
|
|
|
|
|
|
|
|
|
|
|
def import_address(self, address: str) -> str: |
|
|
|
|
|
good_addr, bad_addr = self.import_addresses([address]) |
|
|
|
|
|
if good_addr and good_addr[0] == address: |
|
|
|
|
|
return address |
|
|
|
|
|
else: |
|
|
|
|
|
raise BitcoinException(str(bad_addr[0][1])) |
|
|
|
|
|
|
|
|
def delete_address(self, address): |
|
|
def delete_address(self, address): |
|
|
if address not in self.addresses: |
|
|
if address not in self.addresses: |
|
@ -1293,28 +1306,34 @@ class Imported_Wallet(Simple_Wallet): |
|
|
def get_public_key(self, address): |
|
|
def get_public_key(self, address): |
|
|
return self.addresses[address].get('pubkey') |
|
|
return self.addresses[address].get('pubkey') |
|
|
|
|
|
|
|
|
def import_private_key(self, sec, pw, redeem_script=None): |
|
|
def import_private_keys(self, keys: List[str], password: Optional[str]) -> Tuple[List[str], |
|
|
try: |
|
|
List[Tuple[str, str]]]: |
|
|
txin_type, pubkey = self.keystore.import_privkey(sec, pw) |
|
|
good_addr = [] # type: List[str] |
|
|
except Exception: |
|
|
bad_keys = [] # type: List[Tuple[str, str]] |
|
|
neutered_privkey = str(sec)[:3] + '..' + str(sec)[-2:] |
|
|
for key in keys: |
|
|
raise BitcoinException('Invalid private key: {}'.format(neutered_privkey)) |
|
|
try: |
|
|
if txin_type in ['p2pkh', 'p2wpkh', 'p2wpkh-p2sh']: |
|
|
txin_type, pubkey = self.keystore.import_privkey(key, password) |
|
|
if redeem_script is not None: |
|
|
except Exception: |
|
|
raise BitcoinException('Cannot use redeem script with script type {}'.format(txin_type)) |
|
|
bad_keys.append((key, _('invalid private key'))) |
|
|
|
|
|
continue |
|
|
|
|
|
if txin_type not in ('p2pkh', 'p2wpkh', 'p2wpkh-p2sh'): |
|
|
|
|
|
bad_keys.append((key, _('not implemented type') + f': {txin_type}')) |
|
|
|
|
|
continue |
|
|
addr = bitcoin.pubkey_to_address(txin_type, pubkey) |
|
|
addr = bitcoin.pubkey_to_address(txin_type, pubkey) |
|
|
elif txin_type in ['p2sh', 'p2wsh', 'p2wsh-p2sh']: |
|
|
good_addr.append(addr) |
|
|
if redeem_script is None: |
|
|
self.addresses[addr] = {'type':txin_type, 'pubkey':pubkey, 'redeem_script':None} |
|
|
raise BitcoinException('Redeem script required for script type {}'.format(txin_type)) |
|
|
self.add_address(addr) |
|
|
addr = bitcoin.redeem_script_to_address(txin_type, redeem_script) |
|
|
|
|
|
else: |
|
|
|
|
|
raise NotImplementedError(txin_type) |
|
|
|
|
|
self.addresses[addr] = {'type':txin_type, 'pubkey':pubkey, 'redeem_script':redeem_script} |
|
|
|
|
|
self.save_keystore() |
|
|
self.save_keystore() |
|
|
self.add_address(addr) |
|
|
|
|
|
self.save_addresses() |
|
|
self.save_addresses() |
|
|
self.save_transactions(write=True) |
|
|
self.save_transactions(write=True) |
|
|
return addr |
|
|
return good_addr, bad_keys |
|
|
|
|
|
|
|
|
|
|
|
def import_private_key(self, key: str, password: Optional[str]) -> str: |
|
|
|
|
|
good_addr, bad_keys = self.import_private_keys([key], password=password) |
|
|
|
|
|
if good_addr: |
|
|
|
|
|
return good_addr[0] |
|
|
|
|
|
else: |
|
|
|
|
|
raise BitcoinException(str(bad_keys[0][1])) |
|
|
|
|
|
|
|
|
def get_redeem_script(self, address): |
|
|
def get_redeem_script(self, address): |
|
|
d = self.addresses[address] |
|
|
d = self.addresses[address] |
|
|