Example #1
0
async def get_mock_wallet(sd_hash, storage, balance=10.0, fee=None):
    claim = Claim()
    if fee:
        if fee['currency'] == 'LBC':
            claim.stream.fee.lbc = Decimal(fee['amount'])
        elif fee['currency'] == 'USD':
            claim.stream.fee.usd = Decimal(fee['amount'])
    claim.stream.title = "33rpm"
    claim.stream.languages.append("en")
    claim.stream.source.sd_hash = sd_hash
    claim.stream.source.media_type = "image/png"

    tx = get_claim_transaction("33rpm", claim.to_bytes())
    tx.height = 514081
    txo = tx.outputs[0]
    txo.meta.update({
        "permanent_url":
        "33rpm#c49566d631226492317d06ad7fdbe1ed32925124",
    })

    class FakeHeaders:
        def __init__(self, height):
            self.height = height

        def __getitem__(self, item):
            return {'timestamp': 1984}

    wallet = Wallet()
    ledger = MainNetLedger({
        'db': MainNetLedger.database_class(':memory:'),
        'headers': FakeHeaders(514082)
    })
    await ledger.db.open()
    wallet.generate_account(ledger)
    manager = LbryWalletManager()
    manager.config = Config()
    manager.wallets.append(wallet)
    manager.ledgers[MainNetLedger] = ledger
    manager.ledger.network.client = ClientSession(
        network=manager.ledger.network, server=('fakespv.lbry.com', 50001))

    async def mock_resolve(*args):
        result = {txo.meta['permanent_url']: txo}
        claims = [
            StreamManager._convert_to_old_resolve_output(
                manager, result)[txo.meta['permanent_url']]
        ]
        await storage.save_claims(claims)
        return result

    manager.ledger.resolve = mock_resolve

    async def get_balance(*_):
        return balance

    manager.get_balance = get_balance

    return manager, txo.meta['permanent_url']
Example #2
0
    def test_create_wallet_and_accounts(self):
        wallet = Wallet()
        self.assertEqual(wallet.name, 'Wallet')
        self.assertListEqual(wallet.accounts, [])

        account1 = wallet.generate_account(self.btc_ledger)
        wallet.generate_account(self.btc_ledger)
        wallet.generate_account(self.bch_ledger)
        self.assertEqual(wallet.default_account, account1)
        self.assertEqual(len(wallet.accounts), 3)
Example #3
0
    def test_load_and_save_wallet(self):
        wallet_dict = {
            'version':
            1,
            'name':
            'Main Wallet',
            'preferences': {},
            'accounts': [{
                'name':
                'An Account',
                'ledger':
                'btc_mainnet',
                'modified_on':
                123.456,
                'seed':
                "carbon smart garage balance margin twelve chest sword toast envelope bottom stomac"
                "h absent",
                'encrypted':
                False,
                'private_key':
                'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3Z'
                'T4vYymkp5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna',
                'public_key':
                'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6'
                'mKUMJFc7UbpVNzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g',
                'address_generator': {
                    'name': 'deterministic-chain',
                    'receiving': {
                        'gap': 17,
                        'maximum_uses_per_address': 3
                    },
                    'change': {
                        'gap': 10,
                        'maximum_uses_per_address': 3
                    }
                }
            }]
        }

        storage = WalletStorage(default=wallet_dict)
        wallet = Wallet.from_storage(storage, self.manager)
        self.assertEqual(wallet.name, 'Main Wallet')
        self.assertEqual(
            hexlify(wallet.hash),
            b'1bd61fbe18875cb7828c466022af576104ed861c8a1fdb1dadf5e39417a68483'
        )
        self.assertEqual(len(wallet.accounts), 1)
        account = wallet.default_account
        self.assertIsInstance(account, BTCLedger.account_class)
        self.maxDiff = None
        self.assertDictEqual(wallet_dict, wallet.to_dict())

        encrypted = wallet.pack('password')
        decrypted = Wallet.unpack('password', encrypted)
        self.assertEqual(decrypted['accounts'][0]['name'], 'An Account')
Example #4
0
 async def asyncSetUp(self):
     self.ledger = ledger_class({
         'db': ledger_class.database_class(':memory:'),
         'headers': ledger_class.headers_class(':memory:'),
     })
     await self.ledger.db.open()
     self.account = self.ledger.account_class.generate(self.ledger, Wallet(), "torba")
