コード例 #1
0
        public async Task WalletInfoAsync([Remainder] string _ = null)
        {
            try
            {
                if (!WalletUtilities.CheckWalletExist(SqliteDatabaseService, Context.User.Id, out var walletAccount))
                {
                    await ReplyAsync("Please use the `RegisterWallet` command to register your wallet first.").ConfigureAwait(false);
                    await AddReactionAsync("❌").ConfigureAwait(false);

                    return;
                }

                var embed = new EmbedBuilder()
                            .WithColor(Color.Orange)
                            .WithTitle(":information_desk_person: ACCOUNT INFO")
                            .WithDescription($":purse: Deposit Address: `{walletAccount.TipWalletAddress}`\n\n:purse: Registered Address: `{walletAccount.RegisteredWalletAddress}`");

                await ReplyDMAsync(embed.Build()).ConfigureAwait(false);
                await AddReactionAsync("✅").ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                await CatchError(ex).ConfigureAwait(false);
            }
        }
コード例 #2
0
        public async Task BotWalletBalanceAsync([Remainder] string _ = null)
        {
            try
            {
                if (!WalletUtilities.CheckWalletExist(SqliteDatabaseService, Context.Client.CurrentUser.Id, out var walletAccount))
                {
                    await ReplyAsync("Please use the `RegisterWallet` command to register your wallet first.").ConfigureAwait(false);
                    await AddReactionAsync("❌").ConfigureAwait(false);

                    return;
                }

                var balance = await RpcService.WalletRpcClient.GetBalanceAsync(walletAccount.AccountIndex).ConfigureAwait(false);

                var walletHeight = await RpcService.WalletRpcClient.GetHeightAsync().ConfigureAwait(false);

                var daemonHeight = await RpcService.DaemonRpcClient.GetInfoAsync().ConfigureAwait(false);

                var availableBalance = balance.UnlockedBalance / Convert.ToDecimal(ConfigService.CoinUnit);
                var pendingBalance   = (balance.Balance - balance.UnlockedBalance) / Convert.ToDecimal(ConfigService.CoinUnit);

                var embed = new EmbedBuilder()
                            .WithColor(Color.Orange)
                            .WithTitle(":moneybag: TIP BOT BALANCE")
                            .WithDescription($":moneybag: Available: {WalletUtilities.FormatBalance(ConfigService, availableBalance)} {ConfigService.CoinSymbol}\n:purse: Pending: {WalletUtilities.FormatBalance(ConfigService, pendingBalance)} {ConfigService.CoinSymbol}\n:arrows_counterclockwise: Status: {walletHeight.Height} / {daemonHeight.Height}");

                await ReplyAsync(embed.Build()).ConfigureAwait(false);
                await AddReactionAsync("✅").ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                await CatchError(ex).ConfigureAwait(false);
            }
        }
