def query_channel_list(address): channels = APIChannel.batch_query_channel( filters={ "src_addr": address, "state": EnumChannelState.OPENED.name, "magic": get_magic() }) channel_list = [] if channels: for ch in channels: channel_info = { "ChannelName": ch.channel, "Founder": ch.src_addr, "Receiver": ch.dest_addr, "Balance": ch.balance, "Magic": ch.__dict__.get('magic') } channel_list.append(channel_info) channeld = APIChannel.batch_query_channel( filters={ "dest_addr": address, "state": EnumChannelState.OPENED.name, "magic": get_magic() }) if channeld: for ch in channeld: channel_info = { "ChannelName": ch.channel, "Founder": ch.src_addr, "Receiver": ch.dest_addr, "Balance": ch.balance, "Magic": ch.__dict__.get('magic') } channel_list.append(channel_info) return channel_list
def sync_channel(message_type, channel_name, founder, receiver, balance, asset_type): """ :param message_type: :param channel_name: :param founder: :param receiver: :param balance: :param asset_type: :return: """ message = { "MessageType": message_type, "AssetType": asset_type.upper(), "NetMagic": get_magic(), "MessageBody": { "ChannelName": channel_name, "Founder": founder, "Receiver": receiver, "Balance": balance } } request = { "jsonrpc": "2.0", "method": "SyncChannel", "params": [message], "id": 1 } result = requests.post(Configure["GatewayURL"], json=request) return result.json()
def __init__(self, sender: str, receiver: str, message_type: str, channel_name: str, asset_type: str, nonce: int, nego_nonce=None): # here we could use the regex expression to judge the ip format accurately. assert sender.__contains__('@'), 'Invalid sender<{}>.'.format(sender) assert receiver.__contains__('@'), 'Invalid receiver<{}>.'.format( receiver) assert sender != receiver, 'Sender should be different from receiver.' self.message_header = { 'MessageType': message_type, 'Sender': sender, 'Receiver': receiver, 'TxNonce': str(nonce), 'ChannelName': channel_name, 'AssetType': asset_type.upper(), 'NetMagic': get_magic() } if not nego_nonce: nego_nonce = nonce if 1 < nego_nonce and nonce != nego_nonce: self.message_header.update({'ResetTxNonce': nego_nonce})
def udpate_channel_when_setup(address): channels = APIChannel.batch_query_channel(filters={ "src_addr": address, "magic": get_magic() }) for ch in channels: if ch.state == EnumChannelState.OPENED.name: sync_channel_info_to_gateway(ch.channel, "UpdateChannel") channeld = APIChannel.batch_query_channel(filters={ "dest_addr": address, "magic": get_magic() }) for ch in channeld: if ch.state == EnumChannelState.OPENED.name: sync_channel_info_to_gateway(ch.channel, "UpdateChannel")
def get_channel_list(address, **kwargs): """ :param address: :param kwargs: :return: """ filter_src = {'src_addr': address, 'magic': get_magic()} filter_dest = {'dest_addr': address, 'magic': get_magic()} output_text = '' for key, value in kwargs.items(): if value: filter_dest.update({key: value}) filter_src.update({key: value}) output_text += ' {} {}'.format(key, value) console_log.info('Get Channels with Address {}{}'.format( address, output_text)) if filter_src.get('peer'): filter_src.update({'dest_addr': filter_src.get('peer')}) filter_src.pop('peer') channels = APIChannel.batch_query_channel(filters=filter_src) for ch in channels: balance = Channel.convert_balance(ch.balance) console_log.console('==' * 10, '\nChannelName:', ch.channel, '\nState:', ch.state, '\nPeer:', ch.dest_addr, '\nBalance:', json.dumps(balance, indent=1)) channels = APIChannel.batch_query_channel(filters=filter_dest) for ch in channels: balance = Channel.convert_balance(ch.balance) console_log.console('==' * 10, '\nChannelName:', ch.channel, '\nState:', ch.state, '\nPeer:', ch.src_addr, '\nBalance:', json.dumps(balance, indent=1))
def check_network_magic(cls, magic): """ :param magic: :return: """ net_magic = get_magic() if net_magic != magic: raise GoTo( EnumResponseStatus.RESPONSE_INVALID_NETWORK_MAGIC, 'Invalid network ID<{}>. should be equal to {}'.format( magic, net_magic)) return True, net_magic
def sync_channel_list(channel_list): message = { "MessageType": "SyncChannelList", "AssetType": 'TNC', "NetMagic": get_magic(), "MessageBody": {channel_list} } request = { "jsonrpc": "2.0", "method": "SyncChannel", "params": [message], "id": 1 } result = requests.post(Configure["GatewayURL"], json=request) return result.json()
def close_wallet(): message = { "MessageType": "CloseWallet", "NetMagic": get_magic(), "Ip": "{}:{}".format(Configure.get("NetAddress"), Configure.get("NetPort")) } request = { "jsonrpc": "2.0", "method": "CloseWallet", "params": [message], "id": 1 } result = requests.post(Configure["GatewayURL"], json=request) return result.json()
def generate_payment_code(cls, receiver, asset_type, value, hashcode, comments='', cli=False): """""" if 0 >= int(value): console_log.error('Not support negative number.') return if not IS_SUPPORTED_ASSET_TYPE(asset_type): text = 'AssetType: {} is not supported'.format(asset_type) LOG.error(text) if cli: console_log.error(text) return None asset_type = asset_type.replace('0x', '') if asset_type.upper() in SUPPORTED_ASSET_TYPE.keys(): asset_type = asset_type.upper() hashcode = hashcode.strip() code = "{uri}&{net_magic}&{hashcode}&{asset_type}&{payment}&{comments}".format( uri=receiver, net_magic=get_magic(), hashcode=hashcode, asset_type=asset_type, payment=value, comments=comments) base58_code = base58.b58encode(code.encode()) try: return "TN{}".format(base58_code.decode()) except Exception as error: LOG.debug('generate_payment_code error: {}'.format(error)) return "TN{}".format(base58_code)
def join_gateway(wallet): """ :param wallet: :return: """ LOG.info("JoinGateway {}".format(wallet.address)) messagebody = get_wallet_info(wallet) message = { "MessageType": "SyncWallet", "AssetType": 'TNC', "NetMagic": get_magic(), "MessageBody": messagebody } request = { "jsonrpc": "2.0", "method": "SyncWalletData", "params": [message], "id": 1 } result = requests.post(Configure["GatewayURL"], json=request) return result.json()
def create(wallet, channel_name, asset_type, founder, founder_deposit, partner, partner_deposit, founder_commitment, comments=None): """ :param wallet: :param channel_name: :param asset_type: :param founder: :param founder_deposit: :param partner: :param partner_deposit: :param founder_commitment: :param comments: :return: """ # check the deposit founder_deposit = int(founder_deposit) partner_deposit = int(partner_deposit) FounderResponsesMessage.check_deposit(founder_deposit, partner_deposit) nonce = FounderResponsesMessage._FOUNDER_NONCE # start to sign content founder_address, _, _ = uri_parser(founder) partner_address, _, _ = uri_parser(partner) # Sign this data to the commitment = FounderResponsesMessage.sign_content( wallet, FounderResponsesMessage._sign_type_list, [ channel_name, nonce, founder_address, founder_deposit, partner_address, partner_deposit ]) # start add channel deposit = { founder_address: { asset_type: str(founder_deposit) }, partner_address: { asset_type: str(partner_deposit) } } hlock = { founder_address: { asset_type: '0' }, partner_address: { asset_type: '0' } } Channel.add_channel(channel=channel_name, src_addr=founder, dest_addr=partner, state=EnumChannelState.INIT.name, deposit=deposit, hlock=hlock, magic=get_magic()) APIStatistics.update_statistics(wallet.address, state=EnumChannelState.INIT.name) # add trade to database founder_trade = Channel.founder_trade( type=EnumTradeType.TRADE_TYPE_FOUNDER, role=EnumTradeRole.TRADE_ROLE_PARTNER, asset_type=asset_type, balance=partner_deposit, peer_balance=founder_deposit, commitment=commitment, peer_commitment=founder_commitment, state=EnumTradeState.confirming) Channel.add_trade(channel_name, nonce=nonce, **founder_trade) # create messages asset_type = asset_type.upper() message = FounderResponsesMessage.create_message_header( partner, founder, FounderResponsesMessage._message_name, channel_name, asset_type, nonce) message_body = {"Commitment": commitment} message.update({"MessageBody": message_body}) # Add comments in the messages if comments: message.update({"Comments": comments}) # fill message status message.update({'Status': EnumResponseStatus.RESPONSE_OK.name}) # send message to peer FounderResponsesMessage.send(message) return
def create(wallet, channel_name, asset_type, founder, founder_deposit, partner, partner_deposit=None, comments=None): """ :param wallet: :param channel_name: :param asset_type: :param founder: :param founder_deposit: :param partner: :param partner_deposit: :param comments: :return: """ founder_deposit = int(founder_deposit) if partner_deposit is None: partner_deposit = founder_deposit partner_deposit = int(partner_deposit) # check the deposit FounderMessage.check_deposit(founder_deposit, partner_deposit) # get addresses of peers nonce = FounderMessage._FOUNDER_NONCE founder_address, _, _ = uri_parser(founder) partner_address, _, _ = uri_parser(partner) # Sign this data to hash value commitment = FounderMessage.sign_content( wallet, FounderMessage._sign_type_list, [ channel_name, nonce, founder_address, founder_deposit, partner_address, partner_deposit ]) # add channel asset_type = asset_type.upper() deposit = { founder_address: { asset_type: str(founder_deposit) }, partner_address: { asset_type: str(partner_deposit) } } hlock = { founder_address: { asset_type: '0' }, partner_address: { asset_type: '0' } } Channel.add_channel(channel=channel_name, src_addr=founder, dest_addr=partner, state=EnumChannelState.INIT.name, deposit=deposit, magic=get_magic(), hlock=hlock) APIStatistics.update_statistics(wallet.address, state=EnumChannelState.INIT.name) # record the transaction founder_trade = Channel.founder_trade( type=EnumTradeType.TRADE_TYPE_FOUNDER, role=EnumTradeRole.TRADE_ROLE_FOUNDER, asset_type=asset_type, balance=founder_deposit, peer_balance=partner_deposit, commitment=commitment) Channel.add_trade(channel_name, nonce=nonce, **founder_trade) # create founder request message message = FounderMessage.create_message_header( founder, partner, FounderMessage._message_name, channel_name, asset_type, nonce) message_body = { "FounderDeposit": str(founder_deposit), "PartnerDeposit": str(partner_deposit), "Commitment": commitment, } message.update({'MessageBody': message_body}) # Add comments in the messages if comments: message.update({"Comments": comments}) FounderMessage.send(message) return
def network_magic(self): return get_magic()
def channel_trans(self, arguments): """ :param arguments: :return: """ if len(arguments) == 2: # payment code pay_code = get_arg(arguments, 1) result, info = Payment.decode_payment_code(pay_code) if result: receiver = info.get("uri") net_magic = info.get('net_magic') if not net_magic or net_magic != str(get_magic()): console_log.error("No correct net magic") return None hashcode = info.get("hashcode") asset_type = info.get("asset_type") # asset_type = get_asset_type_name(asset_type) count = info.get("payment") comments = info.get("comments") console_log.info("will pay {} {} to {} comments {}".format( TrinityNumber.convert_to_number(count), asset_type, receiver, comments)) else: console_log.error("The payment code is not correct") return else: receiver = get_arg(arguments, 1) asset_type = get_arg(arguments, 2) count = TrinityNumber(get_arg(arguments, 3).strip()).number hashcode = get_arg(arguments, 4) if not receiver or not asset_type or not count: self.help() return None asset_type = asset_type.upper() if check_support_asset_type( asset_type) else None if not asset_type: console_log.error( "No support asset, current just support {}".format( str(SupportAssetType.SupportAssetType))) return None if 0 >= count: console_log.warn('Not support negative number or zero.') return None # query channels by address channel_set = Channel.get_channel(self.Wallet.url, receiver, EnumChannelState.OPENED) if channel_set and channel_set[0]: Channel.transfer(channel_set[0].channel, self.Wallet, receiver, asset_type, count, cli=True, comments=hashcode, trigger=RsmcMessage.create) else: if not hashcode: console_log.error("No hashcode") return None try: message = { "MessageType": "GetRouterInfo", "Sender": self.Wallet.url, "Receiver": receiver, "AssetType": asset_type, "NetMagic": get_magic(), "MessageBody": { "AssetType": asset_type, "Value": count } } result = gate_way.get_router_info(message) routerinfo = json.loads(result.get("result")) except Exception as error: LOG.error( 'Exception occurred during get route info. Exception: {}'. format(error)) console_log.warning('No router was found.') return else: router = routerinfo.get("RouterInfo") if not router: LOG.error('Router between {} and {} was not found.'.format( self.Wallet.url, receiver)) console_log.error('Router not found for HTLC transfer.') return full_path = router.get("FullPath") LOG.info("Get Router {}".format(str(full_path))) next_jump = router.get("Next") LOG.info("Get Next {}".format(str(next_jump))) fee_router = [ i for i in full_path if i[0] not in (self.Wallet.url, receiver) ] if fee_router: # fee = reduce(lambda x, y:x+y,[TrinityNumber(str(i[1]).strip()).number for i in fee_router]) fee = reduce(lambda x, y: x + y, [float(i[1]) for i in fee_router]) else: fee = 0 fee = TrinityNumber(str(fee)).number count = int(count) + fee fee = fee / pow(10, 8) receiver = full_path[1][0] channel_set = Channel.get_channel(self.Wallet.url, receiver, EnumChannelState.OPENED) if not (channel_set and channel_set[0]): print('No OPENED channel was found for HTLC trade.') return LOG.info("Get Fee {}".format(fee)) answer = prompt( "You will pay extra fee {}. Do you wish continue this transaction? [Yes/No]>" .format(fee)) if answer.upper() in ["YES", "Y"]: channel_name = channel_set[0].channel Channel.transfer(channel_name, self.Wallet, receiver, asset_type, count, hashcode, router=full_path, next_jump=full_path[2][0], cli=True, trigger=HtlcMessage.create) else: return