Example #5
0
    def test_encrypt_wallet(self):
        account = self.ledger.account_class.from_dict(self.ledger, Wallet(), self.unencrypted_account)
        account.init_vectors = {
            'seed': self.init_vector,
            'private_key': self.init_vector
        }

        self.assertFalse(account.encrypted)
        self.assertIsNotNone(account.private_key)
        account.encrypt(self.password)
        self.assertTrue(account.encrypted)
        self.assertEqual(account.seed, self.encrypted_account['seed'])
        self.assertEqual(account.private_key_string, self.encrypted_account['private_key'])
        self.assertIsNone(account.private_key)

        self.assertEqual(account.to_dict()['seed'], self.encrypted_account['seed'])
        self.assertEqual(account.to_dict()['private_key'], self.encrypted_account['private_key'])

        account.decrypt(self.password)
        self.assertEqual(account.init_vectors['private_key'], self.init_vector)
        self.assertEqual(account.init_vectors['seed'], self.init_vector)

        self.assertEqual(account.seed, self.unencrypted_account['seed'])
        self.assertEqual(account.private_key.extended_key_string(), self.unencrypted_account['private_key'])

        self.assertEqual(account.to_dict(encrypt_password=self.password)['seed'], self.encrypted_account['seed'])
        self.assertEqual(account.to_dict(encrypt_password=self.password)['private_key'], self.encrypted_account['private_key'])

        self.assertFalse(account.encrypted)
Example #6
0
    async def test_sign(self):
        account = self.ledger.account_class.from_dict(
            self.ledger, Wallet(), {
                "seed":
                    "carbon smart garage balance margin twelve chest sword toas"
                    "t envelope bottom stomach absent"
            }
        )

        await account.ensure_address_gap()
        address1, address2 = await account.receiving.get_addresses(limit=2)
        pubkey_hash1 = self.ledger.address_to_hash160(address1)
        pubkey_hash2 = self.ledger.address_to_hash160(address2)

        tx = Transaction() \
            .add_inputs([Input.spend(get_output(int(2*COIN), pubkey_hash1))]) \
            .add_outputs([Output.pay_pubkey_hash(int(1.9*COIN), pubkey_hash2)])

        await tx.sign([account])

        self.assertEqual(
            hexlify(tx.inputs[0].script.values['signature']),
            b'304402200dafa26ad7cf38c5a971c8a25ce7d85a076235f146126762296b1223c42ae21e022020ef9eeb8'
            b'398327891008c5c0be4357683f12cb22346691ff23914f457bf679601'
        )
Example #7
0
    async def test_load_and_save_account(self):
        account_data = {
            'name':
            'My Account',
            'modified_on':
            123.456,
            'seed':
            "carbon smart garage balance margin twelve chest sword toast envelope bottom stomac"
            "h absent",
            'encrypted':
            False,
            'private_key':
            'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp'
            '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna',
            'public_key':
            'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7'
            'UbpVNzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g',
            'address_generator': {
                'name': 'single-address'
            }
        }

        account = self.ledger.account_class.from_dict(self.ledger, Wallet(),
                                                      account_data)

        await account.ensure_address_gap()

        addresses = await account.receiving.get_addresses()
        self.assertEqual(len(addresses), 1)
        addresses = await account.change.get_addresses()
        self.assertEqual(len(addresses), 1)

        self.maxDiff = None
        account_data['ledger'] = 'btc_mainnet'
        self.assertDictEqual(account_data, account.to_dict())
Example #8
0
    async def test_generate_account_from_seed(self):
        account = Account.from_dict(
            self.ledger, Wallet(), {
                "seed":
                "carbon smart garage balance margin twelve chest sword toas"
                "t envelope bottom stomach absent"
            })
        self.assertEqual(
            account.private_key.extended_key_string(),
            'xprv9s21ZrQH143K42ovpZygnjfHdAqSd9jo7zceDfPRogM7bkkoNVv7DRNLEoB8'
            'HoirMgH969NrgL8jNzLEegqFzPRWM37GXd4uE8uuRkx4LAe')
        self.assertEqual(
            account.public_key.extended_key_string(),
            'xpub661MyMwAqRbcGWtPvbWh9sc2BCfw2cTeVDYF23o3N1t6UZ5wv3EMmDgp66FxH'
            'uDtWdft3B5eL5xQtyzAtkdmhhC95gjRjLzSTdkho95asu9')
        address = await account.receiving.ensure_address_gap()
        self.assertEqual(address[0], 'bCqJrLHdoiRqEZ1whFZ3WHNb33bP34SuGx')

        private_key = await self.ledger.get_private_key_for_address(
            account.wallet, 'bCqJrLHdoiRqEZ1whFZ3WHNb33bP34SuGx')
        self.assertEqual(
            private_key.extended_key_string(),
            'xprv9vwXVierUTT4hmoe3dtTeBfbNv1ph2mm8RWXARU6HsZjBaAoFaS2FRQu4fptR'
            'AyJWhJW42dmsEaC1nKnVKKTMhq3TVEHsNj1ca3ciZMKktT')
        private_key = await self.ledger.get_private_key_for_address(
            account.wallet, 'BcQjRlhDOIrQez1WHfz3whnB33Bp34sUgX')
        self.assertIsNone(private_key)