コード例 #3
0
        public async Task TipAsync([Summary("Amount to tip")] decimal amount, [Remainder] string _ = null)
        {
            try
            {
                if (!WalletUtilities.CheckWalletExist(SqliteDatabaseService, Context.User.Id, out var walletAccount))
                {
                    await ReplyAsync("Please use the `RegisterWallet` command to register your wallet first.").ConfigureAwait(false);
                    await AddReactionAsync("❌").ConfigureAwait(false);

                    return;
                }

                var atomicAmountToTip = Convert.ToUInt64(Math.Ceiling(amount * ConfigService.CoinUnit));

                if (atomicAmountToTip < ConfigService.TipMinimumAmount)
                {
                    await ReplyAsync($":x: Minimum tip amount is: {WalletUtilities.FormatBalance(ConfigService, ConfigService.TipMinimumAmount / Convert.ToDecimal(ConfigService.CoinUnit))} {ConfigService.CoinSymbol}").ConfigureAwait(false);
                    await AddReactionAsync("❌").ConfigureAwait(false);

                    return;
                }

                var balance = await RpcService.WalletRpcClient.GetBalanceAsync(walletAccount.AccountIndex).ConfigureAwait(false);

                if (atomicAmountToTip * Convert.ToUInt64(Context.Message.MentionedUsers.Count) > balance.UnlockedBalance)
                {
                    await ReplyAsync(":x: Insufficient balance to tip this amount.").ConfigureAwait(false);
                    await AddReactionAsync("❌").ConfigureAwait(false);

                    return;
                }

                var transferDestinations = new List <CommandRpcTransferSplit.TransferDestination>();
                var userTipped           = new List <IUser>();

                foreach (var user in Context.Message.MentionedUsers)
                {
                    // @everyone @here
                    if (user.Id == Context.Guild.Id || user.Id == Context.Channel.Id)
                    {
                        continue;
                    }

                    if (!WalletUtilities.CheckWalletExist(SqliteDatabaseService, user.Id, out var userWalletAccount))
                    {
                        continue;
                    }

                    if (user.Id == Context.User.Id)
                    {
                        continue;
                    }

                    transferDestinations.Add(new CommandRpcTransferSplit.TransferDestination
                    {
                        Address = userWalletAccount.TipWalletAddress,
                        Amount  = atomicAmountToTip
                    });

                    userTipped.Add(user);
                }

                if (userTipped.Count == 0)
                {
                    var failEmbed = new EmbedBuilder()
                                    .WithColor(Color.Red)
                                    .WithTitle(":moneybag: TRANSFER RESULT")
                                    .WithDescription("Failed to tip this amount due to the users have not registered their wallet.");

                    await ReplyDMAsync(failEmbed.Build()).ConfigureAwait(false);
                    await AddReactionAsync("❌").ConfigureAwait(false);

                    return;
                }

                var transferRequest = new CommandRpcTransferSplit.Request
                {
                    AccountIndex = walletAccount.AccountIndex,
                    Destinations = transferDestinations.ToArray(),
                    Mixin        = ConfigService.TipMixIn,
                    GetTxHex     = true
                };

                var transferResult = await RpcService.WalletRpcClient.TransferSplitAsync(transferRequest).ConfigureAwait(false);

                if (!WalletUtilities.IsTransferSuccess(transferResult))
                {
                    var failEmbed = new EmbedBuilder()
                                    .WithColor(Color.Red)
                                    .WithTitle(":moneybag: TRANSFER RESULT")
                                    .WithDescription("Failed to tip this amount due to insufficient balance to cover the transaction fees.");

                    await ReplyDMAsync(failEmbed.Build()).ConfigureAwait(false);
                    await AddReactionAsync("❌").ConfigureAwait(false);

                    return;
                }

                // Tip Success for this user, inform them.
                foreach (var user in userTipped)
                {
                    if (user.IsBot)
                    {
                        continue;
                    }

                    try
                    {
                        var dmChannel = await user.GetOrCreateDMChannelAsync().ConfigureAwait(false);

                        var notificationEmbed = new EmbedBuilder()
                                                .WithColor(Color.Green)
                                                .WithTitle(":moneybag: INCOMING TIP")
                                                .WithDescription($":moneybag: You got a tip of {WalletUtilities.FormatBalance(ConfigService, atomicAmountToTip / Convert.ToDecimal(ConfigService.CoinUnit))} {ConfigService.CoinSymbol} from {Context.User}\n:hash: Transaction hash: {string.Join(", ", transferResult.TxHashList.Select(a => $"`{a}`"))}");

                        await dmChannel.SendMessageAsync("", false, notificationEmbed.Build()).ConfigureAwait(false);
                    }
                    catch (Exception)
                    {
                        // ignore.
                    }
                }

                var successEmbed = new EmbedBuilder()
                                   .WithColor(Color.Green)
                                   .WithTitle(":moneybag: TRANSFER RESULT")
                                   .WithDescription($"You have tipped {WalletUtilities.FormatBalance(ConfigService, atomicAmountToTip / Convert.ToDecimal(ConfigService.CoinUnit))} {ConfigService.CoinSymbol} to {userTipped.Count} users");

                await ReplyDMAsync(successEmbed.Build()).ConfigureAwait(false);

                for (var i = 0; i < transferResult.TxHashList.Length; i++)
                {
                    var txAmount = transferResult.AmountList[i] / Convert.ToDecimal(ConfigService.CoinUnit);
                    var txFee    = transferResult.FeeList[i] / Convert.ToDecimal(ConfigService.CoinUnit);
                    var txHash   = transferResult.TxHashList[i];

                    var txEmbed = new EmbedBuilder()
                                  .WithColor(Color.Orange)
                                  .WithTitle($":moneybag: TRANSACTION PAID ({i + 1}/{transferResult.TxHashList.Length})")
                                  .WithDescription($"Amount: {WalletUtilities.FormatBalance(ConfigService, txAmount)} {ConfigService.CoinSymbol}\nFee: {WalletUtilities.FormatBalance(ConfigService, txFee)} {ConfigService.CoinSymbol}\nTransaction hash: `{txHash}`");

                    await ReplyDMAsync(txEmbed.Build()).ConfigureAwait(false);
                }

                await AddReactionAsync("💰").ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                await CatchError(ex).ConfigureAwait(false);
            }
        }
