From 8f700365a4819fbbfa6e28d726b883c43c071490 Mon Sep 17 00:00:00 2001 From: Hemant Date: Sat, 5 Oct 2024 15:24:30 +0530 Subject: [PATCH 01/40] chore: formatted tvl data --- src/components/TVL.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/TVL.tsx b/src/components/TVL.tsx index 4318d67..49fccc9 100755 --- a/src/components/TVL.tsx +++ b/src/components/TVL.tsx @@ -28,6 +28,15 @@ const TVL: React.FC = () => { const address = useAtomValue(addressAtom); const referralCode = useAtomValue(referralCodeAtom); + const formattedTvlData = (tvlData: number) => { + if (tvlData >= 1000000) { + return `${(tvlData / 1000000).toFixed(2)}m`; + } else if (tvlData >= 1000) { + return `${(tvlData / 1000).toFixed(2)}k`; + } + return tvlData.toString(); + }; + return ( { {isPending ? ( ) : ( - Number(data?.tvl.toFixed(2)).toLocaleString() + formattedTvlData(Number(data?.tvl)) )} From d929f2f3591defccd487bfe79cf6f696cfda732d Mon Sep 17 00:00:00 2001 From: Hemant Date: Sat, 5 Oct 2024 17:08:05 +0530 Subject: [PATCH 02/40] fix: added dollar sign before tvl data --- src/components/TVL.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/TVL.tsx b/src/components/TVL.tsx index 49fccc9..99a021e 100755 --- a/src/components/TVL.tsx +++ b/src/components/TVL.tsx @@ -30,11 +30,11 @@ const TVL: React.FC = () => { const formattedTvlData = (tvlData: number) => { if (tvlData >= 1000000) { - return `${(tvlData / 1000000).toFixed(2)}m`; + return `$${(tvlData / 1000000).toFixed(2)}m`; } else if (tvlData >= 1000) { - return `${(tvlData / 1000).toFixed(2)}k`; + return `$${(tvlData / 1000).toFixed(2)}k`; } - return tvlData.toString(); + return `$${tvlData.toString()}`; }; return ( From 15a78848641b6483b98e1cbddbdb8863ea60977b Mon Sep 17 00:00:00 2001 From: Hemant Date: Sat, 5 Oct 2024 17:09:47 +0530 Subject: [PATCH 03/40] fix: removed dollar sign : ) --- src/components/TVL.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/TVL.tsx b/src/components/TVL.tsx index 99a021e..6ae07de 100755 --- a/src/components/TVL.tsx +++ b/src/components/TVL.tsx @@ -30,11 +30,11 @@ const TVL: React.FC = () => { const formattedTvlData = (tvlData: number) => { if (tvlData >= 1000000) { - return `$${(tvlData / 1000000).toFixed(2)}m`; + return `${(tvlData / 1000000).toFixed(2)}m`; } else if (tvlData >= 1000) { - return `$${(tvlData / 1000).toFixed(2)}k`; + return `${(tvlData / 1000).toFixed(2)}k`; } - return `$${tvlData.toString()}`; + return `${tvlData.toString()}`; }; return ( From a58423918e9938f55a3470401543b648c888c838 Mon Sep 17 00:00:00 2001 From: Akira <156126180+akiraonstarknet@users.noreply.github.com> Date: Sat, 5 Oct 2024 18:52:12 +0530 Subject: [PATCH 04/40] fix: undefined tvl formatting issue --- src/components/TVL.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/TVL.tsx b/src/components/TVL.tsx index 6ae07de..09c5c7f 100755 --- a/src/components/TVL.tsx +++ b/src/components/TVL.tsx @@ -52,7 +52,7 @@ const TVL: React.FC = () => { {isPending ? ( ) : ( - formattedTvlData(Number(data?.tvl)) + {data ? formattedTvlData(Number(data.tvl)) : '0'} )} From 2ba89237fb283183bb9d22f82b5c58e562b5eeac Mon Sep 17 00:00:00 2001 From: Hemant Date: Sat, 5 Oct 2024 19:26:38 +0530 Subject: [PATCH 05/40] fix: compile error in TVL --- src/components/TVL.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/TVL.tsx b/src/components/TVL.tsx index 09c5c7f..41205f0 100755 --- a/src/components/TVL.tsx +++ b/src/components/TVL.tsx @@ -51,8 +51,10 @@ const TVL: React.FC = () => { $ {isPending ? ( + ) : data && data?.tvl ? ( + formattedTvlData(Number(data.tvl)) ) : ( - {data ? formattedTvlData(Number(data.tvl)) : '0'} + '0' )} From 4d2754a798073c1a71569954a1198d4e7ec3b07e Mon Sep 17 00:00:00 2001 From: Hemant Date: Fri, 25 Oct 2024 12:27:35 +0530 Subject: [PATCH 06/40] chore: raffle implementation --- next.config.mjs | 9 +- .../migration.sql | 45 ++ .../migration.sql | 12 + .../migration.sql | 32 + .../migration.sql | 13 + .../migration.sql | 23 + prisma/migrations/migration_lock.toml | 4 +- prisma/schema.prisma | 56 +- public/raffle-hero.svg | 622 ++++++++++++++++++ public/strkfarm-white.svg | 8 + src/app/api/raffle/activeDeposits/route.ts | 53 ++ src/app/api/raffle/getUser/[address]/route.ts | 37 ++ src/app/api/raffle/luckyWinner/route.ts | 70 ++ src/app/api/raffle/registerUser/route.ts | 56 ++ src/app/api/raffle/sharedOnX/route.ts | 53 ++ .../raffle/_components/register-raffle.tsx | 80 +++ src/app/raffle/_components/share-on-x.tsx | 84 +++ src/app/raffle/page.tsx | 135 ++++ vercel.json | 8 + 19 files changed, 1384 insertions(+), 16 deletions(-) create mode 100644 prisma/migrations/20241024083952_added_new_column_in_user_table/migration.sql create mode 100644 prisma/migrations/20241024101112_added_new_raffle_table/migration.sql create mode 100644 prisma/migrations/20241024102031_added_new_raffle_table/migration.sql create mode 100644 prisma/migrations/20241024111304_updated_models/migration.sql create mode 100644 prisma/migrations/20241025043050_added_new_lucky_winners_model/migration.sql create mode 100644 public/raffle-hero.svg create mode 100644 public/strkfarm-white.svg create mode 100644 src/app/api/raffle/activeDeposits/route.ts create mode 100644 src/app/api/raffle/getUser/[address]/route.ts create mode 100644 src/app/api/raffle/luckyWinner/route.ts create mode 100644 src/app/api/raffle/registerUser/route.ts create mode 100644 src/app/api/raffle/sharedOnX/route.ts create mode 100644 src/app/raffle/_components/register-raffle.tsx create mode 100644 src/app/raffle/_components/share-on-x.tsx create mode 100644 src/app/raffle/page.tsx create mode 100644 vercel.json diff --git a/next.config.mjs b/next.config.mjs index 83948df..9b833cd 100755 --- a/next.config.mjs +++ b/next.config.mjs @@ -2,9 +2,9 @@ const nextConfig = { // output: 'export', compiler: { - removeConsole: { - exclude: ['error', 'debug'], - }, + // removeConsole: { + // exclude: ['error', 'debug'], + // }, }, async rewrites() { return [ @@ -62,7 +62,8 @@ const nextConfig = { }, { source: '/tnc/v1', - destination: 'https://github.com/strkfarm/static-assets/blob/177389cad715d69245c1b125df87f90318ac2d7b/tnc.pdf', + destination: + 'https://github.com/strkfarm/static-assets/blob/177389cad715d69245c1b125df87f90318ac2d7b/tnc.pdf', permanent: true, }, ]; diff --git a/prisma/migrations/20241024083952_added_new_column_in_user_table/migration.sql b/prisma/migrations/20241024083952_added_new_column_in_user_table/migration.sql new file mode 100644 index 0000000..dcea1c2 --- /dev/null +++ b/prisma/migrations/20241024083952_added_new_column_in_user_table/migration.sql @@ -0,0 +1,45 @@ +/* + Warnings: + + - A unique constraint covering the columns `[userId,refreeAddress]` on the table `Referral` will be added. If there are existing duplicate values, this will fail. + +*/ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "isRaffleParticipant" BOOLEAN DEFAULT false, +ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP; + +-- CreateTable +CREATE TABLE "Signatures" ( + "id" SERIAL NOT NULL, + "signature" TEXT NOT NULL, + "tncDocVersion" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "userId" INTEGER NOT NULL, + + CONSTRAINT "Signatures_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "og_nft_users" ( + "id" SERIAL NOT NULL, + "userId" INTEGER NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "og_nft_users_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Signatures_userId_tncDocVersion_key" ON "Signatures"("userId", "tncDocVersion"); + +-- CreateIndex +CREATE UNIQUE INDEX "og_nft_users_userId_key" ON "og_nft_users"("userId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Referral_userId_refreeAddress_key" ON "Referral"("userId", "refreeAddress"); + +-- AddForeignKey +ALTER TABLE "Signatures" ADD CONSTRAINT "Signatures_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "og_nft_users" ADD CONSTRAINT "og_nft_users_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20241024101112_added_new_raffle_table/migration.sql b/prisma/migrations/20241024101112_added_new_raffle_table/migration.sql new file mode 100644 index 0000000..79238e0 --- /dev/null +++ b/prisma/migrations/20241024101112_added_new_raffle_table/migration.sql @@ -0,0 +1,12 @@ +-- CreateTable +CREATE TABLE "Raffle" ( + "id" SERIAL NOT NULL, + "address" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "Raffle_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Raffle_address_key" ON "Raffle"("address"); diff --git a/prisma/migrations/20241024102031_added_new_raffle_table/migration.sql b/prisma/migrations/20241024102031_added_new_raffle_table/migration.sql new file mode 100644 index 0000000..3db862d --- /dev/null +++ b/prisma/migrations/20241024102031_added_new_raffle_table/migration.sql @@ -0,0 +1,32 @@ +/* + Warnings: + + - The primary key for the `Raffle` table will be changed. If it partially fails, the table could be left without primary key constraint. + - You are about to drop the column `address` on the `Raffle` table. All the data in the column will be lost. + - You are about to drop the column `id` on the `Raffle` table. All the data in the column will be lost. + - A unique constraint covering the columns `[raffleAddress]` on the table `Raffle` will be added. If there are existing duplicate values, this will fail. + - A unique constraint covering the columns `[userId,raffleAddress]` on the table `Raffle` will be added. If there are existing duplicate values, this will fail. + - Added the required column `raffleAddress` to the `Raffle` table without a default value. This is not possible if the table is not empty. + - Added the required column `userId` to the `Raffle` table without a default value. This is not possible if the table is not empty. + +*/ +-- DropIndex +DROP INDEX "Raffle_address_key"; + +-- AlterTable +ALTER TABLE "Raffle" DROP CONSTRAINT "Raffle_pkey", +DROP COLUMN "address", +DROP COLUMN "id", +ADD COLUMN "raffleAddress" TEXT NOT NULL, +ADD COLUMN "raffleId" SERIAL NOT NULL, +ADD COLUMN "userId" INTEGER NOT NULL, +ADD CONSTRAINT "Raffle_pkey" PRIMARY KEY ("raffleId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Raffle_raffleAddress_key" ON "Raffle"("raffleAddress"); + +-- CreateIndex +CREATE UNIQUE INDEX "Raffle_userId_raffleAddress_key" ON "Raffle"("userId", "raffleAddress"); + +-- AddForeignKey +ALTER TABLE "Raffle" ADD CONSTRAINT "Raffle_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20241024111304_updated_models/migration.sql b/prisma/migrations/20241024111304_updated_models/migration.sql new file mode 100644 index 0000000..d2d4ce3 --- /dev/null +++ b/prisma/migrations/20241024111304_updated_models/migration.sql @@ -0,0 +1,13 @@ +/* + Warnings: + + - You are about to drop the column `isRaffleParticipant` on the `User` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "Raffle" ADD COLUMN "activeDeposits" BOOLEAN DEFAULT false, +ADD COLUMN "isRaffleParticipant" BOOLEAN DEFAULT false, +ADD COLUMN "sharedOnX" BOOLEAN DEFAULT false; + +-- AlterTable +ALTER TABLE "User" DROP COLUMN "isRaffleParticipant"; diff --git a/prisma/migrations/20241025043050_added_new_lucky_winners_model/migration.sql b/prisma/migrations/20241025043050_added_new_lucky_winners_model/migration.sql new file mode 100644 index 0000000..a0e805d --- /dev/null +++ b/prisma/migrations/20241025043050_added_new_lucky_winners_model/migration.sql @@ -0,0 +1,23 @@ +-- CreateTable +CREATE TABLE "LuckyWinner" ( + "winnerId" SERIAL NOT NULL, + "winnerAddress" TEXT NOT NULL, + "updatedAt" TIMESTAMP(3) NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "raffleId" INTEGER NOT NULL, + "userId" INTEGER NOT NULL, + + CONSTRAINT "LuckyWinner_pkey" PRIMARY KEY ("winnerId") +); + +-- CreateIndex +CREATE UNIQUE INDEX "LuckyWinner_winnerAddress_key" ON "LuckyWinner"("winnerAddress"); + +-- CreateIndex +CREATE UNIQUE INDEX "LuckyWinner_userId_winnerAddress_key" ON "LuckyWinner"("userId", "winnerAddress"); + +-- AddForeignKey +ALTER TABLE "LuckyWinner" ADD CONSTRAINT "LuckyWinner_raffleId_fkey" FOREIGN KEY ("raffleId") REFERENCES "Raffle"("raffleId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LuckyWinner" ADD CONSTRAINT "LuckyWinner_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml index 6bf9015..fbffa92 100644 --- a/prisma/migrations/migration_lock.toml +++ b/prisma/migrations/migration_lock.toml @@ -1,3 +1,3 @@ -# Please do not edit this file manually -# It should be added in your version-control system (i.e. Git) +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) provider = "postgresql" \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma index a8a9915..7433bca 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -8,19 +8,55 @@ generator client { } model User { - id Int @id @default(autoincrement()) - address String @unique - isTncSigned Boolean? @default(false) + id Int @id @default(autoincrement()) + address String @unique + isTncSigned Boolean? @default(false) message String? - tncDocVersion String? @default("1.0") - referralCode String @unique + tncDocVersion String? @default("1.0") + referralCode String @unique referrals Referral[] - referralCount Int? @default(0) + referralCount Int? @default(0) + Raffles Raffle[] + og_nft_users og_nft_users? + Signatures Signatures[] + LuckyWinner LuckyWinner[] - createdAt DateTime @default(now()) - og_nft_users og_nft_users? - updatedAt DateTime @updatedAt @default(now()) - Signatures Signatures[] + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt +} + +model Raffle { + raffleId Int @id @default(autoincrement()) + raffleAddress String @unique + isRaffleParticipant Boolean? @default(false) + sharedOnX Boolean? @default(false) + activeDeposits Boolean? @default(false) + + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt + + User User @relation(fields: [userId], references: [id]) + userId Int + + LuckyWinner LuckyWinner[] + + @@unique([userId, raffleAddress], name: "unique_raffle") +} + +model LuckyWinner { + winnerId Int @id @default(autoincrement()) + winnerAddress String @unique + + updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + + Raffle Raffle @relation(fields: [raffleId], references: [raffleId]) + raffleId Int + + User User @relation(fields: [userId], references: [id]) + userId Int + + @@unique([userId, winnerAddress], name: "unique_lucky_winner") } model Signatures { diff --git a/public/raffle-hero.svg b/public/raffle-hero.svg new file mode 100644 index 0000000..91a3f11 --- /dev/null +++ b/public/raffle-hero.svg @@ -0,0 +1,622 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/strkfarm-white.svg b/public/strkfarm-white.svg new file mode 100644 index 0000000..6ae2788 --- /dev/null +++ b/public/strkfarm-white.svg @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/src/app/api/raffle/activeDeposits/route.ts b/src/app/api/raffle/activeDeposits/route.ts new file mode 100644 index 0000000..dae7950 --- /dev/null +++ b/src/app/api/raffle/activeDeposits/route.ts @@ -0,0 +1,53 @@ +import { NextResponse } from 'next/server'; + +import { db } from '@/db'; +import { standariseAddress } from '@/utils'; + +export async function POST(req: Request) { + const { address } = await req.json(); + + if (!address) { + return NextResponse.json({ + success: false, + message: 'address not found', + user: null, + }); + } + + // standardised address + let parsedAddress = address; + try { + parsedAddress = standariseAddress(address); + } catch (e) { + throw new Error('Invalid address'); + } + + const user = await db.raffle.findFirst({ + where: { + raffleAddress: parsedAddress, + }, + }); + + if (!user) { + return NextResponse.json({ + success: false, + message: 'User not found', + user: null, + }); + } + + const createdUser = await db.raffle.update({ + where: { + raffleAddress: parsedAddress, + }, + data: { + activeDeposits: true, + }, + }); + + return NextResponse.json({ + success: true, + message: 'User registered for raffle successfully', + user: createdUser, + }); +} diff --git a/src/app/api/raffle/getUser/[address]/route.ts b/src/app/api/raffle/getUser/[address]/route.ts new file mode 100644 index 0000000..cbbacb7 --- /dev/null +++ b/src/app/api/raffle/getUser/[address]/route.ts @@ -0,0 +1,37 @@ +import { NextResponse } from 'next/server'; + +import { db } from '@/db'; +import { standariseAddress } from '@/utils'; + +export async function GET(_req: Request, context: any) { + const { params } = context; + const address = params.address; + + if (!address) { + return NextResponse.json({ + success: false, + message: 'No address found', + }); + } + + // standardised address + const parsedAddress = standariseAddress(address); + + const user = await db.raffle.findFirst({ + where: { + raffleAddress: parsedAddress, + }, + }); + + if (!user) { + return NextResponse.json({ + success: false, + user: null, + }); + } + + return NextResponse.json({ + success: true, + user, + }); +} diff --git a/src/app/api/raffle/luckyWinner/route.ts b/src/app/api/raffle/luckyWinner/route.ts new file mode 100644 index 0000000..4a83e16 --- /dev/null +++ b/src/app/api/raffle/luckyWinner/route.ts @@ -0,0 +1,70 @@ +import { NextResponse } from 'next/server'; + +import { db } from '@/db'; + +export async function POST() { + try { + // Select a random raffle participant + const randomRaffleParticipant = await db.raffle.findFirst({ + where: { + isRaffleParticipant: true, + }, + orderBy: { + createdAt: 'asc', + }, + take: 1, + skip: Math.floor( + Math.random() * + (await db.raffle.count({ + where: { + isRaffleParticipant: true, + }, + })), + ), + }); + + if (!randomRaffleParticipant) { + return NextResponse.json({ + success: false, + message: 'No raffle participants found', + }); + } + + // Check if the user has already been added to the LuckyWinner table + const existingWinner = await db.luckyWinner.findUnique({ + where: { + winnerAddress: randomRaffleParticipant.raffleAddress, + }, + }); + + if (existingWinner) { + return NextResponse.json({ + success: false, + message: 'User is already a lucky winner', + }); + } + + // Add the selected user to the LuckyWinner table + const newLuckyWinner = await db.luckyWinner.create({ + data: { + winnerAddress: randomRaffleParticipant.raffleAddress, + userId: randomRaffleParticipant.userId, + raffleId: randomRaffleParticipant.raffleId, + }, + }); + + console.log(newLuckyWinner, 'newLuckyWinner------------'); + + return NextResponse.json({ + success: true, + message: 'Lucky winner selected successfully', + luckyWinner: newLuckyWinner, + }); + } catch (error) { + console.error('Error selecting a lucky winner:', error); + return NextResponse.json({ + success: false, + message: 'An error occurred while selecting a lucky winner', + }); + } +} diff --git a/src/app/api/raffle/registerUser/route.ts b/src/app/api/raffle/registerUser/route.ts new file mode 100644 index 0000000..58e7480 --- /dev/null +++ b/src/app/api/raffle/registerUser/route.ts @@ -0,0 +1,56 @@ +import { NextResponse } from 'next/server'; + +import { db } from '@/db'; +import { standariseAddress } from '@/utils'; + +export async function POST(req: Request) { + const { address } = await req.json(); + + if (!address) { + return NextResponse.json({ + success: false, + message: 'address not found', + user: null, + }); + } + + // standardised address + let parsedAddress = address; + try { + parsedAddress = standariseAddress(address); + } catch (e) { + throw new Error('Invalid address'); + } + + const user = await db.user.findFirst({ + where: { + address: parsedAddress, + }, + }); + + if (!user) { + return NextResponse.json({ + success: false, + message: 'User not found', + user: null, + }); + } + + const createdUser = await db.raffle.create({ + data: { + raffleAddress: parsedAddress, + isRaffleParticipant: true, + User: { + connect: { + address: parsedAddress, + }, + }, + }, + }); + + return NextResponse.json({ + success: true, + message: 'User registered for raffle successfully', + user: createdUser, + }); +} diff --git a/src/app/api/raffle/sharedOnX/route.ts b/src/app/api/raffle/sharedOnX/route.ts new file mode 100644 index 0000000..84efa5c --- /dev/null +++ b/src/app/api/raffle/sharedOnX/route.ts @@ -0,0 +1,53 @@ +import { NextResponse } from 'next/server'; + +import { db } from '@/db'; +import { standariseAddress } from '@/utils'; + +export async function POST(req: Request) { + const { address } = await req.json(); + + if (!address) { + return NextResponse.json({ + success: false, + message: 'address not found', + user: null, + }); + } + + // standardised address + let parsedAddress = address; + try { + parsedAddress = standariseAddress(address); + } catch (e) { + throw new Error('Invalid address'); + } + + const user = await db.raffle.findFirst({ + where: { + raffleAddress: parsedAddress, + }, + }); + + if (!user) { + return NextResponse.json({ + success: false, + message: 'User not found', + user: null, + }); + } + + const createdUser = await db.raffle.update({ + where: { + raffleAddress: parsedAddress, + }, + data: { + sharedOnX: true, + }, + }); + + return NextResponse.json({ + success: true, + message: 'User registered for raffle successfully', + user: createdUser, + }); +} diff --git a/src/app/raffle/_components/register-raffle.tsx b/src/app/raffle/_components/register-raffle.tsx new file mode 100644 index 0000000..5cbf63b --- /dev/null +++ b/src/app/raffle/_components/register-raffle.tsx @@ -0,0 +1,80 @@ +'use client'; + +import { Spinner } from '@chakra-ui/react'; +import { useAccount } from '@starknet-react/core'; +import axios from 'axios'; +import React from 'react'; +import toast from 'react-hot-toast'; + +const RegisterRaffle: React.FC = () => { + const { address } = useAccount(); + const [isUserRegistered, setIsUserRegistered] = React.useState(false); + const [loading, setLoading] = React.useState(false); + + const handleRegister = async () => { + setLoading(true); + + if (isUserRegistered) return; + + try { + const res = await axios.post('/api/raffle/registerUser', { + address, + }); + if (res?.data?.success) { + setIsUserRegistered(true); + toast.success('Successfully registered for the raffle!'); + } + } catch (error) { + console.error(error); + toast.error('Something went wrong'); + } finally { + setLoading(false); + } + + setLoading(false); + }; + + React.useEffect(() => { + if (!address) return; + + (async () => { + try { + const res = await axios.get(`/api/raffle/getUser/${address}`); + + if (res?.data?.success && res?.data?.user?.isRaffleParticipant) { + setIsUserRegistered(true); + } else setIsUserRegistered(false); + } catch (error) { + console.error(error); + toast.error('Something went wrong'); + } + })(); + }, [address]); + + return isUserRegistered ? ( + + ) : ( + + ); +}; + +export default RegisterRaffle; diff --git a/src/app/raffle/_components/share-on-x.tsx b/src/app/raffle/_components/share-on-x.tsx new file mode 100644 index 0000000..d34796b --- /dev/null +++ b/src/app/raffle/_components/share-on-x.tsx @@ -0,0 +1,84 @@ +'use client'; + +import { Spinner } from '@chakra-ui/react'; +import { useAccount } from '@starknet-react/core'; +import axios from 'axios'; +import Image from 'next/image'; +import Link from 'next/link'; +import React from 'react'; +import toast from 'react-hot-toast'; + +const ShareOnX = () => { + const { address } = useAccount(); + + const [loading, setLoading] = React.useState(false); + const [isSharedOnX, setIsSharedOnX] = React.useState(false); + + const handleShare = async () => { + setLoading(true); + + try { + const res = await axios.post('/api/raffle/sharedOnX', { + address, + }); + + if (res?.data?.success) { + await new Promise((resolve) => setTimeout(resolve, 8000)); + setIsSharedOnX(true); + toast.success('Shared !'); + } + } catch (error) { + console.error(error); + toast.error('Something went wrong'); + } finally { + setLoading(false); + } + }; + + React.useEffect(() => { + if (!address) return; + + (async () => { + try { + const res = await axios.get(`/api/raffle/getUser/${address}`); + + if (res?.data?.success && res?.data?.user?.sharedOnX) { + setIsSharedOnX(true); + } else setIsSharedOnX(false); + } catch (error) { + console.error(error); + toast.error('Something went wrong'); + } + })(); + }, [address]); + + return ( +
+
+
+ STRKFarm +

Share on X

+
+ + {}} + > + {loading && !isSharedOnX && ( + + )} + {isSharedOnX ? 'Shared !' : 'Share'} + +
+
+ ); +}; + +export default ShareOnX; diff --git a/src/app/raffle/page.tsx b/src/app/raffle/page.tsx new file mode 100644 index 0000000..e823693 --- /dev/null +++ b/src/app/raffle/page.tsx @@ -0,0 +1,135 @@ +import { NextPage } from 'next'; +import Image from 'next/image'; +import React from 'react'; + +import RegisterRaffle from './_components/register-raffle'; +import ShareOnX from './_components/share-on-x'; + +const Raffle: NextPage = () => { + return ( +
+
+
+

+ 8 Pool Raffle +

+

+ Each week, we select 8 lucky addresses from Starknet's pool{' '} +
of active addresses from the previous week.{' '} +

+ + +
+ + Raffle Hero +
+ +
+
+
+

Pool Size

+ +
+
+ 500 STRK +
+
+
+ +
+

+ Raffle end's in +

+
+
+ 18 + + Days + +
+
+ 18 + + Hrs + +
+
+ 05 + + Mins + +
+
+ 1 + + Sec + +
+
+
+
+
+ +
+
+

Tasks

+

+ Earn + + {' '} + 10 tickets each week{' '} + + by staying active on STRKFarm and increase your changes +

+ +
+ + + {[...Array(3)].map((_, i) => ( +
+
+
+ STRKFarm +

+ Any transaction on Starknet +

+
+ + +
+
+ ))} +
+
+
+ +
+
Rules:
+

+ 1. You have upto 1 week to claim your rewards. Any unclaimed reward + will be added to next pool prize. +

+

+ 2. Only account contracts are considered for this raffle +

+
+
+ ); +}; + +export default Raffle; diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..9e0f318 --- /dev/null +++ b/vercel.json @@ -0,0 +1,8 @@ +{ + "crons": [ + { + "path": "/api/raffle/luckyWinner", + "schedule": "0 13,14,15 * * *" + } + ] +} From 93471cdc04522f545dc5697805bf3d8abb7fcfcd Mon Sep 17 00:00:00 2001 From: Hemant Date: Fri, 25 Oct 2024 12:40:18 +0530 Subject: [PATCH 07/40] chore: deploy trigger --- src/app/raffle/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/raffle/page.tsx b/src/app/raffle/page.tsx index e823693..fffd27b 100644 --- a/src/app/raffle/page.tsx +++ b/src/app/raffle/page.tsx @@ -25,7 +25,7 @@ const Raffle: NextPage = () => { src="/raffle-hero.svg" width={385} height={247} - alt="Raffle Hero" + alt="Raffle Hero Image" /> From 8c0bfa526892f414c741020ef7f0bb8e96d11e86 Mon Sep 17 00:00:00 2001 From: Hemant Date: Fri, 25 Oct 2024 12:46:55 +0530 Subject: [PATCH 08/40] chore: updated cron expression --- vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index 9e0f318..6647087 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "crons": [ { "path": "/api/raffle/luckyWinner", - "schedule": "0 13,14,15 * * *" + "schedule": "0 13 * * *" } ] } From 478fddf2ce9ae556f63d5b53f540587cd3089681 Mon Sep 17 00:00:00 2001 From: Hemant Date: Fri, 25 Oct 2024 13:03:01 +0530 Subject: [PATCH 09/40] chore: updated cron expression --- vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index 6647087..e45bd70 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "crons": [ { "path": "/api/raffle/luckyWinner", - "schedule": "0 13 * * *" + "schedule": "10 13 * * *" } ] } From a5b131f223ee70f30ba52daa2c480faff6286125 Mon Sep 17 00:00:00 2001 From: Hemant Date: Fri, 25 Oct 2024 13:12:42 +0530 Subject: [PATCH 10/40] chore: updated cron expression --- vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index e45bd70..1c9f088 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "crons": [ { "path": "/api/raffle/luckyWinner", - "schedule": "10 13 * * *" + "schedule": "48 19 * * *" } ] } From 4c15c9adeba9ef3838ec06c8137e122baefe19e7 Mon Sep 17 00:00:00 2001 From: Hemant Date: Fri, 25 Oct 2024 13:18:23 +0530 Subject: [PATCH 11/40] chore: update route method --- src/app/api/raffle/luckyWinner/route.ts | 4 +++- vercel.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/api/raffle/luckyWinner/route.ts b/src/app/api/raffle/luckyWinner/route.ts index 4a83e16..748ffb5 100644 --- a/src/app/api/raffle/luckyWinner/route.ts +++ b/src/app/api/raffle/luckyWinner/route.ts @@ -2,7 +2,9 @@ import { NextResponse } from 'next/server'; import { db } from '@/db'; -export async function POST() { +export const dynamic = 'force-dynamic'; // static by default, unless reading the request + +export async function GET() { try { // Select a random raffle participant const randomRaffleParticipant = await db.raffle.findFirst({ diff --git a/vercel.json b/vercel.json index 1c9f088..b9def0e 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "crons": [ { "path": "/api/raffle/luckyWinner", - "schedule": "48 19 * * *" + "schedule": "51 19 * * *" } ] } From b8bb7389344dbb8416f22d21b566f3c75fa8f5e0 Mon Sep 17 00:00:00 2001 From: Hemant Date: Fri, 25 Oct 2024 13:44:19 +0530 Subject: [PATCH 12/40] chore: update route logic --- src/app/api/raffle/luckyWinner/route.ts | 69 ++++++++++++++++--------- vercel.json | 2 +- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/src/app/api/raffle/luckyWinner/route.ts b/src/app/api/raffle/luckyWinner/route.ts index 748ffb5..d85db17 100644 --- a/src/app/api/raffle/luckyWinner/route.ts +++ b/src/app/api/raffle/luckyWinner/route.ts @@ -6,43 +6,64 @@ export const dynamic = 'force-dynamic'; // static by default, unless reading the export async function GET() { try { - // Select a random raffle participant - const randomRaffleParticipant = await db.raffle.findFirst({ + const raffleParticipantsCount = await db.raffle.count({ where: { isRaffleParticipant: true, + sharedOnX: true, + activeDeposits: true, }, - orderBy: { - createdAt: 'asc', - }, - take: 1, - skip: Math.floor( - Math.random() * - (await db.raffle.count({ - where: { - isRaffleParticipant: true, - }, - })), - ), }); - if (!randomRaffleParticipant) { + if (raffleParticipantsCount === 0) { return NextResponse.json({ success: false, message: 'No raffle participants found', }); } - // Check if the user has already been added to the LuckyWinner table - const existingWinner = await db.luckyWinner.findUnique({ - where: { - winnerAddress: randomRaffleParticipant.raffleAddress, - }, - }); + let randomRaffleParticipant; + let foundValidParticipant = false; + + // Keep searching until a valid participant is found + while (!foundValidParticipant) { + // Select a random raffle participant + randomRaffleParticipant = await db.raffle.findFirst({ + where: { + isRaffleParticipant: true, + sharedOnX: true, + activeDeposits: true, + }, + orderBy: { + createdAt: 'asc', + }, + take: 1, + skip: Math.floor(Math.random() * raffleParticipantsCount), + }); - if (existingWinner) { + if (!randomRaffleParticipant) { + return NextResponse.json({ + success: false, + message: 'No raffle participants found', + }); + } + + // Check if the selected participant is already a lucky winner + const existingWinner = await db.luckyWinner.findUnique({ + where: { + winnerAddress: randomRaffleParticipant.raffleAddress, + }, + }); + + // If not already a winner, break the loop + if (!existingWinner) { + foundValidParticipant = true; + } + } + + if (!randomRaffleParticipant) { return NextResponse.json({ success: false, - message: 'User is already a lucky winner', + message: 'No raffle participants found', }); } @@ -55,8 +76,6 @@ export async function GET() { }, }); - console.log(newLuckyWinner, 'newLuckyWinner------------'); - return NextResponse.json({ success: true, message: 'Lucky winner selected successfully', diff --git a/vercel.json b/vercel.json index b9def0e..bb107cd 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "crons": [ { "path": "/api/raffle/luckyWinner", - "schedule": "51 19 * * *" + "schedule": "17 20 * * *" } ] } From 31e651d7450143f23283427d6003edb02c95293e Mon Sep 17 00:00:00 2001 From: Hemant Date: Fri, 25 Oct 2024 13:52:28 +0530 Subject: [PATCH 13/40] chore: updated cron expression --- src/app/api/raffle/luckyWinner/route.ts | 2 ++ vercel.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/api/raffle/luckyWinner/route.ts b/src/app/api/raffle/luckyWinner/route.ts index d85db17..fd58ae4 100644 --- a/src/app/api/raffle/luckyWinner/route.ts +++ b/src/app/api/raffle/luckyWinner/route.ts @@ -76,6 +76,8 @@ export async function GET() { }, }); + console.log(newLuckyWinner); + return NextResponse.json({ success: true, message: 'Lucky winner selected successfully', diff --git a/vercel.json b/vercel.json index bb107cd..f3e7056 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "crons": [ { "path": "/api/raffle/luckyWinner", - "schedule": "17 20 * * *" + "schedule": "25 20 * * *" } ] } From 898849c3283c1de17d8b88118c1e1211f86c87c0 Mon Sep 17 00:00:00 2001 From: Hemant Date: Fri, 25 Oct 2024 13:59:52 +0530 Subject: [PATCH 14/40] chore: updated cron expression --- vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index f3e7056..a370e38 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "crons": [ { "path": "/api/raffle/luckyWinner", - "schedule": "25 20 * * *" + "schedule": "33 20 * * *" } ] } From 1a526dab478b5b2f3d6093808285942e34c3f231 Mon Sep 17 00:00:00 2001 From: Hemant Date: Mon, 28 Oct 2024 19:24:34 +0530 Subject: [PATCH 15/40] chore: code refactor --- .../20240818115638_init/migration.sql | 12 -- .../migration.sql | 22 --- .../migration.sql | 14 -- .../migration.sql | 2 - .../migration.sql | 2 - .../migration.sql | 18 --- .../migration.sql | 32 ---- .../migration.sql | 23 --- .../migration.sql | 14 -- .../migration.sql | 45 ------ .../migration.sql | 12 -- .../migration.sql | 32 ---- .../migration.sql | 13 -- .../migration.sql | 23 --- .../20241028130637_changes/migration.sql | 111 ++++++++++++++ prisma/schema.prisma | 8 +- src/app/api/raffle/activeDeposits/route.ts | 53 ------- src/app/api/raffle/getUser/[address]/route.ts | 37 ----- src/app/api/raffle/luckyWinner/route.ts | 5 +- src/app/api/raffle/registerUser/route.ts | 56 ------- src/app/api/raffle/route.ts | 143 ++++++++++++++++++ src/app/api/raffle/sharedOnX/route.ts | 53 ------- src/app/api/tnc/getUser/[address]/route.ts | 26 +++- .../raffle/_components/register-raffle.tsx | 7 +- src/app/raffle/_components/share-on-x.tsx | 7 +- 25 files changed, 294 insertions(+), 476 deletions(-) delete mode 100644 prisma/migrations/20240818115638_init/migration.sql delete mode 100644 prisma/migrations/20240818143249_updated_user_model/migration.sql delete mode 100644 prisma/migrations/20240824114901_updated_user_model/migration.sql delete mode 100644 prisma/migrations/20240824115758_updated_user_model/migration.sql delete mode 100644 prisma/migrations/20240824121027_updated_user_model/migration.sql delete mode 100644 prisma/migrations/20240824132519_added_refree_model/migration.sql delete mode 100644 prisma/migrations/20240825061257_updated_user_model/migration.sql delete mode 100644 prisma/migrations/20240825064700_updated_user_model/migration.sql delete mode 100644 prisma/migrations/20240825141032_updated_referral_model/migration.sql delete mode 100644 prisma/migrations/20241024083952_added_new_column_in_user_table/migration.sql delete mode 100644 prisma/migrations/20241024101112_added_new_raffle_table/migration.sql delete mode 100644 prisma/migrations/20241024102031_added_new_raffle_table/migration.sql delete mode 100644 prisma/migrations/20241024111304_updated_models/migration.sql delete mode 100644 prisma/migrations/20241025043050_added_new_lucky_winners_model/migration.sql create mode 100644 prisma/migrations/20241028130637_changes/migration.sql delete mode 100644 src/app/api/raffle/activeDeposits/route.ts delete mode 100644 src/app/api/raffle/getUser/[address]/route.ts delete mode 100644 src/app/api/raffle/registerUser/route.ts create mode 100644 src/app/api/raffle/route.ts delete mode 100644 src/app/api/raffle/sharedOnX/route.ts diff --git a/prisma/migrations/20240818115638_init/migration.sql b/prisma/migrations/20240818115638_init/migration.sql deleted file mode 100644 index 08f2584..0000000 --- a/prisma/migrations/20240818115638_init/migration.sql +++ /dev/null @@ -1,12 +0,0 @@ --- CreateTable -CREATE TABLE "User" ( - "id" SERIAL NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "email" TEXT NOT NULL, - "name" TEXT, - - CONSTRAINT "User_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); diff --git a/prisma/migrations/20240818143249_updated_user_model/migration.sql b/prisma/migrations/20240818143249_updated_user_model/migration.sql deleted file mode 100644 index 978dd95..0000000 --- a/prisma/migrations/20240818143249_updated_user_model/migration.sql +++ /dev/null @@ -1,22 +0,0 @@ -/* - Warnings: - - - You are about to drop the column `email` on the `User` table. All the data in the column will be lost. - - You are about to drop the column `name` on the `User` table. All the data in the column will be lost. - - A unique constraint covering the columns `[address]` on the table `User` will be added. If there are existing duplicate values, this will fail. - - Added the required column `address` to the `User` table without a default value. This is not possible if the table is not empty. - - Added the required column `message` to the `User` table without a default value. This is not possible if the table is not empty. - -*/ --- DropIndex -DROP INDEX "User_email_key"; - --- AlterTable -ALTER TABLE "User" DROP COLUMN "email", -DROP COLUMN "name", -ADD COLUMN "address" TEXT NOT NULL, -ADD COLUMN "message" TEXT NOT NULL, -ADD COLUMN "tncDocVersion" TEXT NOT NULL DEFAULT '1.0'; - --- CreateIndex -CREATE UNIQUE INDEX "User_address_key" ON "User"("address"); diff --git a/prisma/migrations/20240824114901_updated_user_model/migration.sql b/prisma/migrations/20240824114901_updated_user_model/migration.sql deleted file mode 100644 index 8a0bc97..0000000 --- a/prisma/migrations/20240824114901_updated_user_model/migration.sql +++ /dev/null @@ -1,14 +0,0 @@ -/* - Warnings: - - - A unique constraint covering the columns `[referralCode]` on the table `User` will be added. If there are existing duplicate values, this will fail. - - Added the required column `referralCode` to the `User` table without a default value. This is not possible if the table is not empty. - -*/ --- AlterTable -ALTER TABLE "User" ADD COLUMN "referralCode" TEXT NOT NULL, -ALTER COLUMN "message" DROP NOT NULL, -ALTER COLUMN "tncDocVersion" DROP NOT NULL; - --- CreateIndex -CREATE UNIQUE INDEX "User_referralCode_key" ON "User"("referralCode"); diff --git a/prisma/migrations/20240824115758_updated_user_model/migration.sql b/prisma/migrations/20240824115758_updated_user_model/migration.sql deleted file mode 100644 index ea5ea2c..0000000 --- a/prisma/migrations/20240824115758_updated_user_model/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE "User" ADD COLUMN "isTncSigned" BOOLEAN NOT NULL DEFAULT false; diff --git a/prisma/migrations/20240824121027_updated_user_model/migration.sql b/prisma/migrations/20240824121027_updated_user_model/migration.sql deleted file mode 100644 index 5ec0b27..0000000 --- a/prisma/migrations/20240824121027_updated_user_model/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterTable -ALTER TABLE "User" ALTER COLUMN "isTncSigned" DROP NOT NULL; diff --git a/prisma/migrations/20240824132519_added_refree_model/migration.sql b/prisma/migrations/20240824132519_added_refree_model/migration.sql deleted file mode 100644 index 0f28992..0000000 --- a/prisma/migrations/20240824132519_added_refree_model/migration.sql +++ /dev/null @@ -1,18 +0,0 @@ --- AlterTable -ALTER TABLE "User" ADD COLUMN "refreeCount" INTEGER DEFAULT 0; - --- CreateTable -CREATE TABLE "Refree" ( - "id" SERIAL NOT NULL, - "address" TEXT NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "userId" INTEGER, - - CONSTRAINT "Refree_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "Refree_address_key" ON "Refree"("address"); - --- AddForeignKey -ALTER TABLE "Refree" ADD CONSTRAINT "Refree_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/migrations/20240825061257_updated_user_model/migration.sql b/prisma/migrations/20240825061257_updated_user_model/migration.sql deleted file mode 100644 index 9920d71..0000000 --- a/prisma/migrations/20240825061257_updated_user_model/migration.sql +++ /dev/null @@ -1,32 +0,0 @@ -/* - Warnings: - - - You are about to drop the column `refreeCount` on the `User` table. All the data in the column will be lost. - - You are about to drop the `Refree` table. If the table is not empty, all the data it contains will be lost. - -*/ --- DropForeignKey -ALTER TABLE "Refree" DROP CONSTRAINT "Refree_userId_fkey"; - --- AlterTable -ALTER TABLE "User" DROP COLUMN "refreeCount", -ADD COLUMN "referralCount" INTEGER DEFAULT 0; - --- DropTable -DROP TABLE "Refree"; - --- CreateTable -CREATE TABLE "Referral" ( - "id" SERIAL NOT NULL, - "refreeAddress" TEXT NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "referralId" INTEGER, - - CONSTRAINT "Referral_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "Referral_refreeAddress_key" ON "Referral"("refreeAddress"); - --- AddForeignKey -ALTER TABLE "Referral" ADD CONSTRAINT "Referral_referralId_fkey" FOREIGN KEY ("referralId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/migrations/20240825064700_updated_user_model/migration.sql b/prisma/migrations/20240825064700_updated_user_model/migration.sql deleted file mode 100644 index 4cfcc1c..0000000 --- a/prisma/migrations/20240825064700_updated_user_model/migration.sql +++ /dev/null @@ -1,23 +0,0 @@ -/* - Warnings: - - - The primary key for the `Referral` table will be changed. If it partially fails, the table could be left without primary key constraint. - - You are about to drop the column `id` on the `Referral` table. All the data in the column will be lost. - - Made the column `referralId` on table `Referral` required. This step will fail if there are existing NULL values in that column. - -*/ --- DropForeignKey -ALTER TABLE "Referral" DROP CONSTRAINT "Referral_referralId_fkey"; - --- AlterTable -CREATE SEQUENCE referral_referralid_seq; -ALTER TABLE "Referral" DROP CONSTRAINT "Referral_pkey", -DROP COLUMN "id", -ADD COLUMN "userId" INTEGER, -ALTER COLUMN "referralId" SET NOT NULL, -ALTER COLUMN "referralId" SET DEFAULT nextval('referral_referralid_seq'), -ADD CONSTRAINT "Referral_pkey" PRIMARY KEY ("referralId"); -ALTER SEQUENCE referral_referralid_seq OWNED BY "Referral"."referralId"; - --- AddForeignKey -ALTER TABLE "Referral" ADD CONSTRAINT "Referral_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/migrations/20240825141032_updated_referral_model/migration.sql b/prisma/migrations/20240825141032_updated_referral_model/migration.sql deleted file mode 100644 index 13d9a7a..0000000 --- a/prisma/migrations/20240825141032_updated_referral_model/migration.sql +++ /dev/null @@ -1,14 +0,0 @@ -/* - Warnings: - - - Made the column `userId` on table `Referral` required. This step will fail if there are existing NULL values in that column. - -*/ --- DropForeignKey -ALTER TABLE "Referral" DROP CONSTRAINT "Referral_userId_fkey"; - --- AlterTable -ALTER TABLE "Referral" ALTER COLUMN "userId" SET NOT NULL; - --- AddForeignKey -ALTER TABLE "Referral" ADD CONSTRAINT "Referral_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20241024083952_added_new_column_in_user_table/migration.sql b/prisma/migrations/20241024083952_added_new_column_in_user_table/migration.sql deleted file mode 100644 index dcea1c2..0000000 --- a/prisma/migrations/20241024083952_added_new_column_in_user_table/migration.sql +++ /dev/null @@ -1,45 +0,0 @@ -/* - Warnings: - - - A unique constraint covering the columns `[userId,refreeAddress]` on the table `Referral` will be added. If there are existing duplicate values, this will fail. - -*/ --- AlterTable -ALTER TABLE "User" ADD COLUMN "isRaffleParticipant" BOOLEAN DEFAULT false, -ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP; - --- CreateTable -CREATE TABLE "Signatures" ( - "id" SERIAL NOT NULL, - "signature" TEXT NOT NULL, - "tncDocVersion" TEXT NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "userId" INTEGER NOT NULL, - - CONSTRAINT "Signatures_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "og_nft_users" ( - "id" SERIAL NOT NULL, - "userId" INTEGER NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL, - - CONSTRAINT "og_nft_users_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "Signatures_userId_tncDocVersion_key" ON "Signatures"("userId", "tncDocVersion"); - --- CreateIndex -CREATE UNIQUE INDEX "og_nft_users_userId_key" ON "og_nft_users"("userId"); - --- CreateIndex -CREATE UNIQUE INDEX "Referral_userId_refreeAddress_key" ON "Referral"("userId", "refreeAddress"); - --- AddForeignKey -ALTER TABLE "Signatures" ADD CONSTRAINT "Signatures_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "og_nft_users" ADD CONSTRAINT "og_nft_users_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20241024101112_added_new_raffle_table/migration.sql b/prisma/migrations/20241024101112_added_new_raffle_table/migration.sql deleted file mode 100644 index 79238e0..0000000 --- a/prisma/migrations/20241024101112_added_new_raffle_table/migration.sql +++ /dev/null @@ -1,12 +0,0 @@ --- CreateTable -CREATE TABLE "Raffle" ( - "id" SERIAL NOT NULL, - "address" TEXT NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - - CONSTRAINT "Raffle_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "Raffle_address_key" ON "Raffle"("address"); diff --git a/prisma/migrations/20241024102031_added_new_raffle_table/migration.sql b/prisma/migrations/20241024102031_added_new_raffle_table/migration.sql deleted file mode 100644 index 3db862d..0000000 --- a/prisma/migrations/20241024102031_added_new_raffle_table/migration.sql +++ /dev/null @@ -1,32 +0,0 @@ -/* - Warnings: - - - The primary key for the `Raffle` table will be changed. If it partially fails, the table could be left without primary key constraint. - - You are about to drop the column `address` on the `Raffle` table. All the data in the column will be lost. - - You are about to drop the column `id` on the `Raffle` table. All the data in the column will be lost. - - A unique constraint covering the columns `[raffleAddress]` on the table `Raffle` will be added. If there are existing duplicate values, this will fail. - - A unique constraint covering the columns `[userId,raffleAddress]` on the table `Raffle` will be added. If there are existing duplicate values, this will fail. - - Added the required column `raffleAddress` to the `Raffle` table without a default value. This is not possible if the table is not empty. - - Added the required column `userId` to the `Raffle` table without a default value. This is not possible if the table is not empty. - -*/ --- DropIndex -DROP INDEX "Raffle_address_key"; - --- AlterTable -ALTER TABLE "Raffle" DROP CONSTRAINT "Raffle_pkey", -DROP COLUMN "address", -DROP COLUMN "id", -ADD COLUMN "raffleAddress" TEXT NOT NULL, -ADD COLUMN "raffleId" SERIAL NOT NULL, -ADD COLUMN "userId" INTEGER NOT NULL, -ADD CONSTRAINT "Raffle_pkey" PRIMARY KEY ("raffleId"); - --- CreateIndex -CREATE UNIQUE INDEX "Raffle_raffleAddress_key" ON "Raffle"("raffleAddress"); - --- CreateIndex -CREATE UNIQUE INDEX "Raffle_userId_raffleAddress_key" ON "Raffle"("userId", "raffleAddress"); - --- AddForeignKey -ALTER TABLE "Raffle" ADD CONSTRAINT "Raffle_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20241024111304_updated_models/migration.sql b/prisma/migrations/20241024111304_updated_models/migration.sql deleted file mode 100644 index d2d4ce3..0000000 --- a/prisma/migrations/20241024111304_updated_models/migration.sql +++ /dev/null @@ -1,13 +0,0 @@ -/* - Warnings: - - - You are about to drop the column `isRaffleParticipant` on the `User` table. All the data in the column will be lost. - -*/ --- AlterTable -ALTER TABLE "Raffle" ADD COLUMN "activeDeposits" BOOLEAN DEFAULT false, -ADD COLUMN "isRaffleParticipant" BOOLEAN DEFAULT false, -ADD COLUMN "sharedOnX" BOOLEAN DEFAULT false; - --- AlterTable -ALTER TABLE "User" DROP COLUMN "isRaffleParticipant"; diff --git a/prisma/migrations/20241025043050_added_new_lucky_winners_model/migration.sql b/prisma/migrations/20241025043050_added_new_lucky_winners_model/migration.sql deleted file mode 100644 index a0e805d..0000000 --- a/prisma/migrations/20241025043050_added_new_lucky_winners_model/migration.sql +++ /dev/null @@ -1,23 +0,0 @@ --- CreateTable -CREATE TABLE "LuckyWinner" ( - "winnerId" SERIAL NOT NULL, - "winnerAddress" TEXT NOT NULL, - "updatedAt" TIMESTAMP(3) NOT NULL, - "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "raffleId" INTEGER NOT NULL, - "userId" INTEGER NOT NULL, - - CONSTRAINT "LuckyWinner_pkey" PRIMARY KEY ("winnerId") -); - --- CreateIndex -CREATE UNIQUE INDEX "LuckyWinner_winnerAddress_key" ON "LuckyWinner"("winnerAddress"); - --- CreateIndex -CREATE UNIQUE INDEX "LuckyWinner_userId_winnerAddress_key" ON "LuckyWinner"("userId", "winnerAddress"); - --- AddForeignKey -ALTER TABLE "LuckyWinner" ADD CONSTRAINT "LuckyWinner_raffleId_fkey" FOREIGN KEY ("raffleId") REFERENCES "Raffle"("raffleId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "LuckyWinner" ADD CONSTRAINT "LuckyWinner_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20241028130637_changes/migration.sql b/prisma/migrations/20241028130637_changes/migration.sql new file mode 100644 index 0000000..1e851fd --- /dev/null +++ b/prisma/migrations/20241028130637_changes/migration.sql @@ -0,0 +1,111 @@ +-- CreateTable +CREATE TABLE "User" ( + "id" SERIAL NOT NULL, + "address" TEXT NOT NULL, + "isTncSigned" BOOLEAN DEFAULT false, + "message" TEXT, + "tncDocVersion" TEXT DEFAULT '1.0', + "referralCode" TEXT NOT NULL, + "referralCount" INTEGER DEFAULT 0, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Raffle" ( + "raffleId" SERIAL NOT NULL, + "isRaffleParticipant" BOOLEAN DEFAULT false, + "sharedOnX" BOOLEAN DEFAULT false, + "activeDeposits" BOOLEAN DEFAULT false, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "userId" INTEGER NOT NULL, + + CONSTRAINT "Raffle_pkey" PRIMARY KEY ("raffleId") +); + +-- CreateTable +CREATE TABLE "LuckyWinner" ( + "winnerId" SERIAL NOT NULL, + "updatedAt" TIMESTAMP(3) NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "raffleId" INTEGER NOT NULL, + "userId" INTEGER NOT NULL, + + CONSTRAINT "LuckyWinner_pkey" PRIMARY KEY ("winnerId") +); + +-- CreateTable +CREATE TABLE "Signatures" ( + "id" SERIAL NOT NULL, + "signature" TEXT NOT NULL, + "tncDocVersion" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "userId" INTEGER NOT NULL, + + CONSTRAINT "Signatures_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Referral" ( + "referralId" SERIAL NOT NULL, + "refreeAddress" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "userId" INTEGER NOT NULL, + + CONSTRAINT "Referral_pkey" PRIMARY KEY ("referralId") +); + +-- CreateTable +CREATE TABLE "og_nft_users" ( + "id" SERIAL NOT NULL, + "userId" INTEGER NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "og_nft_users_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_address_key" ON "User"("address"); + +-- CreateIndex +CREATE UNIQUE INDEX "User_referralCode_key" ON "User"("referralCode"); + +-- CreateIndex +CREATE UNIQUE INDEX "Raffle_userId_raffleId_key" ON "Raffle"("userId", "raffleId"); + +-- CreateIndex +CREATE UNIQUE INDEX "LuckyWinner_userId_winnerId_key" ON "LuckyWinner"("userId", "winnerId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Signatures_userId_tncDocVersion_key" ON "Signatures"("userId", "tncDocVersion"); + +-- CreateIndex +CREATE UNIQUE INDEX "Referral_refreeAddress_key" ON "Referral"("refreeAddress"); + +-- CreateIndex +CREATE UNIQUE INDEX "Referral_userId_refreeAddress_key" ON "Referral"("userId", "refreeAddress"); + +-- CreateIndex +CREATE UNIQUE INDEX "og_nft_users_userId_key" ON "og_nft_users"("userId"); + +-- AddForeignKey +ALTER TABLE "Raffle" ADD CONSTRAINT "Raffle_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LuckyWinner" ADD CONSTRAINT "LuckyWinner_raffleId_fkey" FOREIGN KEY ("raffleId") REFERENCES "Raffle"("raffleId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LuckyWinner" ADD CONSTRAINT "LuckyWinner_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Signatures" ADD CONSTRAINT "Signatures_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Referral" ADD CONSTRAINT "Referral_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "og_nft_users" ADD CONSTRAINT "og_nft_users_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 7433bca..41d42cc 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -27,7 +27,6 @@ model User { model Raffle { raffleId Int @id @default(autoincrement()) - raffleAddress String @unique isRaffleParticipant Boolean? @default(false) sharedOnX Boolean? @default(false) activeDeposits Boolean? @default(false) @@ -40,12 +39,11 @@ model Raffle { LuckyWinner LuckyWinner[] - @@unique([userId, raffleAddress], name: "unique_raffle") + @@unique([userId, raffleId], name: "unique_raffle") } model LuckyWinner { - winnerId Int @id @default(autoincrement()) - winnerAddress String @unique + winnerId Int @id @default(autoincrement()) updatedAt DateTime @updatedAt createdAt DateTime @default(now()) @@ -56,7 +54,7 @@ model LuckyWinner { User User @relation(fields: [userId], references: [id]) userId Int - @@unique([userId, winnerAddress], name: "unique_lucky_winner") + @@unique([userId, winnerId], name: "unique_lucky_winner") } model Signatures { diff --git a/src/app/api/raffle/activeDeposits/route.ts b/src/app/api/raffle/activeDeposits/route.ts deleted file mode 100644 index dae7950..0000000 --- a/src/app/api/raffle/activeDeposits/route.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { NextResponse } from 'next/server'; - -import { db } from '@/db'; -import { standariseAddress } from '@/utils'; - -export async function POST(req: Request) { - const { address } = await req.json(); - - if (!address) { - return NextResponse.json({ - success: false, - message: 'address not found', - user: null, - }); - } - - // standardised address - let parsedAddress = address; - try { - parsedAddress = standariseAddress(address); - } catch (e) { - throw new Error('Invalid address'); - } - - const user = await db.raffle.findFirst({ - where: { - raffleAddress: parsedAddress, - }, - }); - - if (!user) { - return NextResponse.json({ - success: false, - message: 'User not found', - user: null, - }); - } - - const createdUser = await db.raffle.update({ - where: { - raffleAddress: parsedAddress, - }, - data: { - activeDeposits: true, - }, - }); - - return NextResponse.json({ - success: true, - message: 'User registered for raffle successfully', - user: createdUser, - }); -} diff --git a/src/app/api/raffle/getUser/[address]/route.ts b/src/app/api/raffle/getUser/[address]/route.ts deleted file mode 100644 index cbbacb7..0000000 --- a/src/app/api/raffle/getUser/[address]/route.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { NextResponse } from 'next/server'; - -import { db } from '@/db'; -import { standariseAddress } from '@/utils'; - -export async function GET(_req: Request, context: any) { - const { params } = context; - const address = params.address; - - if (!address) { - return NextResponse.json({ - success: false, - message: 'No address found', - }); - } - - // standardised address - const parsedAddress = standariseAddress(address); - - const user = await db.raffle.findFirst({ - where: { - raffleAddress: parsedAddress, - }, - }); - - if (!user) { - return NextResponse.json({ - success: false, - user: null, - }); - } - - return NextResponse.json({ - success: true, - user, - }); -} diff --git a/src/app/api/raffle/luckyWinner/route.ts b/src/app/api/raffle/luckyWinner/route.ts index fd58ae4..7ca292d 100644 --- a/src/app/api/raffle/luckyWinner/route.ts +++ b/src/app/api/raffle/luckyWinner/route.ts @@ -48,9 +48,9 @@ export async function GET() { } // Check if the selected participant is already a lucky winner - const existingWinner = await db.luckyWinner.findUnique({ + const existingWinner = await db.luckyWinner.findFirst({ where: { - winnerAddress: randomRaffleParticipant.raffleAddress, + raffleId: randomRaffleParticipant.raffleId, }, }); @@ -70,7 +70,6 @@ export async function GET() { // Add the selected user to the LuckyWinner table const newLuckyWinner = await db.luckyWinner.create({ data: { - winnerAddress: randomRaffleParticipant.raffleAddress, userId: randomRaffleParticipant.userId, raffleId: randomRaffleParticipant.raffleId, }, diff --git a/src/app/api/raffle/registerUser/route.ts b/src/app/api/raffle/registerUser/route.ts deleted file mode 100644 index 58e7480..0000000 --- a/src/app/api/raffle/registerUser/route.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { NextResponse } from 'next/server'; - -import { db } from '@/db'; -import { standariseAddress } from '@/utils'; - -export async function POST(req: Request) { - const { address } = await req.json(); - - if (!address) { - return NextResponse.json({ - success: false, - message: 'address not found', - user: null, - }); - } - - // standardised address - let parsedAddress = address; - try { - parsedAddress = standariseAddress(address); - } catch (e) { - throw new Error('Invalid address'); - } - - const user = await db.user.findFirst({ - where: { - address: parsedAddress, - }, - }); - - if (!user) { - return NextResponse.json({ - success: false, - message: 'User not found', - user: null, - }); - } - - const createdUser = await db.raffle.create({ - data: { - raffleAddress: parsedAddress, - isRaffleParticipant: true, - User: { - connect: { - address: parsedAddress, - }, - }, - }, - }); - - return NextResponse.json({ - success: true, - message: 'User registered for raffle successfully', - user: createdUser, - }); -} diff --git a/src/app/api/raffle/route.ts b/src/app/api/raffle/route.ts new file mode 100644 index 0000000..6511266 --- /dev/null +++ b/src/app/api/raffle/route.ts @@ -0,0 +1,143 @@ +import { NextResponse } from 'next/server'; + +import { db } from '@/db'; +import { getStrategies } from '@/store/strategies.atoms'; +import { standariseAddress } from '@/utils'; + +export async function POST(req: Request) { + const { address, type } = await req.json(); + + if (!address || !type) { + return NextResponse.json({ + success: false, + message: 'address not found', + user: null, + }); + } + + if (!type || !['SHARED_ON_X', 'ACTIVE_DEPOSITS', 'REGISTER'].includes(type)) { + return NextResponse.json({ + success: false, + message: 'Invalid type', + }); + } + + // standardised address + let parsedAddress = address; + try { + parsedAddress = standariseAddress(address); + } catch (e) { + throw new Error('Invalid address'); + } + + const user = await db.user.findFirst({ + where: { + address: parsedAddress, + }, + }); + + if (!user) { + return NextResponse.json({ + success: false, + message: 'User not found', + user: null, + }); + } + + if (type === 'REGISTER') { + const createdUser = await db.raffle.create({ + data: { + isRaffleParticipant: true, + User: { + connect: { + address: parsedAddress, + }, + }, + }, + }); + + return NextResponse.json({ + success: true, + message: 'User registered for raffle successfully', + user: createdUser, + }); + } + + const raffleUser = await db.raffle.findFirst({ + where: { + userId: user.id, + isRaffleParticipant: true, + }, + }); + + if (!raffleUser) { + return NextResponse.json({ + success: false, + message: 'Registered user not found', + user: null, + }); + } + + if (type === 'SHARED_ON_X') { + const updatedUser = await db.raffle.update({ + where: { + raffleId: raffleUser.raffleId, + }, + data: { + sharedOnX: true, + }, + }); + + return NextResponse.json({ + success: true, + message: 'Shared on X successfully', + user: updatedUser, + }); + } + + if (type === 'ACTIVE_DEPOSITS') { + const strategies = getStrategies(); + + const values = strategies.map(async (strategy) => { + const balanceInfo = await strategy.getUserTVL(parsedAddress); + return { + id: strategy.id, + usdValue: balanceInfo.usdValue, + tokenInfo: { + name: balanceInfo.tokenInfo.name, + symbol: balanceInfo.tokenInfo.name, + logo: balanceInfo.tokenInfo.logo, + decimals: balanceInfo.tokenInfo.decimals, + displayDecimals: balanceInfo.tokenInfo.displayDecimals, + }, + amount: balanceInfo.amount.toEtherStr(), + }; + }); + + const result = await Promise.all(values); + const sum = result.reduce((acc, item) => acc + item.usdValue, 0); + + if (sum > 0) { + const createdUser = await db.raffle.update({ + where: { + raffleId: raffleUser.raffleId, + }, + data: { + activeDeposits: true, + }, + }); + + return NextResponse.json({ + success: true, + message: 'Active deposits found', + user: createdUser, + }); + } + + return NextResponse.json({ + success: false, + message: 'No active deposits found', + user: null, + }); + } +} diff --git a/src/app/api/raffle/sharedOnX/route.ts b/src/app/api/raffle/sharedOnX/route.ts deleted file mode 100644 index 84efa5c..0000000 --- a/src/app/api/raffle/sharedOnX/route.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { NextResponse } from 'next/server'; - -import { db } from '@/db'; -import { standariseAddress } from '@/utils'; - -export async function POST(req: Request) { - const { address } = await req.json(); - - if (!address) { - return NextResponse.json({ - success: false, - message: 'address not found', - user: null, - }); - } - - // standardised address - let parsedAddress = address; - try { - parsedAddress = standariseAddress(address); - } catch (e) { - throw new Error('Invalid address'); - } - - const user = await db.raffle.findFirst({ - where: { - raffleAddress: parsedAddress, - }, - }); - - if (!user) { - return NextResponse.json({ - success: false, - message: 'User not found', - user: null, - }); - } - - const createdUser = await db.raffle.update({ - where: { - raffleAddress: parsedAddress, - }, - data: { - sharedOnX: true, - }, - }); - - return NextResponse.json({ - success: true, - message: 'User registered for raffle successfully', - user: createdUser, - }); -} diff --git a/src/app/api/tnc/getUser/[address]/route.ts b/src/app/api/tnc/getUser/[address]/route.ts index 8947b65..6647c81 100644 --- a/src/app/api/tnc/getUser/[address]/route.ts +++ b/src/app/api/tnc/getUser/[address]/route.ts @@ -3,10 +3,13 @@ import { NextResponse } from 'next/server'; import { db } from '@/db'; import { standariseAddress } from '@/utils'; -export async function GET(_req: Request, context: any) { +export async function GET(req: Request, context: any) { const { params } = context; const address = params.address; + const { searchParams } = new URL(req.url); + const type = searchParams.get('type'); + if (!address) { return NextResponse.json({ success: false, @@ -33,6 +36,27 @@ export async function GET(_req: Request, context: any) { }); } + if (type && type === 'RAFFLE') { + const raffleUser = await db.raffle.findFirst({ + where: { + userId: user.id, + }, + }); + + if (!raffleUser) { + return NextResponse.json({ + success: false, + message: 'Raffle user not found', + user: null, + }); + } + + return NextResponse.json({ + success: true, + user: raffleUser, + }); + } + return NextResponse.json({ success: true, user, diff --git a/src/app/raffle/_components/register-raffle.tsx b/src/app/raffle/_components/register-raffle.tsx index 5cbf63b..2195ef8 100644 --- a/src/app/raffle/_components/register-raffle.tsx +++ b/src/app/raffle/_components/register-raffle.tsx @@ -17,8 +17,9 @@ const RegisterRaffle: React.FC = () => { if (isUserRegistered) return; try { - const res = await axios.post('/api/raffle/registerUser', { + const res = await axios.post('/api/raffle', { address, + type: 'REGISTER', }); if (res?.data?.success) { setIsUserRegistered(true); @@ -39,7 +40,9 @@ const RegisterRaffle: React.FC = () => { (async () => { try { - const res = await axios.get(`/api/raffle/getUser/${address}`); + const res = await axios.get(`/api/tnc/getUser/${address}`, { + params: { type: 'RAFFLE' }, + }); if (res?.data?.success && res?.data?.user?.isRaffleParticipant) { setIsUserRegistered(true); diff --git a/src/app/raffle/_components/share-on-x.tsx b/src/app/raffle/_components/share-on-x.tsx index d34796b..eb4d9c7 100644 --- a/src/app/raffle/_components/share-on-x.tsx +++ b/src/app/raffle/_components/share-on-x.tsx @@ -18,8 +18,9 @@ const ShareOnX = () => { setLoading(true); try { - const res = await axios.post('/api/raffle/sharedOnX', { + const res = await axios.post('/api/raffle', { address, + type: 'SHARED_ON_X', }); if (res?.data?.success) { @@ -40,7 +41,9 @@ const ShareOnX = () => { (async () => { try { - const res = await axios.get(`/api/raffle/getUser/${address}`); + const res = await axios.get(`/api/tnc/getUser/${address}`, { + params: { type: 'RAFFLE' }, + }); if (res?.data?.success && res?.data?.user?.sharedOnX) { setIsSharedOnX(true); From 050619b554d6d97e10ce93a2a3065d205b8c0cff Mon Sep 17 00:00:00 2001 From: Hemant Date: Mon, 28 Oct 2024 19:40:44 +0530 Subject: [PATCH 16/40] chore: updated lucky winner route --- src/app/api/raffle/luckyWinner/route.ts | 112 +++++++++++++++--------- 1 file changed, 71 insertions(+), 41 deletions(-) diff --git a/src/app/api/raffle/luckyWinner/route.ts b/src/app/api/raffle/luckyWinner/route.ts index 7ca292d..82bc53a 100644 --- a/src/app/api/raffle/luckyWinner/route.ts +++ b/src/app/api/raffle/luckyWinner/route.ts @@ -1,77 +1,107 @@ -import { NextResponse } from 'next/server'; - import { db } from '@/db'; +import { NextResponse } from 'next/server'; export const dynamic = 'force-dynamic'; // static by default, unless reading the request export async function GET() { try { - const raffleParticipantsCount = await db.raffle.count({ + // Fetch all raffle participants + const raffleParticipants = await db.raffle.findMany({ where: { - isRaffleParticipant: true, - sharedOnX: true, - activeDeposits: true, + OR: [ + { isRaffleParticipant: true }, + { sharedOnX: true }, + { activeDeposits: true }, + ], }, }); - if (raffleParticipantsCount === 0) { + if (raffleParticipants.length === 0) { return NextResponse.json({ success: false, message: 'No raffle participants found', }); } - let randomRaffleParticipant; + // Group participants by ticket count + const threeTicketParticipants: any = []; + const twoTicketParticipants: any = []; + const oneTicketParticipants: any = []; + + raffleParticipants.forEach((participant) => { + let ticketCount = 0; + + if (participant.isRaffleParticipant) ticketCount += 1; + if (participant.sharedOnX) ticketCount += 1; + if (participant.activeDeposits) ticketCount += 1; + + // Add the participant to the corresponding group based on their ticket count + if (ticketCount === 3) { + threeTicketParticipants.push(participant); + } else if (ticketCount === 2) { + twoTicketParticipants.push(participant); + } else if (ticketCount === 1) { + oneTicketParticipants.push(participant); + } + }); + + let selectedParticipant; let foundValidParticipant = false; - // Keep searching until a valid participant is found - while (!foundValidParticipant) { - // Select a random raffle participant - randomRaffleParticipant = await db.raffle.findFirst({ - where: { - isRaffleParticipant: true, - sharedOnX: true, - activeDeposits: true, - }, - orderBy: { - createdAt: 'asc', - }, - take: 1, - skip: Math.floor(Math.random() * raffleParticipantsCount), - }); + // Attempt to select a valid participant, prioritizing higher ticket groups + const groups = [ + threeTicketParticipants, + twoTicketParticipants, + oneTicketParticipants, + ]; - if (!randomRaffleParticipant) { - return NextResponse.json({ - success: false, - message: 'No raffle participants found', - }); + for (const group of groups) { + if (group.length === 0) { + continue; // Move to the next group if the current one is empty } - // Check if the selected participant is already a lucky winner - const existingWinner = await db.luckyWinner.findFirst({ - where: { - raffleId: randomRaffleParticipant.raffleId, - }, - }); + // Keep searching within the current group until a valid participant is found + while (!foundValidParticipant && group.length > 0) { + // Randomly select a participant from the current group + const randomIndex = Math.floor(Math.random() * group.length); + selectedParticipant = group[randomIndex]; + + // Check if the selected participant is already a lucky winner + const existingWinner = await db.luckyWinner.findFirst({ + where: { + raffleId: selectedParticipant.raffleId, + }, + }); + + // If not already a winner, break the loop + if (!existingWinner) { + foundValidParticipant = true; + break; + } else { + // If the selected participant is already a winner, remove them from the group + group.splice(randomIndex, 1); + } + } - // If not already a winner, break the loop - if (!existingWinner) { - foundValidParticipant = true; + // If a valid participant has been found, exit the loop + if (foundValidParticipant) { + break; } } - if (!randomRaffleParticipant) { + // If no valid participant was found after checking all groups + if (!foundValidParticipant) { return NextResponse.json({ success: false, - message: 'No raffle participants found', + message: 'No eligible raffle participants found', }); } // Add the selected user to the LuckyWinner table const newLuckyWinner = await db.luckyWinner.create({ data: { - userId: randomRaffleParticipant.userId, - raffleId: randomRaffleParticipant.raffleId, + userId: selectedParticipant.userId, + raffleId: selectedParticipant.raffleId, }, }); From 78662f007ec88fac4d0a1f39f383bf6a1591878b Mon Sep 17 00:00:00 2001 From: Hemant Date: Mon, 28 Oct 2024 19:58:26 +0530 Subject: [PATCH 17/40] fix: added cron secret --- .env.sample | 2 ++ src/app/api/raffle/luckyWinner/route.ts | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.env.sample b/.env.sample index 5939799..34aa4b7 100644 --- a/.env.sample +++ b/.env.sample @@ -10,3 +10,5 @@ DATABASE_URL= ACCOUNT_PK=0x0574ba4998dd9aedf1c4d6e56b747b29256a795bc3846437d121cd64b972bdd8 NEXT_PUBLIC_OG_NFT_CONTRACT=0x3cb654f2f557a7f71a0c16d97c05a2dec62a0b744979d11afc95b804e1d7307 + +CRON_SECRET= diff --git a/src/app/api/raffle/luckyWinner/route.ts b/src/app/api/raffle/luckyWinner/route.ts index 82bc53a..36106e5 100644 --- a/src/app/api/raffle/luckyWinner/route.ts +++ b/src/app/api/raffle/luckyWinner/route.ts @@ -3,7 +3,14 @@ import { NextResponse } from 'next/server'; export const dynamic = 'force-dynamic'; // static by default, unless reading the request -export async function GET() { +export async function GET(request: Request) { + const authHeader = request.headers.get('authorization'); + if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) { + return new Response('Unauthorized', { + status: 401, + }); + } + try { // Fetch all raffle participants const raffleParticipants = await db.raffle.findMany({ From 0dd8b16fe23ef44950c392256f9cb1fb3a6e4ee7 Mon Sep 17 00:00:00 2001 From: Hemant Date: Tue, 29 Oct 2024 17:31:50 +0530 Subject: [PATCH 18/40] chore: updated lucky winner route.ts --- .../migration.sql | 22 ++++ .../migration.sql | 2 + .../migration.sql | 3 + .../migration.sql | 10 ++ .../migration.sql | 18 +++ .../migration.sql | 11 ++ prisma/schema.prisma | 4 +- src/app/api/raffle/luckyWinner/route.ts | 117 ++++++++++-------- vercel.json | 2 +- 9 files changed, 133 insertions(+), 56 deletions(-) create mode 100644 prisma/migrations/20241029102731_added_round_id/migration.sql create mode 100644 prisma/migrations/20241029103119_updated_round_id_constraints/migration.sql create mode 100644 prisma/migrations/20241029103502_updated_round_id_constraints/migration.sql create mode 100644 prisma/migrations/20241029103711_updated_round_id_constraints/migration.sql create mode 100644 prisma/migrations/20241029105811_updated_raffle_model/migration.sql create mode 100644 prisma/migrations/20241029113615_updated_lucky_winner_model/migration.sql diff --git a/prisma/migrations/20241029102731_added_round_id/migration.sql b/prisma/migrations/20241029102731_added_round_id/migration.sql new file mode 100644 index 0000000..cd1ffba --- /dev/null +++ b/prisma/migrations/20241029102731_added_round_id/migration.sql @@ -0,0 +1,22 @@ +/* + Warnings: + + - The primary key for the `LuckyWinner` table will be changed. If it partially fails, the table could be left without primary key constraint. + - You are about to drop the column `winnerId` on the `LuckyWinner` table. All the data in the column will be lost. + - A unique constraint covering the columns `[roundId]` on the table `LuckyWinner` will be added. If there are existing duplicate values, this will fail. + - A unique constraint covering the columns `[userId,roundId]` on the table `LuckyWinner` will be added. If there are existing duplicate values, this will fail. + +*/ +-- DropIndex +DROP INDEX "LuckyWinner_userId_winnerId_key"; + +-- AlterTable +ALTER TABLE "LuckyWinner" DROP CONSTRAINT "LuckyWinner_pkey", +DROP COLUMN "winnerId", +ADD COLUMN "roundId" INTEGER NOT NULL DEFAULT 0; + +-- CreateIndex +CREATE UNIQUE INDEX "LuckyWinner_roundId_key" ON "LuckyWinner"("roundId"); + +-- CreateIndex +CREATE UNIQUE INDEX "LuckyWinner_userId_roundId_key" ON "LuckyWinner"("userId", "roundId"); diff --git a/prisma/migrations/20241029103119_updated_round_id_constraints/migration.sql b/prisma/migrations/20241029103119_updated_round_id_constraints/migration.sql new file mode 100644 index 0000000..087978e --- /dev/null +++ b/prisma/migrations/20241029103119_updated_round_id_constraints/migration.sql @@ -0,0 +1,2 @@ +-- DropIndex +DROP INDEX "LuckyWinner_roundId_key"; diff --git a/prisma/migrations/20241029103502_updated_round_id_constraints/migration.sql b/prisma/migrations/20241029103502_updated_round_id_constraints/migration.sql new file mode 100644 index 0000000..b4fbb61 --- /dev/null +++ b/prisma/migrations/20241029103502_updated_round_id_constraints/migration.sql @@ -0,0 +1,3 @@ +-- AlterTable +ALTER TABLE "LuckyWinner" ALTER COLUMN "roundId" SET DEFAULT 1, +ADD CONSTRAINT "LuckyWinner_pkey" PRIMARY KEY ("roundId"); diff --git a/prisma/migrations/20241029103711_updated_round_id_constraints/migration.sql b/prisma/migrations/20241029103711_updated_round_id_constraints/migration.sql new file mode 100644 index 0000000..d186da9 --- /dev/null +++ b/prisma/migrations/20241029103711_updated_round_id_constraints/migration.sql @@ -0,0 +1,10 @@ +/* + Warnings: + + - The primary key for the `LuckyWinner` table will be changed. If it partially fails, the table could be left without primary key constraint. + +*/ +-- AlterTable +ALTER TABLE "LuckyWinner" DROP CONSTRAINT "LuckyWinner_pkey", +ADD COLUMN "winnerId" SERIAL NOT NULL, +ADD CONSTRAINT "LuckyWinner_pkey" PRIMARY KEY ("winnerId"); diff --git a/prisma/migrations/20241029105811_updated_raffle_model/migration.sql b/prisma/migrations/20241029105811_updated_raffle_model/migration.sql new file mode 100644 index 0000000..ed8dfcf --- /dev/null +++ b/prisma/migrations/20241029105811_updated_raffle_model/migration.sql @@ -0,0 +1,18 @@ +/* + Warnings: + + - You are about to drop the column `roundId` on the `LuckyWinner` table. All the data in the column will be lost. + - A unique constraint covering the columns `[userId,winnerId]` on the table `LuckyWinner` will be added. If there are existing duplicate values, this will fail. + +*/ +-- DropIndex +DROP INDEX "LuckyWinner_userId_roundId_key"; + +-- AlterTable +ALTER TABLE "LuckyWinner" DROP COLUMN "roundId"; + +-- AlterTable +ALTER TABLE "Raffle" ADD COLUMN "roundId" INTEGER NOT NULL DEFAULT 1; + +-- CreateIndex +CREATE UNIQUE INDEX "LuckyWinner_userId_winnerId_key" ON "LuckyWinner"("userId", "winnerId"); diff --git a/prisma/migrations/20241029113615_updated_lucky_winner_model/migration.sql b/prisma/migrations/20241029113615_updated_lucky_winner_model/migration.sql new file mode 100644 index 0000000..d9c69c8 --- /dev/null +++ b/prisma/migrations/20241029113615_updated_lucky_winner_model/migration.sql @@ -0,0 +1,11 @@ +/* + Warnings: + + - You are about to drop the column `roundId` on the `Raffle` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "LuckyWinner" ADD COLUMN "roundId" SERIAL NOT NULL; + +-- AlterTable +ALTER TABLE "Raffle" DROP COLUMN "roundId"; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 41d42cc..08c7751 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -26,7 +26,8 @@ model User { } model Raffle { - raffleId Int @id @default(autoincrement()) + raffleId Int @id @default(autoincrement()) + isRaffleParticipant Boolean? @default(false) sharedOnX Boolean? @default(false) activeDeposits Boolean? @default(false) @@ -44,6 +45,7 @@ model Raffle { model LuckyWinner { winnerId Int @id @default(autoincrement()) + roundId Int @default(autoincrement()) updatedAt DateTime @updatedAt createdAt DateTime @default(now()) diff --git a/src/app/api/raffle/luckyWinner/route.ts b/src/app/api/raffle/luckyWinner/route.ts index 36106e5..d7a2b31 100644 --- a/src/app/api/raffle/luckyWinner/route.ts +++ b/src/app/api/raffle/luckyWinner/route.ts @@ -11,8 +11,17 @@ export async function GET(request: Request) { }); } + const { searchParams } = new URL(request.url); + const noOfWinners = parseInt(searchParams.get('winnersCount') || '0', 10); + + if (noOfWinners <= 0) { + return NextResponse.json({ + success: false, + message: 'Invalid number of winners requested', + }); + } + try { - // Fetch all raffle participants const raffleParticipants = await db.raffle.findMany({ where: { OR: [ @@ -31,9 +40,9 @@ export async function GET(request: Request) { } // Group participants by ticket count - const threeTicketParticipants: any = []; - const twoTicketParticipants: any = []; - const oneTicketParticipants: any = []; + const threeTicketParticipants: any[] = []; + const twoTicketParticipants: any[] = []; + const oneTicketParticipants: any[] = []; raffleParticipants.forEach((participant) => { let ticketCount = 0; @@ -52,78 +61,78 @@ export async function GET(request: Request) { } }); - let selectedParticipant; - let foundValidParticipant = false; - - // Attempt to select a valid participant, prioritizing higher ticket groups const groups = [ threeTicketParticipants, twoTicketParticipants, oneTicketParticipants, ]; - - for (const group of groups) { - if (group.length === 0) { - continue; // Move to the next group if the current one is empty - } - - // Keep searching within the current group until a valid participant is found - while (!foundValidParticipant && group.length > 0) { - // Randomly select a participant from the current group - const randomIndex = Math.floor(Math.random() * group.length); - selectedParticipant = group[randomIndex]; - - // Check if the selected participant is already a lucky winner - const existingWinner = await db.luckyWinner.findFirst({ - where: { - raffleId: selectedParticipant.raffleId, - }, - }); - - // If not already a winner, break the loop - if (!existingWinner) { - foundValidParticipant = true; - break; - } else { - // If the selected participant is already a winner, remove them from the group - group.splice(randomIndex, 1); + const luckyWinners = []; + + // Continue selecting winners until we reach the desired count + while (luckyWinners.length < noOfWinners) { + let selectedParticipant = null; + let foundValidParticipant = false; + + // Try to find a participant from each group in order + for (const group of groups) { + if (group.length === 0) continue; + + // Keep searching within the current group until a valid participant is found + while (group.length > 0) { + const randomIndex = Math.floor(Math.random() * group.length); + selectedParticipant = group[randomIndex]; + + const existingWinner = await db.luckyWinner.findFirst({ + where: { raffleId: selectedParticipant.raffleId }, + }); + + if (!existingWinner) { + foundValidParticipant = true; + luckyWinners.push(selectedParticipant); + group.splice(randomIndex, 1); // Remove selected participant from the group + break; + } else { + group.splice(randomIndex, 1); // Remove duplicate winner + } } - } - // If a valid participant has been found, exit the loop - if (foundValidParticipant) { - break; + if (foundValidParticipant) break; } + + // If no eligible participants found in any group, break the loop + if (!foundValidParticipant) break; } - // If no valid participant was found after checking all groups - if (!foundValidParticipant) { + // Check if we were able to select enough winners + if (luckyWinners.length < noOfWinners) { return NextResponse.json({ success: false, - message: 'No eligible raffle participants found', + message: 'Not enough eligible raffle participants found', }); } - // Add the selected user to the LuckyWinner table - const newLuckyWinner = await db.luckyWinner.create({ - data: { - userId: selectedParticipant.userId, - raffleId: selectedParticipant.raffleId, - }, - }); - - console.log(newLuckyWinner); + // Add selected users to the LuckyWinner table + const newLuckyWinners = await Promise.all( + luckyWinners.map((winner) => + db.luckyWinner.create({ + data: { + userId: winner.userId, + raffleId: winner.raffleId, + }, + }), + ), + ); return NextResponse.json({ success: true, - message: 'Lucky winner selected successfully', - luckyWinner: newLuckyWinner, + message: 'Lucky winners selected successfully', + luckyWinners: newLuckyWinners, }); } catch (error) { - console.error('Error selecting a lucky winner:', error); + console.error('Error selecting lucky winners:', error); return NextResponse.json({ success: false, - message: 'An error occurred while selecting a lucky winner', + message: 'An error occurred while selecting lucky winners', }); } } diff --git a/vercel.json b/vercel.json index a370e38..62b4b57 100644 --- a/vercel.json +++ b/vercel.json @@ -1,7 +1,7 @@ { "crons": [ { - "path": "/api/raffle/luckyWinner", + "path": "/api/raffle/luckyWinner?winnersCount=2", "schedule": "33 20 * * *" } ] From b596f2a8370c040fae712b35bc11040fdec3354f Mon Sep 17 00:00:00 2001 From: Hemant Date: Fri, 1 Nov 2024 12:29:04 +0530 Subject: [PATCH 19/40] chore: ui updates on raffle page --- public/raffle-hero.svg | 1514 +++++++++++------ .../raffle/_components/active-deposits.tsx | 95 ++ .../raffle/_components/register-raffle.tsx | 76 +- src/app/raffle/_components/share-on-x.tsx | 25 +- src/app/raffle/page.tsx | 85 +- 5 files changed, 1242 insertions(+), 553 deletions(-) create mode 100644 src/app/raffle/_components/active-deposits.tsx diff --git a/public/raffle-hero.svg b/public/raffle-hero.svg index 91a3f11..c534fea 100644 --- a/public/raffle-hero.svg +++ b/public/raffle-hero.svg @@ -1,622 +1,1188 @@ - - + + + + + d="M202.98 266.718C219.231 244.773 251.574 200.863 267.835 178.934C298.569 182.467 360.043 189.507 390.757 193.085L513.354 207.4L514.354 207.515L514.161 208.499L500.091 280.076L499.948 280.814C463.527 280.494 391.154 279.851 354.751 279.469C318.78 279.084 246.279 278.267 210.31 277.778L210.266 277.78L210.243 277.743L202.987 266.718L202.98 266.718ZM202.98 266.718C202.955 266.675 210.559 277.854 210.307 277.617C246.338 277.677 318.742 277.965 354.76 278.135C390.73 278.301 463.24 278.767 499.209 279.004L498.313 279.734L512.334 208.145L513.138 209.244L390.563 194.719C360.023 191.099 298.541 183.674 268.012 179.996C254.014 199.873 218.587 245.585 202.98 266.718Z" + fill="#3B2358" /> + d="M444.966 243.49C439.731 228.586 445.781 212.377 446.96 196.631C447.483 189.636 447.029 182.592 447.753 175.617C448.477 168.642 450.531 161.518 455.305 156.358C457.398 157.412 456.815 160.463 456.288 162.743C453.87 173.215 459.721 184.004 458.607 194.692C458.219 198.396 457.007 201.953 456.171 205.581C453.874 215.543 454.479 226.146 457.888 235.785C455.948 222.517 462.542 209.483 463.117 196.087C463.8 180.116 455.984 163.604 461.547 148.607C464.809 154.718 463.726 162.12 464.703 168.972C465.7 175.978 468.904 182.528 469.908 189.537C471.741 202.363 466.111 215.85 470.162 228.161C469.223 219.256 473.961 210.739 474.807 201.825C475.798 191.406 471.442 180.88 473.318 170.584C477.425 174.349 476.75 180.817 477.906 186.256C479.704 194.715 486.446 201.499 488.192 209.966C490.579 221.522 483.22 232.779 482.123 244.525C481.765 248.365 482.068 252.333 480.805 255.978C478.256 263.338 467.351 269.162 459.731 266.272C452.53 263.542 447.261 250.038 444.962 243.493L444.966 243.49Z" + fill="#97C176" /> + d="M464.681 267.343C462.871 267.416 461.152 267.164 459.616 266.583C454.336 264.58 449.303 256.848 444.652 243.602C440.972 233.125 442.853 221.846 444.674 210.94C445.46 206.228 446.275 201.356 446.628 196.61C446.864 193.448 446.901 190.22 446.936 187.094C446.979 183.319 447.023 179.413 447.42 175.585C448.289 167.22 450.856 160.677 455.061 156.134L455.233 155.948L455.459 156.063C457.894 157.289 457.063 160.887 456.615 162.819C455.319 168.424 456.453 174.263 457.545 179.911C458.484 184.765 459.458 189.781 458.94 194.731C458.673 197.298 458.003 199.824 457.355 202.269C457.06 203.38 456.757 204.527 456.495 205.661C454.46 214.486 454.742 223.97 457.248 232.7C456.898 225.923 458.472 219.148 459.999 212.571C461.249 207.183 462.543 201.615 462.782 196.079C463.046 189.879 462.008 183.49 461.002 177.313C459.434 167.68 457.811 157.719 461.232 148.499L461.491 147.801L461.841 148.457C464.092 152.671 464.31 157.539 464.518 162.25C464.617 164.459 464.721 166.744 465.033 168.931C465.527 172.41 466.593 175.846 467.623 179.17C468.658 182.51 469.731 185.97 470.234 189.493C471.039 195.128 470.408 200.955 469.8 206.585C469.128 212.777 468.435 219.15 469.712 225.196C469.817 220.895 470.998 216.652 472.146 212.523C473.119 209.027 474.128 205.409 474.471 201.793C474.927 197.015 474.234 192.118 473.562 187.381C472.778 181.841 471.967 176.11 472.984 170.522L473.091 169.926L473.539 170.338C476.604 173.144 477.088 177.414 477.556 181.544C477.732 183.094 477.913 184.695 478.232 186.184C479.116 190.346 481.258 194.182 483.329 197.89C485.445 201.676 487.631 205.593 488.517 209.898C489.98 216.975 487.793 224.053 485.683 230.894C484.306 235.348 482.884 239.955 482.456 244.557C482.349 245.688 482.302 246.852 482.254 247.981C482.141 250.684 482.024 253.479 481.12 256.086C479.8 259.888 476.287 263.427 471.72 265.554C469.364 266.652 466.95 267.253 464.678 267.344L464.681 267.343ZM455.37 156.782C451.375 161.206 448.924 167.555 448.082 175.652C447.688 179.448 447.646 183.337 447.603 187.102C447.569 190.234 447.532 193.477 447.293 196.659C446.937 201.436 446.12 206.322 445.331 211.051C443.525 221.874 441.657 233.067 445.279 243.384C449.798 256.254 454.836 264.062 459.85 265.962C463.15 267.212 467.372 266.844 471.438 264.954C475.781 262.932 479.247 259.453 480.489 255.87C481.363 253.354 481.475 250.607 481.587 247.953C481.634 246.817 481.684 245.643 481.791 244.494C482.226 239.823 483.658 235.185 485.043 230.699C487.227 223.625 489.288 216.944 487.863 210.034C486.995 205.831 484.834 201.961 482.744 198.216C480.651 194.464 478.483 190.584 477.578 186.324C477.255 184.804 477.069 183.186 476.893 181.619C476.441 177.653 476.016 173.9 473.538 171.27C472.71 176.558 473.479 182.009 474.225 187.286C474.902 192.06 475.599 196.995 475.136 201.853C474.786 205.527 473.77 209.173 472.789 212.697C471.39 217.722 469.939 222.922 470.488 228.124L470.816 231.238L469.838 228.263C467.532 221.255 468.345 213.761 469.13 206.512C469.736 200.92 470.362 195.138 469.568 189.585C469.07 186.109 468.008 182.68 466.978 179.364C465.94 176.016 464.866 172.553 464.363 169.023C464.047 166.805 463.945 164.503 463.846 162.276C463.651 157.902 463.447 153.387 461.595 149.461C458.576 158.293 460.075 167.486 461.657 177.204C462.668 183.412 463.714 189.835 463.446 196.105C463.206 201.702 461.906 207.301 460.647 212.717C458.896 220.255 457.086 228.046 458.215 235.741L457.569 235.901C454.16 226.265 453.547 215.471 455.84 205.512C456.105 204.367 456.408 203.214 456.702 202.099C457.341 199.678 458.005 197.177 458.267 194.661C458.772 189.812 457.81 184.843 456.88 180.037C455.772 174.321 454.628 168.411 455.953 162.67C456.489 160.342 456.923 157.796 455.363 156.782L455.37 156.782Z" + fill="#3B2358" /> + + d="M355.404 96.205C355.404 96.205 322.506 188.848 323.291 189.566C324.076 190.284 329.669 199.605 329.669 199.605L361.418 96.3435L355.404 96.205Z" + fill="#F5D55F" /> + d="M329.767 200.422L329.379 199.778C327.141 196.045 323.611 190.312 323.063 189.812C322.812 189.585 322.633 189.42 327.66 174.572C330.292 166.796 334.017 156.01 338.735 142.511C346.771 119.525 355.005 96.3309 355.085 96.0974L355.166 95.8708L361.862 96.0269L329.764 200.426L329.767 200.422ZM323.617 189.425C324.536 190.482 328.277 196.65 329.571 198.794L360.969 96.6708L355.639 96.5463C344.606 127.612 323.988 186.249 323.617 189.425Z" + fill="#3B2358" /> + d="M440.261 93.2132L442.583 95.5162L428.135 168.775L424.06 188.019L418.361 184.541L428.83 118.775L440.261 93.2132Z" + fill="#F5D55F" /> + d="M424.288 188.55L417.995 184.71L428.524 118.643L440.152 92.6402L442.945 95.4056L442.911 95.5788L428.459 168.841L424.285 188.55L424.288 188.55ZM418.728 184.372L423.831 187.485L427.807 168.706L442.222 95.6234L440.37 93.7897L429.155 118.869L418.728 184.372Z" + fill="#3B2358" /> + d="M446.598 91.9263C446.598 91.9263 423.206 187.383 424.06 188.019C424.914 188.652 431.419 197.373 431.419 197.373L452.596 91.4675L446.598 91.9297L446.598 91.9263Z" + fill="#F5D55F" /> + d="M431.599 198.174L431.15 197.57C428.545 194.082 424.458 188.729 423.86 188.285C423.589 188.083 423.393 187.936 426.895 172.664C428.727 164.665 431.348 153.563 434.683 139.658C440.36 115.989 446.214 92.0859 446.274 91.8498L446.33 91.6139L453.009 91.1004L452.923 91.53L431.599 198.174ZM424.371 187.845C425.39 188.805 429.739 194.567 431.238 196.57L452.182 91.831L446.866 92.2387C439.025 124.25 424.419 184.647 424.371 187.845Z" + fill="#3B2358" /> + + d="M368.717 98.7164C375.155 99.0201 440.261 93.2167 440.261 93.2167L422.544 182.728L337.624 186.482L368.713 98.7165L368.717 98.7164Z" + fill="#67DAF6" /> + d="M337.144 186.838L368.482 98.3718L368.731 98.3825C375.076 98.683 439.58 92.9413 440.23 92.8811L440.674 92.8428L422.822 183.047L337.144 186.835L337.144 186.838ZM368.951 99.0576L338.107 186.13L422.269 182.409L439.848 93.5871C433.705 94.1343 376.313 99.218 368.951 99.0576Z" + fill="#3B2358" /> + + d="M373.96 271.617L361.88 255.756L396.821 224.37L421.585 222.195L424.26 240.991L373.96 271.617ZM362.785 255.84L374.125 270.734L423.535 240.652L421.009 222.915L397.102 225.019L362.785 255.844L362.785 255.84Z" + fill="#3B2358" /> + d="M276.068 234.944C276.068 234.944 242.004 245.154 246.24 275.725L374.043 271.177C374.043 271.177 368.83 262.023 374.676 249.713C377.375 244.034 381.794 239.338 387.186 236.068L399.584 228.549L412.909 215.584L412.781 212.125L316.536 206.205L284.916 228.013L276.068 234.944Z" + fill="#67DAF6" /> + d="M374.608 271.488L245.95 276.067L245.907 275.769C244.932 268.728 245.908 262.183 248.809 256.307C251.129 251.613 254.675 247.341 259.351 243.611C266.938 237.555 275.113 234.893 275.905 234.645L284.705 227.754L316.44 205.865L316.554 205.87L413.1 211.809L413.246 215.718L399.755 228.831L387.356 236.35C381.87 239.679 377.591 244.345 374.975 249.852C373.328 253.32 371.559 258.766 372.495 265.008C373.051 268.732 374.318 270.984 374.329 271.008L374.6 271.485L374.608 271.488ZM246.534 275.38L373.515 270.862C372.556 268.8 369.273 260.314 374.377 249.57C377.047 243.947 381.419 239.178 387.016 235.783L399.38 228.283L412.572 215.446L412.462 212.436L316.636 206.541L285.11 228.284L276.229 235.24L276.167 235.26C276.082 235.284 267.607 237.872 259.762 244.141C255.167 247.809 251.687 252.007 249.412 256.61C246.612 262.275 245.648 268.59 246.537 275.377L246.534 275.38Z" + fill="#3B2358" /> + + d="M272.787 229.641L272.436 225.084L272.55 224.976L307.723 191.117L310.389 194.915L272.787 229.641ZM273.127 225.345L273.348 228.213L309.504 194.82L307.622 192.135L273.127 225.342L273.127 225.345Z" + fill="#3B2358" /> + + d="M276.455 221.318L276.013 220.82L303.041 197.122L291.369 195.738L270.586 217.026L270.104 216.56L291.12 195.037L304.607 196.641L276.455 221.318Z" + fill="#3B2358" /> + d="M317.567 199.482L278.874 194.926C278.874 194.926 278.903 188.374 287.429 187.681L332.514 191.271L317.563 199.479L317.567 199.482Z" + fill="#A23A6D" /> + d="M317.636 199.823L278.54 195.222L278.542 194.926C278.54 194.857 278.676 188.057 287.406 187.352L287.433 187.351L287.461 187.35L333.658 191.029L317.639 199.823L317.636 199.823ZM279.232 194.63L317.501 199.134L331.38 191.515L287.432 188.014C284.021 188.294 281.602 189.549 280.242 191.737C279.492 192.943 279.287 194.106 279.232 194.63Z" + fill="#3B2358" /> + d="M379.162 265.505C379.162 265.505 405.98 217.448 406.54 215.291L418.582 215.987L393.891 264.372L379.166 265.505L379.162 265.505Z" + fill="#A23A6D" /> + d="M378.57 265.883L378.873 265.342C388.139 248.733 405.784 216.882 406.215 215.208L406.284 214.944L419.108 215.684L394.1 264.69L378.57 265.883ZM406.767 215.636C405.039 219.757 382.779 259.711 379.758 265.124L393.674 264.054L418.048 216.29L406.764 215.64L406.767 215.636Z" + fill="#3B2358" /> + d="M435.514 213.061C435.514 213.061 437.423 216.934 418.581 215.984L394.509 214.279L391.532 208.726L407.466 204.033L429.233 211.61L435.511 213.061L435.514 213.061Z" + fill="#A0F4F7" /> + d="M426.766 216.417C424.445 216.51 421.706 216.478 418.56 216.318L394.298 214.6L391.041 208.526L407.473 203.685L407.574 203.719L429.324 211.29L435.741 212.774L435.812 212.915C435.914 213.121 435.995 213.609 435.65 214.125C434.777 215.445 431.744 216.215 426.766 216.414L426.766 216.417ZM394.714 213.961L418.599 215.653C431.804 216.32 434.517 214.572 435.07 213.787C435.201 213.6 435.229 213.444 435.228 213.341L429.118 211.928L407.455 204.384L392.017 208.934L394.711 213.965L394.714 213.961Z" + fill="#3B2358" /> + d="M358.333 98.8173C356.159 102.162 356.215 106.511 356.325 110.49C356.435 114.469 357.086 118.413 357.548 122.367C357.595 122.767 357.636 123.199 357.447 123.557C357.257 123.915 356.752 124.138 356.431 123.89C357.095 124.97 358.541 125.624 359.792 125.385C358.687 126.687 357.138 127.608 355.438 127.39C356.296 128.222 357.541 128.695 358.735 128.596C357.425 130.48 355.708 132.717 353.969 134.216C352.23 135.715 350.135 136.878 347.863 137.226C349.448 138.544 351.551 139.234 353.618 139.107C352.982 140.132 352.221 140.692 351.255 141.421C350.145 142.259 348.867 143.101 347.486 142.939C348.165 143.943 349.402 144.571 350.617 144.478C349.901 146.263 348.796 147.647 347.099 148.57C349.263 149.319 351.649 149.489 353.884 148.991C350.83 150.694 347.79 154.032 346.257 157.162C348.309 155.712 350.96 155.517 353.473 155.41C352.591 156.233 351.881 157.123 351.152 158.08C353.055 157.905 354.989 157.904 356.895 158.072C356.068 161.421 353.593 164.321 350.473 165.823C349.375 166.352 348.201 166.711 347.115 167.27C344.54 168.593 342.655 170.946 341.122 173.393C339.59 175.842 338.327 178.467 336.567 180.757C334.804 183.048 332.424 185.036 329.576 185.569C329.362 185.413 328.998 185.204 328.747 185.124C328.657 185.987 329.255 186.871 330.093 187.112C327.588 188.631 323.962 188.539 321.811 186.559L319.46 144.523C319.46 144.523 313.695 140.164 292.882 146.668C292.882 146.668 284.74 149.295 289.754 158.217L295.045 153.806L298.62 166.239C298.62 166.239 291.724 164.166 293.999 170.197C293.999 170.197 291.362 172.502 294.228 174.48C294.228 174.48 292.133 177.279 295.419 179.509C295.419 179.509 293.074 181.672 295.988 184.25L300.399 189.316L305.55 190.922C305.55 190.922 306.234 193.269 308.749 193.276L312.731 197.974C312.731 197.974 311.178 197.393 306.534 198.451C306.534 198.451 304.112 195.736 299.468 196.794C299.468 196.794 301.52 197.337 301.735 198.821C301.735 198.821 296.776 198.403 291.149 202.335C291.149 202.335 295.053 202.135 295.685 202.488L286.819 206.172L289.019 206.002C289.019 206.002 285.883 209.646 283.336 217.044L286.335 215.512C286.335 215.512 284.575 223.951 279.676 224.328C279.676 224.328 267.174 210.879 260.726 215.879C260.726 215.879 257.612 214.618 257.113 217.257C257.113 217.257 253.878 218.307 255.238 220.304L266.424 236.256C266.424 236.256 280.271 255.405 288.705 246.15C288.705 246.15 292.281 241.674 292.328 235.764L292.99 240.415L295.859 230.688L296.536 232.936C296.536 232.936 298.196 232.31 299.128 228.733L300.159 232.957L302.067 231.609C302.067 231.609 303.221 234.821 307.488 234.095C307.488 234.095 309.084 236.536 307.946 240.046C307.946 240.046 304.486 252.536 312.805 249.596C312.805 249.596 320.533 248.103 322.877 243.318L323.077 245.905L327.281 243.081L331.995 244.219L330.327 246.049C330.327 246.049 335.755 248.634 341.66 245.677L340.414 247.761L345.812 247.347L344.637 249.05C344.637 249.05 351.947 247.387 352.542 245.941L351.636 248.513C351.636 248.513 361.039 245.29 363.361 241.509C363.361 241.509 370.626 235.346 370.367 226.761L376.549 223.483C376.549 223.483 377.81 225.488 379.448 223.261C379.448 223.261 380.846 228.358 384.037 224.11C384.037 224.11 386.559 228.12 388.659 224.056C388.659 224.056 392.397 225.571 392.378 220.169C392.378 220.169 395.614 216.517 393.872 213.448C393.872 213.448 401.023 213.6 400.93 208.503L430.215 211.454C430.215 211.454 435.772 211.827 434.567 206.617L436.449 207.573C436.449 207.573 437.48 203.992 433.683 201.683L435.484 201.545C435.484 201.545 435.036 197.078 428.617 194.67L431.032 194.684C431.032 194.684 427.371 186.361 422.568 182.727L425.437 183.407C425.437 183.407 421.1 171.533 414.13 168.467L411.937 166.135L418.077 168.818C418.077 168.818 412.991 165.454 411.837 159.64C411.837 159.64 418.204 161.352 419.857 164.527C419.857 164.527 420.404 159.883 417.775 155.781C417.775 155.781 421.92 157.361 422.227 161.343C422.227 161.343 424.479 159.27 418.899 149.491C418.899 149.491 422.789 150.391 424.035 153.5C424.035 153.5 423.972 146.199 417.102 141.826C417.102 141.826 421.092 142.719 422.6 145.305C422.6 145.305 420.585 140.058 417.12 138.12C417.12 138.12 419.849 139.613 422.57 137.103L415.242 134.666L418.64 133.104L412.199 130.398L417.919 128.957C417.919 128.957 414.199 128.943 412.369 127.384L415.36 125.752L412.077 124.904C412.077 124.904 414.299 122.43 414.328 118.927L411.844 120.617C411.844 120.617 416.166 107.577 407.702 95.6203C407.702 95.6203 404.896 93.1338 402.211 97.444C402.211 97.444 397.013 105.649 392.384 110.806L392.313 108.61L387.492 111.283L388.084 108.537L383.395 111.601L382.297 109.084L380.067 111.458L378.208 109.501L378.1 112.011C378.1 112.011 365.279 104.847 362.757 98.208C362.757 98.208 361.849 93.4634 358.361 98.8265L358.333 98.8173Z" + fill="#6124DC" /> + d="M343.86 249.572L345.123 247.742L339.78 248.154L340.81 246.432C335.23 248.71 330.382 246.463 330.167 246.358L329.762 246.164L331.354 244.42L327.333 243.45L322.773 246.512L322.61 244.418C319.832 248.467 313.411 249.823 312.877 249.93C310.84 250.644 309.288 250.523 308.259 249.571C305.653 247.159 307.526 240.262 307.608 239.97C308.508 237.185 307.613 235.086 307.292 234.474C304.215 234.909 302.532 233.312 301.912 232.131L299.937 233.526L299.078 229.999C298.093 232.682 296.71 233.235 296.645 233.262L296.309 233.388L295.855 231.874L292.87 242.001L292.385 238.587C291.549 243.085 289.087 246.214 288.966 246.37C287.245 248.257 285.195 249.139 282.855 249.009C279.539 248.825 275.716 246.65 271.492 242.547C268.37 239.512 266.174 236.493 266.152 236.463L254.963 220.508C254.574 219.935 254.473 219.376 254.658 218.832C255.011 217.804 256.334 217.209 256.827 217.021C256.997 216.337 257.354 215.841 257.894 215.548C258.892 215.007 260.197 215.357 260.673 215.517C267.06 210.884 278.466 222.572 279.814 223.993C283.492 223.561 285.302 218.117 285.839 216.154L282.759 217.727L283.028 216.946C285.006 211.193 287.316 207.723 288.296 206.402L284.774 206.672L294.466 202.643C293.583 202.603 292.31 202.619 291.169 202.678L290.008 202.738L290.959 202.075C295.676 198.777 299.891 198.482 301.286 198.484C300.834 197.526 299.399 197.133 299.385 197.127L298.086 196.78L299.397 196.48C303.603 195.522 306.048 197.521 306.644 198.096C309.324 197.501 310.976 197.452 311.898 197.515L308.593 193.615C306.4 193.527 305.522 191.768 305.295 191.2L300.211 189.615L295.749 184.497C294.725 183.586 294.203 182.617 294.194 181.61C294.185 180.675 294.626 179.957 294.925 179.574C293.991 178.862 293.437 178.024 293.282 177.089C293.096 175.976 293.521 175.028 293.779 174.574C293.013 173.972 292.602 173.284 292.561 172.523C292.496 171.401 293.26 170.477 293.612 170.116C293.013 168.425 293.077 167.175 293.806 166.403C294.883 165.257 297.088 165.558 298.139 165.784L294.865 154.397L289.661 158.736L289.464 158.386C287.776 155.381 287.36 152.737 288.232 150.527C289.436 147.468 292.647 146.402 292.783 146.359C313.525 139.879 319.425 144.084 319.667 144.267L319.791 144.359L322.143 186.412C323.961 187.992 327.004 188.277 329.376 187.137C328.736 186.685 328.342 185.893 328.421 185.103L328.464 184.696L328.855 184.817C329.107 184.897 329.425 185.07 329.662 185.225C332.666 184.611 334.932 182.359 336.314 180.568C337.45 179.09 338.4 177.436 339.317 175.836C339.808 174.978 340.318 174.088 340.853 173.232C342.798 170.119 344.746 168.134 346.976 166.987C347.575 166.681 348.2 166.429 348.809 166.189C349.319 165.986 349.846 165.776 350.34 165.536C353.332 164.094 355.602 161.44 356.482 158.384C354.705 158.252 352.931 158.264 351.2 158.426L350.443 158.497L350.903 157.894C351.516 157.086 352.053 156.415 352.639 155.801C350.352 155.933 348.185 156.236 346.468 157.449L345.4 158.203L345.975 157.032C347.342 154.239 349.808 151.401 352.388 149.573C350.598 149.727 348.735 149.499 347.008 148.897L346.294 148.651L346.956 148.291C348.366 147.523 349.409 146.389 350.127 144.824C348.984 144.742 347.885 144.112 347.228 143.138L346.824 142.536L347.546 142.621C348.826 142.769 350.04 141.951 351.072 141.167L351.149 141.109C351.873 140.561 352.474 140.108 352.987 139.465C351.058 139.429 349.152 138.728 347.669 137.495L347.102 137.022L347.833 136.911C349.854 136.6 351.91 135.587 353.773 133.976C355.082 132.848 356.541 131.154 358.113 128.94C357.054 128.862 356.013 128.398 355.226 127.639L354.505 126.943L355.501 127.071C356.691 127.223 357.93 126.755 358.995 125.767C357.873 125.671 356.749 125.028 356.162 124.076L355.194 122.499L356.656 123.637C356.702 123.673 356.761 123.681 356.836 123.664C356.97 123.634 357.104 123.533 357.165 123.414C357.303 123.15 357.275 122.804 357.228 122.414C357.108 121.388 356.973 120.349 356.844 119.34C356.47 116.454 356.085 113.472 356.001 110.506C355.898 106.788 355.773 102.164 358.06 98.6426C359.358 96.6456 360.466 95.7697 361.448 95.9609C362.607 96.1862 363.002 97.858 363.057 98.1136C365.256 103.838 375.437 110.076 377.767 111.444L377.885 108.696L380.044 110.968L382.38 108.483L383.524 111.104L388.563 107.814L387.953 110.636L392.609 108.055L392.667 109.953C397.078 104.859 401.852 97.345 401.904 97.2673C402.891 95.6814 404.019 94.7875 405.258 94.6075C406.765 94.386 407.853 95.3325 407.899 95.3719L407.95 95.4283C415.144 105.593 413.164 116.66 412.382 119.829L414.641 118.289L414.636 118.928C414.612 121.713 413.274 123.846 412.632 124.71L416.233 125.639L412.957 127.422C414.772 128.591 417.857 128.619 417.892 128.621L420.53 128.633L413.221 130.474L419.441 133.089L416.121 134.617L423.183 136.968L422.77 137.349C421.301 138.703 419.812 138.955 418.704 138.875C421.335 141.207 422.816 145.001 422.886 145.191L422.282 145.476C421.559 144.233 420.2 143.394 419.043 142.869C424.227 147.309 424.343 153.433 424.342 153.498L424.358 155.271L423.698 153.623C422.866 151.55 420.738 150.5 419.578 150.065C424.61 159.172 422.67 161.363 422.427 161.586L421.92 162.053L421.869 161.367C421.675 158.828 419.798 157.309 418.609 156.593C420.621 160.458 420.19 164.387 420.17 164.566L420.043 165.647L419.542 164.681C418.252 162.199 413.82 160.612 412.271 160.124C413.579 165.399 418.196 168.511 418.246 168.544L417.927 169.127L413.281 167.095L414.312 168.195C417.248 169.511 420.059 172.445 422.672 176.925C424.621 180.264 425.725 183.268 425.737 183.299L425.95 183.882L423.848 183.384C428.11 187.315 431.187 194.241 431.327 194.559L431.532 195.028L430.24 195.021C435.345 197.544 435.786 201.348 435.804 201.522L435.838 201.861L434.63 201.954C437.04 203.869 437.106 206.471 436.76 207.678L436.648 208.067L435.006 207.235C435.182 208.531 434.933 209.582 434.264 210.365C432.894 211.963 430.291 211.809 430.18 211.803L401.246 208.886C401.188 210.036 400.764 211.012 399.98 211.789C398.329 213.426 395.555 213.732 394.39 213.785C395.574 216.646 393.199 219.71 392.702 220.304C392.688 222.225 392.195 223.527 391.239 224.166C390.341 224.769 389.302 224.604 388.81 224.469C388.171 225.595 387.421 226.185 386.576 226.218L386.573 226.219C385.425 226.264 384.462 225.251 384.014 224.678C383.088 225.79 382.193 226.276 381.351 226.117C380.265 225.913 379.615 224.688 379.313 223.94C378.832 224.437 378.33 224.681 377.812 224.66C377.168 224.638 376.692 224.21 376.446 223.927L370.697 226.975C370.834 235.177 364.202 241.222 363.612 241.743C361.212 245.561 352.124 248.714 351.739 248.846L351.085 249.072L351.802 247.036C349.807 248.191 345.691 249.17 344.706 249.394L343.871 249.586L343.86 249.572ZM346.47 246.97L345.393 248.532C348.276 247.816 351.889 246.627 352.219 245.823L352.847 246.059L352.174 247.966C354.338 247.158 361.183 244.404 363.064 241.343L363.093 241.297L363.133 241.261C363.203 241.199 370.274 235.096 370.019 226.778L370.011 226.572L376.653 223.053L376.819 223.318C376.819 223.318 377.242 223.971 377.837 223.989C378.262 224.003 378.709 223.696 379.164 223.073L379.574 222.517L379.759 223.184C379.917 223.758 380.534 225.284 381.476 225.459C382.12 225.581 382.91 225.048 383.756 223.921L384.048 223.532L384.306 223.944C384.306 223.944 385.367 225.6 386.543 225.553L386.546 225.553C387.191 225.527 387.797 224.974 388.346 223.914L388.487 223.644L388.771 223.76C388.771 223.76 389.964 224.224 390.868 223.611C391.645 223.085 392.038 221.932 392.03 220.179L392.025 220.052L392.114 219.956C392.144 219.92 395.172 216.445 393.565 213.622L393.275 213.115L393.863 213.126C393.9 213.124 397.625 213.179 399.506 211.313C400.24 210.586 400.6 209.647 400.579 208.521L400.571 208.147L430.23 211.137C430.23 211.137 432.601 211.273 433.749 209.932C434.386 209.188 434.546 208.103 434.221 206.706L434.059 206.012L436.188 207.092C436.319 206.135 436.322 203.705 433.488 201.982L432.603 201.447L435.071 201.256C434.732 199.661 433.036 196.704 428.475 194.996L426.725 194.34L430.484 194.362C429.631 192.561 426.371 186.054 422.341 183.008L421.077 182.051L424.866 182.949C423.889 180.534 419.85 171.37 413.966 168.783L413.903 168.754L410.553 165.186L416.004 167.568C414.388 166.02 412.202 163.344 411.484 159.712L411.381 159.187L411.901 159.328C412.142 159.394 417.309 160.81 419.54 163.509C419.54 161.948 419.284 158.807 417.465 155.972L416.92 155.12L417.87 155.481C418.028 155.54 421.336 156.842 422.296 160.034C422.419 158.627 421.975 155.61 418.581 149.665L418.203 149.003L418.949 149.176C419.088 149.209 421.832 149.869 423.49 151.961C423.062 149.617 421.633 145.131 416.892 142.113L415.287 141.091L417.148 141.508C417.273 141.537 419.522 142.056 421.303 143.429C420.401 141.774 418.899 139.521 416.925 138.42L417.25 137.837C417.346 137.888 419.529 139.028 421.871 137.237L414.308 134.72L417.784 133.121L411.122 130.32L415.908 129.116C414.678 128.921 413.139 128.508 412.123 127.638L411.755 127.326L414.432 125.868L411.435 125.094L411.799 124.688C411.819 124.667 413.662 122.572 413.933 119.588L411.19 121.457L411.498 120.524C411.541 120.395 415.656 107.525 407.425 95.8582C407.268 95.7338 406.428 95.1143 405.344 95.2778C404.314 95.4322 403.347 96.2234 402.471 97.6296C402.419 97.7142 397.203 105.92 392.61 111.038L392.052 111.658L391.973 109.176L386.99 111.939L387.567 109.266L383.225 112.099L382.172 109.684L380.049 111.944L378.488 110.301L378.392 112.567L377.915 112.3C377.389 112.005 364.961 105.001 362.423 98.3244L362.407 98.2701C362.325 97.854 361.973 96.7408 361.319 96.6156C360.939 96.5413 360.084 96.7541 358.62 99.0052C356.443 102.354 356.568 106.865 356.667 110.49C356.749 113.422 357.133 116.386 357.503 119.255C357.633 120.264 357.768 121.31 357.889 122.34C357.935 122.726 357.994 123.257 357.754 123.723C357.632 123.962 357.415 124.153 357.164 124.259C357.842 124.895 358.864 125.24 359.741 125.071L360.673 124.893L360.06 125.615C359.014 126.846 357.738 127.584 356.446 127.738C357.142 128.14 357.951 128.342 358.722 128.277L359.431 128.217L359.026 128.797C357.279 131.314 355.656 133.228 354.204 134.481C352.475 135.977 350.578 136.984 348.675 137.427C350.109 138.405 351.873 138.894 353.609 138.791L354.253 138.752L353.916 139.298C353.264 140.351 352.506 140.921 351.547 141.647L351.47 141.705C350.464 142.467 349.384 143.163 348.218 143.292C348.857 143.892 349.747 144.231 350.601 144.166L351.138 144.124L350.94 144.62C350.262 146.31 349.27 147.584 347.918 148.49C349.856 149.035 351.927 149.103 353.824 148.684L356.048 148.19L354.059 149.3C351.451 150.755 348.779 153.473 347.13 156.289C349.007 155.372 351.203 155.195 353.471 155.098L354.375 155.062L353.712 155.672C353.056 156.283 352.498 156.927 351.887 157.708C353.55 157.593 355.243 157.612 356.934 157.757L357.322 157.79L357.23 158.168C356.388 161.573 353.92 164.555 350.63 166.14C350.112 166.391 349.575 166.605 349.055 166.811C348.463 167.048 347.851 167.289 347.283 167.583C345.164 168.671 343.3 170.58 341.423 173.587C340.894 174.433 340.391 175.316 339.9 176.17C338.973 177.792 338.011 179.466 336.849 180.98C335.378 182.894 332.932 185.301 329.652 185.917L329.508 185.943L329.39 185.855C329.323 185.802 329.231 185.744 329.135 185.69C329.273 186.207 329.682 186.665 330.199 186.812L330.929 187.024L330.278 187.418C327.516 189.091 323.78 188.835 321.593 186.822L321.493 186.73L321.488 186.596L319.143 144.731C318.21 144.191 311.731 141.146 292.988 147.004C292.961 147.012 289.942 148.022 288.857 150.787C288.098 152.718 288.436 155.045 289.858 157.718L295.229 153.242L299.114 166.756L298.527 166.58C297.667 166.322 295.232 165.872 294.294 166.872C293.728 167.475 293.733 168.561 294.316 170.102L294.397 170.319L294.224 170.47C294.224 170.47 293.17 171.412 293.234 172.503C293.269 173.13 293.672 173.709 294.425 174.229L294.709 174.423L294.503 174.7C294.503 174.7 293.736 175.751 293.948 176.994C294.092 177.84 294.655 178.601 295.616 179.254L295.964 179.491L295.654 179.775C295.654 179.775 294.852 180.535 294.868 181.621C294.88 182.435 295.333 183.242 296.217 184.025L296.246 184.054L300.596 189.047L305.827 190.677L305.879 190.85C305.903 190.935 306.533 192.959 308.757 192.966L308.912 192.967L313.822 198.758L312.62 198.308C312.62 198.308 311.052 197.786 306.617 198.798L306.425 198.843L306.295 198.697C306.208 198.601 304.314 196.556 300.652 196.956C301.271 197.313 301.95 197.901 302.079 198.797L302.14 199.21L301.721 199.175C301.676 199.17 297.382 198.86 292.343 201.979C293.637 201.944 295.384 201.954 295.861 202.22L296.462 202.553L288.886 205.701L289.812 205.63L289.287 206.242C289.258 206.277 286.382 209.667 283.945 216.391L286.819 214.922L286.677 215.605C286.601 215.958 284.806 224.296 279.717 224.687L279.556 224.701L279.444 224.581C279.321 224.449 267.081 211.416 260.944 216.169L260.794 216.289L260.615 216.217C260.615 216.217 259.159 215.642 258.222 216.15C257.817 216.373 257.567 216.764 257.455 217.35L257.418 217.543L257.231 217.606C256.784 217.751 255.569 218.298 255.303 219.068C255.189 219.402 255.261 219.757 255.526 220.148L266.707 236.094C266.791 236.207 275.357 247.936 282.902 248.361C285.03 248.479 286.901 247.672 288.466 245.957C288.486 245.929 291.956 241.511 292.001 235.794L292.666 235.75L293.112 238.877L295.862 229.55L296.738 232.461C297.23 232.084 298.185 231.08 298.808 228.687L299.144 227.402L300.373 232.439L302.237 231.121L302.385 231.535C302.428 231.653 303.511 234.473 307.434 233.805L307.651 233.768L307.772 233.953C307.842 234.056 309.441 236.57 308.269 240.188C308.254 240.244 306.426 246.974 308.738 249.112C309.574 249.886 310.906 249.957 312.701 249.322L312.749 249.31C312.824 249.296 320.341 247.791 322.583 243.213L323.122 242.112L323.372 245.35L327.223 242.763L332.628 244.067L330.901 245.961C332.271 246.473 336.762 247.8 341.515 245.421L342.538 244.91L341.036 247.423L346.489 247.003L346.47 246.97Z" + fill="#3B2358" /> + d="M352.307 164.977C354.476 164.729 356.555 163.77 358.147 162.287C357.909 164.479 357.013 166.594 355.606 168.293C357.752 167.991 359.659 167.214 361.345 165.854C361.148 167.323 360.517 168.733 359.55 169.858C360.506 169.751 361.416 169.281 362.058 168.568C361.657 170.035 361.619 171.597 361.951 173.082C362.279 172.124 362.971 171.299 363.86 170.81C363.661 173.443 364.497 176.142 366.154 178.204C364.818 177.006 363.853 175.405 363.414 173.67C362.461 174.708 361.475 175.785 361.146 177.152C360.185 175.386 359.744 173.342 359.899 171.335C358.996 171.471 358.119 171.743 357.288 172.12C357.569 171.284 357.661 170.386 357.558 169.514C357.092 169.973 356.416 170.154 355.775 170.269C354.619 170.473 353.439 170.496 352.265 170.515C352.242 170.097 352.167 169.684 352.006 169.299C351.834 168.879 351.517 168.538 351.203 168.203C350.547 167.501 349.83 166.763 348.889 166.55C350.179 166.254 351.335 165.871 352.307 164.977Z" + fill="#3B2358" /> + d="M376.766 156.455C375.218 156.517 373.689 156.361 372.381 155.609C371.395 156.435 369.938 156.683 368.741 156.201C367.463 155.688 366.544 154.371 366.51 153.001L367.18 152.984C367.207 154.097 367.95 155.167 368.989 155.583C370.028 155.998 371.309 155.741 372.103 154.957L372.292 154.767L372.519 154.913C374.121 155.938 376.198 155.887 378.206 155.676C378.973 155.597 379.856 155.49 380.682 155.241C383.125 154.501 385 152.573 386.709 150.663C387.251 150.057 388.263 148.931 389.529 149.059L389.462 149.722C388.605 149.636 387.852 150.391 387.21 151.107C385.438 153.085 383.49 155.084 380.88 155.879C380 156.148 379.075 156.257 378.281 156.34C377.779 156.391 377.273 156.435 376.77 156.455L376.766 156.455Z" + fill="#3B2358" /> + d="M374.103 160.6C372.986 160.644 371.759 160.349 371.034 159.406C370.793 159.092 370.634 158.741 370.483 158.403C370.381 158.177 370.282 157.961 370.164 157.763C369.846 157.229 369.355 156.799 368.779 156.55L369.045 155.938C369.747 156.24 370.349 156.766 370.737 157.421C370.874 157.652 370.984 157.895 371.09 158.128C371.234 158.446 371.367 158.746 371.56 158.996C372.281 159.933 373.691 160.052 374.771 159.851C375.792 159.659 376.777 159.232 377.727 158.816L383.908 156.123C385.47 155.442 387.082 154.742 388.794 154.381C390.74 153.974 392.554 154.094 394.037 154.729L393.771 155.341C392.06 154.605 390.195 154.769 388.934 155.032C387.287 155.376 385.705 156.065 384.178 156.731L377.996 159.424C377.012 159.855 375.99 160.298 374.897 160.503C374.643 160.551 374.375 160.582 374.099 160.593L374.103 160.6Z" + fill="#3B2358" /> + d="M386.458 138.73L385.792 138.664C386.061 136.048 387.316 134.001 389.152 133.189C390.011 132.811 390.967 132.711 391.8 132.65C393.177 132.551 394.578 132.516 395.931 132.486L395.947 133.152C394.601 133.182 393.211 133.216 391.851 133.315C391.041 133.375 390.185 133.461 389.428 133.797C387.813 134.511 386.705 136.356 386.462 138.73L386.458 138.73Z" + fill="#3B2358" /> + d="M372.106 138.377L371.437 138.397C371.401 137.254 371.131 136.282 370.631 135.508C370.064 134.63 369.184 134.043 368.272 133.935C367.824 133.884 367.364 133.94 366.879 133.997C366.752 134.013 366.621 134.028 366.494 134.043C365.452 134.154 364.398 134.13 363.363 133.976L363.464 133.319C364.444 133.469 365.44 133.487 366.423 133.383C366.547 133.371 366.671 133.356 366.798 133.341C367.299 133.279 367.818 133.214 368.349 133.279C369.456 133.41 370.52 134.11 371.193 135.152C371.757 136.027 372.062 137.114 372.103 138.381L372.106 138.377Z" + fill="#3B2358" /> + d="M366.213 152.476C365.982 151.431 365.717 150.248 365.94 149.085C366.132 148.091 366.67 147.203 367.143 146.418C368.331 144.449 369.559 142.417 370.948 140.527L371.184 140.211C371.676 139.549 372.184 138.866 372.524 138.12C372.784 137.543 372.972 136.879 373.11 136.024C373.468 133.831 373.214 131.947 372.375 130.575L372.948 130.229C373.887 131.762 374.166 133.748 373.774 136.135C373.624 137.049 373.421 137.765 373.136 138.398C372.771 139.207 372.24 139.922 371.725 140.613L371.493 140.928C370.12 142.794 368.902 144.815 367.723 146.769C367.256 147.544 366.774 148.344 366.605 149.22C366.408 150.248 366.656 151.359 366.874 152.34L366.22 152.486L366.213 152.476Z" + fill="#3B2358" /> + d="M408.381 122.123C407.321 122.371 406.23 122.473 405.14 122.427C405.48 122.114 405.82 121.798 406.163 121.486C403.755 121.716 401.263 120.537 399.919 118.535C399.82 118.384 399.724 118.223 399.707 118.045C399.693 117.87 399.758 117.696 399.828 117.535C400.389 116.189 401.157 114.932 402.101 113.818C401.512 113.876 400.921 113.938 400.333 113.995C400.682 113.483 401.031 112.971 401.38 112.455C400.628 112.581 399.925 112.96 399.405 113.51C399.943 111.498 401.176 109.683 402.85 108.437C401.764 108.487 400.697 108.939 399.909 109.689C400.616 108.623 401.553 107.709 402.642 107.03C401.523 107.047 400.415 107.486 399.596 108.244C400.479 105.624 401.457 103.049 402.861 100.659C403.162 100.149 403.523 99.6705 403.93 99.2452C407.157 95.8826 408.109 103.224 408.266 104.998C408.448 107.073 408.607 109.146 408.752 111.223C408.824 112.258 408.945 113.302 408.966 114.339C408.984 115.146 408.665 115.726 408.472 116.5" + fill="#3B2358" /> + d="M360.077 122.236C359.164 117.859 358.827 113.391 358.591 108.936C358.495 107.125 357.718 101.578 360.841 101.697C361.92 101.74 362.442 103.311 362.91 104.055C363.994 105.768 365.299 107.331 366.787 108.705C365.862 108.196 364.947 107.772 364.182 107.042C364.76 109.154 366.465 110.756 368.18 112.124C367.132 112.005 366.116 111.622 365.253 111.021C365.906 112.861 367.257 114.45 368.977 115.392C368.123 116.059 366.945 116.068 365.86 116.049C366.381 116.461 367.072 116.65 367.732 116.555C367.298 117.37 366.887 118.235 366.236 118.887C365.582 119.538 364.763 120.049 363.851 120.216" + fill="#3B2358" /> + d="M373.244 174.842L372.726 174.419C374.782 171.935 377.259 169.877 380.084 168.308L380.881 167.863L379.575 171.325C381.495 169.499 383.794 167.569 386.563 166.843L387.137 166.693L386.969 167.26C386.781 167.896 386.674 168.592 386.65 169.3C388.901 168.242 390.9 166.67 392.449 164.729L392.985 164.058L393.047 164.911C393.092 165.528 393.12 166.139 393.147 166.729C393.162 167.106 393.181 167.494 393.203 167.885L399.197 162.989L399.311 163.527C399.413 164.001 399.501 164.475 399.593 164.949C399.636 165.171 399.676 165.389 399.719 165.611C401.137 163.664 402.689 161.788 404.331 160.031L404.779 159.553L404.904 160.198C405.499 163.253 407.924 165.865 410.941 166.697L410.763 167.34C407.718 166.499 405.228 163.976 404.396 160.95C402.758 162.74 401.217 164.647 399.818 166.624L399.377 167.25L399.219 166.504C399.118 166.03 399.03 165.556 398.938 165.078C398.882 164.789 398.829 164.499 398.772 164.209L392.628 169.224L392.582 168.583C392.537 167.966 392.509 167.355 392.482 166.765C392.469 166.446 392.453 166.124 392.436 165.795C390.791 167.654 388.74 169.142 386.455 170.126L386 170.323L385.988 169.832C385.965 169.094 386.036 168.352 386.184 167.659C383.311 168.602 381.017 170.851 378.977 172.851L377.897 173.911L379.611 169.364C377.193 170.825 375.057 172.67 373.251 174.849L373.244 174.842Z" + fill="#3B2358" /> + d="M405.043 198.778C402.356 196.771 400.323 193.873 399.322 190.675C399.127 191.831 399.032 193.003 399.04 194.175L399.052 195.508L398.412 194.337C395.823 189.594 393.801 184.712 392.55 180.184C388.714 183.392 383.984 185.588 378.838 186.542C373.508 187.527 368.118 187.117 363.247 185.345L363.478 184.72C373.118 188.223 384.787 186.061 392.517 179.336L392.924 178.983L393.062 179.504C394.192 183.772 396.03 188.38 398.403 192.901C398.473 191.633 398.658 190.371 398.961 189.136L399.308 187.713L399.614 189.148C400.375 192.733 402.503 196.051 405.45 198.253L405.046 198.785L405.043 198.778Z" + fill="#3B2358" /> - - - + d="M350.476 187.414C349.939 187.435 349.403 187.426 348.866 187.389C348.129 187.335 347.298 187.204 346.719 186.622C346.33 186.232 346.144 185.706 346.023 185.292C345.41 183.158 345.673 180.817 346.748 178.87L347.334 179.191C346.342 180.983 346.1 183.141 346.665 185.108C346.762 185.445 346.91 185.868 347.194 186.153C347.615 186.579 348.299 186.679 348.912 186.723C352.282 186.967 355.764 185.945 358.463 183.923L358.864 184.457C356.467 186.254 353.476 187.294 350.47 187.414L350.476 187.414Z" + fill="#3B2358" /> + d="M333.63 203.087L333.192 202.582C337.442 198.917 340.838 194.252 343.008 189.089L343.626 189.347C341.415 194.604 337.961 199.354 333.63 203.087Z" + fill="#3B2358" /> + d="M308.316 224.806C307.541 222.355 308.069 219.819 309.661 218.343C310.587 217.484 311.99 217.074 313.32 217.276C314.477 217.45 315.398 218.038 315.914 218.936L315.333 219.268C314.918 218.549 314.167 218.077 313.219 217.933C312.082 217.762 310.895 218.108 310.115 218.83C308.52 220.309 308.384 222.796 308.954 224.605L308.316 224.806Z" + fill="#3B2358" /> + d="M313.552 224.051C313.488 222.703 314.123 221.31 315.251 220.32C316.382 219.329 317.853 218.882 319.188 219.121C320.1 219.284 320.961 219.831 321.435 220.551C321.78 221.073 321.889 221.643 321.756 222.198L321.104 222.042C321.216 221.57 321.041 221.168 320.872 220.914C320.501 220.351 319.793 219.901 319.069 219.772C317.935 219.57 316.673 219.96 315.692 220.817C314.714 221.674 314.161 222.868 314.217 224.018L313.549 224.051L313.552 224.051Z" + fill="#3B2358" /> + d="M311.696 247.757C311.292 247.773 310.891 247.761 310.492 247.719L310.563 247.056C313.569 247.373 316.821 245.862 319.26 243.022C321.477 240.435 322.779 237.218 324.04 234.109C324.936 231.894 325.863 229.606 326.489 227.268C326.822 226.024 327.158 224.231 326.23 223.03C325.247 221.757 323.196 221.766 321.858 222.5C320.351 223.33 319.349 224.875 318.53 226.258L317.954 225.921C318.817 224.46 319.882 222.826 321.534 221.915C323.149 221.026 325.547 221.047 326.759 222.621C327.866 224.055 327.5 226.056 327.134 227.435C326.497 229.811 325.563 232.12 324.657 234.352C323.378 237.514 322.051 240.78 319.764 243.449C317.503 246.086 314.557 247.64 311.689 247.754L311.696 247.757Z" + fill="#3B2358" /> + d="M315.027 218.259L314.428 217.96C316.179 214.495 319.244 211.668 322.833 210.14C321.595 210 320.388 209.608 319.31 208.988L318.299 208.406L319.464 208.367C319.464 208.367 319.492 208.365 319.506 208.365C321.678 208.278 323.803 207.352 325.337 205.82L325.812 206.289C324.43 207.667 322.606 208.592 320.678 208.913C321.934 209.42 323.313 209.622 324.662 209.493L324.788 210.144C320.623 211.365 316.973 214.398 315.024 218.26L315.027 218.259Z" + fill="#3B2358" /> + d="M338.618 235.707L338.064 235.33C339.167 233.723 339.908 231.855 340.215 229.931L340.875 230.036C340.555 232.056 339.773 234.015 338.618 235.704L338.618 235.707Z" + fill="#3B2358" /> + d="M363.801 216.839C359.965 212.362 354.849 208.937 349.006 206.929C343.162 204.921 337.011 204.482 331.215 205.651L331.082 204.996C336.991 203.802 343.267 204.253 349.222 206.298C355.178 208.343 360.394 211.84 364.308 216.406L363.797 216.839L363.801 216.839Z" + fill="#3B2358" /> + d="M299.712 227.101L299.184 226.692C301.626 223.564 302.904 219.502 302.702 215.551L303.37 215.517C303.586 219.629 302.252 223.851 299.715 227.104L299.712 227.101Z" + fill="#3B2358" /> + d="M326.487 205.382C321.67 205.574 316.792 203.61 313.571 199.988L314.071 199.546C317.943 203.901 324.323 205.757 329.944 204.165L330.128 204.807C328.936 205.144 327.714 205.333 326.484 205.382L326.487 205.382Z" + fill="#3B2358" /> + d="M366.614 149.285C366.673 150.056 366.995 150.851 367.562 151.581C368.578 152.887 369.97 153.949 371.431 154.719C373.498 155.809 375.725 152.431 376.634 151.061C378.283 148.579 377.139 145.862 374.101 145.371C372.276 145.076 370.14 145.209 368.49 146.096C367.125 146.831 366.523 148.027 366.621 149.284L366.614 149.285Z" + fill="#3B2358" /> + d="M364.608 131.342L364.025 131.014C364.964 129.358 367.069 128.449 368.924 128.905L368.764 129.55C367.191 129.166 365.402 129.935 364.608 131.342Z" + fill="#3B2358" /> + d="M387.204 130.486L386.679 130.071C388.38 127.948 391.525 127.21 393.995 128.363L393.711 128.966C391.551 127.959 388.69 128.626 387.204 130.486Z" + fill="#3B2358" /> + d="M369.192 138.827C368.513 138.854 367.823 138.696 367.236 138.355C366.306 137.818 365.635 136.824 365.489 135.761L366.151 135.669C366.272 136.53 366.815 137.34 367.572 137.778C368.328 138.215 369.302 138.286 370.114 137.962L370.363 138.581C369.993 138.729 369.592 138.811 369.192 138.827Z" + fill="#3B2358" /> + d="M389.264 137.824C388.761 137.844 388.264 137.761 387.814 137.576L388.073 136.961C388.771 137.249 389.61 137.226 390.381 136.897C391.148 136.567 391.746 135.976 392.018 135.274L392.643 135.514C392.308 136.383 391.58 137.11 390.647 137.508C390.198 137.698 389.729 137.802 389.267 137.821L389.264 137.824Z" + fill="#3B2358" /> + d="M406.795 148.444C406.487 147.909 405.903 147.548 405.336 147.199L405.227 147.131C404.348 146.586 403.223 145.823 402.336 144.775C401.433 143.712 400.911 142.474 400.86 141.294L401.529 141.268C401.571 142.304 402.042 143.395 402.847 144.346C403.673 145.324 404.741 146.044 405.58 146.564L405.69 146.632C406.327 147.026 406.986 147.433 407.376 148.111L406.795 148.444Z" + fill="#3B2358" /> + d="M411.551 144.993C410.933 143.533 409.67 142.339 408.171 141.8L408.398 141.173C410.069 141.773 411.479 143.102 412.169 144.731L411.551 144.989L411.551 144.993Z" + fill="#3B2358" /> + d="M407.571 133.689C407.065 133.287 406.627 132.778 406.308 132.22L406.888 131.888C407.167 132.375 407.55 132.817 407.989 133.167L407.571 133.689Z" + fill="#3B2358" /> + d="M404.118 185.095C402.41 183.668 401.219 181.687 400.76 179.516L401.414 179.38C401.844 181.405 402.957 183.254 404.546 184.586L404.114 185.095L404.118 185.095Z" + fill="#3B2358" /> + d="M410.564 186.529C408.807 186.114 407.36 184.66 406.959 182.909L407.613 182.763C407.956 184.272 409.204 185.525 410.717 185.88L410.564 186.529Z" + fill="#3B2358" /> + d="M387.535 197.242C386.608 197.278 385.684 197.226 384.78 197.176L384.82 196.511C386.135 196.586 387.498 196.662 388.809 196.452C389.811 196.292 391.218 195.885 392.233 194.841L392.714 195.306C391.57 196.483 390.016 196.936 388.915 197.111C388.459 197.184 387.997 197.223 387.539 197.241L387.535 197.242Z" + fill="#3B2358" /> + d="M375.926 223.35C375.108 221.977 375.469 220.306 375.914 219.151C376.098 218.672 376.318 218.203 376.528 217.751C376.894 216.974 377.238 216.238 377.424 215.444C377.592 214.736 377.626 214.016 377.664 213.252C377.687 212.787 377.713 212.305 377.767 211.828C377.87 210.965 378.001 210.767 378.287 210.405C378.405 210.253 378.556 210.065 378.754 209.73C379.867 207.854 381.781 206.747 383.63 205.673C384.694 205.057 385.797 204.418 386.723 203.642C387.479 203.014 388.173 202.248 388.845 201.51C390.195 200.026 391.591 198.493 393.564 197.905C395.243 197.409 396.985 197.707 398.671 198.001C399.068 198.071 399.464 198.138 399.857 198.194C403.111 198.673 406.484 198.387 409.614 197.372C410.531 197.075 411.452 196.708 412.34 196.353C413.794 195.769 415.3 195.17 416.876 194.839C419.92 194.206 422.703 194.868 424.319 196.611L423.826 197.064C422.372 195.493 419.824 194.907 417.012 195.493C415.495 195.808 414.02 196.4 412.589 196.972C411.691 197.331 410.76 197.705 409.822 198.007C406.597 199.053 403.118 199.346 399.762 198.854C399.363 198.795 398.963 198.728 398.559 198.658C396.949 198.379 395.284 198.091 393.755 198.544C391.963 199.076 390.689 200.474 389.339 201.957C388.651 202.713 387.94 203.494 387.151 204.155C386.178 204.967 385.051 205.62 383.964 206.251C382.108 207.328 380.352 208.344 379.327 210.072C379.107 210.445 378.936 210.661 378.807 210.818C378.587 211.098 378.511 211.194 378.426 211.909C378.371 212.361 378.349 212.833 378.325 213.287C378.287 214.045 378.249 214.83 378.069 215.597C377.865 216.457 377.489 217.259 377.126 218.033C376.919 218.475 376.706 218.934 376.528 219.391C376.205 220.225 375.774 221.809 376.492 223.015L375.915 223.354L375.926 223.35Z" + fill="#3B2358" /> + d="M379.714 222.471L379.044 222.487C379.029 221.934 379.104 221.381 379.266 220.849C379.433 220.292 379.692 219.773 379.945 219.272C380.035 219.096 380.121 218.918 380.207 218.739C381.376 216.276 381.75 213.44 381.267 210.761L381.926 210.642C382.435 213.457 382.039 216.436 380.813 219.024C380.727 219.206 380.634 219.389 380.544 219.568C380.295 220.066 380.058 220.536 379.905 221.04C379.765 221.503 379.701 221.983 379.713 222.467L379.714 222.471Z" + fill="#3B2358" /> + d="M383.887 223.397L383.276 223.129C384.483 220.408 384.961 217.405 384.657 214.444C384.64 214.297 384.624 214.15 384.608 214.003C384.464 212.723 384.302 211.273 385.072 210.132L385.629 210.501C384.996 211.441 385.136 212.707 385.271 213.928C385.288 214.079 385.304 214.23 385.32 214.377C385.636 217.451 385.139 220.57 383.887 223.397Z" + fill="#3B2358" /> + d="M388.143 224.018C387.655 223.306 387.855 222.438 388.032 221.675C388.059 221.561 388.085 221.45 388.109 221.342C388.355 220.167 388.26 218.979 388.157 217.714C388.122 217.255 388.082 216.779 388.064 216.312C387.97 214.044 388.476 212.354 389.573 211.286L390.041 211.762C389.087 212.694 388.647 214.217 388.732 216.286C388.751 216.742 388.79 217.208 388.825 217.66C388.927 218.914 389.03 220.209 388.763 221.478C388.74 221.592 388.714 221.707 388.684 221.825C388.531 222.487 388.371 223.171 388.697 223.642L388.142 224.015L388.143 224.018Z" + fill="#3B2358" /> + d="M302.842 171.395L302.695 170.744C303.048 170.665 303.243 170.196 303.18 169.831C303.117 169.456 302.864 169.077 302.406 168.676C301.543 167.917 300.442 167.407 299.302 167.24L299.4 166.579C300.665 166.766 301.889 167.336 302.845 168.178C303.421 168.687 303.749 169.19 303.839 169.722C303.956 170.398 303.581 171.231 302.842 171.398L302.842 171.395Z" + fill="#3B2358" /> + d="M303.794 175.629L303.202 175.319C303.854 174.083 303.204 172.497 302.2 171.675C301.254 170.901 299.881 170.488 298.118 170.445L298.136 169.778C300.051 169.825 301.562 170.291 302.625 171.159C303.821 172.136 304.636 174.032 303.794 175.629Z" + fill="#3B2358" /> + d="M305.288 178.367L304.664 178.131C304.908 177.492 304.523 176.751 304.038 176.379C303.54 175.996 302.855 175.797 301.942 175.768C301.019 175.739 300.109 175.872 299.233 176.161L299.021 175.53C299.972 175.214 300.961 175.071 301.961 175.104C303.019 175.137 303.833 175.38 304.446 175.85C305.14 176.383 305.655 177.421 305.288 178.367Z" + fill="#3B2358" /> + d="M300.537 183.677L300.452 183.017C301.944 182.827 303.356 182.231 304.531 181.294C304.819 181.066 305.133 180.786 305.298 180.429C305.422 180.159 305.462 179.773 305.262 179.516C305.018 179.199 304.494 179.144 304.065 179.134C302.465 179.091 300.882 179.326 299.366 179.833L299.154 179.202C300.746 178.672 302.407 178.423 304.084 178.47C304.661 178.485 305.379 178.573 305.795 179.117C306.115 179.537 306.158 180.161 305.903 180.71C305.677 181.197 305.274 181.557 304.946 181.817C303.674 182.83 302.149 183.475 300.534 183.681L300.537 183.677Z" + fill="#3B2358" /> + d="M300.464 150.717C298.499 150.795 296.538 150.801 294.608 150.809L294.605 150.142C298.618 150.13 302.764 150.116 306.782 149.455C311.269 148.716 315.016 147.233 317.923 145.052L318.328 145.582C315.333 147.829 311.485 149.353 306.891 150.11C304.767 150.459 302.612 150.631 300.464 150.717Z" + fill="#3B2358" /> + d="M299.409 148.161C298.038 147.026 296.231 146.469 294.451 146.626L294.39 145.962C296.341 145.784 298.327 146.399 299.834 147.645L299.406 148.157L299.409 148.161Z" + fill="#3B2358" /> + d="M294.304 151.76C294.078 151.373 294.004 150.902 294.097 150.465L294.751 150.604C294.693 150.881 294.74 151.179 294.881 151.424L294.3 151.756L294.304 151.76Z" + fill="#3B2358" /> + d="M304.107 163.443C301.98 163.528 299.841 163.331 297.759 162.83L297.917 162.181C305.057 163.893 312.919 161.961 318.439 157.136L318.88 157.637C314.809 161.198 309.496 163.228 304.107 163.443Z" + fill="#3B2358" /> + + d="M394.523 268.891L380.073 269.466L378.835 265.178L394.35 264.56L394.523 268.891ZM380.571 268.78L393.828 268.251L393.708 265.252L379.713 265.81L380.571 268.78Z" + fill="#3B2358" /> + + d="M230.161 270.348L220.035 270.751L219.131 266.45L229.989 266.017L230.161 270.348ZM220.577 270.063L229.466 269.709L229.346 266.71L219.951 267.084L220.577 270.063Z" + fill="#3B2358" /> + + d="M393.924 269.196L393.546 264.303L393.588 264.219L418.631 215.14L420.31 219.843L420.239 219.973L393.921 269.196L393.924 269.196ZM394.228 264.438L394.415 266.86L419.583 219.793L418.525 216.828L394.228 264.441L394.228 264.438Z" + fill="#3B2358" /> + + d="M218.639 267.184L260.377 227.07L264.199 232.519L263.993 232.717L229.016 266.389L218.639 267.188L218.639 267.184ZM260.276 228.091L220.441 266.377L228.721 265.741L263.322 232.434L260.276 228.091Z" + fill="#3B2358" /> + + d="M228.875 270.488L228.524 265.931L228.638 265.823L263.811 231.964L266.477 235.762L228.875 270.488ZM229.215 266.192L229.436 269.06L265.592 235.667L263.71 232.982L229.215 266.189L229.215 266.192Z" + fill="#3B2358" /> + d="M414.697 182.721C414.298 182.057 413.817 181.437 413.274 180.881L413.753 180.415C414.332 181.007 414.842 181.667 415.271 182.375L414.697 182.718L414.697 182.721Z" + fill="#3B2358" /> + d="M420.565 191.145C420.36 190.579 420.056 190.059 419.668 189.596L420.183 189.17C420.621 189.692 420.959 190.281 421.195 190.917L420.565 191.145Z" + fill="#3B2358" /> + d="M415.943 177.918C415.567 177.15 415.021 176.453 414.367 175.898L414.799 175.39C415.524 176 416.128 176.773 416.546 177.626L415.943 177.918Z" + fill="#3B2358" /> + d="M409.223 193.095C407.377 192.523 405.943 190.786 405.739 188.869L406.406 188.798C406.586 190.454 407.827 191.962 409.425 192.458L409.226 193.095L409.223 193.095Z" + fill="#3B2358" /> + + d="M408.957 154.266L408.297 154.161C408.372 153.698 408.266 153.204 408.005 152.812L408.564 152.446C408.913 152.975 409.057 153.64 408.957 154.269L408.957 154.266Z" + fill="#3B2358" /> + d="M371.036 135.87C370.632 136.92 369.232 137.406 368.211 136.927C367.191 136.449 366.667 135.167 366.962 134.083C366.866 133.939 367.088 133.693 367.211 133.568C368.792 133.471 370.425 134.413 371.039 135.87L371.036 135.87Z" + fill="#F5D55F" /> + d="M369.168 137.446C368.785 137.461 368.406 137.39 368.068 137.232C366.953 136.709 366.329 135.353 366.611 134.108C366.56 133.886 366.681 133.627 366.97 133.337L367.06 133.248L367.188 133.243C368.937 133.132 370.685 134.186 371.345 135.744L371.398 135.869L371.351 135.995C371.135 136.557 370.66 137.019 370.045 137.263C369.759 137.378 369.465 137.441 369.172 137.453L369.168 137.446ZM367.296 133.981L367.326 134.024L367.287 134.17C367.028 135.125 367.507 136.23 368.355 136.626C368.777 136.826 369.316 136.828 369.795 136.637C370.19 136.481 370.503 136.204 370.673 135.87C370.1 134.673 368.746 133.864 367.362 133.895C367.332 133.931 367.309 133.959 367.296 133.981Z" + fill="#3B2358" /> + d="M387.338 135.43C388.488 133.686 390.36 132.828 392.029 133.277C392.475 134.51 391.154 135.934 390.128 136.267C389.101 136.597 388.094 136.359 387.342 135.43L387.338 135.43Z" + fill="#F5D55F" /> + d="M389.369 136.741C388.49 136.776 387.695 136.399 387.078 135.64L386.925 135.45L387.058 135.249C388.283 133.392 390.315 132.473 392.116 132.958L392.284 133.002L392.342 133.165C392.528 133.677 392.475 134.253 392.194 134.824C391.804 135.613 390.997 136.336 390.23 136.583C389.937 136.677 389.649 136.73 389.369 136.741ZM387.762 135.406C388.375 136.042 389.152 136.231 390.022 135.949C390.537 135.784 391.24 135.244 391.592 134.532C391.713 134.283 391.834 133.928 391.757 133.556C390.35 133.268 388.79 133.99 387.759 135.406L387.762 135.406Z" + fill="#3B2358" /> + d="M377.054 194.724L376.997 194.059C377.998 193.975 378.971 193.513 379.667 192.791L380.149 193.253C379.339 194.086 378.211 194.623 377.051 194.721L377.054 194.724Z" + fill="#3B2358" /> + d="M389.649 190.998L389.574 190.338C390.024 190.289 390.426 189.881 390.47 189.433L391.136 189.499C391.059 190.255 390.405 190.913 389.645 190.999L389.649 190.998Z" + fill="#3B2358" /> + d="M396.483 182.416C395.778 179.718 396.126 176.759 397.44 174.294C398.755 171.832 401.026 169.886 403.665 168.956L403.887 169.583C401.4 170.455 399.267 172.286 398.03 174.604C396.792 176.922 396.465 179.705 397.129 182.246L396.479 182.412L396.483 182.416Z" + fill="#3B2358" /> + + d="M357.397 240.812L357.039 240.249C358.791 239.152 360.057 237.286 360.422 235.258L361.079 235.376C360.68 237.585 359.304 239.619 357.393 240.816L357.397 240.812Z" + fill="#1E0F30" /> + d="M363.003 221.686L362.462 221.292C363.029 220.527 363.777 219.895 364.634 219.473L364.931 220.069C364.169 220.447 363.504 221.006 362.999 221.686L363.003 221.686Z" + fill="#1E0F30" /> + d="M382.909 197.608C380.885 197.864 378.864 198.12 376.84 198.372C378.478 199.169 380.218 199.76 382.004 200.125C379.238 202.205 375.542 202.455 372.082 202.631C373.071 203.88 374.895 204.402 376.403 203.868C373.186 206.416 368.89 208.663 364.804 208.214C365.188 210.92 367.688 213.168 370.431 213.282C369.66 214.045 368.687 214.744 367.612 214.903" + fill="#6124DC" /> + d="M367.663 215.235L367.564 214.575C368.244 214.473 368.949 214.125 369.661 213.536C367.056 213.083 364.849 210.896 364.474 208.265L364.413 207.841L364.843 207.889C368.766 208.317 372.665 206.175 375.13 204.414C373.869 204.402 372.607 203.834 371.821 202.841L371.421 202.334L372.069 202.302C374.943 202.16 378.469 201.981 381.188 200.289C379.637 199.914 378.13 199.372 376.697 198.677L375.693 198.188L382.871 197.283L382.956 197.943L378.057 198.561C379.353 199.107 380.699 199.524 382.077 199.806L382.802 199.956L382.212 200.399C379.489 202.442 375.893 202.768 372.843 202.931C373.786 203.701 375.136 203.97 376.294 203.56L378.188 202.89L376.614 204.135C374.321 205.951 369.845 208.886 365.216 208.589C365.762 210.935 368.021 212.856 370.446 212.955L371.21 212.987L370.665 213.524C369.665 214.512 368.655 215.089 367.66 215.238L367.663 215.235Z" + fill="#3B2358" /> + d="M383.265 132.767L382.61 132.628C382.802 131.73 383.144 130.875 383.621 130.089L384.194 130.434C383.753 131.156 383.442 131.942 383.265 132.767Z" + fill="#3B2358" /> + d="M389.53 151.881L388.977 151.504C389.339 150.974 389.892 149.956 389.518 149.049C389.361 148.667 388.931 148.368 388.474 148.321C388.286 148.301 387.941 148.311 387.739 148.605L387.185 148.228C387.476 147.804 387.972 147.595 388.544 147.655C389.248 147.73 389.888 148.186 390.14 148.794C390.629 149.988 389.968 151.238 389.53 151.877L389.53 151.881Z" + fill="#3B2358" /> + d="M349.783 148.158C349.71 148.161 349.638 148.163 349.569 148.163L349.57 147.496C351.515 147.508 353.407 146.199 354.084 144.391L354.712 144.624C353.966 146.616 351.917 148.073 349.783 148.158Z" + fill="#3B2358" /> + d="M354.733 150.882L354.443 150.282C355.48 149.787 356.324 148.942 356.818 147.908L357.423 148.194C356.865 149.364 355.909 150.319 354.736 150.882L354.733 150.882Z" + fill="#3B2358" /> + d="M357.298 156.327L357.035 155.712C358.081 155.271 358.877 154.264 359.061 153.15L359.721 153.257C359.501 154.593 358.548 155.796 357.295 156.327L357.298 156.327Z" + fill="#3B2358" /> + d="M311.344 190.65C308.503 190.763 306.373 190.157 305.43 189.82C304.061 189.331 303.996 189.097 303.972 189.008C303.296 186.523 302.332 182.963 302.332 182.963L302.978 182.789C302.978 182.789 303.91 186.241 304.585 188.719C305.305 189.096 312.719 192.571 321.61 186.288L321.998 186.833C318.035 189.634 314.303 190.532 311.344 190.65Z" + fill="#1E0F30" /> + d="M308.3 242.964C308.761 241.351 309.556 239.827 309.829 238.174C310.354 234.974 308.864 231.795 308.759 228.555C308.735 227.879 308.79 227.162 309.178 226.61C309.999 225.457 311.809 225.643 313.055 226.318C314.301 226.994 315.396 228.04 316.791 228.3C317.428 228.419 318.089 228.362 318.722 228.485C320.254 228.785 321.422 230.127 321.896 231.606C322.369 233.086 322.25 234.689 321.997 236.225C321.666 238.228 321.109 240.195 320.373 242.091C319.43 244.524 318.097 246.949 315.884 248.346C311.548 251.083 306.872 247.956 308.293 242.964L308.3 242.964Z" + fill="#3B2358" /> + d="M265.272 221.723C266.306 220.98 267.735 220.968 268.93 221.408C270.125 221.852 271.125 222.689 272.048 223.563C276.548 227.817 279.869 233.511 280.435 239.664C280.594 241.39 280.411 243.394 279.012 244.429C277.382 245.635 275.051 244.859 273.31 243.814C268.513 240.933 264.973 236.42 261.548 232.01C260.463 230.613 257.591 226.4 259.313 224.627C260.321 223.587 261.461 224.631 262.652 224.188C263.744 223.784 264.348 222.385 265.271 221.719L265.272 221.723Z" + fill="#3B2358" /> + d="M319.195 159.549L320.621 185.125C320.621 185.125 314.655 192.099 305.32 188.175L303.487 182.381C303.487 182.381 307.038 180.841 305.533 179.313C305.533 179.313 306.619 176.575 304.324 175.305C304.324 175.305 304.584 173.088 303.61 171.612C303.61 171.612 305.296 169.279 302.325 167.356C302.325 167.356 300.47 166.547 299.291 166.089L298.296 163.564L319.195 159.546L319.195 159.549Z" + fill="#A0F4F7" /> + d="M311.434 189.687C309.568 189.762 307.474 189.446 305.187 188.486L305.043 188.426L303.072 182.198L303.347 182.077C303.907 181.835 305.398 181.026 305.553 180.233C305.581 180.084 305.586 179.85 305.291 179.549L305.139 179.394L305.218 179.191C305.258 179.09 306.165 176.706 304.159 175.597L303.965 175.488L303.991 175.267C303.99 175.246 304.224 173.151 303.327 171.795L303.199 171.604L303.333 171.416C303.333 171.416 303.895 170.61 303.707 169.631C303.568 168.895 303.047 168.231 302.161 167.652C301.933 167.554 300.249 166.824 299.165 166.4L299.029 166.347L297.834 163.315L319.503 159.149L320.957 185.239L320.871 185.338C320.825 185.392 317.267 189.451 311.43 189.684L311.434 189.687ZM305.59 187.93C314.008 191.379 319.5 185.857 320.278 185.008L318.883 159.95L298.755 163.821L299.551 165.838C300.722 166.3 302.441 167.049 302.462 167.055L302.511 167.081C303.575 167.767 304.201 168.588 304.376 169.519C304.556 170.467 304.204 171.261 304.007 171.613C304.749 172.889 304.721 174.537 304.679 175.126C306.383 176.206 306.268 178.17 305.917 179.239C306.259 179.669 306.272 180.077 306.217 180.358C306.011 181.414 304.534 182.243 303.894 182.557L305.593 187.927L305.59 187.93Z" + fill="#3B2358" /> + d="M309.188 165.222C315.068 164.303 319.55 161.751 319.199 159.521C318.848 157.292 313.797 156.229 307.917 157.147C302.038 158.066 297.555 160.618 297.906 162.848C298.257 165.078 303.308 166.141 309.188 165.222Z" + fill="#A0F4F7" /> + d="M306.042 165.895C301.39 166.081 297.885 164.935 297.57 162.927C297.186 160.478 301.707 157.809 307.86 156.846C310.743 156.394 313.527 156.4 315.696 156.857C317.974 157.336 319.334 158.272 319.524 159.498C319.715 160.725 318.71 162.029 316.691 163.179C314.766 164.276 312.117 165.128 309.234 165.576C308.128 165.747 307.059 165.851 306.041 165.892L306.042 165.895ZM311.075 157.199C310.072 157.239 309.026 157.342 307.966 157.508C301.795 158.472 297.95 161.035 298.232 162.825C298.514 164.614 302.961 165.884 309.131 164.92C311.935 164.482 314.503 163.658 316.36 162.601C318.096 161.614 319.009 160.519 318.865 159.6C318.721 158.681 317.517 157.918 315.56 157.508C314.261 157.234 312.727 157.13 311.079 157.195L311.075 157.199Z" + fill="#3B2358" /> + d="M376.899 222.377C376.703 223.708 377.084 225.112 377.93 226.157C377.981 225.533 378.032 224.909 378.083 224.288C378.12 223.826 378.152 223.33 377.915 222.931C377.679 222.531 377.063 222.329 376.741 222.665" + fill="#A0F4F7" /> + d="M378.196 227.02L377.669 226.37C376.801 225.295 376.388 223.854 376.547 222.483L376.501 222.44C376.521 222.419 376.541 222.401 376.561 222.383C376.56 222.366 376.566 222.349 376.569 222.331L376.618 222.34C376.802 222.205 377.035 222.148 377.288 222.175C377.659 222.219 378.021 222.452 378.209 222.768C378.509 223.271 378.457 223.878 378.423 224.319L378.199 227.023L378.196 227.02ZM377.19 222.832C377.149 223.628 377.319 224.439 377.679 225.153L377.754 224.264C377.791 223.805 377.81 223.402 377.632 223.103C377.551 222.966 377.377 222.852 377.211 222.835C377.204 222.835 377.197 222.835 377.193 222.836L377.19 222.832Z" + fill="#3B2358" /> + d="M380.898 222.822C380.703 224.153 381.083 225.557 381.929 226.603C381.981 225.979 382.032 225.355 382.083 224.734C382.12 224.272 382.152 223.776 381.915 223.376C381.678 222.977 381.062 222.774 380.74 223.11" + fill="#A0F4F7" /> + d="M382.195 227.462L381.668 226.813C380.8 225.737 380.387 224.296 380.547 222.925L380.5 222.883C380.52 222.861 380.54 222.843 380.56 222.825C380.559 222.808 380.565 222.791 380.568 222.773L380.617 222.782C380.801 222.647 381.034 222.59 381.287 222.618C381.658 222.661 382.02 222.894 382.209 223.21C382.508 223.713 382.457 224.32 382.422 224.762L382.199 227.465L382.195 227.462ZM381.189 223.274C381.148 224.07 381.319 224.881 381.679 225.595L381.754 224.706C381.791 224.247 381.809 223.844 381.632 223.546C381.55 223.408 381.376 223.295 381.21 223.277C381.203 223.277 381.196 223.278 381.193 223.278L381.189 223.274Z" + fill="#3B2358" /> + d="M385.155 223.405C384.96 224.736 385.34 226.14 386.186 227.186C386.238 226.562 386.289 225.938 386.34 225.317C386.377 224.855 386.409 224.359 386.172 223.959C385.935 223.56 385.319 223.357 384.998 223.693" + fill="#A0F4F7" /> + d="M386.452 228.045L385.925 227.396C385.057 226.32 384.644 224.879 384.804 223.509L384.757 223.466C384.777 223.444 384.797 223.426 384.817 223.408C384.816 223.391 384.822 223.374 384.825 223.356L384.874 223.365C385.059 223.23 385.291 223.173 385.544 223.201C385.916 223.244 386.277 223.477 386.466 223.793C386.766 224.296 386.714 224.903 386.679 225.345L386.456 228.048L386.452 228.045ZM385.446 223.858C385.405 224.653 385.576 225.464 385.936 226.179L386.011 225.289C386.048 224.83 386.066 224.427 385.889 224.129C385.807 223.991 385.633 223.878 385.467 223.86C385.46 223.86 385.453 223.861 385.45 223.861L385.446 223.858Z" + fill="#3B2358" /> + d="M389.687 222.383C389.578 223.724 390.054 225.1 390.967 226.088C390.977 225.462 390.986 224.836 390.999 224.21C391.008 223.746 391.006 223.251 390.742 222.866C390.478 222.482 389.85 222.321 389.55 222.677" + fill="#A0F4F7" /> - + d="M391.287 226.928L390.72 226.311C389.782 225.297 389.273 223.884 389.343 222.506L389.293 222.464C389.309 222.442 389.329 222.421 389.349 222.403C389.348 222.386 389.351 222.368 389.354 222.351L389.402 222.356C389.58 222.208 389.805 222.137 390.061 222.148C390.434 222.167 390.812 222.376 391.018 222.677C391.351 223.162 391.341 223.767 391.331 224.211L391.287 226.921L391.287 226.928ZM390.008 222.817C390.019 223.614 390.244 224.409 390.648 225.101L390.664 224.21C390.67 223.749 390.661 223.347 390.466 223.06C390.375 222.926 390.195 222.826 390.029 222.819C390.022 222.82 390.015 222.82 390.011 222.82L390.008 222.817Z" + fill="#3B2358" /> - + d="M301.149 168.341C302.451 167.984 303.899 168.191 305.046 168.901C304.429 169.029 303.816 169.156 303.2 169.28C302.744 169.374 302.254 169.466 301.825 169.28C301.4 169.094 301.121 168.511 301.414 168.152" + fill="#A0F4F7" /> + d="M302.502 169.721C302.237 169.731 301.959 169.701 301.696 169.588C301.359 169.44 301.083 169.114 300.993 168.75C300.931 168.505 300.963 168.266 301.076 168.069L301.064 168.022C301.064 168.022 301.098 168.014 301.115 168.009C301.132 167.988 301.148 167.963 301.164 167.942L301.214 167.981C302.562 167.656 304.053 167.889 305.228 168.615L305.943 169.054L303.275 169.604C303.052 169.651 302.785 169.706 302.506 169.717L302.502 169.721ZM301.638 168.576C301.638 168.576 301.639 168.59 301.639 168.593C301.68 168.753 301.811 168.913 301.958 168.976C302.278 169.114 302.679 169.047 303.132 168.957L304.008 168.774C303.252 168.509 302.424 168.435 301.635 168.573L301.638 168.576Z" + fill="#3B2358" /> + d="M302.081 172.236C303.383 171.878 304.831 172.085 305.978 172.796C305.362 172.923 304.749 173.051 304.132 173.175C303.676 173.269 303.186 173.361 302.757 173.175C302.329 172.989 302.053 172.406 302.346 172.047" + fill="#A0F4F7" /> + d="M303.431 173.616C303.166 173.626 302.888 173.596 302.625 173.483C302.287 173.335 302.012 173.009 301.921 172.645C301.86 172.4 301.892 172.161 302.005 171.964L301.993 171.917C301.993 171.917 302.027 171.908 302.044 171.904C302.06 171.883 302.077 171.858 302.093 171.837L302.143 171.876C303.491 171.551 304.981 171.784 306.157 172.51L306.872 172.949L304.204 173.499C303.981 173.546 303.714 173.601 303.434 173.612L303.431 173.616ZM302.567 172.471C302.567 172.471 302.568 172.485 302.568 172.488C302.609 172.648 302.739 172.808 302.887 172.871C303.207 173.009 303.608 172.942 304.06 172.852L304.937 172.669C304.181 172.403 303.352 172.33 302.564 172.468L302.567 172.471Z" + fill="#3B2358" /> + d="M303.182 176.371C304.483 176.014 305.932 176.221 307.079 176.931C306.462 177.059 305.849 177.186 305.232 177.311C304.777 177.404 304.287 177.496 303.858 177.31C303.429 177.125 303.154 176.541 303.447 176.182" + fill="#A0F4F7" /> + d="M304.535 177.747C304.27 177.758 303.992 177.728 303.729 177.615C303.391 177.466 303.116 177.141 303.025 176.776C302.967 176.531 302.996 176.293 303.109 176.096L303.096 176.048C303.096 176.048 303.131 176.04 303.148 176.036C303.164 176.015 303.18 175.99 303.197 175.969L303.247 176.008C304.594 175.683 306.085 175.916 307.261 176.642L307.972 177.081L305.304 177.631C305.081 177.678 304.814 177.733 304.535 177.744L304.535 177.747ZM303.671 176.603C303.671 176.603 303.672 176.617 303.672 176.62C303.713 176.78 303.843 176.94 303.991 177.003C304.311 177.141 304.708 177.074 305.164 176.983L306.041 176.801C305.284 176.535 304.456 176.462 303.667 176.6L303.671 176.603Z" + fill="#3B2358" /> + d="M302.716 180.975C304.038 180.702 305.469 181.006 306.568 181.787C305.946 181.874 305.324 181.961 304.699 182.047C304.239 182.11 303.744 182.171 303.328 181.958C302.916 181.744 302.678 181.145 302.996 180.806" + fill="#A0F4F7" /> + d="M304.166 182.433C303.842 182.446 303.495 182.411 303.178 182.249C302.85 182.08 302.594 181.736 302.531 181.367C302.487 181.118 302.533 180.883 302.656 180.692L302.647 180.644C302.647 180.644 302.682 180.636 302.699 180.635C302.715 180.614 302.732 180.593 302.752 180.571L302.798 180.614C304.163 180.378 305.634 180.707 306.76 181.508L307.443 181.993L304.743 182.369C304.568 182.393 304.372 182.421 304.162 182.43L304.166 182.433ZM303.189 181.234C303.189 181.234 303.19 181.248 303.19 181.252C303.217 181.415 303.338 181.583 303.482 181.656C303.792 181.815 304.195 181.775 304.652 181.712L305.537 181.588C304.8 181.273 303.98 181.145 303.182 181.231L303.189 181.234Z" + fill="#3B2358" /> + + d="M427.392 240.887L412.292 233.656L416.346 225.837L444.764 239.552L427.392 240.887ZM413.202 233.351L427.52 240.208L442.245 239.075L416.64 226.719L413.202 233.348L413.202 233.351Z" + fill="#3B2358" /> + + d="M444.026 239.936L416.059 226.439L417.735 222.644L442.303 233.77L444.026 239.936ZM416.93 226.119L442.986 238.692L441.745 234.246L418.077 223.527L416.934 226.119L416.93 226.119Z" + fill="#3B2358" /> + d="M400.876 208.447C400.527 207.141 400.182 205.839 399.833 204.533C402.787 206.573 406.029 208.201 409.432 209.357" + fill="#3B2358" /> + d="M404.229 160.486C404.069 162.468 404.252 164.54 405.206 166.29C406.16 168.039 407.989 169.399 409.988 169.392C410.419 169.388 410.887 169.335 411.252 169.561C411.563 169.755 411.722 170.11 411.898 170.432C413.306 173.012 416.791 174.238 419.515 173.112C419.573 173.089 419.634 173.059 419.677 173.013C419.816 172.853 419.661 172.612 419.507 172.463C416.874 169.911 413.747 167.867 410.352 166.469C408.214 165.592 405.815 164.674 405.328 162.425C405.154 161.617 404.758 161.118 404.225 160.482L404.229 160.486Z" + fill="#3B2358" /> + d="M314.646 195.856C313.846 195.451 313.124 194.927 312.494 194.292L312.97 193.823C313.549 194.404 314.214 194.89 314.95 195.263L314.646 195.856Z" + fill="#3B2358" /> + d="M318.666 192.303C318.496 191.767 318.322 191.214 317.971 190.802C317.691 190.473 317.183 190.187 316.73 190.342L316.511 189.712C317.264 189.455 318.043 189.857 318.482 190.372C318.92 190.888 319.126 191.536 319.304 192.106L318.666 192.307L318.666 192.303Z" + fill="#3B2358" /> + + d="M345.139 192.665L344.576 192.306C345.022 191.614 345.33 190.856 345.491 190.053L346.146 190.185C345.963 191.068 345.627 191.903 345.136 192.665L345.139 192.665Z" + fill="#3B2358" /> + + + d="M346.543 199.624L346.032 199.194C346.988 198.066 347.739 196.796 348.253 195.411L348.881 195.643C348.338 197.098 347.552 198.439 346.543 199.624Z" + fill="#3B2358" /> + d="M352.664 196.823L352.18 196.361C352.866 195.646 353.326 194.717 353.477 193.742L354.137 193.843C353.964 194.953 353.44 196.012 352.661 196.823L352.664 196.823Z" + fill="#3B2358" /> + d="M377.854 181.762C377.788 181.765 377.722 181.761 377.653 181.75C377.41 181.708 377.189 181.545 377.076 181.323C376.983 181.134 376.981 180.924 377.071 180.745C377.157 180.574 377.309 180.475 377.434 180.408C377.92 180.138 378.495 180.008 379.049 180.048L379.003 180.713C378.577 180.685 378.136 180.782 377.761 180.989C377.724 181.012 377.7 181.026 377.687 181.037C377.705 181.06 377.737 181.087 377.768 181.092C377.9 181.114 378.067 181.039 378.26 180.945L378.553 181.542C378.377 181.628 378.129 181.748 377.854 181.759L377.854 181.762Z" + fill="#3B2358" /> + d="M417.205 155.59C418.714 155.083 420.47 155.385 421.725 156.366C422.958 157.33 423.069 159.508 422.305 160.872C422.331 160.057 421.955 159.268 421.412 158.653C420.87 158.043 420.175 157.586 419.468 157.17C418.393 156.54 418.363 156.06 417.205 155.59Z" + fill="#3B2358" /> + d="M370.227 226.279C369.887 224.773 369.277 223.326 368.435 222.03C371.276 221.923 374.071 220.836 376.236 218.997C376.133 220.235 376.057 221.798 376.388 222.995C376.433 223.162 376.482 223.349 376.387 223.497C376.332 223.585 376.238 223.637 376.146 223.685C374.233 224.717 372.316 225.752 370.403 226.784C370.269 226.727 370.16 226.408 370.227 226.282L370.227 226.279Z" + fill="#3B2358" /> + d="M378.46 164.042C378.865 162.85 379.83 161.939 380.825 161.167C384.755 158.124 389.755 156.474 394.732 156.578C394.075 154.91 392.058 154.117 390.264 154.261C388.471 154.405 386.827 155.271 385.211 156.054C382.484 157.375 379.588 158.212 376.837 159.436C375.442 160.055 375.206 160.281 376.124 161.323C376.537 161.792 378.748 163.199 378.46 164.042Z" + fill="#3B2358" /> + + d="M393.324 253.788L392.744 253.458C397.645 244.969 401.706 235.954 404.81 226.661L404.909 226.361C405.744 223.85 406.611 221.255 408.49 219.341L408.968 219.807C407.195 221.61 406.357 224.131 405.542 226.573L405.444 226.873C402.324 236.208 398.247 245.261 393.324 253.792L393.324 253.788Z" + fill="#3B2358" /> + d="M408.299 227.127L407.778 226.707C408.562 225.748 409.231 224.694 409.767 223.576L410.372 223.861C409.814 225.028 409.119 226.125 408.299 227.127Z" + fill="#3B2358" /> - - - - - - - - - - + d="M439.882 164.678C439.068 164.095 438.816 163.153 438.573 162.242C438.435 161.721 438.289 161.181 438.04 160.74C437.512 159.796 436.384 159.14 435.031 158.977C433.768 158.828 432.476 159.082 431.229 159.331L431.1 158.676C432.398 158.418 433.741 158.152 435.112 158.314C436.68 158.499 437.992 159.282 438.628 160.411C438.918 160.925 439.072 161.507 439.222 162.068C439.445 162.905 439.656 163.694 440.275 164.136L439.886 164.678L439.882 164.678Z" + fill="#3B2358" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + d="M446.923 194.845C447.859 203.245 448.791 211.649 449.727 220.049C449.914 221.726 450.981 223.983 452.555 223.353C453.089 223.139 453.431 222.627 453.726 222.134C456.621 217.324 458.35 211.825 458.725 206.232C459.154 199.836 457.871 193.203 459.939 187.13C461.639 182.133 465.443 178.095 467.406 173.195C468.524 170.401 469.013 167.405 469.495 164.437C470.388 158.943 471.278 153.447 472.171 147.953C467.704 151.386 464.088 155.97 462.077 161.22C460.497 165.338 459.886 169.844 457.725 173.69C455.623 177.431 452.203 180.279 449.878 183.887C448.002 186.804 445.715 192.068 446.617 195.641C447.645 199.707 450.249 198.923 454.437 199.509C455.559 199.667 469.19 200.742 469.391 201.614C469.412 201.699 487.203 278.678 487.203 278.678L431.986 277.86L420.598 194.746C420.598 194.746 433.993 196.632 446.745 198.426" + fill="white" /> + + + d="M468.41 289.895C479 285.977 483.136 270.875 477.647 256.164C472.157 241.453 459.122 232.703 448.532 236.621C437.941 240.538 433.806 255.64 439.295 270.351C444.784 285.062 457.819 293.812 468.41 289.895Z" + fill="#D5F7F6" /> + d="M463.743 291.199C459.815 291.355 455.69 290.076 451.744 287.429C446.187 283.697 441.652 277.688 438.973 270.509C436.294 263.329 435.791 255.829 437.555 249.39C439.331 242.913 443.183 238.282 448.411 236.348C453.638 234.415 459.594 235.418 465.186 239.172C470.742 242.903 475.277 248.912 477.957 256.092C480.636 263.271 481.138 270.771 479.374 277.21C477.598 283.687 473.746 288.319 468.519 290.252C466.981 290.822 465.38 291.137 463.743 291.202L463.743 291.199ZM453.21 236.068C451.645 236.13 450.113 236.431 448.643 236.975C443.623 238.831 439.916 243.302 438.201 249.568C436.473 255.871 436.97 263.227 439.603 270.277C442.232 277.328 446.68 283.224 452.119 286.877C457.527 290.508 463.267 291.486 468.287 289.629C473.306 287.773 477.013 283.301 478.729 277.036C480.456 270.733 479.96 263.377 477.327 256.326C474.698 249.275 470.25 243.38 464.811 239.726C460.986 237.16 456.992 235.917 453.21 236.068Z" + fill="#3B2358" /> - + d="M453.878 230.39C458.911 228.529 460.876 221.353 458.268 214.363C455.66 207.372 449.466 203.215 444.433 205.076C439.4 206.938 437.435 214.114 440.043 221.104C442.652 228.095 448.846 232.252 453.878 230.39Z" + fill="#D5F7F6" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + d="M83.5129 266.638C81.8864 252.856 80.8308 238.837 80.3751 224.97L81.044 224.944C81.4991 238.797 82.5506 252.798 84.1763 266.56L83.5129 266.638Z" + fill="#3B2358" /> + d="M116.587 199.741C116.1 197.334 116.089 194.788 116.552 192.377L117.21 192.502C116.764 194.83 116.775 197.287 117.244 199.608L116.587 199.741Z" + fill="#3B2358" /> + d="M163.372 222.967L163.253 222.312C168.691 221.339 173.561 217.897 176.278 213.108L176.861 213.435C174.047 218.393 169.002 221.959 163.372 222.967Z" + fill="#3B2358" /> + d="M207.843 223.457C207.667 220.866 207.711 218.245 207.974 215.66L208.64 215.727C208.379 218.273 208.333 220.856 208.507 223.41L207.839 223.457L207.843 223.457Z" + fill="#3B2358" /> + d="M154.808 247.59C154.387 247.517 154.011 247.261 153.753 246.869C153.43 246.38 153.31 245.714 153.449 245.135C153.677 244.177 154.397 243.441 154.975 242.85L155.452 243.316C154.905 243.874 154.281 244.511 154.098 245.288C154.003 245.687 154.088 246.165 154.309 246.503C154.419 246.67 154.614 246.879 154.923 246.932L154.808 247.59Z" + fill="#3B2358" /> + d="M208.722 253.77L208.278 253.272C210.95 250.911 211.871 246.825 210.47 243.558L211.085 243.296C212.593 246.821 211.598 251.225 208.719 253.77L208.722 253.77Z" + fill="#3B2358" /> + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/src/app/raffle/_components/active-deposits.tsx b/src/app/raffle/_components/active-deposits.tsx new file mode 100644 index 0000000..427e753 --- /dev/null +++ b/src/app/raffle/_components/active-deposits.tsx @@ -0,0 +1,95 @@ +'use client'; + +import { Spinner } from '@chakra-ui/react'; +import { useAccount } from '@starknet-react/core'; +import axios from 'axios'; +import Image from 'next/image'; +import React from 'react'; +import toast from 'react-hot-toast'; + +const ActiveDeposits = () => { + const { address } = useAccount(); + + const [loading, setLoading] = React.useState(false); + const [initialLoading, setInitialLoading] = React.useState(false); + const [isActiveDeposits, setIsActiveDeposits] = React.useState(false); + + const handleActiveDeposits = async () => { + setLoading(true); + + try { + const res = await axios.post('/api/raffle', { + address, + type: 'ACTIVE_DEPOSITS', + }); + + if (res?.data?.success) { + setIsActiveDeposits(true); + toast.success('Successfully completed!'); + } + } catch (error) { + console.error(error); + toast.error('Something went wrong'); + } finally { + setLoading(false); + } + }; + + React.useEffect(() => { + if (!address) return; + setInitialLoading(true); + + (async () => { + try { + const res = await axios.get(`/api/tnc/getUser/${address}`, { + params: { type: 'RAFFLE' }, + }); + + if (res?.data?.success && res?.data?.user?.activeDeposits) { + setIsActiveDeposits(true); + } else setIsActiveDeposits(false); + } catch (error) { + console.error(error); + toast.error('Something went wrong'); + } finally { + setInitialLoading(false); + } + })(); + }, [address]); + + return ( +
+
+
+ STRKFarm +

+ Claim your ticket if you have a active deposit +

+
+ + +
+
+ ); +}; + +export default ActiveDeposits; diff --git a/src/app/raffle/_components/register-raffle.tsx b/src/app/raffle/_components/register-raffle.tsx index 2195ef8..7f41637 100644 --- a/src/app/raffle/_components/register-raffle.tsx +++ b/src/app/raffle/_components/register-raffle.tsx @@ -3,13 +3,16 @@ import { Spinner } from '@chakra-ui/react'; import { useAccount } from '@starknet-react/core'; import axios from 'axios'; +import Image from 'next/image'; import React from 'react'; import toast from 'react-hot-toast'; const RegisterRaffle: React.FC = () => { const { address } = useAccount(); + const [isUserRegistered, setIsUserRegistered] = React.useState(false); const [loading, setLoading] = React.useState(false); + const [initialLoading, setInitialLoading] = React.useState(false); const handleRegister = async () => { setLoading(true); @@ -23,7 +26,7 @@ const RegisterRaffle: React.FC = () => { }); if (res?.data?.success) { setIsUserRegistered(true); - toast.success('Successfully registered for the raffle!'); + toast.success('Successfully completed!'); } } catch (error) { console.error(error); @@ -38,6 +41,8 @@ const RegisterRaffle: React.FC = () => { React.useEffect(() => { if (!address) return; + setInitialLoading(true); + (async () => { try { const res = await axios.get(`/api/tnc/getUser/${address}`, { @@ -50,33 +55,62 @@ const RegisterRaffle: React.FC = () => { } catch (error) { console.error(error); toast.error('Something went wrong'); + } finally { + setInitialLoading(false); } })(); }, [address]); return isUserRegistered ? ( - +
+
+
+ STRKFarm +

+ Register on our website if you are coming to Devcon and get one + ticket. +

+
+ + +
+
) : ( - + {initialLoading && 'loading...'} + {isUserRegistered && 'completed'} + {!isUserRegistered && !initialLoading && '1 ticket'} + + + ); }; diff --git a/src/app/raffle/_components/share-on-x.tsx b/src/app/raffle/_components/share-on-x.tsx index eb4d9c7..39d0bd0 100644 --- a/src/app/raffle/_components/share-on-x.tsx +++ b/src/app/raffle/_components/share-on-x.tsx @@ -12,6 +12,7 @@ const ShareOnX = () => { const { address } = useAccount(); const [loading, setLoading] = React.useState(false); + const [initialLoading, setInitialLoading] = React.useState(false); const [isSharedOnX, setIsSharedOnX] = React.useState(false); const handleShare = async () => { @@ -26,7 +27,7 @@ const ShareOnX = () => { if (res?.data?.success) { await new Promise((resolve) => setTimeout(resolve, 8000)); setIsSharedOnX(true); - toast.success('Shared !'); + toast.success('Successfully completed!'); } } catch (error) { console.error(error); @@ -39,6 +40,8 @@ const ShareOnX = () => { React.useEffect(() => { if (!address) return; + setInitialLoading(true); + (async () => { try { const res = await axios.get(`/api/tnc/getUser/${address}`, { @@ -51,13 +54,15 @@ const ShareOnX = () => { } catch (error) { console.error(error); toast.error('Something went wrong'); + } finally { + setInitialLoading(false); } })(); }, [address]); return (
-
+
{ height={64} alt="STRKFarm" /> -

Share on X

+

+ RT our tweet +

{}} + className="border border-[#36E780] group-hover:border-black text-white px-4 py-1 text-sm font-bold rounded-[20px] transition-all active:scale-90 group-hover:text-black" + onClick={!isSharedOnX && !initialLoading ? handleShare : () => {}} > - {loading && !isSharedOnX && ( - - )} - {isSharedOnX ? 'Shared !' : 'Share'} + {loading && } + {initialLoading && 'loading...'} + {isSharedOnX && 'completed'} + {!isSharedOnX && !initialLoading && '1 ticket'}
diff --git a/src/app/raffle/page.tsx b/src/app/raffle/page.tsx index fffd27b..e5bb430 100644 --- a/src/app/raffle/page.tsx +++ b/src/app/raffle/page.tsx @@ -2,46 +2,41 @@ import { NextPage } from 'next'; import Image from 'next/image'; import React from 'react'; +import ActiveDeposits from './_components/active-deposits'; import RegisterRaffle from './_components/register-raffle'; import ShareOnX from './_components/share-on-x'; const Raffle: NextPage = () => { return (
-
+
-

- 8 Pool Raffle -

+

Devcon raffle

- Each week, we select 8 lucky addresses from Starknet's pool{' '} -
of active addresses from the previous week.{' '} + Each day, we shall select 3 winners who will receive
{' '} + exclusive merch during Starkspace (Devcon, Bangkok)

- +
Raffle Hero Image
-
-

Pool Size

- -
-
- 500 STRK -
-
-
+

+ Earn Raffle tickets for every task and get chances to win +

-
+

Raffle end's in

@@ -79,41 +74,19 @@ const Raffle: NextPage = () => {

Tasks

- Earn + Participate and {' '} - 10 tickets each week{' '} + get Raffle tickets - by staying active on STRKFarm and increase your changes

- + - {[...Array(3)].map((_, i) => ( -
-
-
- STRKFarm -

- Any transaction on Starknet -

-
+ - -
-
- ))} +
@@ -121,11 +94,25 @@ const Raffle: NextPage = () => {
Rules:

- 1. You have upto 1 week to claim your rewards. Any unclaimed reward - will be added to next pool prize. + 1. 3 unique winners will be selected each day +

+

+ 2. You just have to register once and you will be part of each round + automatically +

+

+ 3. You have to register if you want to participate. This mean you or + anyone on your behalf will be available t to collect the merch.{' '} +

+

+ 4. The rewards will be in the form of exclusive merch reserved for you +

+

+ 5. Selected winners can collect their merch on 13th Nov, from The Fig + lobby, Bangkok

- 2. Only account contracts are considered for this raffle + 6. Winners will be announced on our socials everyday

From e8966797a7138120adc81681ae88a2f2ce06249e Mon Sep 17 00:00:00 2001 From: Hemant Date: Fri, 1 Nov 2024 14:49:43 +0530 Subject: [PATCH 20/40] fix: bugs and ui tweaks --- ...strkfarm-white.svg => raffle-deposits.svg} | 9 +- public/raffle-register.svg | 14 +++ public/raffle-share.svg | 6 ++ src/app/api/raffle/route.ts | 16 +++- .../raffle/_components/active-deposits.tsx | 25 +++-- src/app/raffle/_components/raffle-timer.tsx | 63 +++++++++++++ .../raffle/_components/register-raffle.tsx | 43 +++------ src/app/raffle/_components/share-on-x.tsx | 19 ++-- src/app/raffle/_components/total-tickets.tsx | 58 ++++++++++++ src/app/raffle/page.tsx | 93 ++++++++----------- src/components/Navbar.tsx | 28 +++++- 11 files changed, 271 insertions(+), 103 deletions(-) rename public/{strkfarm-white.svg => raffle-deposits.svg} (80%) create mode 100644 public/raffle-register.svg create mode 100644 public/raffle-share.svg create mode 100644 src/app/raffle/_components/raffle-timer.tsx create mode 100644 src/app/raffle/_components/total-tickets.tsx diff --git a/public/strkfarm-white.svg b/public/raffle-deposits.svg similarity index 80% rename from public/strkfarm-white.svg rename to public/raffle-deposits.svg index 6ae2788..95342c8 100644 --- a/public/strkfarm-white.svg +++ b/public/raffle-deposits.svg @@ -1,8 +1,15 @@ + fill="url(#paint0_linear_1218_57)" /> + + + + + + \ No newline at end of file diff --git a/public/raffle-register.svg b/public/raffle-register.svg new file mode 100644 index 0000000..a755bd0 --- /dev/null +++ b/public/raffle-register.svg @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/public/raffle-share.svg b/public/raffle-share.svg new file mode 100644 index 0000000..bd8de8c --- /dev/null +++ b/public/raffle-share.svg @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/src/app/api/raffle/route.ts b/src/app/api/raffle/route.ts index 6511266..d4182be 100644 --- a/src/app/api/raffle/route.ts +++ b/src/app/api/raffle/route.ts @@ -45,6 +45,20 @@ export async function POST(req: Request) { } if (type === 'REGISTER') { + const raffleUser = await db.raffle.findFirst({ + where: { + userId: user.id, + }, + }); + + if (raffleUser) { + return NextResponse.json({ + success: false, + message: 'User already registered', + user: raffleUser, + }); + } + const createdUser = await db.raffle.create({ data: { isRaffleParticipant: true, @@ -117,7 +131,7 @@ export async function POST(req: Request) { const result = await Promise.all(values); const sum = result.reduce((acc, item) => acc + item.usdValue, 0); - if (sum > 0) { + if (sum > 10) { const createdUser = await db.raffle.update({ where: { raffleId: raffleUser.raffleId, diff --git a/src/app/raffle/_components/active-deposits.tsx b/src/app/raffle/_components/active-deposits.tsx index 427e753..68fe328 100644 --- a/src/app/raffle/_components/active-deposits.tsx +++ b/src/app/raffle/_components/active-deposits.tsx @@ -26,6 +26,11 @@ const ActiveDeposits = () => { if (res?.data?.success) { setIsActiveDeposits(true); toast.success('Successfully completed!'); + } else if ( + !res?.data?.success && + res?.data?.message === 'No active deposits found' + ) { + toast.error('You should have atleast $10 deposited in STRKFarm'); } } catch (error) { console.error(error); @@ -37,7 +42,9 @@ const ActiveDeposits = () => { React.useEffect(() => { if (!address) return; + setInitialLoading(true); + setIsActiveDeposits(false); (async () => { try { @@ -59,21 +66,21 @@ const ActiveDeposits = () => { return (
-
-
+
+
STRKFarm -

- Claim your ticket if you have a active deposit +

+ Deposit atleast $10 in STRKFarm

-
-
- ) : ( -
-
-
- STRKFarm -

- Register on our website if you are coming to Devcon and get one - ticket. +

+ Register if you are coming to Devcon and get one ticket.

@@ -102,9 +81,15 @@ const RegisterRaffle: React.FC = () => { onClick={ !isUserRegistered && !initialLoading ? handleRegister : () => {} } - className="border border-[#36E780] text-white group-hover:border-black group-hover:text-black px-4 py-1 text-sm font-bold rounded-[20px] transition-all active:scale-90" + className="border border-[#36E780] text-white group-hover:border-black group-hover:text-black px-4 py-1 text-sm font-bold rounded-[20px] transition-all active:scale-90 ml-16 lg:ml-0" > - {loading && } + {loading && ( + + )} {initialLoading && 'loading...'} {isUserRegistered && 'completed'} {!isUserRegistered && !initialLoading && '1 ticket'} diff --git a/src/app/raffle/_components/share-on-x.tsx b/src/app/raffle/_components/share-on-x.tsx index 39d0bd0..616072b 100644 --- a/src/app/raffle/_components/share-on-x.tsx +++ b/src/app/raffle/_components/share-on-x.tsx @@ -41,6 +41,7 @@ const ShareOnX = () => { if (!address) return; setInitialLoading(true); + setIsSharedOnX(false); (async () => { try { @@ -62,15 +63,15 @@ const ShareOnX = () => { return (
-
-
+
+
STRKFarm -

+

RT our tweet

@@ -78,10 +79,16 @@ const ShareOnX = () => { {}} > - {loading && } + {loading && ( + + )} {initialLoading && 'loading...'} {isSharedOnX && 'completed'} {!isSharedOnX && !initialLoading && '1 ticket'} diff --git a/src/app/raffle/_components/total-tickets.tsx b/src/app/raffle/_components/total-tickets.tsx new file mode 100644 index 0000000..0ed2603 --- /dev/null +++ b/src/app/raffle/_components/total-tickets.tsx @@ -0,0 +1,58 @@ +'use client'; + +import { Spinner } from '@chakra-ui/react'; +import { useAccount } from '@starknet-react/core'; +import axios from 'axios'; +import React from 'react'; +import toast from 'react-hot-toast'; + +const TotalTickets: React.FC = () => { + const { address } = useAccount(); + + const [totalTickets, setTotalTickets] = React.useState(0); + const [loading, setLoading] = React.useState(false); + + React.useEffect(() => { + if (!address) return; + + setLoading(true); + setTotalTickets(0); + + (async () => { + try { + const res = await axios.get(`/api/tnc/getUser/${address}`, { + params: { type: 'RAFFLE' }, + }); + + if (res?.data?.success && res?.data?.user?.isRaffleParticipant) { + setTotalTickets((prev) => prev + 1); + console.log('+1'); + } + if (res?.data?.success && res?.data?.user?.sharedOnX) { + setTotalTickets((prev) => prev + 1); + console.log('+1 +1'); + } + if (res?.data?.success && res?.data?.user?.activeDeposits) { + setTotalTickets((prev) => prev + 1); + console.log('+1 +1 +1'); + } + } catch (error) { + console.error(error); + toast.error('Something went wrong'); + } finally { + setLoading(false); + } + })(); + }, [address]); + + return ( +

+ Your tickets:{' '} + + {!loading ? totalTickets : } + +

+ ); +}; + +export default TotalTickets; diff --git a/src/app/raffle/page.tsx b/src/app/raffle/page.tsx index e5bb430..3b9222e 100644 --- a/src/app/raffle/page.tsx +++ b/src/app/raffle/page.tsx @@ -3,18 +3,22 @@ import Image from 'next/image'; import React from 'react'; import ActiveDeposits from './_components/active-deposits'; +import RaffleTimer from './_components/raffle-timer'; import RegisterRaffle from './_components/register-raffle'; import ShareOnX from './_components/share-on-x'; +import TotalTickets from './_components/total-tickets'; const Raffle: NextPage = () => { return ( -
-
-
-

Devcon raffle

-

- Each day, we shall select 3 winners who will receive
{' '} - exclusive merch during Starkspace (Devcon, Bangkok) +

+
+
+

+ Devcon raffle +

+

+ Each day, we shall select 3 winners who will receive exclusive merch + during Starkspace (Devcon, Bangkok)

-
-

+

+

Earn Raffle tickets for every task and get chances to win

-
+

Raffle end's in

-
-
- 18 - - Days - -
-
- 18 - - Hrs - -
-
- 05 - - Mins - -
-
- 1 - - Sec - -
-
+
-

Tasks

-

- Participate and - - {' '} - get Raffle tickets - -

+

Tasks

+
+

+ Participate and + + {' '} + get Raffle tickets + +

+ + +
@@ -91,27 +74,29 @@ const Raffle: NextPage = () => {
-
-
Rules:
-

+

+
+ Rules: +
+

1. 3 unique winners will be selected each day

-

+

2. You just have to register once and you will be part of each round automatically

-

+

3. You have to register if you want to participate. This mean you or anyone on your behalf will be available t to collect the merch.{' '}

-

+

4. The rewards will be in the form of exclusive merch reserved for you

-

+

5. Selected winners can collect their merch on 13th Nov, from The Fig lobby, Bangkok

-

+

6. Winners will be announced on our socials everyday

diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 3090944..c39aece 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -49,12 +49,12 @@ import { import mixpanel from 'mixpanel-browser'; import { useEffect } from 'react'; import { isMobile } from 'react-device-detect'; -import TncModal from './TncModal'; import { ArgentMobileConnector, isInArgentMobileAppBrowser, } from 'starknetkit/argentMobile'; import { WebWalletConnector } from 'starknetkit/webwallet'; +import TncModal from './TncModal'; export const MYCONNECTORS: any[] = isInArgentMobileAppBrowser() ? [ @@ -273,17 +273,17 @@ export default function Navbar(props: NavbarProps) { */} - + + + + +
Date: Wed, 6 Nov 2024 20:16:12 +0530 Subject: [PATCH 27/40] Add dnmm reverse (#101) * temp remove tnc signing validation * add fetchWithRetry for external endpoints * fix haiko api bug * disable sithswap, 10kswap and starkdefi * build fix * re-add fee * add dnmm2 * Add mainnet ETH Sensei XL contracts --- src/constants.ts | 21 +++++++++ src/store/strategies.atoms.ts | 17 ++++++- src/strategies/IStrategy.ts | 8 +++- src/strategies/auto_strk.strat.ts | 5 +- src/strategies/delta_neutral_mm.ts | 26 +++++++---- src/strategies/delta_neutral_mm_2.ts | 68 ++++++++++++++++++++++++++++ 6 files changed, 131 insertions(+), 14 deletions(-) create mode 100644 src/strategies/delta_neutral_mm_2.ts diff --git a/src/constants.ts b/src/constants.ts index 7d645b3..3984b52 100755 --- a/src/constants.ts +++ b/src/constants.ts @@ -62,6 +62,8 @@ const CONSTANTS = { '0x20d5fc4c9df4f943ebb36078e703369c04176ed00accf290e8295b659d2cea6', DeltaNeutralMMETHUSDC: '0x9d23d9b1fa0db8c9d75a1df924c3820e594fc4ab1475695889286f3f6df250', + DeltaNeutralMMETHUSDCXL: + '0x5852a2fa5f3fa08fc8b0b95096792a954009da28e1fa08430bde9e91bf395fe', }, MOBILE_MSG: 'Desktop/Tablet only', }; @@ -100,6 +102,17 @@ export const TOKENS: TokenInfo[] = [ stepAmount: MyNumber.fromEther('10', 18), isERC4626: false, }, + { + token: '0x057146f6409deb4c9fa12866915dd952aa07c1eb2752e451d7f3b042086bdeb8', + name: 'iETH-c', // nostra eth collateral + decimals: 18, + displayDecimals: 2, + logo: CONSTANTS.LOGOS.ETH, + minAmount: MyNumber.fromEther('10', 18), + maxAmount: MyNumber.fromEther('10000', 18), + stepAmount: MyNumber.fromEther('10', 18), + isERC4626: false, + }, { token: '0x1b5bd713e72fdc5d63ffd83762f81297f6175a5e0a4771cdadbc1dd5fe72cb1', name: 'zETH', @@ -193,6 +206,14 @@ export const NFTS: NFTInfo[] = [ mainTokenName: 'ETH', }, }, + { + name: 'frmDNMMETHUSDC2', + address: CONSTANTS.CONTRACTS.DeltaNeutralMMETHUSDCXL, + logo: CONSTANTS.LOGOS.ETH, + config: { + mainTokenName: 'ETH', + }, + }, ]; // ? When updating this, ensure there is redirect available for this route diff --git a/src/store/strategies.atoms.ts b/src/store/strategies.atoms.ts index 0cf8488..db032d5 100755 --- a/src/store/strategies.atoms.ts +++ b/src/store/strategies.atoms.ts @@ -10,6 +10,7 @@ import { DeltaNeutralMM } from '@/strategies/delta_neutral_mm'; import Mustache from 'mustache'; import { getTokenInfoFromName } from '@/utils'; import { allPoolsAtomUnSorted } from './protocols'; +import { DeltaNeutralMM2 } from '@/strategies/delta_neutral_mm_2'; export interface StrategyInfo extends IStrategyProps { name: string; @@ -68,7 +69,7 @@ export function getStrategies() { 'USDC', CONSTANTS.CONTRACTS.DeltaNeutralMMETHUSDC, [1, 0.609886, 1, 0.920975, 0.510078], // precomputed factors based on strategy math - StrategyLiveStatus.NEW, + StrategyLiveStatus.ACTIVE, { maxTVL: 1000, }, @@ -87,12 +88,26 @@ export function getStrategies() { }, ); + const deltaNeutralMMETHUSDCReverse = new DeltaNeutralMM2( + getTokenInfoFromName('ETH'), + 'ETH Sensei XL', + Mustache.render(DNMMDescription, { token1: 'ETH', token2: 'USDC' }), + 'USDC', + CONSTANTS.CONTRACTS.DeltaNeutralMMETHUSDCXL, + [1, 0.5846153846, 1, 0.920975, 0.552509], // precomputed factors based on strategy math + StrategyLiveStatus.NEW, + { + maxTVL: 2000, + }, + ); + const strategies: IStrategy[] = [ autoStrkStrategy, autoUSDCStrategy, deltaNeutralMMUSDCETH, deltaNeutralMMETHUSDC, deltaNeutralMMSTRKETH, + deltaNeutralMMETHUSDCReverse, ]; return strategies; diff --git a/src/strategies/IStrategy.ts b/src/strategies/IStrategy.ts index da89d23..2854896 100755 --- a/src/strategies/IStrategy.ts +++ b/src/strategies/IStrategy.ts @@ -1,5 +1,6 @@ import { IDapp } from '@/store/IDapp.store'; import { BalanceResult, getBalanceAtom } from '@/store/balance.atoms'; +import { LendingSpace } from '@/store/lending.base'; import { Category, PoolInfo } from '@/store/pools'; import { zkLend } from '@/store/zklend.store'; import MyNumber from '@/utils/MyNumber'; @@ -254,14 +255,17 @@ export class IStrategy extends IStrategyProps { return eligiblePools; } - filterZkLend(tokenName: string) { + filterTokenByProtocol( + tokenName: string, + protocol: IDapp = zkLend, + ) { return ( pools: PoolInfo[], amount: string, prevActions: StrategyAction[], ) => { return pools.filter( - (p) => p.pool.name == tokenName && p.protocol.name == zkLend.name, + (p) => p.pool.name == tokenName && p.protocol.name == protocol.name, ); }; } diff --git a/src/strategies/auto_strk.strat.ts b/src/strategies/auto_strk.strat.ts index f4aa5eb..48018a7 100755 --- a/src/strategies/auto_strk.strat.ts +++ b/src/strategies/auto_strk.strat.ts @@ -23,6 +23,7 @@ import { getERC20BalanceAtom, } from '@/store/balance.atoms'; import { getPrice, getTokenInfoFromName } from '@/utils'; +import { zkLend } from '@/store/zklend.store'; interface Step { name: string; @@ -73,12 +74,12 @@ export class AutoTokenStrategy extends IStrategy { { name: `Supplies your ${token} to zkLend`, optimizer: this.optimizer, - filter: [this.filterZkLend(this.token.name)], + filter: [this.filterTokenByProtocol(this.token.name, zkLend)], }, { name: `Re-invest your STRK Rewards every 7 days`, optimizer: this.compounder, - filter: [this.filterZkLend('STRK')], + filter: [this.filterTokenByProtocol('STRK', zkLend)], }, ]; const _risks = [...this.risks]; diff --git a/src/strategies/delta_neutral_mm.ts b/src/strategies/delta_neutral_mm.ts index b52d01b..304d46b 100755 --- a/src/strategies/delta_neutral_mm.ts +++ b/src/strategies/delta_neutral_mm.ts @@ -24,6 +24,8 @@ import { getERC20Balance, } from '@/store/balance.atoms'; import { atom } from 'jotai'; +import { IDapp } from '@/store/IDapp.store'; +import { LendingSpace } from '@/store/lending.base'; export class DeltaNeutralMM extends IStrategy { riskFactor = 0.75; @@ -34,6 +36,8 @@ export class DeltaNeutralMM extends IStrategy { readonly stepAmountFactors: number[]; fee_factor = 0.1; // 10% fee + protocol1: IDapp; + protocol2: IDapp; constructor( token: TokenInfo, name: string, @@ -43,6 +47,8 @@ export class DeltaNeutralMM extends IStrategy { stepAmountFactors: number[], liveStatus: StrategyLiveStatus, settings: IStrategySettings, + protocol1: IDapp = zkLend, + protocol2: IDapp = nostraLending, ) { const rewardTokens = [{ logo: CONSTANTS.LOGOS.STRK }]; const nftInfo = NFTS.find( @@ -54,7 +60,7 @@ export class DeltaNeutralMM extends IStrategy { } const holdingTokens: (TokenInfo | NFTInfo)[] = [nftInfo]; super( - `${token.name.toLowerCase()}_sensei`, + name.toLowerCase().replaceAll(' ', '_'), 'DeltaNeutralMM', name, description, @@ -64,25 +70,27 @@ export class DeltaNeutralMM extends IStrategy { settings, ); this.token = token; + this.protocol1 = protocol1; + this.protocol2 = protocol2; this.steps = [ { - name: `Supply's your ${token.name} to zkLend`, + name: `Supply's your ${token.name} to ${protocol1.name}`, optimizer: this.optimizer, filter: [this.filterMainToken], }, { - name: `Borrow ${secondaryTokenName} from zkLend`, + name: `Borrow ${secondaryTokenName} from ${protocol1.name}`, optimizer: this.optimizer, filter: [this.filterSecondaryToken], }, { - name: `Deposit ${secondaryTokenName} to Nostra`, + name: `Deposit ${secondaryTokenName} to ${protocol2.name}`, optimizer: this.optimizer, filter: [this.filterSecondaryToken], }, { - name: `Borrow ${token.name} from Nostra`, + name: `Borrow ${token.name} from ${protocol2.name}`, optimizer: this.optimizer, filter: [this.filterMainToken], }, @@ -94,7 +102,7 @@ export class DeltaNeutralMM extends IStrategy { { name: `Re-invest your STRK Rewards every 7 days (Compound)`, optimizer: this.compounder, - filter: [this.filterZkLend('STRK')], + filter: [this.filterTokenByProtocol('STRK', this.protocol1)], }, ]; @@ -124,8 +132,8 @@ export class DeltaNeutralMM extends IStrategy { ) { const dapp = prevActions.length == 0 || prevActions.length == 4 - ? zkLend - : nostraLending; + ? this.protocol1 + : this.protocol2; return pools.filter( (p) => p.pool.name == this.token.name && p.protocol.name == dapp.name, ); @@ -136,7 +144,7 @@ export class DeltaNeutralMM extends IStrategy { amount: string, prevActions: StrategyAction[], ) { - const dapp = prevActions.length == 1 ? zkLend : nostraLending; + const dapp = prevActions.length == 1 ? this.protocol1 : this.protocol2; return pools.filter( (p) => p.pool.name == this.secondaryToken && p.protocol.name == dapp.name, ); diff --git a/src/strategies/delta_neutral_mm_2.ts b/src/strategies/delta_neutral_mm_2.ts new file mode 100644 index 0000000..4f1bcc1 --- /dev/null +++ b/src/strategies/delta_neutral_mm_2.ts @@ -0,0 +1,68 @@ +import { TokenName } from '@/constants'; +import { DeltaNeutralMM } from './delta_neutral_mm'; +import { IStrategySettings, StrategyLiveStatus, TokenInfo } from './IStrategy'; +import { nostraLending } from '@/store/nostralending.store'; +import { zkLend } from '@/store/zklend.store'; +import MyNumber from '@/utils/MyNumber'; +import { getPrice, getTokenInfoFromName } from '@/utils'; +import { getERC20Balance } from '@/store/balance.atoms'; + +export class DeltaNeutralMM2 extends DeltaNeutralMM { + constructor( + token: TokenInfo, + name: string, + description: string, + secondaryTokenName: TokenName, + strategyAddress: string, + stepAmountFactors: number[], + liveStatus: StrategyLiveStatus, + settings: IStrategySettings, + ) { + super( + token, + name, + description, + secondaryTokenName, + strategyAddress, + stepAmountFactors, + liveStatus, + settings, + nostraLending, + zkLend, + ); + } + + getTVL = async () => { + if (!this.isLive()) + return { + amount: MyNumber.fromEther('0', this.token.decimals), + usdValue: 0, + tokenInfo: this.token, + }; + + try { + const mainTokenName = this.token.name; + const colToken = getTokenInfoFromName(`i${mainTokenName}-c`); + + const bal = await getERC20Balance(colToken, this.strategyAddress); + console.log('getTVL222', bal.amount.toString()); + // This reduces the zToken TVL to near actual deposits made by users wihout looping + const discountFactor = this.stepAmountFactors[4]; + const amount = bal.amount.operate('div', 1 + discountFactor); + console.log('getTVL1', amount.toString()); + const price = await getPrice(this.token); + return { + amount, + usdValue: Number(amount.toEtherStr()) * price, + tokenInfo: this.token, + }; + } catch (error) { + console.error('Error fetching TVL:', error); + return { + amount: MyNumber.fromEther('0', this.token.decimals), + usdValue: 0, + tokenInfo: this.token, + }; + } + }; +} From dd7a83388be616af9532da01e1dca701ae4a76e0 Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Wed, 6 Nov 2024 22:16:42 +0700 Subject: [PATCH 28/40] fix haiko api bug --- src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants.ts b/src/constants.ts index 3984b52..3b7e589 100755 --- a/src/constants.ts +++ b/src/constants.ts @@ -41,7 +41,7 @@ const CONSTANTS = { BASE_API: '/ekubo', }, HAIKO: { - BASE_APR_API: 'haiko/markets?network=mainnet', + BASE_APR_API: '/haiko/markets?network=mainnet', }, STRKFarm: { BASE_APR_API: '/api/strategies', From 96ef905506e13c30dc81000bcf3d780d689e99b1 Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Tue, 12 Nov 2024 20:15:18 +0700 Subject: [PATCH 29/40] update eth xl address --- src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants.ts b/src/constants.ts index 3b7e589..049567d 100755 --- a/src/constants.ts +++ b/src/constants.ts @@ -63,7 +63,7 @@ const CONSTANTS = { DeltaNeutralMMETHUSDC: '0x9d23d9b1fa0db8c9d75a1df924c3820e594fc4ab1475695889286f3f6df250', DeltaNeutralMMETHUSDCXL: - '0x5852a2fa5f3fa08fc8b0b95096792a954009da28e1fa08430bde9e91bf395fe', + '0x9140757f8fb5748379be582be39d6daf704cc3a0408882c0d57981a885eed9', }, MOBILE_MSG: 'Desktop/Tablet only', }; From 73919e344633a7df3ef634db4109ce5402c63c7e Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Tue, 12 Nov 2024 23:55:05 +0700 Subject: [PATCH 30/40] update audit info on XL pool --- src/components/Navbar.tsx | 4 ++-- src/store/protocols.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 0071425..fe7bcc5 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -213,7 +213,7 @@ export default function Navbar(props: NavbarProps) { top="0" > -
+ {/*
-
+
*/} Date: Thu, 14 Nov 2024 18:55:20 +0530 Subject: [PATCH 31/40] fix: ekubo logo --- src/store/ekobu.store.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/store/ekobu.store.ts b/src/store/ekobu.store.ts index aa3d7d5..a7f341e 100755 --- a/src/store/ekobu.store.ts +++ b/src/store/ekobu.store.ts @@ -1,6 +1,9 @@ import CONSTANTS, { TokenName, TOKENS } from '@/constants'; +import { StrategyLiveStatus } from '@/strategies/IStrategy'; +import { getPrice } from '@/utils'; +import fetchWithRetry from '@/utils/fetchWithRetry'; import { atom } from 'jotai'; -import { AtomWithQueryResult, atomWithQuery } from 'jotai-tanstack-query'; +import { atomWithQuery, AtomWithQueryResult } from 'jotai-tanstack-query'; import { IDapp } from './IDapp.store'; import { APRSplit, @@ -11,9 +14,6 @@ import { ProtocolAtoms, StrkDexIncentivesAtom, } from './pools'; -import { StrategyLiveStatus } from '@/strategies/IStrategy'; -import fetchWithRetry from '@/utils/fetchWithRetry'; -import { getPrice } from '@/utils'; interface EkuboBaseAprDoc { tokens: Token[]; @@ -80,7 +80,7 @@ type PriceOfToken = { export class Ekubo extends IDapp { name = 'Ekubo'; link = 'https://app.ekubo.org/positions'; - logo = 'https://app.ekubo.org/logo.svg'; + logo = 'https://app.ekubo.org/favicon.ico'; incentiveDataKey = 'Ekubo'; From ec3e8602b9f509b9b0be03a262c3386a83b47f14 Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Wed, 20 Nov 2024 20:57:28 +0700 Subject: [PATCH 32/40] fix mobile wallet issue --- src/components/Navbar.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index fe7bcc5..c486530 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -55,14 +55,15 @@ import { } from 'starknetkit/argentMobile'; import { WebWalletConnector } from 'starknetkit/webwallet'; import TncModal from './TncModal'; +import { constants } from 'starknet'; export const MYCONNECTORS: any[] = isInArgentMobileAppBrowser() ? [ ArgentMobileConnector.init({ options: { dappName: 'STRKFarm', - projectId: 'strkfarm', - url: 'https://app.strkfarm.xyz', + url: window.location.hostname, + chainId: constants.NetworkName.SN_MAIN, }, inAppBrowserOptions: {}, }), @@ -74,8 +75,8 @@ export const MYCONNECTORS: any[] = isInArgentMobileAppBrowser() ArgentMobileConnector.init({ options: { dappName: 'STRKFarm', - projectId: 'strkfarm', - url: 'https://app.strkfarm.xyz', + url: window.location.hostname, + chainId: constants.NetworkName.SN_MAIN, }, }), ]; From 765513f861e690e1aa0c3527db6b1eaea4a8616b Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Wed, 20 Nov 2024 21:05:30 +0700 Subject: [PATCH 33/40] fix mobile wallet issue [2] --- src/components/Navbar.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index c486530..9a261ab 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -31,6 +31,7 @@ import { getERC20Balance } from '@/store/balance.atoms'; import { addressAtom } from '@/store/claims.atoms'; import { lastWalletAtom } from '@/store/utils.atoms'; import { + getEndpoint, getTokenInfoFromName, MyMenuItemProps, MyMenuListProps, @@ -62,7 +63,7 @@ export const MYCONNECTORS: any[] = isInArgentMobileAppBrowser() ArgentMobileConnector.init({ options: { dappName: 'STRKFarm', - url: window.location.hostname, + url: getEndpoint(), chainId: constants.NetworkName.SN_MAIN, }, inAppBrowserOptions: {}, @@ -75,7 +76,7 @@ export const MYCONNECTORS: any[] = isInArgentMobileAppBrowser() ArgentMobileConnector.init({ options: { dappName: 'STRKFarm', - url: window.location.hostname, + url: getEndpoint(), chainId: constants.NetworkName.SN_MAIN, }, }), From 1922eb3abff69677063fb0ed5994f30f4bae3963 Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Thu, 21 Nov 2024 15:50:48 +0530 Subject: [PATCH 34/40] fix mobile connect issues --- src/app/api/tnc/signUser/route.ts | 112 +++++++++++++----------------- src/components/TncModal.tsx | 81 ++++++++++++++------- src/components/YieldCard.tsx | 3 +- src/store/strkfarm.atoms.ts | 2 +- 4 files changed, 106 insertions(+), 92 deletions(-) diff --git a/src/app/api/tnc/signUser/route.ts b/src/app/api/tnc/signUser/route.ts index dd777d3..c127aca 100644 --- a/src/app/api/tnc/signUser/route.ts +++ b/src/app/api/tnc/signUser/route.ts @@ -9,16 +9,9 @@ import Mixpanel from 'mixpanel'; const mixpanel = Mixpanel.init('118f29da6a372f0ccb6f541079cad56b'); export async function POST(req: Request) { - const { address, signature, _signature } = await req.json(); - - console.debug( - 'address', - address, - 'signature', - signature, - '_signature', - _signature, - ); + const { address, signature } = await req.json(); + + console.debug('address', address, 'signature', signature); if (!address || !signature) { return NextResponse.json({ success: false, @@ -57,64 +50,64 @@ export async function POST(req: Request) { console.debug(`Verifying signature for address: ${parsedAddress}`); console.debug(`SIGNING_DATA`, SIGNING_DATA); const hash = await myAccount.hashMessage(SIGNING_DATA); - try { - // await debug(); - isValid = await verifyMessageHash(myAccount, hash, parsedSignature); - console.debug('isValid', isValid); - mixpanel.track('TnC signed', { - address, - signature, - _signature, - step: 1, - hash, - }); - } catch (error) { - console.error('verification failed [1]:', error); - if (_signature) { + console.debug('hash', hash); + + const function_sigs = ['is_valid_signature', 'isValidSignature']; + const signatures = [ + parsedSignature, + parsedSignature.slice(parsedSignature.length - 2, parsedSignature.length), + ]; + + for (const fn_sig of function_sigs) { + for (const sig of signatures) { try { - const parsedSignature2 = JSON.parse(_signature) as string[]; - isValid = await verifyMessageHash(myAccount, hash, parsedSignature2); + console.log(`Checking: ${fn_sig}`); + console.log(`Signature: ${JSON.stringify(sig)}`); + isValid = await verifyMessageHash(myAccount, hash, sig, fn_sig); console.debug('isValid', isValid); mixpanel.track('TnC signed', { address, signature, - _signature, + step: 1, hash, - step: 2, - }); - } catch (err) { - console.error('verification failed [2]:', err); - - // temporarily accepting all signtures - isValid = true; - mixpanel.track('TnC signing failed', { - address, - signature, - hash, - isValid, - _signature, + fn_sig, }); + break; + } catch (error) { + console.warn(`verification failed [${fn_sig}]:`, error); } } + if (isValid) { + break; + } } - if (!isValid) { - mixpanel.track('TnC signing failed', { - address, - signature, - _signature, - hash, - isValid, - }); - isValid = true; // temporarily accepting all signtures - } + // if (!isValid) { + // mixpanel.track('TnC signing failed', { + // address, + // signature, + // hash, + // isValid, + // }); + // isValid = true; // temporarily accepting all signtures + // } if (!isValid) { - return NextResponse.json({ - success: false, - message: 'Invalid signature. Ensure account is deployed.', - user: null, - }); + try { + const cls = await provider.getClassAt(address, 'pending'); + // means account is deployed + return NextResponse.json({ + success: false, + message: 'Invalid signature. Please contact us if issue persists.', + user: null, + }); + } catch (error) { + return NextResponse.json({ + success: false, + message: 'Invalid signature. Ensure account is deployed.', + user: null, + }); + } } const user = await db.user.findFirst({ @@ -186,18 +179,11 @@ async function verifyMessageHash( }); console.debug('verifyMessageHash resp', resp); if (Number(resp[0]) == 0) { - return false; + throw new Error('Invalid signature'); } return true; } catch (err: any) { console.error('Error verifying signature:', err); - if (entrypoint === 'isValidSignature') { - console.debug( - 'could be Invalid message selector, trying with is_valid_signature', - ); - return verifyMessageHash(account, hash, signature, 'is_valid_signature'); - } - if ( [ 'argent/invalid-signature', diff --git a/src/components/TncModal.tsx b/src/components/TncModal.tsx index ea8c9cb..d585dcc 100644 --- a/src/components/TncModal.tsx +++ b/src/components/TncModal.tsx @@ -13,7 +13,11 @@ import { Text, useDisclosure, } from '@chakra-ui/react'; -import { useAccount, useDisconnect } from '@starknet-react/core'; +import { + useAccount, + useDisconnect, + useSignTypedData, +} from '@starknet-react/core'; import axios from 'axios'; import { atomWithQuery } from 'jotai-tanstack-query'; import React, { useEffect, useMemo, useState } from 'react'; @@ -55,6 +59,14 @@ const TncModal: React.FC = (props) => { const [isSigningPending, setIsSigningPending] = useState(false); const { disconnectAsync } = useDisconnect(); + const { + signTypedData, + error: signingError, + data: sigData, + } = useSignTypedData({ + params: SIGNING_DATA, + }); + // set ref code of the user if it exists useEffect(() => { if (!userTncInfo) return; @@ -97,39 +109,54 @@ const TncModal: React.FC = (props) => { })(); }, [userTncInfo]); - const handleSign = async () => { - if (!address || !account) { + useEffect(() => { + console.log('signature', sigData); + if (signingError) { + toast.error(signingError.message, { + position: 'bottom-right', + }); + setIsSigningPending(false); + } + if (!address || !account || !sigData) { return; } - mixpanel.track('TnC agreed', { address }); - setIsSigningPending(true); + async function processSign() { + try { + if (!sigData) { + return; + } - try { - const _signature = (await account.signMessage(SIGNING_DATA)) as string[]; - - console.log('signature', _signature); - const sig_len = _signature.length; - const signature = - sig_len > 2 ? _signature.slice(sig_len - 2, sig_len) : _signature; - if (signature && signature.length > 0) { - const res2 = await axios.post('/api/tnc/signUser', { - address, - signature: JSON.stringify(signature), - _signature: JSON.stringify(_signature), - }); - - if (res2.data?.success) { - onClose(); - } else { - toast.error(res2.data?.message || 'Error verifying T&C'); + const signature = sigData; + if (signature && signature.length > 0) { + const res2 = await axios.post('/api/tnc/signUser', { + address, + signature: JSON.stringify(signature), + }); + + if (res2.data?.success) { + onClose(); + } else { + toast.error(res2.data?.message || 'Error verifying T&C'); + } } + } catch (error) { + console.error('signature', error); + mixpanel.track('TnC signing failed', { address }); } - } catch (error) { - console.error('signature', error); - mixpanel.track('TnC signing failed', { address }); + setIsSigningPending(false); } - setIsSigningPending(false); + processSign(); + }, [sigData, signingError]); + + const handleSign = async () => { + if (!address || !account) { + return; + } + mixpanel.track('TnC agreed', { address }); + + setIsSigningPending(true); + signTypedData(); }; return ( diff --git a/src/components/YieldCard.tsx b/src/components/YieldCard.tsx index ea10b20..4dfecd8 100644 --- a/src/components/YieldCard.tsx +++ b/src/components/YieldCard.tsx @@ -32,6 +32,7 @@ import { getPoolInfoFromStrategy, sortAtom } from '@/store/protocols'; import { TriangleDownIcon, TriangleUpIcon } from '@chakra-ui/icons'; import mixpanel from 'mixpanel-browser'; import { STRKFarmStrategyAPIResult } from '@/store/strkfarm.atoms'; +import { isMobile } from 'react-device-detect'; interface YieldCardProps { pool: PoolInfo; @@ -468,7 +469,7 @@ function StrategyMobileCard(props: YieldCardProps) { function getLinkProps(pool: PoolInfo, showProtocolName?: boolean) { return { href: pool.protocol.link, - target: '_blank', + target: isMobile ? '_self' : '_blank', onClick: () => { mixpanel.track('Pool clicked', { pool: pool.pool.name, diff --git a/src/store/strkfarm.atoms.ts b/src/store/strkfarm.atoms.ts index 1733dee..b0b0aa5 100644 --- a/src/store/strkfarm.atoms.ts +++ b/src/store/strkfarm.atoms.ts @@ -87,7 +87,7 @@ export class STRKFarm extends IDapp { additional: { riskFactor, tags: [getLiveStatusEnum(rawPool.status.number)], - isAudited: true, + isAudited: poolName.includes('XL') ? false : true, }, }; return poolInfo; From f0d502c657cb99102f666895ee0c96270e220a18 Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Thu, 21 Nov 2024 19:36:59 +0530 Subject: [PATCH 35/40] auto connect bug --- src/app/slinks/template.tsx | 5 +- src/app/template.tsx | 5 +- src/components/Navbar.tsx | 180 ++++++++++++++++++------------------ 3 files changed, 95 insertions(+), 95 deletions(-) diff --git a/src/app/slinks/template.tsx b/src/app/slinks/template.tsx index 679d6d2..55454e2 100755 --- a/src/app/slinks/template.tsx +++ b/src/app/slinks/template.tsx @@ -1,6 +1,6 @@ 'use client'; -import Navbar, { MYCONNECTORS } from '@/components/Navbar'; +import Navbar, { getConnectors } from '@/components/Navbar'; import { MY_STORE } from '@/store'; import { Center, @@ -16,6 +16,7 @@ import mixpanel from 'mixpanel-browser'; import Image from 'next/image'; import { usePathname } from 'next/navigation'; import * as React from 'react'; +import { isMobile } from 'react-device-detect'; import { Toaster } from 'react-hot-toast'; import { RpcProviderOptions, constants } from 'starknet'; @@ -96,7 +97,7 @@ export default function Template({ children }: { children: React.ReactNode }) { diff --git a/src/app/template.tsx b/src/app/template.tsx index acd3d80..2b8664d 100755 --- a/src/app/template.tsx +++ b/src/app/template.tsx @@ -1,6 +1,6 @@ 'use client'; -import Navbar, { MYCONNECTORS } from '@/components/Navbar'; +import Navbar, { getConnectors } from '@/components/Navbar'; import { MY_STORE } from '@/store'; import { Center, @@ -20,6 +20,7 @@ import { Toaster } from 'react-hot-toast'; import { RpcProviderOptions, constants } from 'starknet'; import { Inter } from 'next/font/google'; +import { isMobile } from 'react-device-detect'; const inter = Inter({ subsets: ['latin'] }); mixpanel.init('118f29da6a372f0ccb6f541079cad56b'); @@ -108,7 +109,7 @@ export default function Template({ children }: { children: React.ReactNode }) { diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 9a261ab..21969fb 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -22,9 +22,12 @@ import { useDisclosure, } from '@chakra-ui/react'; import { useAtom, useSetAtom } from 'jotai'; -import { useStarknetkitConnectModal } from 'starknetkit'; +import { + connect, + ConnectOptionsWithConnectors, + StarknetkitConnector, +} from 'starknetkit'; -import { CONNECTOR_NAMES } from '@/app/template'; import tg from '@/assets/tg.svg'; import CONSTANTS from '@/constants'; import { getERC20Balance } from '@/store/balance.atoms'; @@ -48,7 +51,7 @@ import { useStarkProfile, } from '@starknet-react/core'; import mixpanel from 'mixpanel-browser'; -import { useEffect } from 'react'; +import { useEffect, useMemo } from 'react'; import { isMobile } from 'react-device-detect'; import { ArgentMobileConnector, @@ -58,29 +61,46 @@ import { WebWalletConnector } from 'starknetkit/webwallet'; import TncModal from './TncModal'; import { constants } from 'starknet'; -export const MYCONNECTORS: any[] = isInArgentMobileAppBrowser() - ? [ - ArgentMobileConnector.init({ - options: { - dappName: 'STRKFarm', - url: getEndpoint(), - chainId: constants.NetworkName.SN_MAIN, - }, - inAppBrowserOptions: {}, - }), - ] - : [ - new InjectedConnector({ options: { id: 'braavos', name: 'Braavos' } }), - new InjectedConnector({ options: { id: 'argentX', name: 'Argent X' } }), - new WebWalletConnector({ url: 'https://web.argent.xyz' }), - ArgentMobileConnector.init({ - options: { - dappName: 'STRKFarm', - url: getEndpoint(), - chainId: constants.NetworkName.SN_MAIN, - }, - }), - ]; +export function getConnectors(isMobile: boolean) { + const mobileConnector = ArgentMobileConnector.init({ + options: { + dappName: 'STRKFarm', + url: getEndpoint(), + chainId: constants.NetworkName.SN_MAIN, + }, + inAppBrowserOptions: {}, + }) as StarknetkitConnector; + + const argentXConnector = new InjectedConnector({ + options: { + id: 'argentX', + name: 'Argent X', + }, + }); + + const braavosConnector = new InjectedConnector({ + options: { + id: 'braavos', + name: 'Braavos', + }, + }); + + const webWalletConnector = new WebWalletConnector({ + url: 'https://web.argent.xyz', + }) as StarknetkitConnector; + + if (isInArgentMobileAppBrowser()) { + return [mobileConnector]; + } else if (isMobile) { + return [braavosConnector, mobileConnector, webWalletConnector]; + } + return [ + argentXConnector, + braavosConnector, + mobileConnector, + webWalletConnector, + ]; +} interface NavbarProps { hideTg?: boolean; @@ -89,29 +109,15 @@ interface NavbarProps { export default function Navbar(props: NavbarProps) { const { address, connector, account } = useAccount(); - const { connect, connectors } = useConnect(); const { disconnectAsync } = useDisconnect(); const setAddress = useSetAtom(addressAtom); const { data: starkProfile } = useStarkProfile({ address, useDefaultPfp: true, }); + const { connect: connectSnReact } = useConnect(); const [lastWallet, setLastWallet] = useAtom(lastWalletAtom); - const { starknetkitConnectModal: starknetkitConnectModal1 } = - useStarknetkitConnectModal({ - modalMode: 'canAsk', - modalTheme: 'dark', - connectors: MYCONNECTORS, - }); - - // backup - const { starknetkitConnectModal: starknetkitConnectModal2 } = - useStarknetkitConnectModal({ - modalMode: 'alwaysAsk', - modalTheme: 'dark', - connectors: MYCONNECTORS, - }); const getTokenBalance = async (token: string, address: string) => { const tokenInfo = getTokenInfoFromName(token); @@ -122,6 +128,41 @@ export default function Navbar(props: NavbarProps) { console.log(account, 'account'); + const connectorConfig: ConnectOptionsWithConnectors = useMemo(() => { + return { + modalMode: 'canAsk', + modalTheme: 'dark', + webWalletUrl: 'https://web.argent.xyz', + argentMobileOptions: { + dappName: 'STRKFarm', + chainId: constants.NetworkName.SN_MAIN, + url: window.location.hostname, + }, + dappName: 'Endur.fi', + connectors: getConnectors(isMobile) as StarknetkitConnector[], + }; + }, [isMobile]); + + async function connectWallet(config = connectorConfig) { + try { + const { connector } = await connect(config); + + if (connector) { + connectSnReact({ connector: connector as any }); + } + } catch (error) { + console.error('connectWallet error', error); + } + } + + useEffect(() => { + const config = connectorConfig; + connectWallet({ + ...config, + modalMode: 'neverAsk', + }); + }, []); + useEffect(() => { (async () => { if (address) { @@ -139,55 +180,6 @@ export default function Navbar(props: NavbarProps) { })(); }, [address]); - // Connect wallet using starknetkit - const connectWallet = async () => { - try { - const result = await starknetkitConnectModal1(); - if (!result.connector) { - throw new Error('No connector found'); - } - - connect({ connector: result.connector }); - } catch (error) { - console.warn('connectWallet error', error); - try { - const result = await starknetkitConnectModal2(); - if (!result.connector) { - throw new Error('No connector found'); - } - connect({ connector: result.connector }); - } catch (error) { - console.error('connectWallet error', error); - alert('Error connecting wallet'); - } - } - }; - - function autoConnect(retry = 0) { - console.log('lastWallet', lastWallet, connectors); - try { - if (!address && lastWallet) { - const connectorIndex = CONNECTOR_NAMES.findIndex( - (name) => name === lastWallet, - ); - if (connectorIndex >= 0) { - connect({ connector: MYCONNECTORS[connectorIndex] }); - } - } - } catch (error) { - console.error('lastWallet error', error); - if (retry < 10) { - setTimeout(() => { - autoConnect(retry + 1); - }, 1000); - } - } - } - // Auto-connects to last wallet - useEffect(() => { - autoConnect(); - }, [lastWallet]); - // Set last wallet when a new wallet is connected useEffect(() => { console.log('lastWallet connector', connector?.name); @@ -402,7 +394,13 @@ export default function Navbar(props: NavbarProps) { my={{ base: 'auto', sm: 'initial' }} paddingX={{ base: '0.5rem', sm: '1rem' }} fontSize={{ base: '0.8rem', sm: '1rem' }} - onClick={address ? undefined : connectWallet} + onClick={ + address + ? undefined + : () => { + connectWallet(); + } + } size="xs" >
From 9d34cc24dfff172b776bdf4c464a7d15baf06b16 Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Thu, 21 Nov 2024 19:40:54 +0530 Subject: [PATCH 36/40] fix build issue --- src/components/Navbar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 21969fb..4c27ea2 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -136,7 +136,7 @@ export default function Navbar(props: NavbarProps) { argentMobileOptions: { dappName: 'STRKFarm', chainId: constants.NetworkName.SN_MAIN, - url: window.location.hostname, + url: getEndpoint(), }, dappName: 'Endur.fi', connectors: getConnectors(isMobile) as StarknetkitConnector[], From 5e4c07aaa801b0456feb282e724566249aa4139a Mon Sep 17 00:00:00 2001 From: akiraonstarknet Date: Thu, 21 Nov 2024 19:46:51 +0530 Subject: [PATCH 37/40] remove raffle --- src/components/Navbar.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 4c27ea2..c70c8f5 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -285,7 +285,7 @@ export default function Navbar(props: NavbarProps) { Home - + {/* - + */}