public async Task GetDallarDeposit(CommandContext Context) { if (Program.DaemonClient.GetWalletAddressFromAccount(Context.User.Id.ToString(), true, out string Wallet)) { DiscordEmbedBuilder EmbedBuilder = new DiscordEmbedBuilder(); EmbedBuilder.WithTitle("Dallar Bot Depositing Help"); EmbedBuilder.WithDescription("DallarBot is a Discord bot dedicated to allowing individual users on the server to easily tip each other in the chatbox. It generates a wallet for every Discord user, and you can withdraw into any address any time." + Environment.NewLine + Environment.NewLine + "Dallar Bot does not access anyone's wallets directly in order to protect everyone's privacy."); EmbedBuilder.AddField("Warning About Storage", "Dallar Bot should not be used as a long term storage for your Dallar. Dallar Bot is only accessible through Discord and if the Bot or Discord are down for any reason, you will *not* be able to access your stored Dallar."); EmbedBuilder.AddField("Dallar Bot Fees", $"All transactions with Dallar Bot incur a flat {Program.SettingsHandler.Dallar.Txfee} DAL fee to cover the Dallar blockchain transaction fees as well as funding and maintenance costs sent to the Dallar Bot server hoster."); EmbedBuilder.AddField("Blockchain Transactions", $"Dallar Bot uses the blockchain to keep track of its transactions, meaning your transactions will require 6 confirmation blocks before they are completed. This should take approximately 5 to 10 minutes under normal Dallar network conditions."); EmbedBuilder.AddField("Depositing", $"You can deposit Dallar into your Dallar Bot balance by sending Dallar to this address generated specifically for you: `{Wallet}`"); EmbedBuilder.WithImageUrl($"https://api.qrserver.com/v1/create-qr-code/?data=dallar:{Wallet}&qzone=2"); await LogHandlerService.LogUserActionAsync(Context, $"Fetched deposit info."); await DiscordHelpers.RespondAsDM(Context, EmbedBuilder.Build()); } else { await DiscordHelpers.RespondAsDM(Context, $"{Context.User.Mention}: Failed to fetch your wallet address. Please contact an Administrator."); await LogHandlerService.LogUserActionAsync(Context, $"Failed to fetch deposit info."); } DiscordHelpers.DeleteNonPrivateMessage(Context); }
public async Task GetAccountBalance(CommandContext Context) { await Context.TriggerTypingAsync(); bool bDisplayUSD = false; // if (Program.DigitalPriceExchange.GetPriceInfo(out DigitalPriceCurrencyInfo PriceInfo, out bool bPriceStale)) // { // bDisplayUSD = true; // } if (Program.DaemonClient.GetWalletAddressFromAccount(Context.User.Id.ToString(), true, out string Wallet)) { decimal balance = Program.DaemonClient.GetRawAccountBalance(Context.User.Id.ToString()); decimal pendingBalance = Program.DaemonClient.GetUnconfirmedAccountBalance(Context.User.Id.ToString()); string pendingBalanceStr = pendingBalance != 0 ? $" with {pendingBalance} DAL Pending" : ""; string resultStr = $"{Context.User.Mention}: Your balance is {balance} DAL"; if (bDisplayUSD) { //resultStr += $" (${decimal.Round(balance * PriceInfo.USDValue.GetValueOrDefault(), 4)} USD){pendingBalanceStr}"; } else { resultStr += pendingBalanceStr; } await LogHandlerService.LogUserActionAsync(Context, $"Checked balance. {balance} DAL with {pendingBalance} DAL pending."); await Context.RespondAsync(resultStr); } else { await LogHandlerService.LogUserActionAsync(Context, $"Failed to check balance. Getting wallet address failed."); await Context.RespondAsync($"{Context.User.Mention}: Failed to check balance. Getting wallet address failed. Please contact an Administrator."); } DiscordHelpers.DeleteNonPrivateMessage(Context); }
public async Task DefaultHelpAsync(CommandContext ctx, [Description("Optional command to provide help for.")] params string[] command) { // We have to use reflection because TopLevelCommands is marked private and we're not forking DSharpPlus PropertyInfo TopLevelCommandsProp = typeof(CommandsNextExtension).GetProperty("TopLevelCommands", BindingFlags.NonPublic | BindingFlags.Instance); MethodInfo TopLevelCommandsGetter = TopLevelCommandsProp.GetGetMethod(nonPublic: true); var toplevel = ((Dictionary <string, Command>)TopLevelCommandsGetter.Invoke(ctx.CommandsNext, null)).Values.Distinct(); // We instance our help formatter directly because we don't have access to the help formatting factory var helpbuilder = new HelpFormatter(ctx); if (command != null && command.Any()) { Command cmd = null; var search_in = toplevel; foreach (var c in command) { if (search_in == null) { cmd = null; break; } // We don't have access to config so f**k it, case insensitive help //if (ctx.Config.CaseSensitive) // cmd = search_in.FirstOrDefault(xc => xc.Name == c || (xc.Aliases != null && xc.Aliases.Contains(c))); //else cmd = search_in.FirstOrDefault(xc => xc.Name.ToLowerInvariant() == c.ToLowerInvariant() || (xc.Aliases != null && xc.Aliases.Select(xs => xs.ToLowerInvariant()).Contains(c.ToLowerInvariant()))); if (cmd == null) { break; } var cfl = await cmd.RunChecksAsync(ctx, true).ConfigureAwait(false); if (cfl.Any()) { throw new ChecksFailedException(cmd, ctx, cfl); } if (cmd is CommandGroup) { search_in = (cmd as CommandGroup).Children; } else { search_in = null; } } if (cmd == null) { throw new CommandNotFoundException(string.Join(" ", command)); } helpbuilder.WithCommand(cmd); if (cmd is CommandGroup gx) { var sxs = gx.Children.Where(xc => !xc.IsHidden); var scs = new List <Command>(); foreach (var sc in sxs) { if (sc.ExecutionChecks == null || !sc.ExecutionChecks.Any()) { scs.Add(sc); continue; } var cfl = await sc.RunChecksAsync(ctx, true).ConfigureAwait(false); if (!cfl.Any()) { scs.Add(sc); } } if (scs.Any()) { helpbuilder.WithSubcommands(scs.OrderBy(xc => xc.Name)); } } } else { var sxs = toplevel.Where(xc => !xc.IsHidden); var scs = new List <Command>(); foreach (var sc in sxs) { if (sc.ExecutionChecks == null || !sc.ExecutionChecks.Any()) { scs.Add(sc); continue; } var cfl = await sc.RunChecksAsync(ctx, true).ConfigureAwait(false); if (!cfl.Any()) { scs.Add(sc); } } if (scs.Any()) { helpbuilder.WithSubcommands(scs.OrderBy(xc => xc.Name)); } } var hmsg = helpbuilder.Build(); // The main reason for this change, allowing help to be DM'd and the original command deleted. DiscordHelpers.DeleteNonPrivateMessage(ctx); await DiscordHelpers.RespondAsDM(ctx, hmsg.Embed).ConfigureAwait(false); }
public async Task WithdrawFromWalletInstant(CommandContext Context, [Description("Amount of DAL to withdraw. Use 'all' for your entire balance")] string AmountStr, [Description("Dallar Wallet Address to withdraw Dallar to")] string PublicAddress) { // Make sure supplied address is a valid Dallar address if (!Program.DaemonClient.IsAddressValid(PublicAddress)) { // handle invalid public address await LogHandlerService.LogUserActionAsync(Context, $"Tried to withdraw but PublicAddress ({PublicAddress}) is invalid."); await Context.RespondAsync($"{Context.User.Mention}: Seems like you tried withdrawing Dallar to an invalid Dallar address. You supplied: {PublicAddress}"); DiscordHelpers.DeleteNonPrivateMessage(Context); return; } // Try to interpret the user's amount input as a sane value if (!DallarHelpers.TryParseUserAmountString(Context.User, AmountStr, out decimal Amount)) { // handle amount parse fail await LogHandlerService.LogUserActionAsync(Context, $"Tried to withdraw {Amount} but value could not be parsed."); await Context.RespondAsync($"{Context.User.Mention}: The amount you tried to withdraw can not be parsed as a number. You tried withdrawing {Amount} DAL."); DiscordHelpers.DeleteNonPrivateMessage(Context); return; } // Make sure Amount is greater than zero if (Amount <= 0) { await LogHandlerService.LogUserActionAsync(Context, $"Tried to withdraw {Amount} but value is invalid."); await Context.RespondAsync($"{Context.User.Mention}: You can not withdraw 0 or less Dallar. You tried withdrawing {Amount} DAL."); DiscordHelpers.DeleteNonPrivateMessage(Context); return; } // Verify user has requested balance to withdraw if (!DallarHelpers.CanUserAffordTransactionAmount(Context.User, Amount)) { // user can not afford requested withdraw amount await LogHandlerService.LogUserActionAsync(Context, $"Tried to withdraw {Amount} but has insufficient funds. ({Program.DaemonClient.GetRawAccountBalance(Context.User.Id.ToString())})"); await Context.RespondAsync($"{Context.User.Mention}: Looks like you don't have enough funds withdraw {Amount} DAL! Remember, there is a {Program.SettingsHandler.Dallar.Txfee} DAL fee for performing bot transactions."); DiscordHelpers.DeleteNonPrivateMessage(Context); return; } // Amount should be guaranteed a good value to withdraw // Fetch user's wallet if (Program.DaemonClient.GetWalletAddressFromAccount(Context.User.Id.ToString(), true, out string Wallet)) { if (Program.DaemonClient.SendMinusFees(Context.User.Id.ToString(), PublicAddress, Amount, Program.SettingsHandler.Dallar.Txfee, Program.SettingsHandler.Dallar.FeeAccount)) { // Successfully withdrew await LogHandlerService.LogUserActionAsync(Context, $"Successfully withdrew {Amount} from wallet ({Wallet})."); await Context.RespondAsync($"You have successfully withdrawn {Amount} DAL" + (Context.Member == null ? "." : $" to address {PublicAddress}.")); } else { // unable to send dallar await LogHandlerService.LogUserActionAsync(Context, $"Tried to withdraw {Amount} from wallet ({Wallet}) but daemon failed to send transaction."); await Context.RespondAsync("Something went wrong trying to send your Dallar through the Dallar daemon. (Please contact the Administrators!)"); DiscordHelpers.DeleteNonPrivateMessage(Context); return; } } else { // unable to fetch user's wallet await LogHandlerService.LogUserActionAsync(Context, $"Tried to withdraw {Amount} but bot could not determine user's wallet."); await Context.RespondAsync("Something went wrong trying to get your DallarBot Dallar Address. (Please contact the Administrators!)"); DiscordHelpers.DeleteNonPrivateMessage(Context); return; } // After withdraw success DiscordHelpers.DeleteNonPrivateMessage(Context); }
static async Task MainAsync(string[] args) { Console.WriteLine(LogHandlerService.CenterString("▒█▀▀▄ █▀▀█ █░░ █░░ █▀▀█ █▀▀█ ▒█▀▀█ █▀▀█ ▀▀█▀▀ ")); Console.WriteLine(LogHandlerService.CenterString("▒█░▒█ █▄▄█ █░░ █░░ █▄▄█ █▄▄▀ ▒█▀▀▄ █░░█ ░░█░░ ")); Console.WriteLine(LogHandlerService.CenterString("▒█▄▄▀ ▀░░▀ ▀▀▀ ▀▀▀ ▀░░▀ ▀░▀▀ ▒█▄▄█ ▀▀▀▀ ░░▀░░ ")); Console.WriteLine(); Console.WriteLine(LogHandlerService.CenterString("----------------------------")); Console.WriteLine(); Console.WriteLine(LogHandlerService.CenterString("Initializing bot...")); DiscordClient = new DiscordShardedClient(new DiscordConfiguration { Token = SettingsHandler.Discord.BotToken, TokenType = TokenType.Bot, MinimumLogLevel = Microsoft.Extensions.Logging.LogLevel.Information, }); //DiscordClient.DebugLogger.LogMessageReceived += LogHandlerService.DiscordLogMessageReceived; DiscordClient.MessageCreated += async(s, e) => { if (e.Message.Content.ToLower().StartsWith("ping")) { await e.Message.RespondAsync("pong!"); } }; await DiscordClient.UseCommandsNextAsync(new CommandsNextConfiguration { StringPrefixes = new string[] { "d!" }, EnableDms = true, EnableMentionPrefix = true, EnableDefaultHelp = false }); var Values = await DiscordClient.GetCommandsNextAsync(); foreach (System.Collections.Generic.KeyValuePair <int, CommandsNextExtension> CommandsModule in Values) { CommandsModule.Value.RegisterCommands <HelpCommands>(); CommandsModule.Value.RegisterCommands <TipCommands>(); CommandsModule.Value.RegisterCommands <MiscCommands>(); CommandsModule.Value.RegisterCommands <ExchangeCommands>(); CommandsModule.Value.RegisterCommands <DallarCommands>(); CommandsModule.Value.SetHelpFormatter <HelpFormatter>(); CommandsModule.Value.CommandErrored += async(s, e) => { // first command failure on boot throws a null exception. Not sure why? // Afterwards, this event logic always seems to work okay without error if (e.Exception is ChecksFailedException) { return; } if (e.Command == null) { return; } await LogHandlerService.LogUserActionAsync(e.Context, "Failed to invoke " + e.Command.ToString()); DiscordChannel Channel = e.Context.Channel; if (e.Context.Member != null) { Channel = await e.Context.Member.CreateDmChannelAsync(); } //await e.Context.Client.GetCommandsNext().SudoAsync(e.Context.User, Channel, "d!help " + e.Command.Name); DiscordHelpers.DeleteNonPrivateMessage(e.Context); }; } await DiscordClient.UseInteractivityAsync(new InteractivityConfiguration { }); await DiscordClient.StartAsync(); await Task.Delay(-1); }