コード例 #4
0
        public async Task RegisterWalletAsync([Summary("Wallet address.")][Remainder]
                                              string address)
        {
            try
            {
                if (!WalletUtilities.CheckWalletAddress(address))
                {
                    await ReplyAsync($"Address is not a valid {ConfigService.CoinName} address!").ConfigureAwait(false);
                    await AddReactionAsync("❌").ConfigureAwait(false);

                    return;
                }

                if (WalletUtilities.CheckWalletExist(SqliteDatabaseService, Context.User.Id, out var walletAccount))
                {
                    using (var sqliteContext = SqliteDatabaseService.GetContext())
                    {
                        sqliteContext.WalletAccountTable.Attach(walletAccount);
                        walletAccount.RegisteredWalletAddress = address;
                        sqliteContext.WalletAccountTable.Update(walletAccount);
                        await sqliteContext.SaveChangesAsync().ConfigureAwait(false);
                    }

                    await ReplyDMAsync("Successfully updated your wallet!").ConfigureAwait(false);
                    await AddReactionAsync("✅").ConfigureAwait(false);
                }
                else
                {
                    var newAccount = await RpcService.WalletRpcClient.CreateAccountAsync(Context.User.Id.ToString()).ConfigureAwait(false);

                    if (newAccount == null)
                    {
                        throw new Exception("Unable to create account.");
                    }

                    using (var sqliteContext = SqliteDatabaseService.GetContext())
                    {
                        var wallet = new WalletAccount
                        {
                            UserId                  = Context.User.Id,
                            AccountIndex            = newAccount.AccountIndex,
                            RegisteredWalletAddress = address,
                            TipWalletAddress        = newAccount.Address
                        };

                        sqliteContext.WalletAccountTable.Add(wallet);
                        await sqliteContext.SaveChangesAsync().ConfigureAwait(false);
                    }

                    var embed = new EmbedBuilder()
                                .WithColor(Color.Orange)
                                .WithTitle("Successfully registered your wallet!")
                                .WithDescription($"Deposit {ConfigService.CoinSymbol} to start tipping!\n\nAddress: `{newAccount.Address}`");

                    await ReplyDMAsync(embed.Build()).ConfigureAwait(false);
                    await AddReactionAsync("✅").ConfigureAwait(false);
                }
            }
            catch (Exception ex)
            {
                await CatchError(ex).ConfigureAwait(false);
            }
        }
