forked from LBRYCommunity/lbry-sdk
lots of stuff deleted
This commit is contained in:
parent
0872a6fea3
commit
67dcede2d8
7 changed files with 157 additions and 292 deletions
|
@ -252,14 +252,12 @@ class WalletComponent(Component):
|
||||||
|
|
||||||
async def get_status(self):
|
async def get_status(self):
|
||||||
if self.wallet_manager and self.running:
|
if self.wallet_manager and self.running:
|
||||||
local_height = self.wallet_manager.network.get_local_height()
|
local_height = self.wallet_manager.ledger.headers.height
|
||||||
remote_height = self.wallet_manager.network.get_server_height()
|
|
||||||
best_hash = self.wallet_manager.get_best_blockhash()
|
best_hash = self.wallet_manager.get_best_blockhash()
|
||||||
return {
|
return {
|
||||||
'blocks': max(local_height, 0),
|
'blocks': max(local_height, 0),
|
||||||
'blocks_behind': max(remote_height - local_height, 0),
|
|
||||||
'best_blockhash': best_hash,
|
'best_blockhash': best_hash,
|
||||||
'is_encrypted': self.wallet_manager.wallet.use_encryption,
|
'is_encrypted': self.wallet_manager.use_encryption,
|
||||||
'is_locked': not self.wallet_manager.is_wallet_unlocked,
|
'is_locked': not self.wallet_manager.is_wallet_unlocked,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -569,7 +569,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
Resolve a name and return the estimated stream cost
|
Resolve a name and return the estimated stream cost
|
||||||
"""
|
"""
|
||||||
|
|
||||||
resolved = await self.wallet_manager.resolve(uri)
|
resolved = await self.resolve(uri)
|
||||||
if resolved:
|
if resolved:
|
||||||
claim_response = resolved[uri]
|
claim_response = resolved[uri]
|
||||||
else:
|
else:
|
||||||
|
@ -807,7 +807,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
except URIParseError:
|
except URIParseError:
|
||||||
results[u] = {"error": "%s is not a valid url" % u}
|
results[u] = {"error": "%s is not a valid url" % u}
|
||||||
|
|
||||||
resolved = await self.wallet_manager.resolve(*tuple(valid_urls))
|
resolved = await self.resolve(*tuple(valid_urls))
|
||||||
|
|
||||||
for resolved_uri in resolved:
|
for resolved_uri in resolved:
|
||||||
results[resolved_uri] = resolved[resolved_uri]
|
results[resolved_uri] = resolved[resolved_uri]
|
||||||
|
@ -912,80 +912,6 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
setattr(c, key, cleaned)
|
setattr(c, key, cleaned)
|
||||||
return {key: cleaned}
|
return {key: cleaned}
|
||||||
|
|
||||||
WALLET_DOC = """
|
|
||||||
Wallet management.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@deprecated("account_balance")
|
|
||||||
def jsonrpc_wallet_balance(self, address=None):
|
|
||||||
""" deprecated """
|
|
||||||
|
|
||||||
@requires(WALLET_COMPONENT, conditions=[WALLET_IS_UNLOCKED])
|
|
||||||
async def jsonrpc_wallet_send(self, amount, address=None, claim_id=None, account_id=None):
|
|
||||||
"""
|
|
||||||
Send credits. If given an address, send credits to it. If given a claim id, send a tip
|
|
||||||
to the owner of a claim specified by uri. A tip is a claim support where the recipient
|
|
||||||
of the support is the claim address for the claim being supported.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
wallet_send (<amount> | --amount=<amount>)
|
|
||||||
((<address> | --address=<address>) | (<claim_id> | --claim_id=<claim_id>))
|
|
||||||
[--account_id=<account_id>]
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--amount=<amount> : (decimal) amount of credit to send
|
|
||||||
--address=<address> : (str) address to send credits to
|
|
||||||
--claim_id=<claim_id> : (str) claim_id of the claim to send to tip to
|
|
||||||
--account_id=<account_id> : (str) account to fund the transaction
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
If sending to an address:
|
|
||||||
(dict) Dictionary containing the transaction information
|
|
||||||
{
|
|
||||||
"hex": (str) raw transaction,
|
|
||||||
"inputs": (list) inputs(dict) used for the transaction,
|
|
||||||
"outputs": (list) outputs(dict) for the transaction,
|
|
||||||
"total_fee": (int) fee in dewies,
|
|
||||||
"total_input": (int) total of inputs in dewies,
|
|
||||||
"total_output": (int) total of outputs in dewies(input - fees),
|
|
||||||
"txid": (str) txid of the transaction,
|
|
||||||
}
|
|
||||||
|
|
||||||
If sending a claim tip:
|
|
||||||
(dict) Dictionary containing the result of the support
|
|
||||||
{
|
|
||||||
txid : (str) txid of resulting support claim
|
|
||||||
nout : (int) nout of the resulting support claim
|
|
||||||
fee : (float) fee paid for the transaction
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
amount = self.get_dewies_or_error("amount", amount)
|
|
||||||
if not amount:
|
|
||||||
raise NullFundsError
|
|
||||||
if amount < 0:
|
|
||||||
raise NegativeFundsError()
|
|
||||||
|
|
||||||
if address and claim_id:
|
|
||||||
raise Exception("Given both an address and a claim id")
|
|
||||||
if not address and not claim_id:
|
|
||||||
raise Exception("Not given an address or a claim id")
|
|
||||||
|
|
||||||
if address:
|
|
||||||
# raises an error if the address is invalid
|
|
||||||
self.ledger.is_valid_address(address)
|
|
||||||
|
|
||||||
reserved_points = self.wallet_manager.reserve_points(address, amount)
|
|
||||||
if reserved_points is None:
|
|
||||||
raise InsufficientFundsError()
|
|
||||||
account = self.get_account_or_default(account_id)
|
|
||||||
result = await self.wallet_manager.send_points_to_address(reserved_points, amount, account)
|
|
||||||
await self.analytics_manager.send_credits_sent()
|
|
||||||
else:
|
|
||||||
log.info("This command is deprecated for sending tips, please use the newer claim_tip command")
|
|
||||||
result = await self.jsonrpc_claim_tip(claim_id=claim_id, amount=amount, account_id=account_id)
|
|
||||||
return result
|
|
||||||
|
|
||||||
ACCOUNT_DOC = """
|
ACCOUNT_DOC = """
|
||||||
Account management.
|
Account management.
|
||||||
"""
|
"""
|
||||||
|
@ -1342,19 +1268,20 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
)
|
)
|
||||||
|
|
||||||
@requires(WALLET_COMPONENT, conditions=[WALLET_IS_UNLOCKED])
|
@requires(WALLET_COMPONENT, conditions=[WALLET_IS_UNLOCKED])
|
||||||
async def jsonrpc_account_send(self, amount, addresses, account_id=None, broadcast=False):
|
async def jsonrpc_account_send(self, amount, addresses, account_id=None, preview=False):
|
||||||
"""
|
"""
|
||||||
Send the same number of credits to multiple addresses.
|
Send the same number of credits to multiple addresses.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
account_send <amount> <addresses>... [--account_id=<account_id>] [--broadcast]
|
account_send <amount> <addresses>... [--account_id=<account_id>] [--preview]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--account_id=<account_id> : (str) account to fund the transaction
|
--account_id=<account_id> : (str) account to fund the transaction
|
||||||
--broadcast : (bool) actually broadcast the transaction, default: false.
|
--preview : (bool) do not broadcast the transaction
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
"""
|
"""
|
||||||
|
account = self.get_account_or_default(account_id)
|
||||||
|
|
||||||
amount = self.get_dewies_or_error("amount", amount)
|
amount = self.get_dewies_or_error("amount", amount)
|
||||||
if not amount:
|
if not amount:
|
||||||
|
@ -1362,13 +1289,29 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
if amount < 0:
|
if amount < 0:
|
||||||
raise NegativeFundsError()
|
raise NegativeFundsError()
|
||||||
|
|
||||||
for address in addresses:
|
if addresses and not isinstance(addresses, list):
|
||||||
self.ledger.is_valid_address(address)
|
addresses = [addresses]
|
||||||
|
|
||||||
account = self.get_account_or_default(account_id)
|
outputs = []
|
||||||
result = await account.send_to_addresses(amount, addresses, broadcast)
|
for address in addresses:
|
||||||
await self.analytics_manager.send_credits_sent()
|
self.valid_address_or_error(address)
|
||||||
return result
|
outputs.append(
|
||||||
|
Output.pay_pubkey_hash(
|
||||||
|
amount, self.ledger.address_to_hash160(address)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
tx = await Transaction.create(
|
||||||
|
[], outputs, [account], account
|
||||||
|
)
|
||||||
|
|
||||||
|
if not preview:
|
||||||
|
await self.ledger.broadcast(tx)
|
||||||
|
await self.analytics_manager.send_credits_sent()
|
||||||
|
else:
|
||||||
|
await account.ledger.release_tx(tx)
|
||||||
|
|
||||||
|
return tx
|
||||||
|
|
||||||
SYNC_DOC = """
|
SYNC_DOC = """
|
||||||
Wallet synchronization.
|
Wallet synchronization.
|
||||||
|
@ -1437,7 +1380,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@requires(WALLET_COMPONENT)
|
@requires(WALLET_COMPONENT)
|
||||||
def jsonrpc_address_is_mine(self, address, account_id=None):
|
async def jsonrpc_address_is_mine(self, address, account_id=None):
|
||||||
"""
|
"""
|
||||||
Checks if an address is associated with the current wallet.
|
Checks if an address is associated with the current wallet.
|
||||||
|
|
||||||
|
@ -1452,9 +1395,11 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
Returns:
|
Returns:
|
||||||
(bool) true, if address is associated with current wallet
|
(bool) true, if address is associated with current wallet
|
||||||
"""
|
"""
|
||||||
return self.wallet_manager.address_is_mine(
|
account = self.get_account_or_default(account_id)
|
||||||
address, self.get_account_or_default(account_id)
|
match = await self.ledger.db.get_address(address=address, account=account)
|
||||||
)
|
if match is not None:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
@requires(WALLET_COMPONENT)
|
@requires(WALLET_COMPONENT)
|
||||||
def jsonrpc_address_list(self, account_id=None, page=None, page_size=None):
|
def jsonrpc_address_list(self, account_id=None, page=None, page_size=None):
|
||||||
|
@ -1815,7 +1760,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
amount = old_txo.amount
|
amount = old_txo.amount
|
||||||
|
|
||||||
if claim_address is not None:
|
if claim_address is not None:
|
||||||
self.ledger.is_valid_address(claim_address)
|
self.valid_address_or_error(claim_address)
|
||||||
else:
|
else:
|
||||||
claim_address = old_txo.get_address(account.ledger)
|
claim_address = old_txo.get_address(account.ledger)
|
||||||
|
|
||||||
|
@ -2078,7 +2023,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
amount = old_txo.amount
|
amount = old_txo.amount
|
||||||
|
|
||||||
if claim_address is not None:
|
if claim_address is not None:
|
||||||
self.ledger.is_valid_address(claim_address)
|
self.valid_address_or_error(claim_address)
|
||||||
else:
|
else:
|
||||||
claim_address = old_txo.get_address(account.ledger)
|
claim_address = old_txo.get_address(account.ledger)
|
||||||
|
|
||||||
|
@ -2193,7 +2138,12 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
if nout is None and txid is not None:
|
if nout is None and txid is not None:
|
||||||
raise Exception('Must specify nout')
|
raise Exception('Must specify nout')
|
||||||
|
|
||||||
tx = await self.wallet_manager.abandon_claim(claim_id, txid, nout, account)
|
claim = await account.get_claim(claim_id=claim_id, txid=txid, nout=nout)
|
||||||
|
if not claim:
|
||||||
|
raise Exception('No claim found for the specified claim_id or txid:nout')
|
||||||
|
|
||||||
|
tx = await Transaction.abandon(claim, [account], account)
|
||||||
|
await account.ledger.broadcast(tx)
|
||||||
await self.analytics_manager.send_claim_action('abandon')
|
await self.analytics_manager.send_claim_action('abandon')
|
||||||
if blocking:
|
if blocking:
|
||||||
await self.ledger.wait(tx)
|
await self.ledger.wait(tx)
|
||||||
|
@ -2234,7 +2184,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
--winning : (bool) limit to winning claims
|
--winning : (bool) limit to winning claims
|
||||||
"""
|
"""
|
||||||
response = await self.wallet_manager.ledger.network.get_claims_for_name(name)
|
response = await self.wallet_manager.ledger.network.get_claims_for_name(name)
|
||||||
resolutions = await self.wallet_manager.resolve(*(f"{claim['name']}#{claim['claim_id']}" for claim in response['claims']))
|
resolutions = await self.resolve(*(f"{claim['name']}#{claim['claim_id']}" for claim in response['claims']))
|
||||||
response['claims'] = [value.get('claim', value.get('certificate')) for value in resolutions.values()]
|
response['claims'] = [value.get('claim', value.get('certificate')) for value in resolutions.values()]
|
||||||
response['claims'] = sort_claim_results(response['claims'])
|
response['claims'] = sort_claim_results(response['claims'])
|
||||||
return response
|
return response
|
||||||
|
@ -2260,7 +2210,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
except URIParseError:
|
except URIParseError:
|
||||||
results[chan_uri] = {"error": "%s is not a valid uri" % chan_uri}
|
results[chan_uri] = {"error": "%s is not a valid uri" % chan_uri}
|
||||||
|
|
||||||
resolved = await self.wallet_manager.resolve(*valid_uris, page=page, page_size=page_size)
|
resolved = await self.resolve(*valid_uris, page=page, page_size=page_size)
|
||||||
if 'error' in resolved:
|
if 'error' in resolved:
|
||||||
return {'error': resolved['error']}
|
return {'error': resolved['error']}
|
||||||
for u in resolved:
|
for u in resolved:
|
||||||
|
@ -2329,7 +2279,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
Abandon a name and reclaim credits from the claim
|
Abandon a name and reclaim credits from the claim
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
claim_abandon [<claim_id> | --claim_id=<claim_id>]
|
support abandon [<claim_id> | --claim_id=<claim_id>]
|
||||||
[<txid> | --txid=<txid>] [<nout> | --nout=<nout>]
|
[<txid> | --txid=<txid>] [<nout> | --nout=<nout>]
|
||||||
[--account_id=<account_id>]
|
[--account_id=<account_id>]
|
||||||
[--blocking]
|
[--blocking]
|
||||||
|
@ -2710,7 +2660,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
|
|
||||||
if uri or stream_hash or sd_hash:
|
if uri or stream_hash or sd_hash:
|
||||||
if uri:
|
if uri:
|
||||||
metadata = (await self.wallet_manager.resolve(uri))[uri]
|
metadata = (await self.resolve(uri))[uri]
|
||||||
sd_hash = utils.get_sd_hash(metadata)
|
sd_hash = utils.get_sd_hash(metadata)
|
||||||
stream_hash = await self.storage.get_stream_hash_for_sd_hash(sd_hash)
|
stream_hash = await self.storage.get_stream_hash_for_sd_hash(sd_hash)
|
||||||
elif stream_hash:
|
elif stream_hash:
|
||||||
|
@ -2878,16 +2828,23 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
result['node_id'] = hexlify(self.dht_node.protocol.node_id).decode()
|
result['node_id'] = hexlify(self.dht_node.protocol.node_id).decode()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def valid_address_or_error(self, address):
|
||||||
|
try:
|
||||||
|
if not self.ledger.is_valid_address(address):
|
||||||
|
raise Exception(f"'{address}' is not a valid address")
|
||||||
|
except:
|
||||||
|
raise Exception(f"'{address}' is not a valid address")
|
||||||
|
|
||||||
def get_fee_address(self, kwargs: dict, claim_address: str) -> str:
|
def get_fee_address(self, kwargs: dict, claim_address: str) -> str:
|
||||||
if 'fee_address' in kwargs:
|
if 'fee_address' in kwargs:
|
||||||
self.ledger.is_valid_address(kwargs['fee_address'])
|
self.valid_address_or_error(kwargs['fee_address'])
|
||||||
return kwargs['fee_address']
|
return kwargs['fee_address']
|
||||||
return claim_address
|
return claim_address
|
||||||
|
|
||||||
async def get_receiving_address(self, address: str, account: LBCAccount) -> str:
|
async def get_receiving_address(self, address: str, account: LBCAccount) -> str:
|
||||||
if address is None:
|
if address is None:
|
||||||
return await account.receiving.get_or_create_usable_address()
|
return await account.receiving.get_or_create_usable_address()
|
||||||
self.ledger.is_valid_address(address)
|
self.valid_address_or_error(address)
|
||||||
return address
|
return address
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -2965,6 +2922,23 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise ValueError(f"Invalid value for '{argument}': {e.args[0]}")
|
raise ValueError(f"Invalid value for '{argument}': {e.args[0]}")
|
||||||
|
|
||||||
|
async def resolve(self, *uris, **kwargs):
|
||||||
|
page = kwargs.get('page', 0)
|
||||||
|
page_size = kwargs.get('page_size', 10)
|
||||||
|
ledger: MainNetLedger = self.default_account.ledger
|
||||||
|
results = await ledger.resolve(page, page_size, *uris)
|
||||||
|
if 'error' not in results:
|
||||||
|
await self.storage.save_claims_for_resolve([
|
||||||
|
value for value in results.values() if 'error' not in value
|
||||||
|
])
|
||||||
|
return results
|
||||||
|
|
||||||
|
async def get_claims_for_name(self, name: str):
|
||||||
|
response = await self.ledger.network.get_claims_for_name(name)
|
||||||
|
resolutions = await self.resolve(*(f"{claim['name']}#{claim['claim_id']}" for claim in response['claims']))
|
||||||
|
response['claims'] = [value.get('claim', value.get('certificate')) for value in resolutions.values()]
|
||||||
|
return response
|
||||||
|
|
||||||
def _old_get_temp_claim_info(self, tx, txo, address, claim_dict, name, bid):
|
def _old_get_temp_claim_info(self, tx, txo, address, claim_dict, name, bid):
|
||||||
return {
|
return {
|
||||||
"claim_id": txo.claim_id,
|
"claim_id": txo.claim_id,
|
||||||
|
|
|
@ -398,7 +398,7 @@ class StreamManager:
|
||||||
raise ResolveError("cannot download a channel claim, specify a /path")
|
raise ResolveError("cannot download a channel claim, specify a /path")
|
||||||
|
|
||||||
# resolve the claim
|
# resolve the claim
|
||||||
resolved = (await self.wallet.resolve(uri)).get(uri, {})
|
resolved = (await self.wallet.ledger.resolve(0, 10, uri)).get(uri, {})
|
||||||
resolved = resolved if 'value' in resolved else resolved.get('claim')
|
resolved = resolved if 'value' in resolved else resolved.get('claim')
|
||||||
|
|
||||||
if not resolved:
|
if not resolved:
|
||||||
|
|
|
@ -183,7 +183,7 @@ class Account(BaseAccount):
|
||||||
return super().get_balance(confirmations, **constraints)
|
return super().get_balance(confirmations, **constraints)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_private_key_from_seed(cls, ledger: 'baseledger.BaseLedger', seed: str, password: str):
|
def get_private_key_from_seed(cls, ledger: 'ledger.MainNetLedger', seed: str, password: str):
|
||||||
return super().get_private_key_from_seed(
|
return super().get_private_key_from_seed(
|
||||||
ledger, seed, password or 'lbryum'
|
ledger, seed, password or 'lbryum'
|
||||||
)
|
)
|
||||||
|
@ -241,26 +241,5 @@ class Account(BaseAccount):
|
||||||
def get_support_count(self, **constraints):
|
def get_support_count(self, **constraints):
|
||||||
return self.ledger.db.get_support_count(account=self, **constraints)
|
return self.ledger.db.get_support_count(account=self, **constraints)
|
||||||
|
|
||||||
async def send_to_addresses(self, amount, addresses, broadcast=False):
|
|
||||||
tx_class = self.ledger.transaction_class
|
|
||||||
tx = await tx_class.create(
|
|
||||||
inputs=[],
|
|
||||||
outputs=[
|
|
||||||
tx_class.output_class.pay_pubkey_hash(amount, self.ledger.address_to_hash160(address))
|
|
||||||
for address in addresses
|
|
||||||
],
|
|
||||||
funding_accounts=[self],
|
|
||||||
change_account=self
|
|
||||||
)
|
|
||||||
|
|
||||||
if broadcast:
|
|
||||||
await self.ledger.broadcast(tx)
|
|
||||||
else:
|
|
||||||
await self.ledger.release_outputs(
|
|
||||||
[txi.txo_ref.txo for txi in tx.inputs]
|
|
||||||
)
|
|
||||||
|
|
||||||
return tx
|
|
||||||
|
|
||||||
async def release_all_outputs(self):
|
async def release_all_outputs(self):
|
||||||
await self.ledger.db.release_all_outputs(self)
|
await self.ledger.db.release_all_outputs(self)
|
||||||
|
|
|
@ -18,25 +18,6 @@ from lbrynet.wallet.dewies import dewies_to_lbc
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ReservedPoints:
|
|
||||||
def __init__(self, identifier, amount):
|
|
||||||
self.identifier = identifier
|
|
||||||
self.amount = amount
|
|
||||||
|
|
||||||
|
|
||||||
class BackwardsCompatibleNetwork:
|
|
||||||
def __init__(self, manager):
|
|
||||||
self.manager = manager
|
|
||||||
|
|
||||||
def get_local_height(self):
|
|
||||||
for ledger in self.manager.ledgers.values():
|
|
||||||
assert isinstance(ledger, MainNetLedger)
|
|
||||||
return ledger.headers.height
|
|
||||||
|
|
||||||
def get_server_height(self):
|
|
||||||
return self.get_local_height()
|
|
||||||
|
|
||||||
|
|
||||||
class LbryWalletManager(BaseWalletManager):
|
class LbryWalletManager(BaseWalletManager):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -47,14 +28,6 @@ class LbryWalletManager(BaseWalletManager):
|
||||||
def db(self) -> WalletDatabase:
|
def db(self) -> WalletDatabase:
|
||||||
return self.ledger.db
|
return self.ledger.db
|
||||||
|
|
||||||
@property
|
|
||||||
def wallet(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
@property
|
|
||||||
def network(self):
|
|
||||||
return BackwardsCompatibleNetwork(self)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def use_encryption(self):
|
def use_encryption(self):
|
||||||
return self.default_account.serialize_encrypted
|
return self.default_account.serialize_encrypted
|
||||||
|
@ -214,46 +187,12 @@ class LbryWalletManager(BaseWalletManager):
|
||||||
def get_unused_address(self):
|
def get_unused_address(self):
|
||||||
return self.default_account.receiving.get_or_create_usable_address()
|
return self.default_account.receiving.get_or_create_usable_address()
|
||||||
|
|
||||||
def get_new_address(self):
|
|
||||||
return self.get_unused_address()
|
|
||||||
|
|
||||||
def reserve_points(self, address, amount: int):
|
|
||||||
# TODO: check if we have enough to cover amount
|
|
||||||
return ReservedPoints(address, amount)
|
|
||||||
|
|
||||||
async def send_amount_to_address(self, amount: int, destination_address: bytes, account=None):
|
async def send_amount_to_address(self, amount: int, destination_address: bytes, account=None):
|
||||||
account = account or self.default_account
|
account = account or self.default_account
|
||||||
tx = await Transaction.pay(amount, destination_address, [account], account)
|
tx = await Transaction.pay(amount, destination_address, [account], account)
|
||||||
await account.ledger.broadcast(tx)
|
await account.ledger.broadcast(tx)
|
||||||
return tx
|
return tx
|
||||||
|
|
||||||
def send_points_to_address(self, reserved: ReservedPoints, amount: int, account=None):
|
|
||||||
destination_address: bytes = reserved.identifier.encode('latin1')
|
|
||||||
return self.send_amount_to_address(amount, destination_address, account)
|
|
||||||
|
|
||||||
async def resolve(self, *uris, **kwargs):
|
|
||||||
page = kwargs.get('page', 0)
|
|
||||||
page_size = kwargs.get('page_size', 10)
|
|
||||||
ledger: MainNetLedger = self.default_account.ledger
|
|
||||||
results = await ledger.resolve(page, page_size, *uris)
|
|
||||||
if 'error' not in results:
|
|
||||||
await self.old_db.save_claims_for_resolve([
|
|
||||||
value for value in results.values() if 'error' not in value
|
|
||||||
])
|
|
||||||
return results
|
|
||||||
|
|
||||||
async def get_claims_for_name(self, name: str):
|
|
||||||
response = await self.ledger.network.get_claims_for_name(name)
|
|
||||||
resolutions = await self.resolve(*(f"{claim['name']}#{claim['claim_id']}" for claim in response['claims']))
|
|
||||||
response['claims'] = [value.get('claim', value.get('certificate')) for value in resolutions.values()]
|
|
||||||
return response
|
|
||||||
|
|
||||||
async def address_is_mine(self, unknown_address, account):
|
|
||||||
match = await self.ledger.db.get_address(address=unknown_address, account=account)
|
|
||||||
if match is not None:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def get_transaction(self, txid):
|
async def get_transaction(self, txid):
|
||||||
tx = await self.db.get_transaction(txid=txid)
|
tx = await self.db.get_transaction(txid=txid)
|
||||||
if not tx:
|
if not tx:
|
||||||
|
@ -364,36 +303,6 @@ class LbryWalletManager(BaseWalletManager):
|
||||||
history.append(item)
|
history.append(item)
|
||||||
return history
|
return history
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_utxos(account: BaseAccount):
|
|
||||||
return account.get_utxos()
|
|
||||||
|
|
||||||
async def abandon_claim(self, claim_id, txid, nout, account):
|
|
||||||
claim = await account.get_claim(claim_id=claim_id, txid=txid, nout=nout)
|
|
||||||
if not claim:
|
|
||||||
raise Exception('No claim found for the specified claim_id or txid:nout')
|
|
||||||
|
|
||||||
tx = await Transaction.abandon(claim, [account], account)
|
|
||||||
await account.ledger.broadcast(tx)
|
|
||||||
# TODO: release reserved tx outputs in case anything fails by this point
|
|
||||||
return tx
|
|
||||||
|
|
||||||
def update_peer_address(self, peer, address):
|
|
||||||
pass # TODO: Data payments is disabled
|
|
||||||
|
|
||||||
def get_unused_address_for_peer(self, peer):
|
|
||||||
# TODO: Data payments is disabled
|
|
||||||
return self.get_unused_address()
|
|
||||||
|
|
||||||
def add_expected_payment(self, peer, amount):
|
|
||||||
pass # TODO: Data payments is disabled
|
|
||||||
|
|
||||||
def send_points(self, reserved_points, amount):
|
|
||||||
pass # TODO: Data payments is disabled
|
|
||||||
|
|
||||||
def cancel_point_reservation(self, reserved_points):
|
|
||||||
pass # fixme: disabled for now.
|
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
for wallet in self.wallets:
|
for wallet in self.wallets:
|
||||||
wallet.save()
|
wallet.save()
|
||||||
|
|
|
@ -159,6 +159,85 @@ class ChannelCommands(CommandTestCase):
|
||||||
self.assertIsNotNone(txo.private_key)
|
self.assertIsNotNone(txo.private_key)
|
||||||
|
|
||||||
|
|
||||||
|
class SupportCommands(CommandTestCase):
|
||||||
|
|
||||||
|
async def test_regular_supports_and_tip_supports(self):
|
||||||
|
# account2 will be used to send tips and supports to account1
|
||||||
|
account2_id = (await self.daemon.jsonrpc_account_create('second account'))['id']
|
||||||
|
account2 = self.daemon.get_account_or_error(account2_id)
|
||||||
|
|
||||||
|
# send account2 5 LBC out of the 10 LBC in account1
|
||||||
|
result = await self.out(self.daemon.jsonrpc_account_send(
|
||||||
|
'5.0', await self.daemon.jsonrpc_address_unused(account2_id)
|
||||||
|
))
|
||||||
|
await self.on_transaction_dict(result)
|
||||||
|
|
||||||
|
# account1 and account2 balances:
|
||||||
|
await self.assertBalance(self.account, '4.999876')
|
||||||
|
await self.assertBalance(account2, '5.0')
|
||||||
|
|
||||||
|
# create the claim we'll be tipping and supporting
|
||||||
|
tx = await self.create_claim()
|
||||||
|
claim_id = tx['outputs'][0]['']
|
||||||
|
|
||||||
|
# account1 and account2 balances:
|
||||||
|
await self.assertBalance(self.account, '3.979769')
|
||||||
|
await self.assertBalance(account2, '5.0')
|
||||||
|
|
||||||
|
# send a tip to the claim using account2
|
||||||
|
tip = await self.out(
|
||||||
|
self.daemon.jsonrpc_claim_tip(claim['claim_id'], '1.0', account2_id)
|
||||||
|
)
|
||||||
|
await self.on_transaction_dict(tip)
|
||||||
|
await self.generate(1)
|
||||||
|
await self.on_transaction_dict(tip)
|
||||||
|
|
||||||
|
# tips don't affect balance so account1 balance is same but account2 balance went down
|
||||||
|
self.assertEqual('3.979769', await self.daemon.jsonrpc_account_balance())
|
||||||
|
self.assertEqual('3.9998585', await self.daemon.jsonrpc_account_balance(account2_id))
|
||||||
|
|
||||||
|
# verify that the incoming tip is marked correctly as is_tip=True in account1
|
||||||
|
txs = await self.out(self.daemon.jsonrpc_transaction_list())
|
||||||
|
self.assertEqual(len(txs[0]['support_info']), 1)
|
||||||
|
self.assertEqual(txs[0]['support_info'][0]['balance_delta'], '1.0')
|
||||||
|
self.assertEqual(txs[0]['support_info'][0]['claim_id'], claim['claim_id'])
|
||||||
|
self.assertEqual(txs[0]['support_info'][0]['is_tip'], True)
|
||||||
|
self.assertEqual(txs[0]['value'], '1.0')
|
||||||
|
self.assertEqual(txs[0]['fee'], '0.0')
|
||||||
|
|
||||||
|
# verify that the outgoing tip is marked correctly as is_tip=True in account2
|
||||||
|
txs2 = await self.out(
|
||||||
|
self.daemon.jsonrpc_transaction_list(account2_id)
|
||||||
|
)
|
||||||
|
self.assertEqual(len(txs2[0]['support_info']), 1)
|
||||||
|
self.assertEqual(txs2[0]['support_info'][0]['balance_delta'], '-1.0')
|
||||||
|
self.assertEqual(txs2[0]['support_info'][0]['claim_id'], claim['claim_id'])
|
||||||
|
self.assertEqual(txs2[0]['support_info'][0]['is_tip'], True)
|
||||||
|
self.assertEqual(txs2[0]['value'], '-1.0')
|
||||||
|
self.assertEqual(txs2[0]['fee'], '-0.0001415')
|
||||||
|
|
||||||
|
# send a support to the claim using account2
|
||||||
|
support = await self.out(
|
||||||
|
self.daemon.jsonrpc_claim_new_support('hovercraft', claim['claim_id'], '2.0', account2_id)
|
||||||
|
)
|
||||||
|
await self.on_transaction_dict(support)
|
||||||
|
await self.generate(1)
|
||||||
|
await self.on_transaction_dict(support)
|
||||||
|
|
||||||
|
# account2 balance went down ~2
|
||||||
|
self.assertEqual('3.979769', await self.daemon.jsonrpc_account_balance())
|
||||||
|
self.assertEqual('1.999717', await self.daemon.jsonrpc_account_balance(account2_id))
|
||||||
|
|
||||||
|
# verify that the outgoing support is marked correctly as is_tip=False in account2
|
||||||
|
txs2 = await self.out(self.daemon.jsonrpc_transaction_list(account2_id))
|
||||||
|
self.assertEqual(len(txs2[0]['support_info']), 1)
|
||||||
|
self.assertEqual(txs2[0]['support_info'][0]['balance_delta'], '-2.0')
|
||||||
|
self.assertEqual(txs2[0]['support_info'][0]['claim_id'], claim['claim_id'])
|
||||||
|
self.assertEqual(txs2[0]['support_info'][0]['is_tip'], False)
|
||||||
|
self.assertEqual(txs2[0]['value'], '0.0')
|
||||||
|
self.assertEqual(txs2[0]['fee'], '-0.0001415')
|
||||||
|
|
||||||
|
|
||||||
class ClaimCommands(CommandTestCase):
|
class ClaimCommands(CommandTestCase):
|
||||||
|
|
||||||
async def test_create_claim_names(self):
|
async def test_create_claim_names(self):
|
||||||
|
@ -488,80 +567,6 @@ class ClaimCommands(CommandTestCase):
|
||||||
out_of_bounds = await self.out(self.daemon.jsonrpc_claim_list_by_channel(2, page_size=20, uri='@abc'))
|
out_of_bounds = await self.out(self.daemon.jsonrpc_claim_list_by_channel(2, page_size=20, uri='@abc'))
|
||||||
self.assertEqual(out_of_bounds['error'], 'claim 20 greater than max 12')
|
self.assertEqual(out_of_bounds['error'], 'claim 20 greater than max 12')
|
||||||
|
|
||||||
async def test_regular_supports_and_tip_supports(self):
|
|
||||||
# account2 will be used to send tips and supports to account1
|
|
||||||
account2_id = (await self.daemon.jsonrpc_account_create('second account'))['id']
|
|
||||||
|
|
||||||
# send account2 5 LBC out of the 10 LBC in account1
|
|
||||||
result = await self.out(self.daemon.jsonrpc_wallet_send(
|
|
||||||
'5.0', await self.daemon.jsonrpc_address_unused(account2_id)
|
|
||||||
))
|
|
||||||
await self.confirm_tx(result['txid'])
|
|
||||||
|
|
||||||
# account1 and account2 balances:
|
|
||||||
self.assertEqual('4.999876', await self.daemon.jsonrpc_account_balance())
|
|
||||||
self.assertEqual('5.0', await self.daemon.jsonrpc_account_balance(account2_id))
|
|
||||||
|
|
||||||
# create the claim we'll be tipping and supporting
|
|
||||||
claim = await self.make_claim()
|
|
||||||
|
|
||||||
# account1 and account2 balances:
|
|
||||||
self.assertEqual('3.979769', await self.daemon.jsonrpc_account_balance())
|
|
||||||
self.assertEqual('5.0', await self.daemon.jsonrpc_account_balance(account2_id))
|
|
||||||
|
|
||||||
# send a tip to the claim using account2
|
|
||||||
tip = await self.out(
|
|
||||||
self.daemon.jsonrpc_claim_tip(claim['claim_id'], '1.0', account2_id)
|
|
||||||
)
|
|
||||||
await self.on_transaction_dict(tip)
|
|
||||||
await self.generate(1)
|
|
||||||
await self.on_transaction_dict(tip)
|
|
||||||
|
|
||||||
# tips don't affect balance so account1 balance is same but account2 balance went down
|
|
||||||
self.assertEqual('3.979769', await self.daemon.jsonrpc_account_balance())
|
|
||||||
self.assertEqual('3.9998585', await self.daemon.jsonrpc_account_balance(account2_id))
|
|
||||||
|
|
||||||
# verify that the incoming tip is marked correctly as is_tip=True in account1
|
|
||||||
txs = await self.out(self.daemon.jsonrpc_transaction_list())
|
|
||||||
self.assertEqual(len(txs[0]['support_info']), 1)
|
|
||||||
self.assertEqual(txs[0]['support_info'][0]['balance_delta'], '1.0')
|
|
||||||
self.assertEqual(txs[0]['support_info'][0]['claim_id'], claim['claim_id'])
|
|
||||||
self.assertEqual(txs[0]['support_info'][0]['is_tip'], True)
|
|
||||||
self.assertEqual(txs[0]['value'], '1.0')
|
|
||||||
self.assertEqual(txs[0]['fee'], '0.0')
|
|
||||||
|
|
||||||
# verify that the outgoing tip is marked correctly as is_tip=True in account2
|
|
||||||
txs2 = await self.out(
|
|
||||||
self.daemon.jsonrpc_transaction_list(account2_id)
|
|
||||||
)
|
|
||||||
self.assertEqual(len(txs2[0]['support_info']), 1)
|
|
||||||
self.assertEqual(txs2[0]['support_info'][0]['balance_delta'], '-1.0')
|
|
||||||
self.assertEqual(txs2[0]['support_info'][0]['claim_id'], claim['claim_id'])
|
|
||||||
self.assertEqual(txs2[0]['support_info'][0]['is_tip'], True)
|
|
||||||
self.assertEqual(txs2[0]['value'], '-1.0')
|
|
||||||
self.assertEqual(txs2[0]['fee'], '-0.0001415')
|
|
||||||
|
|
||||||
# send a support to the claim using account2
|
|
||||||
support = await self.out(
|
|
||||||
self.daemon.jsonrpc_claim_new_support('hovercraft', claim['claim_id'], '2.0', account2_id)
|
|
||||||
)
|
|
||||||
await self.on_transaction_dict(support)
|
|
||||||
await self.generate(1)
|
|
||||||
await self.on_transaction_dict(support)
|
|
||||||
|
|
||||||
# account2 balance went down ~2
|
|
||||||
self.assertEqual('3.979769', await self.daemon.jsonrpc_account_balance())
|
|
||||||
self.assertEqual('1.999717', await self.daemon.jsonrpc_account_balance(account2_id))
|
|
||||||
|
|
||||||
# verify that the outgoing support is marked correctly as is_tip=False in account2
|
|
||||||
txs2 = await self.out(self.daemon.jsonrpc_transaction_list(account2_id))
|
|
||||||
self.assertEqual(len(txs2[0]['support_info']), 1)
|
|
||||||
self.assertEqual(txs2[0]['support_info'][0]['balance_delta'], '-2.0')
|
|
||||||
self.assertEqual(txs2[0]['support_info'][0]['claim_id'], claim['claim_id'])
|
|
||||||
self.assertEqual(txs2[0]['support_info'][0]['is_tip'], False)
|
|
||||||
self.assertEqual(txs2[0]['value'], '0.0')
|
|
||||||
self.assertEqual(txs2[0]['fee'], '-0.0001415')
|
|
||||||
|
|
||||||
async def test_normalization_resolution(self):
|
async def test_normalization_resolution(self):
|
||||||
|
|
||||||
# this test assumes that the lbrycrd forks normalization at height == 250 on regtest
|
# this test assumes that the lbrycrd forks normalization at height == 250 on regtest
|
||||||
|
|
|
@ -39,7 +39,7 @@ def get_test_daemon(conf: Config, with_fee=False):
|
||||||
daemon.payment_rate_manager = OnlyFreePaymentsManager()
|
daemon.payment_rate_manager = OnlyFreePaymentsManager()
|
||||||
daemon.wallet_manager = mock.Mock(spec=LbryWalletManager)
|
daemon.wallet_manager = mock.Mock(spec=LbryWalletManager)
|
||||||
daemon.wallet_manager.wallet = mock.Mock(spec=Wallet)
|
daemon.wallet_manager.wallet = mock.Mock(spec=Wallet)
|
||||||
daemon.wallet_manager.wallet.use_encryption = False
|
daemon.wallet_manager.use_encryption = False
|
||||||
daemon.wallet_manager.network = FakeNetwork()
|
daemon.wallet_manager.network = FakeNetwork()
|
||||||
daemon.storage = mock.Mock(spec=SQLiteStorage)
|
daemon.storage = mock.Mock(spec=SQLiteStorage)
|
||||||
market_feeds = [BTCLBCFeed(), USDBTCFeed()]
|
market_feeds = [BTCLBCFeed(), USDBTCFeed()]
|
||||||
|
@ -66,7 +66,7 @@ def get_test_daemon(conf: Config, with_fee=False):
|
||||||
metadata.update(
|
metadata.update(
|
||||||
{"fee": {"USD": {"address": "bQ6BGboPV2SpTMEP7wLNiAcnsZiH8ye6eA", "amount": 0.75}}})
|
{"fee": {"USD": {"address": "bQ6BGboPV2SpTMEP7wLNiAcnsZiH8ye6eA", "amount": 0.75}}})
|
||||||
migrated = smart_decode(json.dumps(metadata))
|
migrated = smart_decode(json.dumps(metadata))
|
||||||
daemon._resolve = daemon.wallet_manager.resolve = lambda *_: defer.succeed(
|
daemon._resolve = daemon.resolve = lambda *_: defer.succeed(
|
||||||
{"test": {'claim': {'value': migrated.claim_dict}}})
|
{"test": {'claim': {'value': migrated.claim_dict}}})
|
||||||
return daemon
|
return daemon
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue