async def wrapper(call: types.CallbackQuery): offer_id = call.data.split()[1] offer = await database.escrow.find_one({"_id": ObjectId(offer_id)}) if not offer: await call.answer(i18n("offer_not_active")) return return await handler(call, EscrowOffer(**offer))
async def wrapper(message: types.Message, state: FSMContext): offer = await database.escrow.find_one( {"pending_input_from": message.from_user.id}) if not offer: await tg.send_message(message.chat.id, i18n("offer_not_active")) return return await handler(message, EscrowOffer(**offer))
async def decline_offer(call: types.CallbackQuery, offer: EscrowOffer): """React to counteragent declining offer.""" offer.react_time = time() await offer.delete_document() await tg.send_message( offer.init["id"], i18n("escrow_offer_declined", locale=offer.init["locale"]), ) await call.answer() await tg.send_message(call.message.chat.id, i18n("offer_declined"))
async def cancel_offer(call: types.CallbackQuery, offer: EscrowOffer): """React to offer cancellation. While first party is transferring, second party can't cancel offer, because we can't be sure that first party hasn't already completed transfer before confirming. """ if offer.trx_id: return await call.answer(i18n("cancel_after_transfer")) if offer.memo: if offer.type == "buy": escrow_user = offer.init elif offer.type == "sell": escrow_user = offer.counter if call.from_user.id != escrow_user["id"]: return await call.answer(i18n("cancel_before_verification")) escrow_instance = get_escrow_instance(offer.escrow) if isinstance(escrow_instance, StreamBlockchain): escrow_instance.remove_from_queue(offer._id) sell_answer = i18n("escrow_cancelled", locale=offer.init["locale"]) buy_answer = i18n("escrow_cancelled", locale=offer.counter["locale"]) offer.cancel_time = time() await offer.delete_document() await call.answer() await tg.send_message(offer.init["id"], sell_answer, reply_markup=start_keyboard()) await tg.send_message(offer.counter["id"], buy_answer, reply_markup=start_keyboard()) sell_state = FSMContext(dp.storage, offer.init["id"], offer.init["id"]) buy_state = FSMContext(dp.storage, offer.counter["id"], offer.counter["id"]) await sell_state.finish() await buy_state.finish()
async def escrow_button(call: types.CallbackQuery, order: OrderType): """React to "Escrow" button by starting escrow exchange.""" if not config.ESCROW_ENABLED: await call.answer(i18n("escrow_unavailable")) return args = call.data.split() currency_arg = args[2] edit = bool(int(args[3])) if currency_arg == "sum_buy": sum_currency = order["buy"] new_currency = order["sell"] new_currency_arg = "sum_sell" elif currency_arg == "sum_sell": sum_currency = order["sell"] new_currency = order["buy"] new_currency_arg = "sum_buy" else: return keyboard = types.InlineKeyboardMarkup() keyboard.row( types.InlineKeyboardButton( i18n("change_to {currency}").format(currency=new_currency), callback_data="escrow {} {} 1".format(order["_id"], new_currency_arg), ) ) answer = i18n("send_exchange_sum {currency}").format(currency=sum_currency) if edit: cancel_data = call.message.reply_markup.inline_keyboard[1][0].callback_data keyboard.row( types.InlineKeyboardButton(i18n("cancel"), callback_data=cancel_data) ) await database.escrow.update_one( {"pending_input_from": call.from_user.id}, {"$set": {"sum_currency": currency_arg}}, ) await call.answer() await tg.edit_message_text( answer, call.message.chat.id, call.message.message_id, reply_markup=keyboard ) else: offer_id = ObjectId() keyboard.row( types.InlineKeyboardButton( i18n("cancel"), callback_data=f"init_cancel {offer_id}" ) ) escrow_type = "buy" if get_escrow_instance(order["buy"]) else "sell" user = database_user.get() init_user = { "id": user["id"], "locale": user["locale"], "mention": user["mention"], } counter_user = await database.users.find_one( {"id": order["user_id"]}, projection={"id": True, "locale": True, "mention": True}, ) await database.escrow.delete_many({"init.send_address": {"$exists": False}}) offer = EscrowOffer( **{ "_id": offer_id, "order": order["_id"], "buy": order["buy"], "sell": order["sell"], "type": escrow_type, "escrow": order[escrow_type], "time": time(), "sum_currency": currency_arg, "init": init_user, "counter": counter_user, "pending_input_from": call.message.chat.id, } ) await offer.insert_document() await call.answer() await tg.send_message(call.message.chat.id, answer, reply_markup=keyboard) await states.Escrow.amount.set()