コード例 #5
0
        public async Task WalletWithdrawAsync([Summary("Amount to withdraw")] decimal amount, [Remainder] string _ = null)
        {
            try
            {
                if (!WalletUtilities.CheckWalletExist(SqliteDatabaseService, Context.User.Id, out var walletAccount))
                {
                    await ReplyAsync("Please use the `RegisterWallet` command to register your wallet first.").ConfigureAwait(false);
                    await AddReactionAsync("❌").ConfigureAwait(false);

                    return;
                }

                var atomicAmountToWithdraw = Convert.ToUInt64(Math.Ceiling(amount * ConfigService.CoinUnit));

                if (atomicAmountToWithdraw < ConfigService.WithdrawMinimumAmount)
                {
                    await ReplyAsync($":x: Minimum withdrawal amount is: {WalletUtilities.FormatBalance(ConfigService, ConfigService.WithdrawMinimumAmount / Convert.ToDecimal(ConfigService.CoinUnit))} {ConfigService.CoinSymbol}").ConfigureAwait(false);
                    await AddReactionAsync("❌").ConfigureAwait(false);

                    return;
                }

                var balance = await RpcService.WalletRpcClient.GetBalanceAsync(walletAccount.AccountIndex).ConfigureAwait(false);

                if (atomicAmountToWithdraw > balance.UnlockedBalance)
                {
                    await ReplyAsync(":x: Insufficient balance to withdraw this amount.").ConfigureAwait(false);
                    await AddReactionAsync("❌").ConfigureAwait(false);

                    return;
                }

                var transferRequest = new CommandRpcTransferSplit.Request
                {
                    AccountIndex = walletAccount.AccountIndex,
                    Destinations = new[]
                    {
                        new CommandRpcTransferSplit.TransferDestination
                        {
                            Address = walletAccount.RegisteredWalletAddress,
                            Amount  = atomicAmountToWithdraw
                        }
                    },
                    Mixin    = ConfigService.TipMixIn,
                    GetTxHex = true
                };

                var transferResult = await RpcService.WalletRpcClient.TransferSplitAsync(transferRequest).ConfigureAwait(false);

                if (!WalletUtilities.IsTransferSuccess(transferResult))
                {
                    var failEmbed = new EmbedBuilder()
                                    .WithColor(Color.Red)
                                    .WithTitle(":moneybag: TRANSFER RESULT")
                                    .WithDescription("Failed to withdrawn this amount due to insufficient balance to cover the transaction fees.");

                    await ReplyDMAsync(failEmbed.Build()).ConfigureAwait(false);
                    await AddReactionAsync("❌").ConfigureAwait(false);

                    return;
                }

                var successEmbed = new EmbedBuilder()
                                   .WithColor(Color.Green)
                                   .WithTitle(":moneybag: TRANSFER RESULT")
                                   .WithDescription($"You have withdrawn {WalletUtilities.FormatBalance(ConfigService, atomicAmountToWithdraw / Convert.ToDecimal(ConfigService.CoinUnit))} {ConfigService.CoinSymbol}");

                await ReplyDMAsync(successEmbed.Build()).ConfigureAwait(false);

                for (var i = 0; i < transferResult.TxHashList.Length; i++)
                {
                    var txAmount = transferResult.AmountList[i] / Convert.ToDecimal(ConfigService.CoinUnit);
                    var txFee    = transferResult.FeeList[i] / Convert.ToDecimal(ConfigService.CoinUnit);
                    var txHash   = transferResult.TxHashList[i];

                    var txEmbed = new EmbedBuilder()
                                  .WithColor(Color.Orange)
                                  .WithTitle($":moneybag: TRANSACTION PAID ({i + 1}/{transferResult.TxHashList.Length})")
                                  .WithDescription($"Amount: {WalletUtilities.FormatBalance(ConfigService, txAmount)} {ConfigService.CoinSymbol}\nFee: {WalletUtilities.FormatBalance(ConfigService, txFee)} {ConfigService.CoinSymbol}\nTransaction hash: `{txHash}`");

                    await ReplyDMAsync(txEmbed.Build()).ConfigureAwait(false);
                }

                await AddReactionAsync("💰").ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                await CatchError(ex).ConfigureAwait(false);
            }
        }