From 5edb130cc53d77afd7cbd6cdd5da6bd5a2e4e80d Mon Sep 17 00:00:00 2001 From: Vraj Ved Date: Fri, 5 Dec 2025 22:41:30 +0530 Subject: [PATCH 1/2] added balance --- app/src/commands/economy/balance.ts | 30 ++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/app/src/commands/economy/balance.ts b/app/src/commands/economy/balance.ts index 2cd9ad1..5c1d381 100644 --- a/app/src/commands/economy/balance.ts +++ b/app/src/commands/economy/balance.ts @@ -1,13 +1,29 @@ import { createCommand } from "@lib/utils"; import { getUserBalance } from "@/modules/economy/economy.service"; -import { SlashCommandBuilder, EmbedBuilder } from "discord.js"; +import { createUser, getUserById } from "@/modules/users/users.service"; +import { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits } from "discord.js"; export const balance = createCommand({ - data: new SlashCommandBuilder().setName("balance").setDescription("Check your balance"), - execute: async (interaction) => { - const balance = await getUserBalance(interaction.user.id) || 0; - const embed = new EmbedBuilder().setDescription(`Your balance is ${balance}`); + data: new SlashCommandBuilder() + .setName("balance") + .setDescription("Check your balance") + + + , execute: async (interaction) => { + const user = interaction.user; + // Ensure user exists in DB + let dbUser = await getUserById(user.id); + if (!dbUser) { + await createUser(user.id); + } + + const balance = await getUserBalance(user.id); + + const embed = new EmbedBuilder() + .setTitle(`${user.username}'s Balance`) + .setDescription(`💰 **${balance} coins**`) + .setColor("Green"); + await interaction.reply({ embeds: [embed] }); } -}); - +}); \ No newline at end of file From 24138988e66f1dd4d57dc1eb838a98862cb0b05f Mon Sep 17 00:00:00 2001 From: Vraj Ved Date: Sat, 6 Dec 2025 00:08:49 +0530 Subject: [PATCH 2/2] Added Pay and Daily --- src/commands/economy/daily.ts | 68 ++++++++++++++++++++++++++ src/commands/economy/pay.ts | 61 +++++++++++++++++++++++ src/index.ts | 1 + src/modules/economy/economy.service.ts | 6 +++ src/modules/users/users.service.ts | 4 ++ 5 files changed, 140 insertions(+) create mode 100644 src/commands/economy/daily.ts create mode 100644 src/commands/economy/pay.ts diff --git a/src/commands/economy/daily.ts b/src/commands/economy/daily.ts new file mode 100644 index 0000000..683d3c3 --- /dev/null +++ b/src/commands/economy/daily.ts @@ -0,0 +1,68 @@ +import { createCommand } from "@lib/utils"; +import { addUserBalance } from "@/modules/economy/economy.service"; +import { createUser, getUserById, updateUserDaily } from "@/modules/users/users.service"; +import { SlashCommandBuilder, EmbedBuilder } from "discord.js"; + +export const daily = createCommand({ + data: new SlashCommandBuilder() + .setName("daily") + .setDescription("Get rewarded with daily coins"), + execute: async (interaction) => { + const user = interaction.user; + // Ensure user exists in DB + let dbUser = await getUserById(user.id); + if (!dbUser) { + dbUser = await createUser(user.id); + } + + const now = new Date(); + const lastDaily = dbUser.lastDaily; + + if (lastDaily) { + const diff = now.getTime() - lastDaily.getTime(); + const oneDay = 24 * 60 * 60 * 1000; + + if (diff < oneDay) { + const remaining = oneDay - diff; + const hours = Math.floor(remaining / (1000 * 60 * 60)); + const minutes = Math.floor((remaining % (1000 * 60 * 60)) / (1000 * 60)); + + const embed = new EmbedBuilder() + .setTitle("Daily Reward") + .setDescription(`You have already claimed your daily reward.\nCome back in **${hours}h ${minutes}m**.`) + .setColor("Red"); + + await interaction.reply({ embeds: [embed], ephemeral: true }); + return; + } + } + + // Calculate streak + let streak = dbUser.dailyStreak; + if (lastDaily) { + const diff = now.getTime() - lastDaily.getTime(); + const twoDays = 48 * 60 * 60 * 1000; + if (diff < twoDays) { + streak += 1; + } else { + streak = 1; + } + } else { + streak = 1; + } + + const baseReward = 100; + const streakBonus = (streak - 1) * 10; + const totalReward = baseReward + streakBonus; + + await updateUserDaily(user.id, now, streak); + await addUserBalance(user.id, totalReward); + + const embed = new EmbedBuilder() + .setTitle("Daily Reward Claimed!") + .setDescription(`You received **${totalReward} coins**! 💰\n\n**Streak:** ${streak} days 🔥`) + .setColor("Green"); + + await interaction.reply({ embeds: [embed] }); + } +}); \ No newline at end of file diff --git a/src/commands/economy/pay.ts b/src/commands/economy/pay.ts new file mode 100644 index 0000000..a728a02 --- /dev/null +++ b/src/commands/economy/pay.ts @@ -0,0 +1,61 @@ +import { createCommand } from "@lib/utils"; +import { getUserBalance, setUserBalance } from "@/modules/economy/economy.service"; +import { createUser, getUserById } from "@/modules/users/users.service"; +import { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits } from "discord.js"; + +export const pay = createCommand({ + data: new SlashCommandBuilder() + .setName("pay") + .setDescription("Send balance to another user") + .addUserOption(option => + option.setName('recipient') + .setDescription('The user to send balance to') + .setRequired(true)) + .addIntegerOption(option => + option.setName('amount') + .setDescription('The amount of balance to send') + .setRequired(true)) + + + , execute: async (interaction) => { + const user = interaction.user; + // Ensure if your user exists in DB + let dbUser = await getUserById(user.id); + if (!dbUser) { + await createUser(user.id); + } + + const balance = await getUserBalance(user.id); + const recipient = interaction.options.getUser('recipient'); + const amount = interaction.options.getInteger('amount'); + + if (amount! <= 0) { + await interaction.reply({ content: "❌ Amount must be greater than zero.", ephemeral: true }); + return; + } + if (amount! > balance) { + await interaction.reply({ content: "❌ You do not have enough coins to complete this transaction.", ephemeral: true }); + return; + } + + if (recipient!.id === user.id) { + await interaction.reply({ content: "❌ You cannot send coins to yourself.", ephemeral: true }); + return; + } + + // Ensure recipient exists in DB + let dbRecipient = await getUserById(recipient!.id); + if (!dbRecipient) { + dbRecipient = await createUser(recipient!.id); + } + + await setUserBalance(user.id, balance - amount!); // Deduct from sender + await setUserBalance(recipient!.id, (await getUserBalance(recipient!.id)) + amount!); // Add to recipient + + const embed = new EmbedBuilder() + .setDescription(`sent **${amount} coins** to ${recipient!.username}`) + .setColor("Green"); + + await interaction.reply({ embeds: [embed] }); + } +}); \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 2a3fb90..722c847 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,7 @@ import { env } from "@lib/env"; // Load commands await KyokoClient.loadCommands(); +await KyokoClient.deployCommands(); KyokoClient.once(Events.ClientReady, async c => { console.log(`Ready! Logged in as ${c.user.tag}`); diff --git a/src/modules/economy/economy.service.ts b/src/modules/economy/economy.service.ts index 7323bc3..14d2fdd 100644 --- a/src/modules/economy/economy.service.ts +++ b/src/modules/economy/economy.service.ts @@ -9,4 +9,10 @@ export async function getUserBalance(userId: string) { export async function setUserBalance(userId: string, balance: number) { await DrizzleClient.update(users).set({ balance }).where(eq(users.userId, userId)); +} + +export async function addUserBalance(userId: string, amount: number) { + const user = await DrizzleClient.query.users.findFirst({ where: eq(users.userId, userId) }); + if (!user) return; + await DrizzleClient.update(users).set({ balance: user.balance + amount }).where(eq(users.userId, userId)); } \ No newline at end of file diff --git a/src/modules/users/users.service.ts b/src/modules/users/users.service.ts index 5a3905c..c93e57c 100644 --- a/src/modules/users/users.service.ts +++ b/src/modules/users/users.service.ts @@ -8,4 +8,8 @@ export async function getUserById(userId: string) { export async function createUser(userId: string) { return (await DrizzleClient.insert(users).values({ userId }).returning())[0]!; +} + +export async function updateUserDaily(userId: string, lastDaily: Date, dailyStreak: number) { + await DrizzleClient.update(users).set({ lastDaily, dailyStreak }).where(eq(users.userId, userId)); } \ No newline at end of file