Exemplo n.º 1
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);
            }
        }
Exemplo n.º 2
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);
            }
        }