forked from LBRYCommunity/lbry-sdk
transaction_list produces same output as old version
This commit is contained in:
parent
1c2849235c
commit
b16c36b55f
4 changed files with 117 additions and 20 deletions
|
@ -16,6 +16,7 @@ from twisted.internet.task import LoopingCall
|
||||||
from twisted.python.failure import Failure
|
from twisted.python.failure import Failure
|
||||||
|
|
||||||
from torba.constants import COIN
|
from torba.constants import COIN
|
||||||
|
from torba.baseaccount import SingleKey, HierarchicalDeterministic
|
||||||
|
|
||||||
from lbryschema.claim import ClaimDict
|
from lbryschema.claim import ClaimDict
|
||||||
from lbryschema.uri import parse_lbry_uri
|
from lbryschema.uri import parse_lbry_uri
|
||||||
|
@ -46,7 +47,7 @@ from lbrynet.core.Peer import Peer
|
||||||
from lbrynet.core.SinglePeerDownloader import SinglePeerDownloader
|
from lbrynet.core.SinglePeerDownloader import SinglePeerDownloader
|
||||||
from lbrynet.core.client.StandaloneBlobDownloader import StandaloneBlobDownloader
|
from lbrynet.core.client.StandaloneBlobDownloader import StandaloneBlobDownloader
|
||||||
from lbrynet.wallet.account import Account as LBCAccount
|
from lbrynet.wallet.account import Account as LBCAccount
|
||||||
from torba.baseaccount import SingleKey, HierarchicalDeterministic
|
from lbrynet.wallet.manager import LbryWalletManager
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
requires = AuthJSONRPCServer.requires
|
requires = AuthJSONRPCServer.requires
|
||||||
|
@ -226,7 +227,7 @@ class Daemon(AuthJSONRPCServer):
|
||||||
# TODO: delete these, get the components where needed
|
# TODO: delete these, get the components where needed
|
||||||
self.storage = None
|
self.storage = None
|
||||||
self.dht_node = None
|
self.dht_node = None
|
||||||
self.wallet_manager = None
|
self.wallet_manager: LbryWalletManager = None
|
||||||
self.sd_identifier = None
|
self.sd_identifier = None
|
||||||
self.file_manager = None
|
self.file_manager = None
|
||||||
self.exchange_rate_manager = None
|
self.exchange_rate_manager = None
|
||||||
|
|
|
@ -64,7 +64,7 @@ class WalletDatabase(BaseDatabase):
|
||||||
SELECT tx.txid, txo.position, txo.claim_id
|
SELECT tx.txid, txo.position, txo.claim_id
|
||||||
FROM txo JOIN tx ON tx.txid=txo.txid
|
FROM txo JOIN tx ON tx.txid=txo.txid
|
||||||
WHERE {} AND (is_claim OR is_update)
|
WHERE {} AND (is_claim OR is_update)
|
||||||
GROUP BY txo.claim_id ORDER BY tx.height DESC;
|
GROUP BY txo.claim_id ORDER BY tx.height DESC, tx.position ASC;
|
||||||
""".format(filter_sql), (filter_value,)
|
""".format(filter_sql), (filter_value,)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -89,23 +89,30 @@ class WalletDatabase(BaseDatabase):
|
||||||
filter_sql = "claim_id=?"
|
filter_sql = "claim_id=?"
|
||||||
filter_value = (claim_id,)
|
filter_value = (claim_id,)
|
||||||
else:
|
else:
|
||||||
filter_sql = "txo.txid=? AND position=?"
|
filter_sql = "txo.txid=? AND txo.position=?"
|
||||||
filter_value = (txid, nout)
|
filter_value = (txid, nout)
|
||||||
utxos = yield self.db.runQuery(
|
utxos = yield self.db.runQuery(
|
||||||
"""
|
"""
|
||||||
SELECT amount, script, txo.txid, position
|
SELECT amount, script, txo.txid, txo.position, account
|
||||||
FROM txo JOIN tx ON tx.txid=txo.txid
|
FROM txo
|
||||||
WHERE {} AND (is_claim OR is_update) AND txoid NOT IN (SELECT txoid FROM txi)
|
JOIN tx ON tx.txid=txo.txid
|
||||||
ORDER BY tx.height DESC LIMIT 1;
|
JOIN pubkey_address ON pubkey_address.address=txo.address
|
||||||
|
WHERE {}
|
||||||
|
AND (is_claim OR is_update)
|
||||||
|
AND txoid NOT IN (SELECT txoid FROM txi)
|
||||||
|
ORDER BY tx.height DESC, tx.position ASC LIMIT 1;
|
||||||
""".format(filter_sql), filter_value
|
""".format(filter_sql), filter_value
|
||||||
)
|
)
|
||||||
output_class = account.ledger.transaction_class.output_class
|
output_class = account.ledger.transaction_class.output_class
|
||||||
|
account_id = account.public_key.address
|
||||||
return [
|
return [
|
||||||
output_class(
|
output_class(
|
||||||
values[0],
|
values[0],
|
||||||
output_class.script_class(values[1]),
|
output_class.script_class(values[1]),
|
||||||
TXRefImmutable.from_id(values[2]),
|
TXRefImmutable.from_id(values[2]),
|
||||||
position=values[3]
|
position=values[3],
|
||||||
|
is_change=False,
|
||||||
|
is_my_account=values[4] == account_id
|
||||||
) for values in utxos
|
) for values in utxos
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -113,11 +120,15 @@ class WalletDatabase(BaseDatabase):
|
||||||
def get_claims(self, account):
|
def get_claims(self, account):
|
||||||
utxos = yield self.db.runQuery(
|
utxos = yield self.db.runQuery(
|
||||||
"""
|
"""
|
||||||
SELECT amount, script, txo.txid, position
|
SELECT amount, script, txo.txid, txo.position
|
||||||
FROM txo JOIN tx ON tx.txid=txo.txid
|
FROM txo
|
||||||
WHERE (is_claim OR is_update) AND txoid NOT IN (SELECT txoid FROM txi)
|
JOIN tx ON tx.txid=txo.txid
|
||||||
ORDER BY tx.height DESC;
|
JOIN pubkey_address ON pubkey_address.address=txo.address
|
||||||
"""
|
WHERE (is_claim OR is_update)
|
||||||
|
AND txoid NOT IN (SELECT txoid FROM txi)
|
||||||
|
AND account = :account
|
||||||
|
ORDER BY tx.height DESC, tx.position ASC;
|
||||||
|
""", {'account': account.public_key.address}
|
||||||
)
|
)
|
||||||
output_class = account.ledger.transaction_class.output_class
|
output_class = account.ledger.transaction_class.output_class
|
||||||
return [
|
return [
|
||||||
|
@ -125,6 +136,8 @@ class WalletDatabase(BaseDatabase):
|
||||||
values[0],
|
values[0],
|
||||||
output_class.script_class(values[1]),
|
output_class.script_class(values[1]),
|
||||||
TXRefImmutable.from_id(values[2]),
|
TXRefImmutable.from_id(values[2]),
|
||||||
position=values[3]
|
position=values[3],
|
||||||
|
is_change=False,
|
||||||
|
is_my_account=True
|
||||||
) for values in utxos
|
) for values in utxos
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import List
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from torba.basemanager import BaseWalletManager
|
from torba.basemanager import BaseWalletManager
|
||||||
|
@ -8,7 +11,7 @@ from torba.basemanager import BaseWalletManager
|
||||||
from lbryschema.claim import ClaimDict
|
from lbryschema.claim import ClaimDict
|
||||||
|
|
||||||
from .ledger import MainNetLedger
|
from .ledger import MainNetLedger
|
||||||
from .account import generate_certificate
|
from .account import BaseAccount, generate_certificate
|
||||||
from .transaction import Transaction
|
from .transaction import Transaction
|
||||||
from .database import WalletDatabase
|
from .database import WalletDatabase
|
||||||
|
|
||||||
|
@ -227,13 +230,62 @@ class LbryWalletManager(BaseWalletManager):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_transaction(self, txid):
|
def get_transaction(self, txid: str):
|
||||||
return self.default_account.ledger.get_transaction(txid)
|
return self.default_account.ledger.get_transaction(txid)
|
||||||
|
|
||||||
def get_history(self, account):
|
@staticmethod
|
||||||
return account.get_transactions()
|
@defer.inlineCallbacks
|
||||||
|
def get_history(account: BaseAccount):
|
||||||
|
headers = account.ledger.headers
|
||||||
|
txs: List[Transaction] = (yield account.get_transactions())
|
||||||
|
history = []
|
||||||
|
for tx in txs:
|
||||||
|
ts = headers[tx.height]['timestamp']
|
||||||
|
history.append({
|
||||||
|
'txid': tx.id,
|
||||||
|
'timestamp': ts,
|
||||||
|
'value': tx.net_account_balance,
|
||||||
|
'fee': tx.fee,
|
||||||
|
'date': datetime.fromtimestamp(ts).isoformat(' ')[:-3],
|
||||||
|
'confirmations': headers.height - tx.height,
|
||||||
|
'claim_info': [{
|
||||||
|
'address': txo.get_address(account.ledger),
|
||||||
|
'balance_delta': -txo.amount,
|
||||||
|
'amount': txo.amount,
|
||||||
|
'claim_id': txo.claim_id,
|
||||||
|
'claim_name': txo.claim_name,
|
||||||
|
'nout': txo.position
|
||||||
|
} for txo in tx.my_claim_outputs],
|
||||||
|
'update_info': [{
|
||||||
|
'address': txo.get_address(account.ledger),
|
||||||
|
'balance_delta': -txo.amount,
|
||||||
|
'amount': txo.amount,
|
||||||
|
'claim_id': txo.claim_id,
|
||||||
|
'claim_name': txo.claim_name,
|
||||||
|
'nout': txo.position
|
||||||
|
} for txo in tx.my_update_outputs],
|
||||||
|
'support_info': [{
|
||||||
|
'address': txo.get_address(account.ledger),
|
||||||
|
'balance_delta': -txo.amount,
|
||||||
|
'amount': txo.amount,
|
||||||
|
'claim_id': txo.claim_id,
|
||||||
|
'claim_name': txo.claim_name,
|
||||||
|
'is_tip': False, # TODO: need to add lookup
|
||||||
|
'nout': txo.position
|
||||||
|
} for txo in tx.my_support_outputs],
|
||||||
|
'abandon_info': [{
|
||||||
|
'address': txo.get_address(account.ledger),
|
||||||
|
'balance_delta': txo.amount,
|
||||||
|
'amount': txo.amount,
|
||||||
|
'claim_id': txo.claim_id,
|
||||||
|
'claim_name': txo.claim_name,
|
||||||
|
'nout': txo.position
|
||||||
|
} for txo in tx.my_abandon_outputs],
|
||||||
|
})
|
||||||
|
return history
|
||||||
|
|
||||||
def get_utxos(self, account):
|
@staticmethod
|
||||||
|
def get_utxos(account: BaseAccount):
|
||||||
return account.get_unspent_outputs()
|
return account.get_unspent_outputs()
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
|
|
|
@ -123,3 +123,34 @@ class Transaction(BaseTransaction):
|
||||||
@classmethod
|
@classmethod
|
||||||
def abandon(cls, claims: Iterable[Output], funding_accounts: Iterable[Account], change_account: Account):
|
def abandon(cls, claims: Iterable[Output], funding_accounts: Iterable[Account], change_account: Account):
|
||||||
return cls.create([Input.spend(txo) for txo in claims], [], funding_accounts, change_account)
|
return cls.create([Input.spend(txo) for txo in claims], [], funding_accounts, change_account)
|
||||||
|
|
||||||
|
def _filter_my_outputs(self, f):
|
||||||
|
for txo in self.outputs:
|
||||||
|
if txo.is_my_account and f(txo.script):
|
||||||
|
yield txo
|
||||||
|
|
||||||
|
@property
|
||||||
|
def my_claim_outputs(self):
|
||||||
|
return self._filter_my_outputs(lambda s: s.is_claim_name)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def my_update_outputs(self):
|
||||||
|
return self._filter_my_outputs(lambda s: s.is_update_claim)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def my_support_outputs(self):
|
||||||
|
return self._filter_my_outputs(lambda s: s.is_support_claim)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def my_abandon_outputs(self):
|
||||||
|
for txi in self.inputs:
|
||||||
|
abandon = txi.txo_ref.txo
|
||||||
|
if abandon is not None and abandon.is_my_account and abandon.script.is_claim_involved:
|
||||||
|
is_update = False
|
||||||
|
if abandon.script.is_claim_name or abandon.script.is_update_claim:
|
||||||
|
for update in self.my_update_outputs:
|
||||||
|
if abandon.claim_id == update.claim_id:
|
||||||
|
is_update = True
|
||||||
|
break
|
||||||
|
if not is_update:
|
||||||
|
yield abandon
|
||||||
|
|
Loading…
Reference in a new issue