Example #9
0
    async def test_sign(self):
        account = self.ledger.account_class.from_dict(
            self.ledger, Wallet(), {
                "seed":
                "carbon smart garage balance margin twelve chest sword "
                "toast envelope bottom stomach absent"
            })

        await account.ensure_address_gap()
        address1, address2 = await account.receiving.get_addresses(limit=2)
        pubkey_hash1 = self.ledger.address_to_hash160(address1)
        pubkey_hash2 = self.ledger.address_to_hash160(address2)

        tx_class = ledger_class.transaction_class

        tx = tx_class() \
            .add_inputs([tx_class.input_class.spend(get_output(2*COIN, pubkey_hash1))]) \
            .add_outputs([tx_class.output_class.pay_pubkey_hash(int(1.9*COIN), pubkey_hash2)]) \

        await tx.sign([account])

        self.assertEqual(
            hexlify(tx.inputs[0].script.values['signature']),
            b'304402205a1df8cd5d2d2fa5934b756883d6c07e4f83e1350c740992d47a12422'
            b'226aaa202200098ac8675827aea2b0d6f0e49566143a95d523e311d342172cd99e2021e47cb01'
        )
Example #10
0
    def test_load_and_save_account(self):
        account_data = {
            'name':
            'Main Account',
            'modified_on':
            123.456,
            'seed':
            "carbon smart garage balance margin twelve chest sword toast envelope bottom stomac"
            "h absent",
            'encrypted':
            False,
            'private_key':
            'xprv9s21ZrQH143K42ovpZygnjfHdAqSd9jo7zceDfPRogM7bkkoNVv7DRNLEoB8'
            'HoirMgH969NrgL8jNzLEegqFzPRWM37GXd4uE8uuRkx4LAe',
            'public_key':
            'xpub661MyMwAqRbcGWtPvbWh9sc2BCfw2cTeVDYF23o3N1t6UZ5wv3EMmDgp66FxH'
            'uDtWdft3B5eL5xQtyzAtkdmhhC95gjRjLzSTdkho95asu9',
            'certificates': {},
            'address_generator': {
                'name': 'deterministic-chain',
                'receiving': {
                    'gap': 17,
                    'maximum_uses_per_address': 2
                },
                'change': {
                    'gap': 10,
                    'maximum_uses_per_address': 2
                }
            }
        }

        account = Account.from_dict(self.ledger, Wallet(), account_data)
        account_data['ledger'] = 'lbc_mainnet'
        self.assertDictEqual(account_data, account.to_dict())
Example #11
0
 async def asyncSetUp(self):
     self.ledger = ledger_class({
         'db': ledger_class.database_class(':memory:'),
         'headers': ledger_class.headers_class(':memory:'),
     })
     self.wallet = Wallet()
     await self.ledger.db.open()
Example #12
0
 async def asyncSetUp(self):
     self.ledger = MainNetLedger({
         'db': MainNetLedger.database_class(':memory:'),
         'headers': MainNetLedger.headers_class(':memory:')
     })
     self.account = Account.generate(self.ledger, Wallet(), "lbryum")
     await self.ledger.db.open()
Example #13
0
    def test_decrypt_wallet(self):
        account = self.ledger.account_class.from_dict(self.ledger, Wallet(),
                                                      self.encrypted_account)

        self.assertTrue(account.encrypted)
        self.assertTrue(account.serialize_encrypted)
        account.decrypt(self.password)
        self.assertEqual(account.private_key_encryption_init_vector,
                         self.init_vector)
        self.assertEqual(account.seed_encryption_init_vector, self.init_vector)

        self.assertFalse(account.encrypted)
        self.assertTrue(account.serialize_encrypted)

        self.assertEqual(account.seed, self.unencrypted_account['seed'])
        self.assertEqual(account.private_key.extended_key_string(),
                         self.unencrypted_account['private_key'])

        self.assertEqual(account.to_dict()['seed'],
                         self.encrypted_account['seed'])
        self.assertEqual(account.to_dict()['private_key'],
                         self.encrypted_account['private_key'])

        account.serialize_encrypted = False
        self.assertEqual(account.to_dict()['seed'],
                         self.unencrypted_account['seed'])
        self.assertEqual(account.to_dict()['private_key'],
                         self.unencrypted_account['private_key'])
