def get_validator(address) -> (dict, None): """ Return json of desired validator node """ if DEBUG: nodes = get_validators() # Get the right node node = next( filter(lambda node: node['operator_address'] == address, nodes), None) return node else: response = requests.get(VALIDATORS_ENDPOINT + "/" + address) if response.status_code != 200: if response.status_code == 500 and ('validator does not exist' in response.json().get( 'error', '')): return None else: logger.info("ConnectionError while requesting " + NODE_INFO_ENDPOINT) raise ConnectionError node = response.json() return node['result']
def get_validators() -> (dict, None): """ Return json of all validator nodes """ if DEBUG: # Get local validator file response = requests.get(VALIDATORS_ENDPOINT) if response.status_code != 200: logger.info("ConnectionError while requesting " + VALIDATORS_ENDPOINT) raise ConnectionError nodes = response.json() return nodes['result'] else: response = requests.get(VALIDATORS_ENDPOINT) if response.status_code != 200: if not is_lcd_reachable(): logger.info("ConnectionError while requesting " + NODE_INFO_ENDPOINT) raise ConnectionError else: return None nodes = response.json() return nodes['result']
def try_message(context, chat_id, text, reply_markup=None, remove_job_when_blocked=True): """ Send a message to a user. """ try: context.bot.send_message(chat_id, text, parse_mode='markdown', reply_markup=reply_markup, disable_web_page_preview=True) except TelegramError as e: if 'bot was blocked by the user' in e.message: logger.info("Telegram user " + str(chat_id) + " blocked me; removing him from the user list") del context.dispatcher.user_data[chat_id] del context.dispatcher.chat_data[chat_id] del context.dispatcher.persistence.user_data[chat_id] del context.dispatcher.persistence.chat_data[chat_id] # Somehow session.data does not get updated if all users block the bot. # That makes problems on bot restart. That's why we delete the file ourselves. if len(context.dispatcher.persistence.user_data ) == 0 and os.path.exists("./storage/session.data"): os.remove("./storage/session.data") if remove_job_when_blocked: context.job.schedule_removal() else: logger.error(e, exc_info=True) logger.info("Telegram user " + str(chat_id))
def on_vote_send_clicked(update, context): query = update.callback_query _, proposal_id, vote = query.data.split("-") proposal_title = context.user_data['proposals_cache'][proposal_id]['title'] keyboard = [[ InlineKeyboardButton(BACK_BUTTON_MSG, callback_data=f'proposal-{proposal_id}-1') ]] try: vote_result = vote_delegated(proposal_id=proposal_id, vote=vote, telegram_user_id=query.from_user['id']) logger.info(f"Voted successfully. Transaction result:\n{vote_result}") except Exception as e: logger.exception(e) query.edit_message_text(NETWORK_ERROR_MSG, reply_markup=InlineKeyboardMarkup(keyboard)) return tx_hash = vote_result['result'].get('txhash', None) if tx_hash is None: text = f"Error while voting:\n{vote_result.get('result', None)}" else: text = f"Successfully voted *{vote}* on proposal *{proposal_title}*. 🎉\n" \ f"See your vote here:\n" \ f"{TERRA_FINDER_URL}tx/{tx_hash}" query.edit_message_text(text, parse_mode='markdown', reply_markup=InlineKeyboardMarkup(keyboard))
def is_node_catching_up(): response = requests.get(url=NODE_STATUS_ENDPOINT) if response.status_code != 200: logger.info("ConnectionError while requesting " + NODE_STATUS_ENDPOINT) raise ConnectionError status = response.json() return status['result']['sync_info']['catching_up']
def get_node_block_height(): """ Return block height of your Terra Node """ response = requests.get(url=NODE_STATUS_ENDPOINT) if response.status_code != 200: logger.info("ConnectionError while requesting " + NODE_STATUS_ENDPOINT) raise ConnectionError status = response.json() return status['result']['sync_info']['latest_block_height']
def main(): """ Init telegram bot, attach handlers and wait for incoming requests. """ # Init telegram bot bot = Updater(TELEGRAM_BOT_TOKEN, persistence=PicklePersistence(filename=session_data_path), use_context=True) dispatcher = bot.dispatcher setup_existing_user(dispatcher=dispatcher) setup_sentry_jobs(dispatcher=dispatcher) dispatcher.add_handler(CommandHandler('start', start, run_async=True)) dispatcher.add_handler(CommandHandler('cancel', cancel, run_async=True)) dispatcher.add_handler(CallbackQueryHandler(dispatch_query, run_async=True)) dispatcher.add_handler( MessageHandler(Filters.text, plain_input, run_async=True)) # Start the bot bot.start_polling() logger.info(BOT_STARTUP_MSG) logger.info(f""" ========================================================================== ========================================================================== Debug: {DEBUG} Telegram bot token: {"SET" if TELEGRAM_BOT_TOKEN else "MISSING!"} Slack webhook: {SLACK_WEBHOOK} LCD endpoint: {LCD_ENDPOINT} Sentry nodes: {SENTRY_NODES} Node IP: {NODE_IP} ========================================================================== ========================================================================== """) # Run the bot until you press Ctrl-C or the process receives SIGINT, # SIGTERM or SIGABRT. This should be used most of the time, since # start_polling() is non-blocking and will stop the bot gracefully. bot.idle()
def setup_existing_user(dispatcher): """ Tasks to ensure smooth user experience for existing users upon Bot restart """ chat_ids = dispatcher.user_data.keys() delete_chat_ids = [] for chat_id in chat_ids: try: dispatcher.bot.send_message(chat_id, BOT_RESTARTED_MSG) dispatcher.job_queue.run_repeating( node_checks, interval=JOB_INTERVAL_IN_SECONDS, context={ 'chat_id': chat_id, 'user_data': dispatcher.user_data[chat_id] }) except TelegramError as e: if 'bot was blocked by the user' in e.message: delete_chat_ids.append(chat_id) continue else: logger.error("Got Error\n" + str(e) + "\nwith telegram user " + str(chat_id)) for chat_id in delete_chat_ids: logger.info("Telegram user " + str(chat_id) + " blocked me; removing him from the user list") del dispatcher.user_data[chat_id] del dispatcher.chat_data[chat_id] del dispatcher.persistence.user_data[chat_id] del dispatcher.persistence.chat_data[chat_id] # Somehow session.data does not get updated if all users block the bot. # That's why we delete the file ourselves. if len(dispatcher.persistence.user_data) == 0 and os.path.exists( session_data_path): os.remove(session_data_path)
def get_price_feed_prevotes(address): """ Return the current prevotes oracle json """ if DEBUG: # Get local prevotes file response = requests.get('http://localhost:8000/prevotes.json') if response.status_code != 200: logger.info( "ConnectionError while requesting http://localhost:8000/prevotes.json" ) raise ConnectionError return response.json() else: response = requests.get('https://lcd.terra.dev/oracle/voters/' + address + '/prevotes') if response.status_code != 200: logger.info( "ConnectionError while requesting https://lcd.terra.dev/oracle/voters/" + address + "/prevotes") raise ConnectionError return response.json()