diff --git a/tests/unit/test_account.py b/tests/unit/test_account.py index 47266fef6..3399d6cce 100644 --- a/tests/unit/test_account.py +++ b/tests/unit/test_account.py @@ -92,29 +92,35 @@ class TestHierarchicalDeterministicAccount(unittest.TestCase): @defer.inlineCallbacks def test_generate_account_from_seed(self): - account = self.ledger.account_class.from_seed( - self.ledger, - "carbon smart garage balance margin twelve chest sword toast envelope bottom stomach ab" - "sent", "torba", {'name': 'deterministic-chain', 'receiving_gap': 3, 'change_gap': 2} + account = self.ledger.account_class.from_dict( + self.ledger, { + "seed": "carbon smart garage balance margin twelve chest sword " + "toast envelope bottom stomach absent", + "address_generator": { + 'name': 'deterministic-chain', + 'receiving': {'gap': 3, 'maximum_uses_per_address': 1}, + 'change': {'gap': 2, 'maximum_uses_per_address': 1} + } + } ) self.assertEqual( account.private_key.extended_key_string(), - 'xprv9s21ZrQH143K2dyhK7SevfRG72bYDRNv25yKPWWm6dqApNxm1Zb1m5gGcBWYfbsPjTr2v5joit8Af2Zp5P' - '6yz3jMbycrLrRMpeAJxR8qDg8' + 'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp5BxK' + 'Kfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna' ) self.assertEqual( account.public_key.extended_key_string(), - 'xpub661MyMwAqRbcF84AR8yfHoMzf4S2ct6mPJtvBtvNeyN9hBHuZ6uGJszkTSn5fQUCdz3XU17eBzFeAUwV6f' - 'iW44g14WF52fYC5J483wqQ5ZP' + 'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7UbpV' + 'NzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g' ) address = yield account.receiving.ensure_address_gap() - self.assertEqual(address[0], '1PmX9T3sCiDysNtWszJa44SkKcpGc2NaXP') + self.assertEqual(address[0], '1CDLuMfwmPqJiNk5C2Bvew6tpgjAGgUk8J') - private_key = yield self.ledger.get_private_key_for_address('1PmX9T3sCiDysNtWszJa44SkKcpGc2NaXP') + private_key = yield self.ledger.get_private_key_for_address('1CDLuMfwmPqJiNk5C2Bvew6tpgjAGgUk8J') self.assertEqual( private_key.extended_key_string(), - 'xprv9xNEfQ296VTRaEUDZ8oKq74xw2U6kpj486vFUB4K1wT9U25GX4UwuzFgJN1YuRrqkQ5TTwCpkYnjNpSoH' - 'SBaEigNHPkoeYbuPMRo6mRUjxg' + 'xprv9xV7rhbg6M4yWrdTeLorz3Q1GrQb4aQzzGWboP3du7W7UUztzNTUrEYTnDfz7o' + 'ptBygDxXYRppyiuenJpoBTgYP2C26E1Ah5FEALM24CsWi' ) invalid_key = yield self.ledger.get_private_key_for_address('BcQjRlhDOIrQez1WHfz3whnB33Bp34sUgX') @@ -122,7 +128,7 @@ class TestHierarchicalDeterministicAccount(unittest.TestCase): self.assertEqual( hexlify(private_key.wif()), - b'1cc27be89ad47ef932562af80e95085eb0ab2ae3e5c019b1369b8b05ff2e94512f01' + b'1c01ae1e4c7d89e39f6d3aa7792c097a30ca7d40be249b6de52c81ec8cf9aab48b01' ) @defer.inlineCallbacks @@ -134,11 +140,11 @@ class TestHierarchicalDeterministicAccount(unittest.TestCase): "h absent", 'encrypted': False, 'private_key': - 'xprv9s21ZrQH143K2dyhK7SevfRG72bYDRNv25yKPWWm6dqApNxm1Zb1m5gGcBWYfbsPjTr2v5joit8Af2Zp5P' - '6yz3jMbycrLrRMpeAJxR8qDg8', + 'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp' + '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna', 'public_key': - 'xpub661MyMwAqRbcF84AR8yfHoMzf4S2ct6mPJtvBtvNeyN9hBHuZ6uGJszkTSn5fQUCdz3XU17eBzFeAUwV6f' - 'iW44g14WF52fYC5J483wqQ5ZP', + 'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7' + 'UbpVNzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g', 'address_generator': { 'name': 'deterministic-chain', 'receiving': {'gap': 5, 'maximum_uses_per_address': 2}, @@ -244,20 +250,23 @@ class TestSingleKeyAccount(unittest.TestCase): @defer.inlineCallbacks def test_generate_account_from_seed(self): - account = self.ledger.account_class.from_seed( - self.ledger, - "carbon smart garage balance margin twelve chest sword toast envelope bottom stomach ab" - "sent", "torba", {'name': 'single-address'} + account = self.ledger.account_class.from_dict( + self.ledger, { + "seed": + "carbon smart garage balance margin twelve chest sword toas" + "t envelope bottom stomach absent", + 'address_generator': {'name': 'single-address'} + } ) self.assertEqual( account.private_key.extended_key_string(), - 'xprv9s21ZrQH143K2dyhK7SevfRG72bYDRNv25yKPWWm6dqApNxm1Zb1m5gGcBWYfbsPjTr2v5joit8Af2Zp5P' - '6yz3jMbycrLrRMpeAJxR8qDg8' + 'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp' + '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna', ) self.assertEqual( account.public_key.extended_key_string(), - 'xpub661MyMwAqRbcF84AR8yfHoMzf4S2ct6mPJtvBtvNeyN9hBHuZ6uGJszkTSn5fQUCdz3XU17eBzFeAUwV6f' - 'iW44g14WF52fYC5J483wqQ5ZP' + 'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7' + 'UbpVNzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g', ) address = yield account.receiving.ensure_address_gap() self.assertEqual(address[0], account.public_key.address) @@ -265,8 +274,8 @@ class TestSingleKeyAccount(unittest.TestCase): private_key = yield self.ledger.get_private_key_for_address(address[0]) self.assertEqual( private_key.extended_key_string(), - 'xprv9s21ZrQH143K2dyhK7SevfRG72bYDRNv25yKPWWm6dqApNxm1Zb1m5gGcBWYfbsPjTr2v5joit8Af2Zp5P' - '6yz3jMbycrLrRMpeAJxR8qDg8' + 'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp' + '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna', ) invalid_key = yield self.ledger.get_private_key_for_address('BcQjRlhDOIrQez1WHfz3whnB33Bp34sUgX') @@ -274,7 +283,7 @@ class TestSingleKeyAccount(unittest.TestCase): self.assertEqual( hexlify(private_key.wif()), - b'1c2423f3dc6087d9683f73a684935abc0ccd8bc26370588f56653128c6a6f0bf7c01' + b'1c92caa0ef99bfd5e2ceb73b66da8cd726a9370be8c368d448a322f3c5b23aaab901' ) @defer.inlineCallbacks @@ -286,11 +295,11 @@ class TestSingleKeyAccount(unittest.TestCase): "h absent", 'encrypted': False, 'private_key': - 'xprv9s21ZrQH143K2dyhK7SevfRG72bYDRNv25yKPWWm6dqApNxm1Zb1m5gGcBWYfbsPjTr2v5joit8Af2Zp5P' - '6yz3jMbycrLrRMpeAJxR8qDg8', + 'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp' + '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna', 'public_key': - 'xpub661MyMwAqRbcF84AR8yfHoMzf4S2ct6mPJtvBtvNeyN9hBHuZ6uGJszkTSn5fQUCdz3XU17eBzFeAUwV6f' - 'iW44g14WF52fYC5J483wqQ5ZP', + 'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7' + 'UbpVNzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g', 'address_generator': {'name': 'single-address'} } diff --git a/tests/unit/test_transaction.py b/tests/unit/test_transaction.py index 61b6b4187..a0722cbfd 100644 --- a/tests/unit/test_transaction.py +++ b/tests/unit/test_transaction.py @@ -141,10 +141,12 @@ class TestTransactionSigning(unittest.TestCase): @defer.inlineCallbacks def test_sign(self): - account = self.ledger.account_class.from_seed( - self.ledger, - u"carbon smart garage balance margin twelve chest sword toast envelope bottom stomach ab" - u"sent", u"torba", {} + account = self.ledger.account_class.from_dict( + self.ledger, { + "seed": "carbon smart garage balance margin twelve chest sword " + "toast envelope bottom stomach absent" + + } ) yield account.ensure_address_gap() @@ -160,10 +162,11 @@ class TestTransactionSigning(unittest.TestCase): yield tx.sign([account]) + print(hexlify(tx.inputs[0].script.values['signature'])) self.assertEqual( hexlify(tx.inputs[0].script.values['signature']), - b'304402203d463519290d06891e461ea5256c56097ccdad53379b1bb4e51ec5abc6e9fd02022034ed15b9' - b'd7c678716c4aa7c0fd26c688e8f9db8075838f2839ab55d551b62c0a01' + b'304402205a1df8cd5d2d2fa5934b756883d6c07e4f83e1350c740992d47a12422' + b'226aaa202200098ac8675827aea2b0d6f0e49566143a95d523e311d342172cd99e2021e47cb01' ) @@ -173,10 +176,11 @@ class TransactionIOBalancing(unittest.TestCase): def setUp(self): self.ledger = ledger_class({'db': ledger_class.database_class(':memory:')}) yield self.ledger.db.start() - self.account = self.ledger.account_class.from_seed( - self.ledger, - u"carbon smart garage balance margin twelve chest sword toast envelope bottom stomach ab" - u"sent", u"torba", {} + self.account = self.ledger.account_class.from_dict( + self.ledger, { + "seed": "carbon smart garage balance margin twelve chest sword " + "toast envelope bottom stomach absent" + } ) addresses = yield self.account.ensure_address_gap() diff --git a/tests/unit/test_wallet.py b/tests/unit/test_wallet.py index 31a9cb8ab..9f825834f 100644 --- a/tests/unit/test_wallet.py +++ b/tests/unit/test_wallet.py @@ -39,11 +39,11 @@ class TestWalletCreation(unittest.TestCase): "h absent", 'encrypted': False, 'private_key': - 'xprv9s21ZrQH143K2dyhK7SevfRG72bYDRNv25yKPWWm6dqApNxm1Zb1m5gGcBWYfbsPjTr2v5joit8Af2Zp5P' - '6yz3jMbycrLrRMpeAJxR8qDg8', + 'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3Z' + 'T4vYymkp5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna', 'public_key': - 'xpub661MyMwAqRbcF84AR8yfHoMzf4S2ct6mPJtvBtvNeyN9hBHuZ6uGJszkTSn5fQUCdz3XU17eBzFeAUwV6f' - 'iW44g14WF52fYC5J483wqQ5ZP', + 'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6' + 'mKUMJFc7UbpVNzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g', 'address_generator': { 'name': 'deterministic-chain', 'receiving': {'gap': 17, 'maximum_uses_per_address': 3}, diff --git a/torba/baseaccount.py b/torba/baseaccount.py index ce32e7df5..783530cfc 100644 --- a/torba/baseaccount.py +++ b/torba/baseaccount.py @@ -211,20 +211,12 @@ class BaseAccount: ledger.add_account(self) @classmethod - def generate(cls, ledger: 'baseledger.BaseLedger', password: str, address_generator: dict = None): - seed = cls.mnemonic_class().make_seed() - return cls.from_seed(ledger, seed, password, address_generator or {}) - - @classmethod - def from_seed(cls, ledger: 'baseledger.BaseLedger', seed: str, password: str, address_generator: dict): - private_key = cls.get_private_key_from_seed(ledger, seed, password) - return cls( - ledger=ledger, name='Account #{}'.format(private_key.public_key.address), - seed=seed, encrypted=False, - private_key=private_key, - public_key=private_key.public_key, - address_generator=address_generator - ) + def generate(cls, ledger: 'baseledger.BaseLedger', name: str = None, address_generator: dict = None): + return cls.from_dict(ledger, { + 'name': name, + 'seed': cls.mnemonic_class().make_seed(), + 'address_generator': address_generator or {} + }) @classmethod def get_private_key_from_seed(cls, ledger: 'baseledger.BaseLedger', seed: str, password: str): @@ -234,23 +226,30 @@ class BaseAccount: @classmethod def from_dict(cls, ledger: 'baseledger.BaseLedger', d: dict): - if not d['private_key'] and not d['public_key'] and d['seed']: - private_key = cls.get_private_key_from_seed(ledger, d['seed'], '') - public_key = private_key.public_key - elif not d['encrypted'] and d['private_key']: - private_key = from_extended_key_string(ledger, d['private_key']) - public_key = private_key.public_key - else: - private_key = d['private_key'] + seed = d.get('seed', '') + private_key = d.get('private_key', '') + public_key = None + encrypted = d.get('encrypted', False) + if not encrypted: + if seed: + private_key = cls.get_private_key_from_seed(ledger, seed, '') + public_key = private_key.public_key + elif private_key: + private_key = from_extended_key_string(ledger, private_key) + public_key = private_key.public_key + if public_key is None: public_key = from_extended_key_string(ledger, d['public_key']) + name = d.get('name') + if not name: + name = 'Account #{}'.format(public_key.address) return cls( ledger=ledger, - name=d['name'], - seed=d['seed'], - encrypted=d['encrypted'], + name=name, + seed=seed, + encrypted=encrypted, private_key=private_key, public_key=public_key, - address_generator=d['address_generator'] + address_generator=d.get('address_generator', {}) ) def to_dict(self):