Example #14
0
    def test_apply_diff(self):
        account_data = {
            'name':
            'My Account',
            'modified_on':
            123.456,
            'seed':
            "carbon smart garage balance margin twelve chest sword toast envelope bottom stomac"
            "h absent",
            'encrypted':
            False,
            'private_key':
            'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp'
            '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna',
            'public_key':
            'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7'
            'UbpVNzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g',
            'address_generator': {
                'name': 'deterministic-chain',
                'receiving': {
                    'gap': 5,
                    'maximum_uses_per_address': 2
                },
                'change': {
                    'gap': 5,
                    'maximum_uses_per_address': 2
                }
            }
        }
        account = self.ledger.account_class.from_dict(self.ledger, Wallet(),
                                                      account_data)

        self.assertEqual(account.name, 'My Account')
        self.assertEqual(account.modified_on, 123.456)
        self.assertEqual(account.change.gap, 5)
        self.assertEqual(account.change.maximum_uses_per_address, 2)
        self.assertEqual(account.receiving.gap, 5)
        self.assertEqual(account.receiving.maximum_uses_per_address, 2)

        account_data['name'] = 'Changed Name'
        account_data['address_generator']['change']['gap'] = 6
        account_data['address_generator']['change'][
            'maximum_uses_per_address'] = 7
        account_data['address_generator']['receiving']['gap'] = 8
        account_data['address_generator']['receiving'][
            'maximum_uses_per_address'] = 9

        account.apply(account_data)
        # no change because modified_on is not newer
        self.assertEqual(account.name, 'My Account')

        account_data['modified_on'] = 200.00

        account.apply(account_data)
        self.assertEqual(account.name, 'Changed Name')
        self.assertEqual(account.change.gap, 6)
        self.assertEqual(account.change.maximum_uses_per_address, 7)
        self.assertEqual(account.receiving.gap, 8)
        self.assertEqual(account.receiving.maximum_uses_per_address, 9)
Example #15
0
    async def test_update_history(self):
        account = self.ledger.account_class.generate(self.ledger, Wallet(),
                                                     "torba")
        address = await account.receiving.get_or_create_usable_address()
        address_details = await self.ledger.db.get_address(address=address)
        self.assertEqual(address_details['history'], None)

        self.add_header(block_height=0, merkle_root=b'abcd04')
        self.add_header(block_height=1, merkle_root=b'abcd04')
        self.add_header(block_height=2, merkle_root=b'abcd04')
        self.add_header(block_height=3, merkle_root=b'abcd04')
        self.ledger.network = MockNetwork(
            [
                {
                    'tx_hash': 'abcd01',
                    'height': 0
                },
                {
                    'tx_hash': 'abcd02',
                    'height': 1
                },
                {
                    'tx_hash': 'abcd03',
                    'height': 2
                },
            ], {
                'abcd01': hexlify(get_transaction(get_output(1)).raw),
                'abcd02': hexlify(get_transaction(get_output(2)).raw),
                'abcd03': hexlify(get_transaction(get_output(3)).raw),
            })
        await self.ledger.update_history(address)
        self.assertEqual(self.ledger.network.get_history_called, [address])
        self.assertEqual(self.ledger.network.get_transaction_called,
                         ['abcd01', 'abcd02', 'abcd03'])

        address_details = await self.ledger.db.get_address(address=address)
        self.assertEqual(address_details['history'],
                         'abcd01:0:abcd02:1:abcd03:2:')

        self.ledger.network.get_history_called = []
        self.ledger.network.get_transaction_called = []
        await self.ledger.update_history(address)
        self.assertEqual(self.ledger.network.get_history_called, [address])
        self.assertEqual(self.ledger.network.get_transaction_called, [])

        self.ledger.network.history.append({'tx_hash': 'abcd04', 'height': 3})
        self.ledger.network.transaction['abcd04'] = hexlify(
            get_transaction(get_output(4)).raw)
        self.ledger.network.get_history_called = []
        self.ledger.network.get_transaction_called = []
        await self.ledger.update_history(address)
        self.assertEqual(self.ledger.network.get_history_called, [address])
        self.assertEqual(self.ledger.network.get_transaction_called,
                         ['abcd04'])
        address_details = await self.ledger.db.get_address(address=address)
        self.assertEqual(address_details['history'],
                         'abcd01:0:abcd02:1:abcd03:2:abcd04:3:')
