def quick_close(cls, channel_name, wallet=None, cli=False, trigger=None): """ :param channel_name: :param wallet: :param cli: :param trigger: :return: """ try: channel = cls.query_channel(channel_name)[0] # get peer address peer = channel.src_addr if wallet.url == peer: peer = channel.dest_addr # start trigger to close channel quickly trigger(wallet, peer, channel_name, 'TNC') except Exception as error: if cli: console_log.error( 'Failed to close channel: {}'.format(channel_name)) LOG.error('Failed to close channel<{}>, Exception: {}'.format( channel_name, error))
def _wapper(self, arguments): ar_len = length if isinstance(length, list) else [length] if len(arguments) in ar_len: return func(self, arguments) else: console_log.error( "Arguments length should be {}".format(ar_len)) self.help() return
def wrapper(*args, **kwargs): try: callback(*args, **kwargs) except Exception as error: console_log.error( 'Error occurred to run command: {}. Please check logs for details.' .format(command)) LOG.error( 'Error occurred to run command: {}. Exception: {}'.format( command, error))
def channel_qrcode(self, arguments): """ :param arguments: :return: """ enable = get_arg(arguments, 1) if enable.upper() not in ["ON", "OFF"]: console_log.error("should be on or off") self.qrcode = True if enable.upper() == "ON" else False console_log.console( "Qrcode opened") if self.qrcode else console_log.info( "Qrcode closed") return None
def do_channel(self, arguments): """ :param arguments: :return: """ command = get_arg(arguments) channel_command = [i.split()[1] for i in self.user_commands] if command not in channel_command: console_log.error("no support command, please check the help") self.help() return if command == 'create': self.do_channel_create(arguments) elif command == "enable": if not self.enable_channel(): self._channel_noopen() elif command == "tx": self.channel_trans(arguments) elif command == "qrcode": self.channel_qrcode(arguments) elif command == "close": self.channel_close(arguments) elif command == "force-close": self.channel_force_close(arguments) elif command == "htlc-unlock": self.channel_htlc_unlock(arguments) elif command == "peer": self.channel_peer(arguments) elif command == "payment": self.channel_payment(arguments) elif command == "show": self.channel_show(arguments) elif command == "deposit_limit": self.channel_deposit_limit(arguments) else: return None
def do_send(self, arguments): """ :param arguments: :return: """ if not self.Wallet: print("please open a wallet") return False if len(arguments) < 3: print("Not enough arguments") return False assetId = get_arg(arguments).upper() address_to = get_arg(arguments, 1) amount = float(get_arg(arguments, 2)) if amount <= 0: console_log.error("value can not less then 0") return None if not assetId in self.Wallet.SupportAssert: console_log.error("No support assert") return None gaslimit = int(get_arg(arguments, 3)) if get_arg(arguments, 3) else None gasprice = int(get_arg(arguments, 4)) if get_arg(arguments, 4) else None if assetId == "ETH": if amount >= self.Wallet.eth_balance: console_log.error("No balance") return None try: res = self.Wallet.send_eth(address_to, amount, gaslimit) print("txid: 0x" + res) except Exception as e: print("send failed %s" % e) elif assetId == "TNC": if amount > self.Wallet.tnc_balance or self.Wallet.eth_balance < 0: console_log.error("No balance") return None try: res = self.Wallet.send_erc20(assetId, address_to, amount, gaslimit, gasprice) print("txid: 0x" + res) except Exception as e: print("send failed %s" % e) else: pass return
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 channel_show(self, arguments): """ :param arguments: :return: """ subcommand = get_arg(arguments, 1) if not subcommand: self.help() return None if subcommand.upper() == "URI": console_log.console(self.Wallet.url) elif subcommand.upper() == "TRANS_HISTORY": channel_name = get_arg(arguments, 2) if channel_name is None: console_log.error("No provide channel") return None tx_his = Channel.batch_query_trade(channel_name) for tx in tx_his: console_log.console(tx) return None else: self.help() return None
def channel_payment(self, arguments): """ :param arguments: :return: """ asset_type = get_arg(arguments, 1) if not check_support_asset_type(asset_type): console_log.error( "No support asset, current just support {}".format( SupportAssetType.SupportAssetType)) return None value = TrinityNumber(get_arg(arguments, 2).strip()).number if not value: console_log.error("command not give the count") return None try: if 0 >= value or not check_float_decimals(value, asset_type): console_log.error("value should not be less than 0") return None except ValueError: console_log.error("value format error") return None comments = " ".join(arguments[3:]) comments = comments if comments else "None" if len(comments) > 128: console_log.error("comments length should be less than 128") return None try: hash_r, rcode = Payment.create_hr() Channel.add_payment(None, hash_r, rcode, value) paycode = Payment.generate_payment_code(self.Wallet.url, asset_type, value, hash_r, comments, True) except Exception as e: LOG.error(e) console_log.error("Get payment link error, please check the log") return None if self.qrcode: qrcode_terminal.draw(paycode, version=4) console_log.console(paycode) return None
def wapper(self, *args, **kwargs): if not self.Wallet: console_log.error("No opened wallet, please open wallet first") return None else: return func(self, *args, **kwargs)
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
def do_channel_create(self, arguments): """ :return: """ partner = get_arg(arguments, 1) if not is_correct_uri(partner): console_log.error("No correct uri format") return None asset_type = get_arg(arguments, 2) 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 try: deposit_limit = DepositAuth.deposit_limit() deposit_cmp = TrinityNumber(str(deposit_limit)).number deposit = TrinityNumber(get_arg(arguments, 3).strip()).number #when partner_deposit not given ,partner_deposit is equal to deposit if get_arg(arguments, 4) == None: partner_deposit = deposit elif TrinityNumber(get_arg(arguments, 4)).number == None: console_log.error("partner_deposit is not valid") return else: partner_deposit = TrinityNumber(get_arg(arguments, 4)).number if deposit_cmp > deposit: console_log.error( "Founder's Deposit MUST be larger than {}".format( deposit_limit)) return None elif deposit_cmp > partner_deposit: console_log.error( "Partner's Deposit should be larger than {}".format( deposit_limit)) return None elif partner_deposit > deposit: console_log.error( "Founder's Deposit should not be less than Partner's") return None except ValueError: console_log.error( "Founder's Deposit should not be less than Partner'") return None if not check_partner(self.Wallet, partner): console_log.error( "Partner URI is not correct, Please check the partner uri") return None if not check_onchain_balance(self.Wallet.address, asset_type, deposit): console_log.error( "Now the balance on-chain is less than the deposit.") return None if not check_onchain_balance(partner.strip().split("@")[0], asset_type, partner_deposit): console_log.error( "Partner balance on chain is less than the deposit") return None Channel.create(self.Wallet, self.Wallet.url, partner, asset_type, deposit, partner_deposit, trigger=FounderMessage.create)
def create(cls, wallet, founder, partner, asset_type, deposit, partner_deposit=None, comments=None, trigger=None, cli=True): """ Provide one method to be called by the wallet prompt console. :param wallet: :param partner: :param asset_type: :param deposit: :param partner_deposit: :param comments: :param cli: :return: """ if not (wallet and partner and asset_type and deposit): LOG.error('Invalid parameters:wallet<{}>, founder<{}>, partner<{}>, asset_type<{}>, deposit<{}>' \ .format(wallet, founder, partner, asset_type, deposit)) # here we could use some hooks to register event to handle output console ???? console_log.error( 'Illegal mandatory parameters. Please check in your command.') return False # use deposit as default value for both partners if partner's deposit is not set: if not partner_deposit: partner_deposit = deposit # judge whether the channel exist or not if Channel.get_channel(founder, partner, EnumChannelState.OPENED): console_log.warning('OPENED channel already exists.') return False else: # creating channel is ongoing # channel = Channel.get_channel(founder, partner, EnumChannelState.OPENING) # if : # console.warning('Channel {} is on the way. Please try later if failed') # return pass channel_name = cls.new_channel_name(founder, partner) if cli: deposit = int(deposit) partner_deposit = int(partner_deposit) if 0 >= deposit or 0 >= partner_deposit: LOG.error('Could not register channel because of illegal deposit<{}:{}>.'\ .format(deposit, partner_deposit)) return False try: trigger(wallet, channel_name, asset_type, founder, deposit, partner, partner_deposit, comments) except Exception as error: LOG.info('Create channel<{}> failed. Exception: {}'.format( channel_name, error)) return False return True