client.start() может принимать сопрограмму как аргумент. Я использую это как раз так как вы описываете.
Кода под рукой нет, но я попробую
async def GetCode(self, timeout):
while not self.code and timeout > int(time.time()):
self.project = await self.getDB()
bot_last_message = self.project.bot_last_message.split(":")
if bot_last_message:
message_type = bot_last_message[0]
if message_type == "telegram_code":
telegram_code = bot_last_message[2]
self.code = telegram_code
await self.clear_bot_last_message()
return self.code
await asyncio.sleep(1)
return None
client.start(phone, code_callback=self.GetCode)
сначала получаем phone от бота, затем создаем клиента и ждем код. Как только он появится в базе, сопрограмма GetCode завершится и client.start продолжит выполнение
bot_last_message выглядит так: telegram_code:phone:code