diff --git a/lbry/conf.py b/lbry/conf.py index 604cba086..bc23f0984 100644 --- a/lbry/conf.py +++ b/lbry/conf.py @@ -698,8 +698,6 @@ class Config(CLIConfig): ('lbrynet4.lbry.com', 4444) # ASIA ]) - comment_server = String("Comment server API URL", "https://comments.lbry.com/api/v2") - # blockchain blockchain_name = String("Blockchain name - lbrycrd_main, lbrycrd_regtest, or lbrycrd_testnet", 'lbrycrd_main') diff --git a/lbry/extras/daemon/comment_client.py b/lbry/extras/daemon/comment_client.py index c836978da..ec4a76192 100644 --- a/lbry/extras/daemon/comment_client.py +++ b/lbry/extras/daemon/comment_client.py @@ -4,7 +4,6 @@ import hashlib import binascii import ecdsa -from lbry import utils from lbry.crypto.hash import sha256 from lbry.wallet.transaction import Output @@ -18,20 +17,6 @@ def get_encoded_signature(signature): return ecdsa.util.sigencode_der(r, s, len(signature) * 4) -def cid2hash(claim_id: str) -> bytes: - return binascii.unhexlify(claim_id.encode())[::-1] - - -def is_comment_signed_by_channel(comment: dict, channel: Output, sign_comment_id=False): - if isinstance(channel, Output): - try: - signing_field = comment['comment_id'] if sign_comment_id else comment['comment'] - return verify(channel, signing_field.encode(), comment, cid2hash(comment['channel_id'])) - except KeyError: - pass - return False - - def verify(channel, data, signature, channel_hash=None): pieces = [ signature['signing_ts'].encode(), @@ -45,11 +30,6 @@ def verify(channel, data, signature, channel_hash=None): ) -def sign_comment(comment: dict, channel: Output, sign_comment_id=False): - signing_field = comment['comment_id'] if sign_comment_id else comment['comment'] - comment.update(sign(channel, signing_field.encode())) - - def sign(channel, data): timestamp = str(int(time.time())) pieces = [timestamp.encode(), channel.claim_hash, data] @@ -59,21 +39,3 @@ def sign(channel, data): 'signature': binascii.hexlify(signature).decode(), 'signing_ts': timestamp } - - -def sign_reaction(reaction: dict, channel: Output): - signing_field = reaction['channel_name'] - reaction.update(sign(channel, signing_field.encode())) - - -async def jsonrpc_post(url: str, method: str, params: dict = None, **kwargs) -> any: - params = params or {} - params.update(kwargs) - json_body = {'jsonrpc': '2.0', 'id': 1, 'method': method, 'params': params} - async with utils.aiohttp_request('POST', url, json=json_body) as response: - try: - result = await response.json() - return result['result'] if 'result' in result else result - except Exception as cte: - log.exception('Unable to decode response from server: %s', cte) - return await response.text() diff --git a/lbry/extras/daemon/daemon.py b/lbry/extras/daemon/daemon.py index b6a926079..2ea85c84b 100644 --- a/lbry/extras/daemon/daemon.py +++ b/lbry/extras/daemon/daemon.py @@ -5166,440 +5166,6 @@ class Daemon(metaclass=JSONRPCServerType): break return results - COMMENT_DOC = """ - View, create and abandon comments. - """ - - async def jsonrpc_comment_list(self, claim_id, parent_id=None, page=1, page_size=50, - include_replies=False, skip_validation=False, - is_channel_signature_valid=False, hidden=False, visible=False): - """ - List comments associated with a claim. - - Usage: - comment_list ( | --claim_id=) - [(--page= --page_size=)] - [--parent_id=] [--include_replies] - [--skip_validation] [--is_channel_signature_valid] - [--visible | --hidden] - - Options: - --claim_id= : (str) The claim on which the comment will be made on - --parent_id= : (str) CommentId of a specific thread you'd like to see - --page= : (int) The page you'd like to see in the comment list. - --page_size= : (int) The amount of comments that you'd like to retrieve - --skip_validation : (bool) Skip resolving comments to validate channel names - --include_replies : (bool) Whether or not you want to include replies in list - --is_channel_signature_valid : (bool) Only include comments with valid signatures. - [Warning: Paginated total size will not change, even - if list reduces] - --visible : (bool) Select only Visible Comments - --hidden : (bool) Select only Hidden Comments - - Returns: - (dict) Containing the list, and information about the paginated content: - { - "page": "Page number of the current items.", - "page_size": "Number of items to show on a page.", - "total_pages": "Total number of pages.", - "total_items": "Total number of items.", - "items": "A List of dict objects representing comments." - [ - { - "comment": (str) The actual string as inputted by the user, - "comment_id": (str) The Comment's unique identifier, - "channel_name": (str) Name of the channel this was posted under, prepended with a '@', - "channel_id": (str) The Channel Claim ID that this comment was posted under, - "signature": (str) The signature of the comment, - "channel_url": (str) Channel's URI in the ClaimTrie, - "parent_id": (str) Comment this is replying to, (None) if this is the root, - "timestamp": (int) The time at which comment was entered into the server at, in nanoseconds. - }, - ... - ] - } - """ - if hidden ^ visible: - result = await comment_client.jsonrpc_post( - self.conf.comment_server, - 'comment.List', - claim_id=claim_id, - visible=visible, - hidden=hidden, - page=page, - page_size=page_size - ) - else: - result = await comment_client.jsonrpc_post( - self.conf.comment_server, - 'comment.List', - claim_id=claim_id, - parent_id=parent_id, - page=page, - page_size=page_size, - top_level=not include_replies - ) - if not skip_validation: - for comment in result.get('items', []): - channel_url = comment.get('channel_url') - if not channel_url: - continue - resolve_response = await self.resolve([], [channel_url]) - if isinstance(resolve_response[channel_url], Output): - comment['is_channel_signature_valid'] = comment_client.is_comment_signed_by_channel( - comment, resolve_response[channel_url] - ) - else: - comment['is_channel_signature_valid'] = False - if is_channel_signature_valid: - result['items'] = [ - c for c in result.get('items', []) if c.get('is_channel_signature_valid', False) - ] - return result - - @requires(WALLET_COMPONENT) - async def jsonrpc_comment_create(self, comment, claim_id=None, parent_id=None, channel_account_id=None, - channel_name=None, channel_id=None, wallet_id=None): - """ - Create and associate a comment with a claim using your channel identity. - - Usage: - comment_create ( | --comment=) - ( | --claim_id=) [--parent_id=] - (--channel_id= | --channel_name=) - [--channel_account_id=...] [--wallet_id=] - - Options: - --comment= : (str) Comment to be made, should be at most 2000 characters. - --claim_id= : (str) The ID of the claim to comment on - --parent_id= : (str) The ID of a comment to make a response to - --channel_id= : (str) The ID of the channel you want to post under - --channel_name= : (str) The channel you want to post as, prepend with a '@' - --channel_account_id= : (str) one or more account ids for accounts to look in - for channel certificates, defaults to all accounts - --wallet_id= : (str) restrict operation to specific wallet - - Returns: - (dict) Comment object if successfully made, (None) otherwise - { - "comment": (str) The actual string as inputted by the user, - "comment_id": (str) The Comment's unique identifier, - "claim_id": (str) The claim commented on, - "channel_name": (str) Name of the channel this was posted under, prepended with a '@', - "channel_id": (str) The Channel Claim ID that this comment was posted under, - "is_pinned": (boolean) Channel owner has pinned this comment, - "signature": (str) The signature of the comment, - "signing_ts": (str) The timestamp used to sign the comment, - "channel_url": (str) Channel's URI in the ClaimTrie, - "parent_id": (str) Comment this is replying to, (None) if this is the root, - "timestamp": (int) The time at which comment was entered into the server at, in nanoseconds. - } - """ - wallet = self.wallet_manager.get_wallet_or_default(wallet_id) - channel = await self.get_channel_or_error( - wallet, channel_account_id, channel_id, channel_name, for_signing=True - ) - - comment_body = { - 'comment': comment.strip(), - 'claim_id': claim_id, - 'parent_id': parent_id, - 'channel_id': channel.claim_id, - 'channel_name': channel.claim_name, - } - comment_client.sign_comment(comment_body, channel) - - response = await comment_client.jsonrpc_post(self.conf.comment_server, 'comment.Create', comment_body) - response.update({ - 'is_claim_signature_valid': comment_client.is_comment_signed_by_channel(response, channel) - }) - return response - - @requires(WALLET_COMPONENT) - async def jsonrpc_comment_update(self, comment, comment_id, wallet_id=None): - """ - Edit a comment published as one of your channels. - - Usage: - comment_update ( | --comment=) - ( | --comment_id=) - [--wallet_id=] - - Options: - --comment= : (str) New comment replacing the old one - --comment_id= : (str) Hash identifying the comment to edit - --wallet_id= | --comment_id=) [--wallet_id=] - - Options: - --comment_id= : (str) The ID of the comment to be abandoned. - --wallet_id= (str): { - "abandoned": (bool) - } - } - """ - wallet = self.wallet_manager.get_wallet_or_default(wallet_id) - abandon_comment_body = {'comment_id': comment_id} - channel = await comment_client.jsonrpc_post( - self.conf.comment_server, 'comment.GetChannelFromCommentID', comment_id=comment_id - ) - if 'error' in channel: - return {comment_id: {'abandoned': False}} - channel = await self.get_channel_or_none(wallet, None, **channel) - abandon_comment_body.update({ - 'channel_id': channel.claim_id, - 'channel_name': channel.claim_name, - }) - comment_client.sign_comment(abandon_comment_body, channel, sign_comment_id=True) - return await comment_client.jsonrpc_post(self.conf.comment_server, 'comment.Abandon', abandon_comment_body) - - @requires(WALLET_COMPONENT) - async def jsonrpc_comment_hide(self, comment_ids: typing.Union[str, list], wallet_id=None): - """ - Hide a comment published to a claim you control. - - Usage: - comment_hide ... [--wallet_id=] - - Options: - --comment_ids= : (str, list) one or more comment_id to hide. - --wallet_id= : (str) restrict operation to specific wallet - - Returns: lists containing the ids comments that are hidden and visible. - - { - "hidden": (list) IDs of hidden comments. - "visible": (list) IDs of visible comments. - } - """ - wallet = self.wallet_manager.get_wallet_or_default(wallet_id) - - if isinstance(comment_ids, str): - comment_ids = [comment_ids] - - comments = await comment_client.jsonrpc_post( - self.conf.comment_server, 'get_comments_by_id', comment_ids=comment_ids - ) - comments = comments['items'] - claim_ids = {comment['claim_id'] for comment in comments} - claims = {cid: await self.ledger.get_claim_by_claim_id(wallet.accounts, claim_id=cid) for cid in claim_ids} - pieces = [] - for comment in comments: - claim = claims.get(comment['claim_id']) - if claim: - channel = await self.get_channel_or_none( - wallet, - account_ids=[], - channel_id=claim.channel.claim_id, - channel_name=claim.channel.claim_name, - for_signing=True - ) - piece = {'comment_id': comment['comment_id']} - comment_client.sign_comment(piece, channel, sign_comment_id=True) - pieces.append(piece) - return await comment_client.jsonrpc_post(self.conf.comment_server, 'comment.Hide', pieces=pieces) - - @requires(WALLET_COMPONENT) - async def jsonrpc_comment_pin(self, comment_id=None, channel_id=None, channel_name=None, - channel_account_id=None, remove=False, wallet_id=None): - """ - Pin a comment published to a claim you control. - - Usage: - comment_pin ( | --comment_id=) - (--channel_id=) - (--channel_name=) - [--remove] - [--channel_account_id=...] [--wallet_id=] - - Options: - --comment_id= : (str) Hash identifying the comment to pin - --channel_id= : (str) The ID of channel owning the commented claim - --channel_name= : (str) The name of channel owning the commented claim - --remove : (bool) remove the pin - --channel_account_id= : (str) one or more account ids for accounts to look in - --wallet_id=