Example #16
0
 def from_config(cls, config: dict) -> 'BaseWalletManager':
     manager = cls()
     for ledger_id, ledger_config in config.get('ledgers', {}).items():
         manager.get_or_create_ledger(ledger_id, ledger_config)
     for wallet_path in config.get('wallets', []):
         wallet_storage = WalletStorage(wallet_path)
         wallet = Wallet.from_storage(wallet_storage, manager)
         manager.wallets.append(wallet)
     return manager
Example #17
0
 def test_encrypt_decrypt_read_only_account(self):
     account_data = self.unencrypted_account.copy()
     del account_data['seed']
     del account_data['private_key']
     account = self.ledger.account_class.from_dict(self.ledger, Wallet(), account_data)
     encrypted = account.to_dict('password')
     self.assertFalse(encrypted['seed'])
     self.assertFalse(encrypted['private_key'])
     account.encrypt('password')
     account.decrypt('password')
Example #18
0
    async def test_update_history(self):
        account = self.ledger.account_class.generate(self.ledger, Wallet(), "torba")
        address = await account.receiving.get_or_create_usable_address()
        address_details = await self.ledger.db.get_address(address=address)
        self.assertEqual(address_details['history'], None)

        self.add_header(block_height=0, merkle_root=b'abcd04')
        self.add_header(block_height=1, merkle_root=b'abcd04')
        self.add_header(block_height=2, merkle_root=b'abcd04')
        self.add_header(block_height=3, merkle_root=b'abcd04')
        self.ledger.network = MockNetwork([
            {'tx_hash': 'abcd01', 'height': 0},
            {'tx_hash': 'abcd02', 'height': 1},
            {'tx_hash': 'abcd03', 'height': 2},
        ], {
            'abcd01': hexlify(get_transaction(get_output(1)).raw),
            'abcd02': hexlify(get_transaction(get_output(2)).raw),
            'abcd03': hexlify(get_transaction(get_output(3)).raw),
        })
        await self.ledger.update_history(address, '')
        self.assertEqual(self.ledger.network.get_history_called, [address])
        self.assertEqual(self.ledger.network.get_transaction_called, ['abcd01', 'abcd02', 'abcd03'])

        address_details = await self.ledger.db.get_address(address=address)
        self.assertEqual(
            address_details['history'],
            '252bda9b22cc902ca2aa2de3548ee8baf06b8501ff7bfb3b0b7d980dbd1bf792:0:'
            'ab9c0654dd484ac20437030f2034e25dcb29fc507e84b91138f80adc3af738f9:1:'
            'a2ae3d1db3c727e7d696122cab39ee20a7f81856dab7019056dd539f38c548a0:2:'
        )

        self.ledger.network.get_history_called = []
        self.ledger.network.get_transaction_called = []
        await self.ledger.update_history(address, '')
        self.assertEqual(self.ledger.network.get_history_called, [address])
        self.assertEqual(self.ledger.network.get_transaction_called, [])

        self.ledger.network.history.append({'tx_hash': 'abcd04', 'height': 3})
        self.ledger.network.transaction['abcd04'] = hexlify(get_transaction(get_output(4)).raw)
        self.ledger.network.get_history_called = []
        self.ledger.network.get_transaction_called = []
        await self.ledger.update_history(address, '')
        self.assertEqual(self.ledger.network.get_history_called, [address])
        self.assertEqual(self.ledger.network.get_transaction_called, ['abcd04'])
        address_details = await self.ledger.db.get_address(address=address)
        self.assertEqual(
            address_details['history'],
            '252bda9b22cc902ca2aa2de3548ee8baf06b8501ff7bfb3b0b7d980dbd1bf792:0:'
            'ab9c0654dd484ac20437030f2034e25dcb29fc507e84b91138f80adc3af738f9:1:'
            'a2ae3d1db3c727e7d696122cab39ee20a7f81856dab7019056dd539f38c548a0:2:'
            '047cf1d53ef68f0fd586d46f90c09ff8e57a4180f67e7f4b8dd0135c3741e828:3:'
        )
Example #19
0
 async def test_save_max_gap(self):
     account = Account.generate(
         self.ledger, Wallet(), 'lbryum', {
             'name': 'deterministic-chain',
             'receiving': {
                 'gap': 3,
                 'maximum_uses_per_address': 2
             },
             'change': {
                 'gap': 4,
                 'maximum_uses_per_address': 2
             }
         })
     self.assertEqual(account.receiving.gap, 3)
     self.assertEqual(account.change.gap, 4)
     await account.save_max_gap()
     self.assertEqual(account.receiving.gap, 20)
     self.assertEqual(account.change.gap, 6)
     # doesn't fail for single-address account
     account2 = Account.generate(self.ledger, Wallet(), 'lbryum',
                                 {'name': 'single-address'})
     await account2.save_max_gap()
