forked from LBRYCommunity/lbry-sdk
working claim_send_to_address
This commit is contained in:
parent
a93957178a
commit
dd1d1be994
4 changed files with 85 additions and 121 deletions
|
@ -1215,7 +1215,7 @@ class Daemon(AuthJSONRPCServer):
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.ledger.network.is_connected:
|
if self.ledger.network.is_connected:
|
||||||
await self.ledger.update_account(account)
|
await self.ledger.subscribe_account(account)
|
||||||
|
|
||||||
self.default_wallet.save()
|
self.default_wallet.save()
|
||||||
|
|
||||||
|
@ -1250,7 +1250,7 @@ class Daemon(AuthJSONRPCServer):
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.ledger.network.is_connected:
|
if self.ledger.network.is_connected:
|
||||||
await self.ledger.update_account(account)
|
await self.ledger.subscribe_account(account)
|
||||||
|
|
||||||
self.default_wallet.save()
|
self.default_wallet.save()
|
||||||
|
|
||||||
|
|
|
@ -1,40 +1,33 @@
|
||||||
import re
|
|
||||||
import textwrap
|
import textwrap
|
||||||
from torba.client.constants import COIN
|
from torba.client.util import coins_to_satoshis, satoshis_to_coins
|
||||||
|
|
||||||
|
|
||||||
def lbc_to_dewies(lbc):
|
def lbc_to_dewies(lbc):
|
||||||
if isinstance(lbc, str):
|
try:
|
||||||
result = re.search(r'^(\d{1,10})\.(\d{1,8})$', lbc)
|
return coins_to_satoshis(lbc)
|
||||||
if result is not None:
|
except ValueError:
|
||||||
whole, fractional = result.groups()
|
raise ValueError(textwrap.dedent(
|
||||||
return int(whole+fractional.ljust(8, "0"))
|
"""
|
||||||
raise ValueError(textwrap.dedent(
|
Decimal inputs require a value in the ones place and in the tenths place
|
||||||
"""
|
separated by a period. The value provided, '{}', is not of the correct
|
||||||
Decimal inputs require a value in the ones place and in the tenths place
|
format.
|
||||||
separated by a period. The value provided, '{}', is not of the correct
|
|
||||||
format.
|
|
||||||
|
|
||||||
The following are examples of valid decimal inputs:
|
The following are examples of valid decimal inputs:
|
||||||
|
|
||||||
1.0
|
1.0
|
||||||
0.001
|
0.001
|
||||||
2.34500
|
2.34500
|
||||||
4534.4
|
4534.4
|
||||||
2323434.0000
|
2323434.0000
|
||||||
|
|
||||||
The following are NOT valid:
|
The following are NOT valid:
|
||||||
|
|
||||||
83
|
83
|
||||||
.456
|
.456
|
||||||
123.
|
123.
|
||||||
""".format(lbc)
|
""".format(lbc)
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
def dewies_to_lbc(dewies):
|
def dewies_to_lbc(dewies):
|
||||||
lbc = '{:.8f}'.format(dewies / COIN).rstrip('0')
|
return satoshis_to_coins(dewies)
|
||||||
if lbc.endswith('.'):
|
|
||||||
return lbc+'0'
|
|
||||||
else:
|
|
||||||
return lbc
|
|
||||||
|
|
|
@ -137,8 +137,8 @@ class LbryWalletManager(BaseWalletManager):
|
||||||
'certificates': unmigrated.get('claim_certificates', {}),
|
'certificates': unmigrated.get('claim_certificates', {}),
|
||||||
'address_generator': {
|
'address_generator': {
|
||||||
'name': 'deterministic-chain',
|
'name': 'deterministic-chain',
|
||||||
'receiving': {'gap': 20, 'maximum_uses_per_address': 2},
|
'receiving': {'gap': 20, 'maximum_uses_per_address': 1},
|
||||||
'change': {'gap': 6, 'maximum_uses_per_address': 2}
|
'change': {'gap': 6, 'maximum_uses_per_address': 1}
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
}, indent=4, sort_keys=True)
|
}, indent=4, sort_keys=True)
|
||||||
|
@ -239,11 +239,13 @@ class LbryWalletManager(BaseWalletManager):
|
||||||
async def send_claim_to_address(self, claim_id: str, destination_address: str, amount: Optional[int],
|
async def send_claim_to_address(self, claim_id: str, destination_address: str, amount: Optional[int],
|
||||||
account=None):
|
account=None):
|
||||||
account = account or self.default_account
|
account = account or self.default_account
|
||||||
claims = await account.ledger.db.get_utxos(claim_id=claim_id)
|
claims = await account.get_claims(is_claim=1, claim_id=claim_id)
|
||||||
if not claims:
|
if not claims:
|
||||||
raise NameError(f"Claim not found: {claim_id}")
|
raise NameError(f"Claim not found: {claim_id}")
|
||||||
|
if not amount:
|
||||||
|
amount = claims[0].get_estimator(self.ledger).effective_amount
|
||||||
tx = await Transaction.update(
|
tx = await Transaction.update(
|
||||||
claims[0], ClaimDict.deserialize(claims[0].script.value['claim']), amount,
|
claims[0], ClaimDict.deserialize(claims[0].script.values['claim']), amount,
|
||||||
destination_address.encode(), [account], account
|
destination_address.encode(), [account], account
|
||||||
)
|
)
|
||||||
await self.ledger.broadcast(tx)
|
await self.ledger.broadcast(tx)
|
||||||
|
@ -387,19 +389,6 @@ class LbryWalletManager(BaseWalletManager):
|
||||||
# TODO: release reserved tx outputs in case anything fails by this point
|
# TODO: release reserved tx outputs in case anything fails by this point
|
||||||
return tx
|
return tx
|
||||||
|
|
||||||
def _old_get_temp_claim_info(self, tx, txo, address, claim_dict, name, bid):
|
|
||||||
return {
|
|
||||||
"claim_id": txo.claim_id,
|
|
||||||
"name": name,
|
|
||||||
"amount": bid,
|
|
||||||
"address": address,
|
|
||||||
"txid": tx.id,
|
|
||||||
"nout": txo.position,
|
|
||||||
"value": claim_dict,
|
|
||||||
"height": -1,
|
|
||||||
"claim_sequence": -1,
|
|
||||||
}
|
|
||||||
|
|
||||||
async def support_claim(self, claim_name, claim_id, amount, account):
|
async def support_claim(self, claim_name, claim_id, amount, account):
|
||||||
holding_address = await account.receiving.get_or_create_usable_address()
|
holding_address = await account.receiving.get_or_create_usable_address()
|
||||||
tx = await Transaction.support(claim_name, claim_id, amount, holding_address, [account], account)
|
tx = await Transaction.support(claim_name, claim_id, amount, holding_address, [account], account)
|
||||||
|
@ -433,6 +422,19 @@ class LbryWalletManager(BaseWalletManager):
|
||||||
# TODO: release reserved tx outputs in case anything fails by this point
|
# TODO: release reserved tx outputs in case anything fails by this point
|
||||||
return tx
|
return tx
|
||||||
|
|
||||||
|
def _old_get_temp_claim_info(self, tx, txo, address, claim_dict, name, bid):
|
||||||
|
return {
|
||||||
|
"claim_id": txo.claim_id,
|
||||||
|
"name": name,
|
||||||
|
"amount": bid,
|
||||||
|
"address": address,
|
||||||
|
"txid": tx.id,
|
||||||
|
"nout": txo.position,
|
||||||
|
"value": claim_dict,
|
||||||
|
"height": -1,
|
||||||
|
"claim_sequence": -1,
|
||||||
|
}
|
||||||
|
|
||||||
def get_certificates(self, private_key_accounts, exclude_without_key=True, **constraints):
|
def get_certificates(self, private_key_accounts, exclude_without_key=True, **constraints):
|
||||||
return self.db.get_certificates(
|
return self.db.get_certificates(
|
||||||
private_key_accounts=private_key_accounts,
|
private_key_accounts=private_key_accounts,
|
||||||
|
|
|
@ -2,6 +2,7 @@ import json
|
||||||
import asyncio
|
import asyncio
|
||||||
import tempfile
|
import tempfile
|
||||||
import logging
|
import logging
|
||||||
|
from binascii import unhexlify
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
|
|
||||||
|
@ -174,11 +175,9 @@ class CommandTestCase(IntegrationTestCase):
|
||||||
await self.on_transaction_id(txid)
|
await self.on_transaction_id(txid)
|
||||||
|
|
||||||
async def on_transaction_dict(self, tx):
|
async def on_transaction_dict(self, tx):
|
||||||
await asyncio.wait([
|
await self.ledger.wait(
|
||||||
self.ledger.on_transaction.where(
|
self.ledger.transaction_class(unhexlify(tx['hex']))
|
||||||
partial(lambda address, event: address == event.address, address)
|
)
|
||||||
) for address in self.get_all_addresses(tx)
|
|
||||||
])
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_all_addresses(tx):
|
def get_all_addresses(tx):
|
||||||
|
@ -479,10 +478,41 @@ class AccountManagement(CommandTestCase):
|
||||||
self.assertEqual(response['name'], 'recreated account')
|
self.assertEqual(response['name'], 'recreated account')
|
||||||
|
|
||||||
|
|
||||||
class PublishCommand(CommandTestCase):
|
class ClaimManagement(CommandTestCase):
|
||||||
|
|
||||||
VERBOSITY = logging.WARN
|
VERBOSITY = logging.WARN
|
||||||
|
|
||||||
|
async def make_claim(self, name='hovercraft', amount='1.0', data=b'hi!'):
|
||||||
|
with tempfile.NamedTemporaryFile() as file:
|
||||||
|
file.write(data)
|
||||||
|
file.flush()
|
||||||
|
claim = await self.out(self.daemon.jsonrpc_publish(
|
||||||
|
name, amount, file_path=file.name
|
||||||
|
))
|
||||||
|
self.assertTrue(claim['success'])
|
||||||
|
await self.on_transaction_dict(claim['tx'])
|
||||||
|
await self.generate(1)
|
||||||
|
return claim
|
||||||
|
|
||||||
|
async def test_update_claim_holding_address(self):
|
||||||
|
other_account_id = (await self.daemon.jsonrpc_account_create('second account'))['id']
|
||||||
|
other_account = self.daemon.get_account_or_error(other_account_id)
|
||||||
|
other_address = await other_account.receiving.get_or_create_usable_address()
|
||||||
|
|
||||||
|
self.assertEqual('10.0', await self.daemon.jsonrpc_account_balance())
|
||||||
|
|
||||||
|
# create the initial name claim
|
||||||
|
claim = await self.make_claim()
|
||||||
|
|
||||||
|
self.assertEqual(len(await self.daemon.jsonrpc_claim_list_mine()), 1)
|
||||||
|
self.assertEqual(len(await self.daemon.jsonrpc_claim_list_mine(account_id=other_account_id)), 0)
|
||||||
|
tx = await self.daemon.jsonrpc_claim_send_to_address(
|
||||||
|
claim['claim_id'], other_address
|
||||||
|
)
|
||||||
|
await self.ledger.wait(tx)
|
||||||
|
self.assertEqual(len(await self.daemon.jsonrpc_claim_list_mine()), 0)
|
||||||
|
self.assertEqual(len(await self.daemon.jsonrpc_claim_list_mine(account_id=other_account_id)), 1)
|
||||||
|
|
||||||
async def test_publishing_checks_all_accounts_for_certificate(self):
|
async def test_publishing_checks_all_accounts_for_certificate(self):
|
||||||
account1_id, account1 = self.account.id, self.account
|
account1_id, account1 = self.account.id, self.account
|
||||||
new_account = await self.daemon.jsonrpc_account_create('second account')
|
new_account = await self.daemon.jsonrpc_account_create('second account')
|
||||||
|
@ -547,49 +577,17 @@ class PublishCommand(CommandTestCase):
|
||||||
))
|
))
|
||||||
|
|
||||||
async def test_updating_claim_includes_claim_value_in_balance_check(self):
|
async def test_updating_claim_includes_claim_value_in_balance_check(self):
|
||||||
|
|
||||||
self.assertEqual('10.0', await self.daemon.jsonrpc_account_balance())
|
self.assertEqual('10.0', await self.daemon.jsonrpc_account_balance())
|
||||||
|
|
||||||
# create the initial name claim
|
await self.make_claim(amount='9.0')
|
||||||
with tempfile.NamedTemporaryFile() as file:
|
|
||||||
file.write(b'hi!')
|
|
||||||
file.flush()
|
|
||||||
claim = await self.out(self.daemon.jsonrpc_publish(
|
|
||||||
'hovercraft', '9.0', file_path=file.name
|
|
||||||
))
|
|
||||||
self.assertTrue(claim['success'])
|
|
||||||
|
|
||||||
await self.on_transaction_dict(claim['tx'])
|
|
||||||
await self.generate(1)
|
|
||||||
|
|
||||||
self.assertEqual('0.979893', await self.daemon.jsonrpc_account_balance())
|
self.assertEqual('0.979893', await self.daemon.jsonrpc_account_balance())
|
||||||
|
|
||||||
# update the claim first time
|
# update the same claim
|
||||||
with tempfile.NamedTemporaryFile() as file:
|
await self.make_claim(amount='9.0')
|
||||||
file.write(b'hi!')
|
|
||||||
file.flush()
|
|
||||||
claim = await self.out(self.daemon.jsonrpc_publish(
|
|
||||||
'hovercraft', '9.0', file_path=file.name
|
|
||||||
))
|
|
||||||
self.assertTrue(claim['success'])
|
|
||||||
|
|
||||||
await self.on_transaction_dict(claim['tx'])
|
|
||||||
await self.generate(1)
|
|
||||||
|
|
||||||
self.assertEqual('0.9796205', await self.daemon.jsonrpc_account_balance())
|
self.assertEqual('0.9796205', await self.daemon.jsonrpc_account_balance())
|
||||||
|
|
||||||
# update the claim a second time but use even more funds
|
# update the claim a second time but use even more funds
|
||||||
with tempfile.NamedTemporaryFile() as file:
|
await self.make_claim(amount='9.97')
|
||||||
file.write(b'hi!')
|
|
||||||
file.flush()
|
|
||||||
claim = await self.out(self.daemon.jsonrpc_publish(
|
|
||||||
'hovercraft', '9.97', file_path=file.name
|
|
||||||
))
|
|
||||||
self.assertTrue(claim['success'])
|
|
||||||
|
|
||||||
await self.on_transaction_dict(claim['tx'])
|
|
||||||
await self.generate(1)
|
|
||||||
|
|
||||||
self.assertEqual('0.009348', await self.daemon.jsonrpc_account_balance())
|
self.assertEqual('0.009348', await self.daemon.jsonrpc_account_balance())
|
||||||
|
|
||||||
# fails when specifying more than available
|
# fails when specifying more than available
|
||||||
|
@ -605,35 +603,13 @@ class PublishCommand(CommandTestCase):
|
||||||
'hovercraft', '9.98', file_path=file.name
|
'hovercraft', '9.98', file_path=file.name
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
class AbandonCommand(CommandTestCase):
|
|
||||||
|
|
||||||
VERBOSITY = logging.WARN
|
|
||||||
|
|
||||||
async def test_abandoning_claim_at_loss(self):
|
async def test_abandoning_claim_at_loss(self):
|
||||||
|
|
||||||
self.assertEqual('10.0', await self.daemon.jsonrpc_account_balance())
|
self.assertEqual('10.0', await self.daemon.jsonrpc_account_balance())
|
||||||
|
claim = await self.make_claim(amount='0.0001')
|
||||||
# create the initial name claim
|
|
||||||
with tempfile.NamedTemporaryFile() as file:
|
|
||||||
file.write(b'hi!')
|
|
||||||
file.flush()
|
|
||||||
claim = await self.out(self.daemon.jsonrpc_publish(
|
|
||||||
'hovercraft', '0.0001', file_path=file.name
|
|
||||||
))
|
|
||||||
self.assertTrue(claim['success'])
|
|
||||||
await self.on_transaction_dict(claim['tx'])
|
|
||||||
await self.generate(1)
|
|
||||||
|
|
||||||
self.assertEqual('9.979793', await self.daemon.jsonrpc_account_balance())
|
self.assertEqual('9.979793', await self.daemon.jsonrpc_account_balance())
|
||||||
await self.out(self.daemon.jsonrpc_claim_abandon(claim['claim_id']))
|
await self.out(self.daemon.jsonrpc_claim_abandon(claim['claim_id']))
|
||||||
self.assertEqual('9.97968399', await self.daemon.jsonrpc_account_balance())
|
self.assertEqual('9.97968399', await self.daemon.jsonrpc_account_balance())
|
||||||
|
|
||||||
|
|
||||||
class SupportingSupports(CommandTestCase):
|
|
||||||
|
|
||||||
VERBOSITY = logging.WARN
|
|
||||||
|
|
||||||
async def test_regular_supports_and_tip_supports(self):
|
async def test_regular_supports_and_tip_supports(self):
|
||||||
# account2 will be used to send tips and supports to account1
|
# account2 will be used to send tips and supports to account1
|
||||||
account2_id = (await self.daemon.jsonrpc_account_create('second account'))['id']
|
account2_id = (await self.daemon.jsonrpc_account_create('second account'))['id']
|
||||||
|
@ -649,14 +625,7 @@ class SupportingSupports(CommandTestCase):
|
||||||
self.assertEqual('5.0', await self.daemon.jsonrpc_account_balance(account2_id))
|
self.assertEqual('5.0', await self.daemon.jsonrpc_account_balance(account2_id))
|
||||||
|
|
||||||
# create the claim we'll be tipping and supporting
|
# create the claim we'll be tipping and supporting
|
||||||
with tempfile.NamedTemporaryFile() as file:
|
claim = await self.make_claim()
|
||||||
file.write(b'hi!')
|
|
||||||
file.flush()
|
|
||||||
claim = await self.out(self.daemon.jsonrpc_publish(
|
|
||||||
'hovercraft', '1.0', file_path=file.name
|
|
||||||
))
|
|
||||||
self.assertTrue(claim['success'])
|
|
||||||
await self.confirm_tx(claim['tx']['txid'])
|
|
||||||
|
|
||||||
# account1 and account2 balances:
|
# account1 and account2 balances:
|
||||||
self.assertEqual('3.979769', await self.daemon.jsonrpc_account_balance())
|
self.assertEqual('3.979769', await self.daemon.jsonrpc_account_balance())
|
||||||
|
|
Loading…
Add table
Reference in a new issue