private async Task <TokenProps> GetTokenFaucetProps(Message m) // verify that user is a part of the master chat { var text = m.Text?.Trim(); var args = text.Split(" "); var cliArgs = CLIHelper.GetNamedArguments(args); var user = m.From; var props = GetTokenPropsFromTextCommand(text); var baseName = props?.name?.ToUpper(); if (props.name.IsNullOrWhitespace() || props.name.Length < 2 || props.name.Length > 10) // validate token name { await _TBC.SendTextMessageAsync(text : $"Token name `${props.name ?? "undefined"}` is invalid.\nCheck description to see allowed parameters.", chatId : new ChatId(m.Chat.Id), replyToMessageId : m.MessageId, parseMode : Telegram.Bot.Types.Enums.ParseMode.Markdown); return(null); } if (props.index < 0 || props.index > 99999999) { props.index = (cliArgs.GetValueOrDefault("index")).ToIntOrDefault(BitcoinEx.GetCoinIndex(baseName)); } if (props.index < 0 || props.index > 99999999) // vlaidate coin index { await _TBC.SendTextMessageAsync(text : $"*index* flag `{props.index}` is invalid.\nCheck description to see allowed parameters.", chatId : new ChatId(m.Chat.Id), replyToMessageId : m.MessageId, parseMode : Telegram.Bot.Types.Enums.ParseMode.Markdown); return(null); } props.address = cliArgs.GetValueOrDefault("address") ?? args.FirstOrDefault(x => Bech32Ex.CanDecode(x)); if (Bech32Ex.TryDecode(props.address, out var hrp, out var addrBytes)) { props.prefix = hrp; } props.prefix = props.prefix ?? cliArgs.GetValueOrDefault("prefix"); if (props.prefix.IsNullOrWhitespace()) { await _TBC.SendTextMessageAsync(text : $"*prefix* ({props.prefix ?? "undefined"}) or *address* ({props.address ?? "undefined"}) flag was not defined.\nCheck description to see allowed parameters.", chatId : new ChatId(m.Chat.Id), replyToMessageId : m.MessageId, parseMode : Telegram.Bot.Types.Enums.ParseMode.Markdown); return(null); } if (!Bech32Ex.CanDecode(props.address)) { var ua = await GetUserAccount(user, createNewAcount : false); var acc = new AsmodatStandard.Cryptography.Cosmos.Account(props.prefix, (uint)props.index); acc.InitializeWithMnemonic(ua.GetSecret()); props.address = acc.CosmosAddress; } var client = new CosmosHub(lcd: props.lcd, timeoutSeconds: _cosmosHubClientTimeout); node_info nodeInfo; try { nodeInfo = await client.GetNodeInfo(); } catch { await _TBC.SendTextMessageAsync(text : $"*lcd* flag `{props.lcd ?? "undefined"}` is invalid or node can NOT be reached.\nCheck description to see allowed parameters.", chatId : new ChatId(m.Chat.Id), replyToMessageId : m.MessageId, parseMode : Telegram.Bot.Types.Enums.ParseMode.Markdown); return(null); } var network = cliArgs.GetValueOrDefault("network"); if (network.IsNullOrWhitespace()) { network = nodeInfo?.network; } if (network.IsNullOrWhitespace()) { network = props.network; } props.network = network; if (props.network.IsNullOrWhitespace() || props.network.Length <= 1) { await _TBC.SendTextMessageAsync(text : $"*network* flag `{props.network ?? "undefined"}` is invalid.\nCheck description to see allowed parameters.", chatId : new ChatId(m.Chat.Id), replyToMessageId : m.MessageId, parseMode : Telegram.Bot.Types.Enums.ParseMode.Markdown); return(null); } props.denom = cliArgs.GetValueOrDefault("denom") ?? props.denom ?? props.name.ToLower(); return(props); }
private async Task TransactionProcessMessage(Message m) { if (!await this.CheckMasterChatMembership(m)) { return; } var chat = m.Chat; var from = m.From; var to = m.ReplyToMessage?.From; var text = (m.Text?.Trim() ?? "").Trim('\'', '"', '`', '*', '[', ']'); var args = text.Split(" "); var cliArgs = CLIHelper.GetNamedArguments(args); var toUsername = args.TryGetValueOrDefault(1, "").Trim(' ', '\'', '"', '*', '`', '[', ']'); var toAddress = (cliArgs.GetValueOrDefault("address") ?? args.TryGetValueOrDefault(3, "")).Trim(' ', '\'', '"', '*', '`', '[', ']'); if (!Bech32Ex.TryDecode(toAddress, out var hrp, out var addrBytes)) { toAddress = null; } if (!toAddress.IsNullOrWhitespace()) { to = null; } if (toAddress.IsNullOrWhitespace() && to == null && toUsername.StartsWith("@")) { to = await TryGetUserByUsername(toUsername.TrimStart("@")); } if (to == null && toAddress.IsNullOrWhitespace()) { await _TBC.SendTextMessageAsync(chatId : chat, $"Transaction can't be send.\n" + $"User @{toUsername ?? "null"} is not an active member of *{chat.Title}* group, `address` property is invalid or you responded to the old message that bot can't see.\n" + $"Try a 'reply to option', for example: Reply to -> `tip <amount> $<token_name>` rather then `tx @<username> <amount> $<token>` or specify `address` argument, e.g: `tx <amount> $<token> --address=<publicKey>`.", replyToMessageId : m.MessageId, parseMode : Telegram.Bot.Types.Enums.ParseMode.Markdown); return; } var token = (args.FirstOrDefault(x => x.StartsWith("$")).Trim() ?? cliArgs.GetValueOrDefault("token") ?? "").TrimStart("$"); var propsVar = Environment.GetEnvironmentVariable($"{token?.ToLower()}_PROPS"); TokenProps props; if (!propsVar.IsNullOrEmpty()) { props = propsVar.JsonDeserialize <TokenProps>(); } else { props = new TokenProps(); } props.denom = cliArgs.GetValueOrDefault("denom") ?? props.denom ?? token.ToLower(); props.amount = (args.FirstOrDefault(x => x.Trim().IsDigits()).Trim() ?? cliArgs.GetValueOrDefault("amount")).ToLongOrDefault(0); props.fees = cliArgs.GetValueOrDefault("fees", props.fees.ToString()).ToLongOrDefault(0); if (props.amount < 0 || props.fees < 0) { await _TBC.SendTextMessageAsync(chatId : chat, $"`amount` or `fees` or `token` were not specified.", replyToMessageId : m.MessageId, parseMode : ParseMode.Markdown); return; } string wallet = null; try { var account = await GetUserAccount(from); var acc = new AsmodatStandard.Cryptography.Cosmos.Account(props.prefix, (uint)props.index); acc.InitializeWithMnemonic(account.GetSecret()); var client = new CosmosHub(lcd: props.lcd, timeoutSeconds: _cosmosHubClientTimeout); var fromAccountInfo = await client.GetAccount(account : acc.CosmosAddress); var fromAccountBalance = fromAccountInfo?.coins?.FirstOrDefault(x => x?.denom?.ToLower() == props.denom.ToLower()); var fromBalance = (fromAccountBalance?.amount).ToBigIntOrDefault(0); wallet = $"Wallet: `{fromBalance} {props.denom}`"; } catch { } var optionsKeyboard = new InlineKeyboardMarkup(new[] { new [] // first row { InlineKeyboardButton.WithCallbackData("YES, SEND", $"{OptionKeys.txConfirm.ToString()} {from.Id} {to?.Id.ToString() ?? toAddress}"), InlineKeyboardButton.WithCallbackData("NO!, CANCEL", OptionKeys.txCancel.ToString()) }, }); string toConfirm = (to == null ? $"To: `{toAddress}`\n" : $"To: {to.GetMarkDownUsername()} (`{to.Id}`)\n"); await _TBC.SendTextMessageAsync(chatId : chat, $"*[ CONFIRM REQUEST {m.MessageId} ]*\n" + $"Action: `transfer`\n" + $"From: {from.GetMarkDownUsername()} (`{from.Id}`)\n" + toConfirm + $"Amount: `{props.amount} {props.denom}`\n" + $"Fees: `{props.fees} {props.denom}`\n" + wallet, replyToMessageId : m.MessageId, replyMarkup : optionsKeyboard, parseMode : ParseMode.Markdown); }