Example #20
0
    async def test_generate_account_from_seed(self):
        account = self.ledger.account_class.from_dict(
            self.ledger, Wallet(), {
                "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(),
            'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp5BxK'
            'Kfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna')
        self.assertEqual(
            account.public_key.extended_key_string(),
            'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7UbpV'
            'NzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g')
        address = await account.receiving.ensure_address_gap()
        self.assertEqual(address[0], '1CDLuMfwmPqJiNk5C2Bvew6tpgjAGgUk8J')

        private_key = await self.ledger.get_private_key_for_address(
            '1CDLuMfwmPqJiNk5C2Bvew6tpgjAGgUk8J')
        self.assertEqual(
            private_key.extended_key_string(),
            'xprv9xV7rhbg6M4yWrdTeLorz3Q1GrQb4aQzzGWboP3du7W7UUztzNTUrEYTnDfz7o'
            'ptBygDxXYRppyiuenJpoBTgYP2C26E1Ah5FEALM24CsWi')

        invalid_key = await self.ledger.get_private_key_for_address(
            'BcQjRlhDOIrQez1WHfz3whnB33Bp34sUgX')
        self.assertIsNone(invalid_key)

        self.assertEqual(
            hexlify(private_key.wif()),
            b'1c01ae1e4c7d89e39f6d3aa7792c097a30ca7d40be249b6de52c81ec8cf9aab48b01'
        )
Example #21
0
    def test_read_write(self):
        manager = BaseWalletManager()
        config = {'data_path': '/tmp/wallet'}
        ledger = manager.get_or_create_ledger(BTCLedger.get_id(), config)

        with tempfile.NamedTemporaryFile(suffix='.json') as wallet_file:
            wallet_file.write(b'{"version": 1}')
            wallet_file.seek(0)

            # create and write wallet to a file
            wallet = manager.import_wallet(wallet_file.name)
            account = wallet.generate_account(ledger)
            wallet.save()

            # read wallet from file
            wallet_storage = WalletStorage(wallet_file.name)
            wallet = Wallet.from_storage(wallet_storage, manager)

            self.assertEqual(account.public_key.address, wallet.default_account.public_key.address)
Example #22
0
    async def asyncSetUp(self):
        self.ledger = ledger_class({
            'db':
            ledger_class.database_class(':memory:'),
            'headers':
            ledger_class.headers_class(':memory:'),
        })
        await self.ledger.db.open()
        self.account = self.ledger.account_class.from_dict(
            self.ledger, Wallet(), {
                "seed":
                "carbon smart garage balance margin twelve chest sword "
                "toast envelope bottom stomach absent"
            })

        addresses = await self.account.ensure_address_gap()
        self.pubkey_hash = [
            self.ledger.address_to_hash160(a) for a in addresses
        ]
        self.hash_cycler = cycle(self.pubkey_hash)
Example #23
0
    async def test_generate_account(self):
        account = Account.generate(self.ledger, Wallet(), 'lbryum')
        self.assertEqual(account.ledger, self.ledger)
        self.assertIsNotNone(account.seed)
        self.assertEqual(account.public_key.ledger, self.ledger)
        self.assertEqual(account.private_key.public_key, account.public_key)

        self.assertEqual(account.public_key.ledger, self.ledger)
        self.assertEqual(account.private_key.public_key, account.public_key)

        addresses = await account.receiving.get_addresses()
        self.assertEqual(len(addresses), 0)
        addresses = await account.change.get_addresses()
        self.assertEqual(len(addresses), 0)

        await account.ensure_address_gap()

        addresses = await account.receiving.get_addresses()
        self.assertEqual(len(addresses), 20)
        addresses = await account.change.get_addresses()
        self.assertEqual(len(addresses), 6)
Example #24
0
    async def test_generate_account_from_seed(self):
        account = self.ledger.account_class.from_dict(
            self.ledger, Wallet(), {
                "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(),
            'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp'
            '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna',
        )
        self.assertEqual(
            account.public_key.extended_key_string(),
            'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7'
            'UbpVNzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g',
        )
        address = await account.receiving.ensure_address_gap()
        self.assertEqual(address[0], account.public_key.address)

        private_key = await self.ledger.get_private_key_for_address(
            account.wallet, address[0]
        )
        self.assertEqual(
            private_key.extended_key_string(),
            'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp'
            '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna',
        )

        invalid_key = await self.ledger.get_private_key_for_address(
            account.wallet, 'BcQjRlhDOIrQez1WHfz3whnB33Bp34sUgX'
        )
        self.assertIsNone(invalid_key)

        self.assertEqual(
            hexlify(private_key.wif()),
            b'1c92caa0ef99bfd5e2ceb73b66da8cd726a9370be8c368d448a322f3c5b23aaab901'
        )
Example #25
0
 async def create_account(self):
     account = self.ledger.account_class.generate(self.ledger, Wallet())
     await account.ensure_address_gap()
     return account
Example #26
0
 def import_wallet(self, path):
     storage = WalletStorage(path)
     wallet = Wallet.from_storage(storage, self)
     self.wallets.append(wallet)
     return wallet
Example #27
0
    def test_merge(self):
        wallet1 = Wallet()
        wallet1.preferences['one'] = 1
        wallet1.preferences['conflict'] = 1
        wallet1.generate_account(self.btc_ledger)
        wallet2 = Wallet()
        wallet2.preferences['two'] = 2
        wallet2.preferences['conflict'] = 2  # will be more recent
        wallet2.generate_account(self.btc_ledger)

        self.assertEqual(len(wallet1.accounts), 1)
        self.assertEqual(wallet1.preferences, {'one': 1, 'conflict': 1})

        added = wallet1.merge(self.manager, 'password', wallet2.pack('password'))
        self.assertEqual(added[0].id, wallet2.default_account.id)
        self.assertEqual(len(wallet1.accounts), 2)
        self.assertEqual(wallet1.accounts[1].id, wallet2.default_account.id)
        self.assertEqual(wallet1.preferences, {'one': 1, 'two': 2, 'conflict': 2})
Example #28
0
    async def test_queries(self):
        wallet1 = Wallet()
        account1 = await self.create_account(wallet1)
        self.assertEqual(
            26, await self.ledger.db.get_address_count(accounts=[account1]))
        wallet2 = Wallet()
        account2 = await self.create_account(wallet2)
        account3 = await self.create_account(wallet2)
        self.assertEqual(
            26, await self.ledger.db.get_address_count(accounts=[account2]))

        self.assertEqual(
            0, await self.ledger.db.get_transaction_count(
                accounts=[account1, account2, account3]))
        self.assertEqual(0, await self.ledger.db.get_utxo_count())
        self.assertListEqual([], await self.ledger.db.get_utxos())
        self.assertEqual(0, await self.ledger.db.get_txo_count())
        self.assertEqual(0, await self.ledger.db.get_balance(wallet=wallet1))
        self.assertEqual(0, await self.ledger.db.get_balance(wallet=wallet2))
        self.assertEqual(0, await
                         self.ledger.db.get_balance(accounts=[account1]))
        self.assertEqual(0, await
                         self.ledger.db.get_balance(accounts=[account2]))
        self.assertEqual(0, await
                         self.ledger.db.get_balance(accounts=[account3]))

        tx1 = await self.create_tx_from_nothing(account1, 1)
        self.assertEqual(
            1, await self.ledger.db.get_transaction_count(accounts=[account1]))
        self.assertEqual(
            0, await self.ledger.db.get_transaction_count(accounts=[account2]))
        self.assertEqual(
            1, await self.ledger.db.get_utxo_count(accounts=[account1]))
        self.assertEqual(
            1, await self.ledger.db.get_txo_count(accounts=[account1]))
        self.assertEqual(
            0, await self.ledger.db.get_txo_count(accounts=[account2]))
        self.assertEqual(10**8, await
                         self.ledger.db.get_balance(wallet=wallet1))
        self.assertEqual(0, await self.ledger.db.get_balance(wallet=wallet2))
        self.assertEqual(10**8, await
                         self.ledger.db.get_balance(accounts=[account1]))
        self.assertEqual(0, await
                         self.ledger.db.get_balance(accounts=[account2]))
        self.assertEqual(0, await
                         self.ledger.db.get_balance(accounts=[account3]))

        tx2 = await self.create_tx_from_txo(tx1.outputs[0], account2, 2)
        tx2b = await self.create_tx_from_nothing(account3, 2)
        self.assertEqual(
            2, await self.ledger.db.get_transaction_count(accounts=[account1]))
        self.assertEqual(
            1, await self.ledger.db.get_transaction_count(accounts=[account2]))
        self.assertEqual(
            1, await self.ledger.db.get_transaction_count(accounts=[account3]))
        self.assertEqual(
            0, await self.ledger.db.get_utxo_count(accounts=[account1]))
        self.assertEqual(
            1, await self.ledger.db.get_txo_count(accounts=[account1]))
        self.assertEqual(
            1, await self.ledger.db.get_utxo_count(accounts=[account2]))
        self.assertEqual(
            1, await self.ledger.db.get_txo_count(accounts=[account2]))
        self.assertEqual(
            1, await self.ledger.db.get_utxo_count(accounts=[account3]))
        self.assertEqual(
            1, await self.ledger.db.get_txo_count(accounts=[account3]))
        self.assertEqual(0, await self.ledger.db.get_balance(wallet=wallet1))
        self.assertEqual(10**8 + 10**8, await
                         self.ledger.db.get_balance(wallet=wallet2))
        self.assertEqual(0, await
                         self.ledger.db.get_balance(accounts=[account1]))
        self.assertEqual(10**8, await
                         self.ledger.db.get_balance(accounts=[account2]))
        self.assertEqual(10**8, await
                         self.ledger.db.get_balance(accounts=[account3]))

        tx3 = await self.create_tx_to_nowhere(tx2.outputs[0], 3)
        self.assertEqual(
            2, await self.ledger.db.get_transaction_count(accounts=[account1]))
        self.assertEqual(
            2, await self.ledger.db.get_transaction_count(accounts=[account2]))
        self.assertEqual(
            0, await self.ledger.db.get_utxo_count(accounts=[account1]))
        self.assertEqual(
            1, await self.ledger.db.get_txo_count(accounts=[account1]))
        self.assertEqual(
            0, await self.ledger.db.get_utxo_count(accounts=[account2]))
        self.assertEqual(
            1, await self.ledger.db.get_txo_count(accounts=[account2]))
        self.assertEqual(0, await self.ledger.db.get_balance(wallet=wallet1))
        self.assertEqual(10**8, await
                         self.ledger.db.get_balance(wallet=wallet2))
        self.assertEqual(0, await
                         self.ledger.db.get_balance(accounts=[account1]))
        self.assertEqual(0, await
                         self.ledger.db.get_balance(accounts=[account2]))
        self.assertEqual(10**8, await
                         self.ledger.db.get_balance(accounts=[account3]))

        txs = await self.ledger.db.get_transactions(
            accounts=[account1, account2])
        self.assertListEqual([tx3.id, tx2.id, tx1.id], [tx.id for tx in txs])
        self.assertListEqual([3, 2, 1], [tx.height for tx in txs])

        txs = await self.ledger.db.get_transactions(wallet=wallet1,
                                                    accounts=wallet1.accounts)
        self.assertListEqual([tx2.id, tx1.id], [tx.id for tx in txs])
        self.assertEqual(txs[0].inputs[0].is_my_account, True)
        self.assertEqual(txs[0].outputs[0].is_my_account, False)
        self.assertEqual(txs[1].inputs[0].is_my_account, False)
        self.assertEqual(txs[1].outputs[0].is_my_account, True)

        txs = await self.ledger.db.get_transactions(wallet=wallet2,
                                                    accounts=[account2])
        self.assertListEqual([tx3.id, tx2.id], [tx.id for tx in txs])
        self.assertEqual(txs[0].inputs[0].is_my_account, True)
        self.assertEqual(txs[0].outputs[0].is_my_account, False)
        self.assertEqual(txs[1].inputs[0].is_my_account, False)
        self.assertEqual(txs[1].outputs[0].is_my_account, True)
        self.assertEqual(
            2, await self.ledger.db.get_transaction_count(accounts=[account2]))

        tx = await self.ledger.db.get_transaction(txid=tx2.id)
        self.assertEqual(tx.id, tx2.id)
        self.assertEqual(tx.inputs[0].is_my_account, False)
        self.assertEqual(tx.outputs[0].is_my_account, False)
        tx = await self.ledger.db.get_transaction(wallet=wallet1, txid=tx2.id)
        self.assertEqual(tx.inputs[0].is_my_account, True)
        self.assertEqual(tx.outputs[0].is_my_account, False)
        tx = await self.ledger.db.get_transaction(wallet=wallet2, txid=tx2.id)
        self.assertEqual(tx.inputs[0].is_my_account, False)
        self.assertEqual(tx.outputs[0].is_my_account, True)

        # height 0 sorted to the top with the rest in descending order
        tx4 = await self.create_tx_from_nothing(account1, 0)
        txos = await self.ledger.db.get_txos()
        self.assertListEqual([0, 2, 2, 1], [txo.tx_ref.height for txo in txos])
        self.assertListEqual([tx4.id, tx2.id, tx2b.id, tx1.id],
                             [txo.tx_ref.id for txo in txos])
        txs = await self.ledger.db.get_transactions(
            accounts=[account1, account2])
        self.assertListEqual([0, 3, 2, 1], [tx.height for tx in txs])
        self.assertListEqual([tx4.id, tx3.id, tx2.id, tx1.id],
                             [tx.id for tx in txs])