lbry-sdk/lbrynet/extras/daemon/json_response_encoder.py

120 lines
4.6 KiB
Python
Raw Normal View History

import logging
2018-08-16 01:23:06 +02:00
from decimal import Decimal
from binascii import hexlify
from datetime import datetime
from json import JSONEncoder
2018-10-26 00:54:07 +02:00
from ecdsa import BadSignatureError
2019-03-20 22:31:00 +01:00
from lbrynet.schema.claim import Claim
2019-03-20 06:46:23 +01:00
from lbrynet.wallet.ledger import MainNetLedger
from lbrynet.wallet.transaction import Transaction, Output
from lbrynet.wallet.dewies import dewies_to_lbc
2018-08-16 01:23:06 +02:00
log = logging.getLogger(__name__)
2018-08-16 01:23:06 +02:00
class JSONResponseEncoder(JSONEncoder):
def __init__(self, *args, ledger: MainNetLedger, **kwargs):
2018-08-16 01:23:06 +02:00
super().__init__(*args, **kwargs)
self.ledger = ledger
2018-08-16 17:24:22 +02:00
def default(self, obj): # pylint: disable=method-hidden
2018-08-16 01:23:06 +02:00
if isinstance(obj, Transaction):
return self.encode_transaction(obj)
if isinstance(obj, Output):
return self.encode_output(obj)
2019-03-20 22:31:00 +01:00
if isinstance(obj, Claim):
2019-03-22 08:38:54 +01:00
claim_dict = obj.to_dict()
if obj.is_stream:
claim_dict['stream']['sd_hash'] = obj.stream.sd_hash
fee = claim_dict['stream'].get('fee', {})
if 'address' in fee:
fee['address'] = obj.stream.fee.address
if 'amount' in fee:
fee['amount'] = obj.stream.fee.amount
if 'languages' in claim_dict['stream']:
claim_dict['stream']['languages'] = obj.stream.langtags
elif obj.is_channel:
claim_dict['channel']['public_key'] = obj.channel.public_key
if 'languages' in claim_dict['channel']:
claim_dict['channel']['languages'] = obj.channel.langtags
2019-03-22 08:38:54 +01:00
return claim_dict
2018-08-16 01:23:06 +02:00
if isinstance(obj, datetime):
return obj.strftime("%Y%m%dT%H:%M:%S")
if isinstance(obj, Decimal):
return float(obj)
2018-08-16 21:55:33 +02:00
if isinstance(obj, bytes):
return obj.decode()
2018-08-16 01:23:06 +02:00
return super().default(obj)
def encode_transaction(self, tx):
return {
'txid': tx.id,
'height': tx.height,
2018-08-16 01:23:06 +02:00
'inputs': [self.encode_input(txo) for txo in tx.inputs],
'outputs': [self.encode_output(txo) for txo in tx.outputs],
2018-10-03 22:38:47 +02:00
'total_input': dewies_to_lbc(tx.input_sum),
'total_output': dewies_to_lbc(tx.input_sum - tx.fee),
'total_fee': dewies_to_lbc(tx.fee),
2018-08-16 01:23:06 +02:00
'hex': hexlify(tx.raw).decode(),
}
def encode_output(self, txo, check_signature=True):
tx_height = txo.tx_ref.height
best_height = self.ledger.headers.height
output = {
2018-09-19 15:58:50 +02:00
'txid': txo.tx_ref.id,
2018-08-16 01:23:06 +02:00
'nout': txo.position,
2018-10-03 22:38:47 +02:00
'amount': dewies_to_lbc(txo.amount),
2018-09-19 15:58:50 +02:00
'address': txo.get_address(self.ledger),
'height': tx_height,
'confirmations': (best_height+1) - tx_height if tx_height > 0 else tx_height
2018-08-16 01:23:06 +02:00
}
if txo.is_change is not None:
output['is_change'] = txo.is_change
2018-10-05 15:02:02 +02:00
if txo.is_my_account is not None:
output['is_mine'] = txo.is_my_account
2018-10-05 15:02:02 +02:00
if txo.script.is_claim_involved:
output.update({
'name': txo.claim_name,
'claim_id': txo.claim_id,
'permanent_url': txo.permanent_url,
})
if txo.script.is_claim_name or txo.script.is_update_claim:
claim = txo.claim
2019-03-22 08:38:54 +01:00
output['value'] = claim
2019-03-20 06:46:23 +01:00
if claim.is_signed:
output['valid_signature'] = None
if check_signature and txo.channel is not None:
2018-10-18 03:10:23 +02:00
output['channel_name'] = txo.channel.claim_name
2018-10-26 00:54:07 +02:00
try:
2019-03-20 06:46:23 +01:00
output['valid_signature'] = txo.is_signed_by(txo.channel, self.ledger)
2018-10-26 00:54:07 +02:00
except BadSignatureError:
output['valid_signature'] = False
except ValueError:
2018-10-30 18:48:25 +01:00
log.exception(
'txo.id: %s, txo.channel.id:%s, output: %s',
txo.id, txo.channel.id, output
)
output['valid_signature'] = False
2018-10-05 15:02:02 +02:00
if txo.script.is_claim_name:
output['type'] = 'claim'
2018-10-05 15:02:02 +02:00
elif txo.script.is_update_claim:
output['type'] = 'update'
2018-10-05 15:02:02 +02:00
elif txo.script.is_support_claim:
output['type'] = 'support'
else:
output['type'] = 'basic'
return output
2018-08-16 01:23:06 +02:00
def encode_input(self, txi):
return self.encode_output(txi.txo_ref.txo, False) if txi.txo_ref.txo is not None else {
'txid': txi.txo_ref.tx_ref.id,
'nout': txi.txo_ref.position
}