├── back-end ├── src │ ├── program │ │ ├── web3.ts │ │ ├── pumpfun.ts │ │ ├── web3Test.ts │ │ └── programId.ts │ ├── utils │ │ ├── chart.ts │ │ ├── constants.ts │ │ ├── type.ts │ │ └── calculateTokenPrice.ts │ ├── routes │ │ ├── coinStatus.ts │ │ ├── coinTradeRoutes.ts │ │ ├── curveRoutes.ts │ │ ├── chart.ts │ │ ├── feedback.ts │ │ ├── user.ts │ │ └── coin.ts │ ├── sockets │ │ ├── logger.ts │ │ └── index.ts │ ├── controller │ │ └── coinController.ts │ ├── logListeners │ │ └── AgentsLandListener.ts │ ├── models │ │ ├── Feedback.ts │ │ ├── PendingUser.ts │ │ ├── CurveConfig.ts │ │ ├── User.ts │ │ ├── CoinsStatus.ts │ │ └── Coin.ts │ ├── db │ │ └── dbConncetion.ts │ ├── @types │ │ └── global.d.ts │ ├── middleware │ │ └── authorization.ts │ └── index.ts ├── tests │ └── coinTests.spec.ts ├── mongo-docker │ └── docker-compose.yml ├── .gitignore ├── .env.example ├── Dockerfile ├── tsconfig.json ├── README.md └── package.json ├── front-end ├── src │ ├── utils │ │ ├── types.ts │ │ ├── util.ts │ │ ├── constants.ts │ │ ├── fileUpload.ts │ │ ├── getChartTable.ts │ │ └── handleEndPoint.ts │ ├── program │ │ ├── pumpfun.ts │ │ ├── web3.ts │ │ ├── programId.ts │ │ ├── pumpfun.json │ │ ├── logListeners │ │ │ ├── types.ts │ │ │ ├── utils.ts │ │ │ ├── listenerTest.ts │ │ │ ├── AgentsLandListener.ts │ │ │ ├── CreatedTokenHandler.ts │ │ │ ├── TokenSwapHandler.ts │ │ │ └── constants.ts │ │ └── seed.ts │ ├── components │ │ ├── cards │ │ │ ├── CoinBlog.tsx │ │ │ ├── KingOfHill.tsx │ │ │ └── DataCard.tsx │ │ ├── header │ │ │ └── Header.tsx │ │ ├── home │ │ │ ├── TopToken.tsx │ │ │ ├── index.tsx │ │ │ └── FilterList.tsx │ │ ├── profile │ │ │ └── index.tsx │ │ ├── trading │ │ │ ├── Trade.tsx │ │ │ ├── index.tsx │ │ │ ├── Chatting.tsx │ │ │ └── TradeForm.tsx │ │ ├── TVChart │ │ │ ├── datafeed.ts │ │ │ ├── streaming.ts │ │ │ ├── TVChartContainer.tsx │ │ │ └── TradingChart.tsx │ │ ├── creatToken │ │ │ └── index.tsx │ │ ├── others │ │ │ ├── TokenData.tsx │ │ │ ├── FilterListButton.tsx │ │ │ ├── TokenDistribution.tsx │ │ │ ├── socialList.tsx │ │ │ └── ToastGroup.tsx │ │ ├── select │ │ │ ├── SelectInput.tsx │ │ │ └── SellTaxRange.tsx │ │ ├── loadings │ │ │ └── Spinner.tsx │ │ ├── buttons │ │ │ ├── TimeTranding.tsx │ │ │ └── ConnectButton.tsx │ │ ├── MessageForm.tsx │ │ ├── upload │ │ │ └── ImageUpload.tsx │ │ └── modals │ │ │ ├── ReplyModal.tsx │ │ │ └── Modal.tsx │ ├── contexts │ │ ├── SocketContext.tsx │ │ ├── PageContext.tsx │ │ ├── ModalProvider.tsx │ │ └── SolanaWalletProvider.tsx │ ├── app │ │ ├── dashboard │ │ │ └── page.tsx │ │ ├── favicon.ico │ │ ├── create-coin │ │ │ └── page.tsx │ │ ├── profile │ │ │ └── [address] │ │ │ │ └── page.tsx │ │ ├── trading │ │ │ └── [address] │ │ │ │ └── page.tsx │ │ ├── page.tsx │ │ ├── layout.tsx │ │ └── globals.css │ ├── context │ │ ├── CoinContex.ts │ │ └── UserContext.ts │ ├── config.ts │ ├── config │ │ └── TextData.tsx │ └── provider │ │ └── providers.tsx ├── README.md ├── .eslintrc.json ├── public │ ├── bonkz10157.png │ ├── bonkz14134.png │ ├── assets │ │ ├── token01.gif │ │ ├── king-logo.png │ │ ├── logo-light.png │ │ └── images │ │ │ ├── imce-logo.jpg │ │ │ ├── switch-off.png │ │ │ ├── switch-on.png │ │ │ ├── user-avatar.png │ │ │ ├── test-token-bg.png │ │ │ └── test-token-bg1.png │ ├── vercel.svg │ ├── next.svg │ └── tradingview-chart.css ├── postcss.config.mjs ├── .env.example ├── next.config.mjs ├── .gitignore ├── tsconfig.json ├── package.json └── tailwind.config.ts ├── smart contract ├── programs │ └── pump │ │ ├── Xargo.toml │ │ ├── src │ │ ├── utils │ │ │ ├── mod.rs │ │ │ ├── calc.rs │ │ │ └── transfer.rs │ │ ├── states │ │ │ ├── mod.rs │ │ │ ├── config.rs │ │ │ └── bonding_curve.rs │ │ ├── instructions │ │ │ ├── mod.rs │ │ │ ├── migrate.rs │ │ │ ├── get_curve_info.rs │ │ │ ├── configure.rs │ │ │ ├── swap.rs │ │ │ └── launch.rs │ │ ├── consts.rs │ │ ├── errors.rs │ │ └── lib.rs │ │ └── Cargo.toml ├── .gitignore ├── .prettierignore ├── Cargo.toml ├── tsconfig.json ├── Anchor.toml ├── tests │ ├── constant.ts │ ├── utils.ts │ └── pumpfun.ts ├── lib │ ├── constant.ts │ ├── util.ts │ └── scripts.ts ├── package.json ├── cli │ ├── command.ts │ └── scripts.ts ├── README.md └── SMART_CONTRACT_UPDATES.md └── README.md /back-end/src/program/web3.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /back-end/src/utils/chart.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/utils/types.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/utils/util.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /back-end/src/program/pumpfun.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /back-end/src/program/web3Test.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /back-end/src/routes/coinStatus.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /back-end/src/sockets/logger.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /back-end/src/utils/constants.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /back-end/src/utils/type.ts: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /back-end/tests/coinTests.spec.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/program/pumpfun.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/program/web3.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/utils/constants.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/utils/fileUpload.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/program/programId.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/program/pumpfun.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/utils/getChartTable.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/utils/handleEndPoint.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /back-end/src/utils/calculateTokenPrice.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/README.md: -------------------------------------------------------------------------------- 1 | Pump.fun project 2 | -------------------------------------------------------------------------------- /front-end/src/components/cards/CoinBlog.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/components/header/Header.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/components/home/TopToken.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/components/home/index.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/components/profile/index.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/components/trading/Trade.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/components/trading/index.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/contexts/SocketContext.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/program/logListeners/types.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/program/logListeners/utils.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /back-end/mongo-docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /back-end/src/controller/coinController.ts: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /front-end/src/components/TVChart/datafeed.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/components/TVChart/streaming.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/components/cards/KingOfHill.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/components/creatToken/index.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/components/others/TokenData.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/components/select/SelectInput.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /back-end/src/logListeners/AgentsLandListener.ts: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /front-end/src/components/TVChart/TVChartContainer.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/components/TVChart/TradingChart.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/components/others/FilterListButton.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/components/others/TokenDistribution.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/program/logListeners/listenerTest.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/program/logListeners/AgentsLandListener.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/program/logListeners/CreatedTokenHandler.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/program/logListeners/TokenSwapHandler.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/program/seed.ts: -------------------------------------------------------------------------------- 1 | export const SEED_CONFIG = "config"; -------------------------------------------------------------------------------- /back-end/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | dist 4 | id.json 5 | *.txt -------------------------------------------------------------------------------- /front-end/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /front-end/src/program/logListeners/constants.ts: -------------------------------------------------------------------------------- 1 | export const GLOBAL_VAULT = "global"; 2 | -------------------------------------------------------------------------------- /smart contract/programs/pump/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /front-end/src/app/dashboard/page.tsx: -------------------------------------------------------------------------------- 1 | export default function Page() { 2 | return

Hello, Home page!

3 | } -------------------------------------------------------------------------------- /smart contract/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | **/*.rs.bk 6 | node_modules 7 | test-ledger 8 | .yarn 9 | -------------------------------------------------------------------------------- /smart contract/.prettierignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | node_modules 6 | dist 7 | build 8 | test-ledger 9 | -------------------------------------------------------------------------------- /smart contract/programs/pump/src/utils/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod calc; 2 | pub use calc::*; 3 | pub mod transfer; 4 | pub use transfer::*; 5 | -------------------------------------------------------------------------------- /smart contract/programs/pump/src/states/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | pub use config::*; 3 | pub mod bonding_curve; 4 | pub use bonding_curve::*; -------------------------------------------------------------------------------- /front-end/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topsecretagent007/pumpfun-smart-contract-frontend-backend/HEAD/front-end/src/app/favicon.ico -------------------------------------------------------------------------------- /front-end/public/bonkz10157.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topsecretagent007/pumpfun-smart-contract-frontend-backend/HEAD/front-end/public/bonkz10157.png -------------------------------------------------------------------------------- /front-end/public/bonkz14134.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topsecretagent007/pumpfun-smart-contract-frontend-backend/HEAD/front-end/public/bonkz14134.png -------------------------------------------------------------------------------- /front-end/public/assets/token01.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topsecretagent007/pumpfun-smart-contract-frontend-backend/HEAD/front-end/public/assets/token01.gif -------------------------------------------------------------------------------- /front-end/public/assets/king-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topsecretagent007/pumpfun-smart-contract-frontend-backend/HEAD/front-end/public/assets/king-logo.png -------------------------------------------------------------------------------- /front-end/public/assets/logo-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topsecretagent007/pumpfun-smart-contract-frontend-backend/HEAD/front-end/public/assets/logo-light.png -------------------------------------------------------------------------------- /front-end/public/assets/images/imce-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topsecretagent007/pumpfun-smart-contract-frontend-backend/HEAD/front-end/public/assets/images/imce-logo.jpg -------------------------------------------------------------------------------- /front-end/public/assets/images/switch-off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topsecretagent007/pumpfun-smart-contract-frontend-backend/HEAD/front-end/public/assets/images/switch-off.png -------------------------------------------------------------------------------- /front-end/public/assets/images/switch-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topsecretagent007/pumpfun-smart-contract-frontend-backend/HEAD/front-end/public/assets/images/switch-on.png -------------------------------------------------------------------------------- /front-end/public/assets/images/user-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topsecretagent007/pumpfun-smart-contract-frontend-backend/HEAD/front-end/public/assets/images/user-avatar.png -------------------------------------------------------------------------------- /front-end/public/assets/images/test-token-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topsecretagent007/pumpfun-smart-contract-frontend-backend/HEAD/front-end/public/assets/images/test-token-bg.png -------------------------------------------------------------------------------- /front-end/public/assets/images/test-token-bg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topsecretagent007/pumpfun-smart-contract-frontend-backend/HEAD/front-end/public/assets/images/test-token-bg1.png -------------------------------------------------------------------------------- /front-end/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /back-end/src/models/Feedback.ts: -------------------------------------------------------------------------------- 1 | // models/Feedback.ts 2 | import mongoose from 'mongoose'; 3 | 4 | 5 | 6 | const Message = mongoose.model('Message', messageSchema); 7 | 8 | export default Message; 9 | -------------------------------------------------------------------------------- /front-end/.env.example: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_SOLANA_RPC= 2 | NEXT_PUBLIC_SOLANA_WS= 3 | NEXT_PUBLIC_BACKEND_URL= 4 | 5 | NEXT_PUBLIC_PINATA_API_KEY= 6 | NEXT_PUBLIC_PINATA_SECRET_API_KEY= 7 | NEXT_PUBLIC_PROGRAM_ID= -------------------------------------------------------------------------------- /back-end/src/db/dbConncetion.ts: -------------------------------------------------------------------------------- 1 | import database from "mongoose"; 2 | 3 | require("dotenv").config("../.env"); 4 | const DB_CONNECTION = process.env.MONGODB_URI; 5 | 6 | export const init = () => { 7 | 8 | }; 9 | -------------------------------------------------------------------------------- /back-end/src/models/PendingUser.ts: -------------------------------------------------------------------------------- 1 | // models/PendingUser.ts 2 | import mongoose from 'mongoose'; 3 | 4 | 5 | const PendingUser = mongoose.model('PendingUser', pendingUserSchema); 6 | 7 | export default PendingUser; 8 | -------------------------------------------------------------------------------- /back-end/src/routes/coinTradeRoutes.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import CoinStatus from "../models/CoinsStatus"; 3 | import Coin from "../models/Coin"; 4 | 5 | const router = express.Router(); 6 | 7 | 8 | export default router; 9 | -------------------------------------------------------------------------------- /back-end/src/routes/curveRoutes.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { logger } from "../sockets/logger"; 3 | import CurveConfig from "../models/CurveConfig"; 4 | 5 | 6 | 7 | const router = express.Router(); 8 | 9 | 10 | export default router; -------------------------------------------------------------------------------- /back-end/.env.example: -------------------------------------------------------------------------------- 1 | MONGODB_URI= 2 | PORT=4000 3 | SIGN_IN_MSG=agentland 4 | 5 | PUBLIC_SOLANA_RPC= 6 | PUBLIC_SOLANA_WS= 7 | 8 | PRIVATE_KEY= 9 | PINATA_API_KEY= 10 | 11 | 12 | PINATA_SECRET_API_KEY= 13 | PINATA_GATEWAY_URL= 14 | DEFAULT_IMG_HASH= 15 | PROGRAM_ID= -------------------------------------------------------------------------------- /smart contract/programs/pump/src/instructions/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod configure; 2 | pub use configure::*; 3 | pub mod launch; 4 | pub use launch::*; 5 | pub mod swap; 6 | pub use swap::*; 7 | pub mod migrate; 8 | pub use migrate::*; 9 | pub mod get_curve_info; 10 | pub use get_curve_info::*; -------------------------------------------------------------------------------- /back-end/src/sockets/index.ts: -------------------------------------------------------------------------------- 1 | import { Server, Socket } from 'socket.io'; 2 | import * as http from "http"; 3 | import { logger } from './logger'; 4 | 5 | export let io: Server | null = null; 6 | export let counter = 0; 7 | export const socketio = async (server: http.Server) => { 8 | 9 | }; 10 | -------------------------------------------------------------------------------- /smart contract/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | resolver = "1" 6 | 7 | [profile.release] 8 | overflow-checks = true 9 | lto = "fat" 10 | codegen-units = 1 11 | [profile.release.build-override] 12 | opt-level = 3 13 | incremental = false 14 | codegen-units = 1 15 | -------------------------------------------------------------------------------- /back-end/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:20 as builder 2 | 3 | # Install global package 4 | RUN npm i -g tsx tsc 5 | 6 | WORKDIR /app 7 | 8 | COPY package*.json ./ 9 | 10 | # Install production dependencies. 11 | RUN yarn 12 | 13 | COPY . . 14 | 15 | # Run the web service on container startup. 16 | CMD [ "yarn", "start" ] 17 | -------------------------------------------------------------------------------- /front-end/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | eslint: { 4 | // Warning: This allows production builds to successfully complete even if 5 | // your project has ESLint errors. 6 | ignoreDuringBuilds: true, 7 | }, 8 | 9 | }; 10 | 11 | export default nextConfig; 12 | -------------------------------------------------------------------------------- /back-end/src/models/CurveConfig.ts: -------------------------------------------------------------------------------- 1 | // models/User.ts 2 | import mongoose, { Types } from 'mongoose'; 3 | 4 | 5 | const curveConfigSchema = new mongoose.Schema({ 6 | curveLimit: { type: Number, required: true } 7 | }); 8 | 9 | const CurveConfig = mongoose.model('CurveConfig', curveConfigSchema); 10 | 11 | export default CurveConfig; -------------------------------------------------------------------------------- /front-end/src/app/create-coin/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import CreateToken from "@/components/creatToken"; 3 | 4 | export default function Page() { 5 | 6 | return ( 7 |
8 |
9 | 10 |
11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /front-end/src/app/profile/[address]/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import ProfilePage from "@/components/profile"; 3 | 4 | export default function Page() { 5 | 6 | return ( 7 |
8 |
9 | 10 |
11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /front-end/src/app/trading/[address]/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import TradingPage from "@/components/trading"; 3 | 4 | export default function Page() { 5 | 6 | return ( 7 |
8 |
9 | 10 |
11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /back-end/src/models/User.ts: -------------------------------------------------------------------------------- 1 | // models/User.ts 2 | import mongoose, { Types } from 'mongoose'; 3 | 4 | const PINATA_GATEWAY_URL = process.env.PINATA_GATEWAY_URL; 5 | const defualtImg = process.env.DEFAULT_IMG_HASH 6 | 7 | const userSchema = new mongoose.Schema({ 8 | 9 | }); 10 | 11 | const User = mongoose.model('User', userSchema); 12 | 13 | export default User; -------------------------------------------------------------------------------- /front-end/src/app/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import HomePage from "@/components/home"; 3 | 4 | export default function Home() { 5 | 6 | return ( 7 |
8 |
9 | 10 |
11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /smart contract/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": [ 4 | "mocha", 5 | "chai" 6 | ], 7 | "typeRoots": [ 8 | "./node_modules/@types" 9 | ], 10 | "lib": [ 11 | "es2015" 12 | ], 13 | "module": "commonjs", 14 | "target": "es6", 15 | "esModuleInterop": true, 16 | "resolveJsonModule": true 17 | } 18 | } -------------------------------------------------------------------------------- /back-end/src/@types/global.d.ts: -------------------------------------------------------------------------------- 1 | import { Logger } from "winston"; 2 | import { Environment, Config } from "../config/config"; 3 | 4 | // Extend NodeJS global object 5 | declare global { 6 | // eslint-disable-next-line no-var 7 | var logger: Logger; // Declare logger as a global variable 8 | } 9 | 10 | export {}; // This is needed to prevent TypeScript from treating this as a global script 11 | -------------------------------------------------------------------------------- /back-end/src/routes/chart.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import NodeCache from "node-cache"; 3 | import { logger } from "../sockets/logger"; 4 | import { fetchPriceChartData } from "../utils/chart"; 5 | 6 | 7 | 8 | const router = express.Router(); 9 | 10 | // @route GET /coin/ 11 | // @desc Get all created coins 12 | // @access Public 13 | 14 | export default router; 15 | 16 | 17 | -------------------------------------------------------------------------------- /back-end/src/program/programId.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js" 2 | 3 | // Program ID defined in the provided IDL. Do not edit, it will get overwritten. 4 | export const PROGRAM_ID_IDL = new PublicKey( 5 | 6 | ) 7 | 8 | // This constant will not get overwritten on subsequent code generations and it's safe to modify it's value. 9 | export const PROGRAM_ID: PublicKey = PROGRAM_ID_IDL 10 | -------------------------------------------------------------------------------- /back-end/src/routes/feedback.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import Message from "../models/Feedback"; 3 | import { Date, Types } from "mongoose"; 4 | import { AuthRequest, auth } from "../middleware/authorization"; 5 | import { io } from "../sockets"; 6 | 7 | const router = express.Router(); 8 | 9 | // @route GET /message/: 10 | // @desc Get messages about this coin 11 | // @access Public 12 | 13 | 14 | export default router; -------------------------------------------------------------------------------- /back-end/src/middleware/authorization.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from "express" 2 | import jwt from 'jsonwebtoken' 3 | import { UserInfo } from "../routes/user"; 4 | 5 | export const auth = (req: AuthRequest, res: Response, next: NextFunction): void => { 6 | // const { authorization } = req.headers; 7 | // const token = authorization?.split(' ')[1]; 8 | 9 | 10 | } 11 | 12 | export interface AuthRequest extends Request { 13 | user?: any; 14 | } 15 | 16 | 17 | -------------------------------------------------------------------------------- /smart contract/Anchor.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | 3 | [features] 4 | resolution = true 5 | skip-lint = false 6 | 7 | [programs.devnet] 8 | pump = "Cu3ZCXsVh7xC64gWH23vjDeytWC6ZGcMRVYZAka92QTq" 9 | 10 | [registry] 11 | url = "https://api.apr.dev" 12 | 13 | [provider] 14 | cluster = "Devnet" 15 | wallet = "./id.json" 16 | 17 | [scripts] 18 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" 19 | 20 | [test] 21 | startup_wait = 10000 22 | shutdown_wait = 2000 23 | upgradeable = false 24 | -------------------------------------------------------------------------------- /back-end/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["ES2020", "dom"], 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "skipLibCheck": true, 8 | "sourceMap": true, 9 | "experimentalDecorators": true, 10 | "emitDecoratorMetadata": true, 11 | "declaration": false, 12 | "outDir": "dist", 13 | "typeRoots": ["node_modules/@types"], 14 | "allowJs": true, 15 | "resolveJsonModule": true, 16 | "esModuleInterop": true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /smart contract/programs/pump/src/consts.rs: -------------------------------------------------------------------------------- 1 | pub const INITIAL_PRICE: u64 = 600; // lamports per one token (without decimal) 2 | pub const TOKEN_DECIMAL: u8 = 6; // token decimal 3 | pub const MAX_FEE_PERCENT: f64 = 20.0; // maximum allowed fee percentage 4 | pub const MIN_CURVE_LIMIT: u64 = 1_000_000; // minimum curve limit in lamports (0.001 SOL) 5 | pub const MAX_CURVE_LIMIT: u64 = 1_000_000_000_000; // maximum curve limit in lamports (1000 SOL) 6 | pub const PRICE_PRECISION: u64 = 1_000_000; // precision for price calculations 7 | -------------------------------------------------------------------------------- /smart contract/programs/pump/src/instructions/migrate.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | #[derive(Accounts)] 4 | pub struct Migrate<'info> { 5 | #[account(mut)] 6 | payer: Signer<'info>, 7 | } 8 | 9 | impl<'info> Migrate<'info> { 10 | pub fn process(&mut self, _nonce: u8) -> Result<()> { 11 | //////////////////// DM if you want full implementation //////////////////// 12 | // telegram - https://t.me/microgift88 13 | // discord - https://discord.com/users/1074514238325927956 14 | 15 | Ok(()) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /front-end/src/context/CoinContex.ts: -------------------------------------------------------------------------------- 1 | import { createContext, useContext, useState, ReactNode } from 'react'; 2 | import { coinInfo } from '@/utils/types'; 3 | // interface WalletContextType { 4 | // user : userInfo; 5 | // setUser: (value: userInfo)=> void; 6 | 7 | 8 | // } 9 | // const walletContext = createContext ; 10 | 11 | // export default walletContext; 12 | 13 | const CoinContext = createContext({ 14 | coin:{} as coinInfo, 15 | setCoin: (value: coinInfo) => {}, 16 | 17 | }) 18 | 19 | export default CoinContext; -------------------------------------------------------------------------------- /smart contract/programs/pump/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pump" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "pump" 10 | 11 | [features] 12 | no-entrypoint = [] 13 | no-idl = [] 14 | no-log-ix-name = [] 15 | cpi = ["no-entrypoint"] 16 | default = [] 17 | idl-build = ["anchor-lang/idl-build", "anchor-spl/idl-build"] 18 | 19 | [dependencies] 20 | anchor-lang = { version="0.30.1", features = ["init-if-needed"] } 21 | anchor-spl = { version="0.30.1", features = ["metadata"] } 22 | -------------------------------------------------------------------------------- /front-end/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | .env 9 | 10 | # testing 11 | /coverage 12 | 13 | # next.js 14 | /.next/ 15 | /out/ 16 | 17 | # production 18 | /build 19 | 20 | # misc 21 | .DS_Store 22 | *.pem 23 | 24 | # debug 25 | npm-debug.log* 26 | yarn-debug.log* 27 | yarn-error.log* 28 | 29 | # local env files 30 | .env*.local 31 | 32 | # vercel 33 | .vercel 34 | 35 | # typescript 36 | *.tsbuildinfo 37 | next-env.d.ts 38 | -------------------------------------------------------------------------------- /smart contract/tests/constant.ts: -------------------------------------------------------------------------------- 1 | export const SEED_CONFIG = "config"; 2 | export const SEED_BONDING_CURVE = "bonding_curve"; 3 | export const SEED_GLOBAL = "global"; 4 | export const TEST_NAME = "test spl token"; 5 | export const TEST_SYMBOL = "TEST"; 6 | export const TEST_URI = 7 | "https://ipfs.io/ipfs/QmWVzSC1ZTFiBYFiZZ6QivGUZ9awPJwqZECSFL1UD4gitC"; 8 | export const TEST_VIRTUAL_RESERVES = 1_000_000_000; // 10^9, decimals = 9 9 | export const TEST_TOKEN_SUPPLY = 1_000_000_000_000_000; // 1 bil, decimals = 6 10 | export const TEST_DECIMALS = 6; 11 | export const TEST_INIT_BONDING_CURVE = 95; 12 | -------------------------------------------------------------------------------- /front-end/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /smart contract/lib/constant.ts: -------------------------------------------------------------------------------- 1 | import { MAINNET_PROGRAM_ID, DEVNET_PROGRAM_ID } from "@raydium-io/raydium-sdk"; 2 | import { Cluster, PublicKey } from "@solana/web3.js"; 3 | 4 | export const SEED_CONFIG = "config"; 5 | export const SEED_BONDING_CURVE = "bonding_curve"; 6 | 7 | export const TEST_NAME = "test spl token"; 8 | export const TEST_SYMBOL = "TEST"; 9 | export const TEST_URI = 10 | "https://ipfs.io/ipfs/QmWVzSC1ZTFiBYFiZZ6QivGUZ9awPJwqZECSFL1UD4gitC"; 11 | export const TEST_VIRTUAL_RESERVES = 2_000_000_000; 12 | export const TEST_TOKEN_SUPPLY = 1_000_000_000_000; 13 | export const TEST_DECIMALS = 6; 14 | export const TEST_INIT_BONDING_CURVE = 95; 15 | -------------------------------------------------------------------------------- /front-end/src/components/loadings/Spinner.tsx: -------------------------------------------------------------------------------- 1 | import { Circles } from "react-loader-spinner" 2 | 3 | export const Spinner = () => { 4 | return ( 5 |
6 |
7 |
8 | 17 |
18 |
19 |
20 | ) 21 | 22 | } -------------------------------------------------------------------------------- /front-end/src/components/cards/DataCard.tsx: -------------------------------------------------------------------------------- 1 | import { HiOutlinePuzzle } from "react-icons/hi"; 2 | import { TbWorld } from "react-icons/tb"; 3 | import { FaXTwitter } from "react-icons/fa6"; 4 | import { FaTelegramPlane } from "react-icons/fa"; 5 | 6 | interface CoinBlogProps { 7 | text: string; 8 | data: string | number; 9 | } 10 | 11 | export const DataCard: React.FC = ({ text, data }) => { 12 | 13 | return ( 14 |
15 |

{text}

16 |

17 | {data} 18 |

19 |
20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /front-end/src/config.ts: -------------------------------------------------------------------------------- 1 | import { LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js"; 2 | 3 | export const SOLANA_RPC = process.env.NEXT_PUBLIC_SOLANA_RPC ?? ""; 4 | 5 | 6 | 7 | const endpoints = { 8 | tradingVariables:"", 9 | tradingHistory24:"", 10 | prices24Ago:"", 11 | pricingChart: "https://tizz-be-api-production.up.railway.app/charts", 12 | chartSocket: "http://", 13 | personalTradingHistoryTable: 14 | "https://backend-$$network_name$$$$collateral_type$$.gains.trade/personal-trading-history-table", 15 | userTradingVariables: 16 | "https://backend-$$network_name$$$$collateral_type$$.gains.trade/user-trading-variables", 17 | backendSocket: "wss://tizz-be-api-production.up.railway.app", 18 | }; 19 | -------------------------------------------------------------------------------- /smart contract/programs/pump/src/errors.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | #[error_code] 4 | pub enum PumpError { 5 | #[msg("Not authorized address")] 6 | NotAuthorized, 7 | 8 | #[msg("Fee recipient address is not match with the one in the config")] 9 | IncorrectFeeRecipient, 10 | 11 | #[msg("The value is not in the expected range")] 12 | IncorrectValue, 13 | 14 | #[msg("Amount out is smaller than required amount")] 15 | ReturnAmountTooSmall, 16 | 17 | #[msg("An overflow or underflow occurred during the calculation")] 18 | OverflowOrUnderflowOccurred, 19 | 20 | #[msg("Curve is already completed")] 21 | CurveAlreadyCompleted, 22 | 23 | #[msg("Insufficient reserves for this operation")] 24 | InsufficientReserves, 25 | } 26 | -------------------------------------------------------------------------------- /back-end/src/routes/user.ts: -------------------------------------------------------------------------------- 1 | // routes/users.js 2 | import express from "express"; 3 | import User from "../models/User"; 4 | import PendingUser from "../models/PendingUser"; 5 | import crypto from "crypto"; 6 | import Joi from "joi"; 7 | import base58 from "bs58"; 8 | import nacl from "tweetnacl"; 9 | import { PublicKey, Transaction } from "@solana/web3.js"; 10 | import jwt from "jsonwebtoken"; 11 | 12 | const router = express.Router(); 13 | 14 | // @route POST api/users 15 | // @desc Resgister user 16 | // @access Public 17 | 18 | 19 | export default router; 20 | 21 | export interface UserInfo { 22 | name: string; 23 | wallet: string; 24 | avatar?: string; 25 | } 26 | 27 | export interface PendingUserInfo { 28 | name: string; 29 | wallet: string; 30 | nonce: string; 31 | } 32 | -------------------------------------------------------------------------------- /front-end/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2015", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": false, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./src/*"], 23 | "@/libraries/*": ["./public/libraries/*"], 24 | } 25 | }, 26 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 27 | "exclude": ["node_modules"] 28 | } 29 | -------------------------------------------------------------------------------- /front-end/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Inter } from "next/font/google"; 3 | import "./globals.css"; 4 | import Providers from "@/provider/providers"; 5 | import "dotenv/config.js"; 6 | import Header from "@/components/header/Header"; 7 | 8 | const inter = Inter({ 9 | subsets: ["latin"], 10 | }); 11 | 12 | export const metadata: Metadata = { 13 | title: "LB Pump", 14 | description: "Forking Pump.fun", 15 | }; 16 | 17 | export default function RootLayout({ 18 | children, 19 | }: Readonly<{ 20 | children: React.ReactNode; 21 | }>) { 22 | return ( 23 | 24 | 25 | 26 |
27 | {children} 28 |
29 | 30 | 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /back-end/src/routes/coin.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import Coin from "../models/Coin"; 3 | import { TOKEN_LIST_QUERY_LIMIT } from "../utils/constants"; 4 | import { AuthRequest, auth } from "../middleware/authorization"; 5 | import { Types } from "mongoose"; 6 | import { Keypair, PublicKey } from "@solana/web3.js"; 7 | import CoinStatus from "../models/CoinsStatus"; 8 | import { io } from "../sockets"; 9 | import { coinKing } from "../controller/coinController"; 10 | 11 | 12 | const router = express.Router(); 13 | 14 | // @route GET /coin/ 15 | // @desc Get all created coins 16 | // @access Public 17 | router.get('/', async (req, res) => { 18 | const coins = await Coin.find({}).populate('creator') 19 | return res.status(200).send(coins) 20 | }) 21 | 22 | router.post('/king', async (req, res) => { 23 | const data = coinKing(); 24 | }) 25 | -------------------------------------------------------------------------------- /front-end/src/contexts/PageContext.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import { createContext, useContext, ReactNode } from "react"; 3 | 4 | interface PageContextType { 5 | solPrice: number; 6 | } 7 | 8 | export const PageContext = createContext( 9 | undefined 10 | ); 11 | 12 | export function useData() { 13 | const context = useContext(PageContext); 14 | if (!context) { 15 | throw new Error("useData must be used within a ModalProvider"); 16 | } 17 | return context; 18 | } 19 | 20 | interface PageProviderProps { 21 | children: ReactNode; 22 | } 23 | 24 | export function PageProvider({ children }: PageProviderProps) { 25 | 26 | const pageContextValue: PageContextType = { 27 | solPrice: 101, 28 | }; 29 | return ( 30 | 31 | {children} 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /smart contract/programs/pump/src/states/config.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | #[account] 4 | pub struct Config { 5 | pub authority: Pubkey, // authority of the program 6 | pub fee_recipient: Pubkey, // team wallet address to receive the fee 7 | 8 | // lamports to complete the bonding curve 9 | pub curve_limit: u64, 10 | 11 | // curve token/sol amount config 12 | pub initial_virtual_token_reserves: u64, 13 | pub initial_virtual_sol_reserves: u64, 14 | pub initial_real_token_reserves: u64, 15 | pub total_token_supply: u64, 16 | 17 | // platform fee percentage 18 | pub buy_fee_percent: f64, 19 | pub sell_fee_percent: f64, 20 | pub migration_fee_percent: f64, 21 | } 22 | 23 | impl Config { 24 | pub const SEED_PREFIX: &'static str = "global-config"; 25 | pub const LEN: usize = 32 + 32 + 8 + 8 * 4 + 8 * 3; 26 | } 27 | -------------------------------------------------------------------------------- /back-end/src/models/CoinsStatus.ts: -------------------------------------------------------------------------------- 1 | // models/CoinStatus.ts 2 | import mongoose from "mongoose"; 3 | 4 | const coinStatusSchema = new mongoose.Schema({ 5 | 6 | coinId: { type: mongoose.Schema.Types.ObjectId, ref: "Coin", required: true }, 7 | record: [ 8 | { 9 | holder: { 10 | type: mongoose.Schema.Types.ObjectId, 11 | ref: "User", 12 | required: true, 13 | }, 14 | time: { type: Date, default: Date.now }, 15 | tokenAmount: { type: Number, default: 0, required: true }, 16 | lamportAmount: { type: Number, default: 0, required: true }, 17 | swapDirection: { type: Number, default: 0, required: true }, 18 | price: { type: Number, required: true }, 19 | tx: { type: String, required: true }, 20 | }, 21 | ], 22 | }); 23 | 24 | const CoinStatus = mongoose.model("CoinStatus", coinStatusSchema); 25 | 26 | export default CoinStatus; 27 | -------------------------------------------------------------------------------- /smart contract/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", 4 | "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check", 5 | "test": "mocha -r ts-node/register tests/**/*.ts", 6 | "script": "ts-node ./cli/command.ts" 7 | }, 8 | "dependencies": { 9 | "@coral-xyz/anchor": "^0.30.1", 10 | "@project-serum/serum": "^0.13.65", 11 | "@raydium-io/raydium-sdk": "^1.3.1-beta.58", 12 | "@solana/spl-token": "^0.4.8", 13 | "@solana/web3.js": "^1.68.0", 14 | "dotenv": "^16.4.5" 15 | }, 16 | "devDependencies": { 17 | "@types/bn.js": "^5.1.0", 18 | "@types/chai": "^5.0.1", 19 | "@types/mocha": "^10.0.10", 20 | "chai": "^5.1.2", 21 | "mocha": "^11.0.1", 22 | "prettier": "^3.4.2", 23 | "ts-mocha": "^10.0.0", 24 | "typescript": "^5.7.2" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /smart contract/programs/pump/src/utils/calc.rs: -------------------------------------------------------------------------------- 1 | use std::ops::{Div, Mul}; 2 | 3 | pub fn convert_to_float(value: u64, decimals: u8) -> f64 { 4 | (value as f64).div(f64::powf(10.0, decimals as f64)) 5 | } 6 | 7 | pub fn convert_from_float(value: f64, decimals: u8) -> u64 { 8 | value.mul(f64::powf(10.0, decimals as f64)) as u64 9 | } 10 | 11 | pub fn calculate_price_impact(amount_in: u64, reserves: u64) -> f64 { 12 | if reserves == 0 { 13 | return 0.0; 14 | } 15 | (amount_in as f64 / reserves as f64) * 100.0 16 | } 17 | 18 | pub fn calculate_slippage(amount_in: u64, amount_out: u64, expected_amount: u64) -> f64 { 19 | if expected_amount == 0 { 20 | return 0.0; 21 | } 22 | let difference = if amount_out > expected_amount { 23 | amount_out - expected_amount 24 | } else { 25 | expected_amount - amount_out 26 | }; 27 | (difference as f64 / expected_amount as f64) * 100.0 28 | } 29 | -------------------------------------------------------------------------------- /back-end/README.md: -------------------------------------------------------------------------------- 1 | # Pump.fun Backend 2 | 3 | ## Run tests 4 | 5 | ### Prepare local MongoDb 6 | 7 | 1. The local MongoDb is run via docker-compose with secrets. You need to create two files: 8 | 9 | - mongo-docker/db_root_username.txt 10 | - mongo-docker/db_root_password.txt 11 | 12 | you can choose whatever username and password for your local MongoDb. 13 | 14 | 2. Start MongoDb 15 | 16 | You can start MongoDb locally via Docker: `docker-compose -f mongo-docker/docker-compose.yml up -d` 17 | 18 | 3. Setup local Mongo URI env 19 | 20 | The Mongo URI for connection is fairly simple. It looks like this: `mongodb://:@localhost:27017/` 21 | 22 | ### Start your local Solana chain 23 | 24 | You will need to setup your Solana test validator yourself along with your deployed program. 25 | 26 | ### Run API tests 27 | 28 | ```bash 29 | # run all tests 30 | yarn test 31 | 32 | # Run a single test 33 | yarn test -t "test-create-a-new-coin" 34 | ``` 35 | -------------------------------------------------------------------------------- /back-end/src/models/Coin.ts: -------------------------------------------------------------------------------- 1 | // models/Coin.ts 2 | import mongoose from "mongoose"; 3 | 4 | const coinSchema = new mongoose.Schema({ 5 | creator: { 6 | type: mongoose.Schema.Types.ObjectId, 7 | ref: "User", 8 | required: true, 9 | }, 10 | name: { type: String, required: true }, 11 | ticker: { type: String, required: true }, 12 | description: { type: String }, 13 | decimals: { type: Number, required: true }, 14 | token: { type: String, unique: true, required: true }, 15 | tokenReserves: { type: Number, required: true }, 16 | lamportReserves: { type: Number, required: true }, 17 | url: { type: String, requried: true }, 18 | progressMcap: { type: Number, required: true }, 19 | date: { type: Date, default: new Date() }, 20 | limit: { type: Number, required: true }, 21 | bondingCurve: {type: Boolean, default: false } 22 | }); 23 | 24 | const Coin = mongoose.model("Coin", coinSchema); 25 | 26 | export default Coin; 27 | -------------------------------------------------------------------------------- /front-end/src/components/buttons/TimeTranding.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | import { FC, useContext } from "react"; 3 | import { BiLineChart } from "react-icons/bi"; 4 | 5 | const TimeTranding: FC = () => { 6 | const Time = [ 7 | { id: "5m", name: "5M" }, 8 | { id: "1h", name: "1H" }, 9 | { id: "6h", name: "6H" }, 10 | { id: "24h", name: "24H" }, 11 | ] 12 | 13 | return ( 14 |
15 |
16 | 17 | Trending 18 |
19 | {Time.map((item: any, index: number) => { 20 | return ( 21 |
console.log(item.id)} className="bg-custom-gradient py-1 px-2.5 xs:px-5 rounded-sm cursor-pointer hover:bg-[#147EDF] text-sm"> 22 | {item.name} 23 |
24 | ) 25 | })} 26 |
27 | ); 28 | }; 29 | 30 | export default TimeTranding; 31 | -------------------------------------------------------------------------------- /front-end/src/components/others/socialList.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | import { coinInfo } from "@/utils/types"; 3 | import { FC, useContext, useState } from "react"; 4 | import { FaXTwitter } from "react-icons/fa6"; 5 | import { FaTelegramPlane } from "react-icons/fa"; 6 | import { TbWorld } from "react-icons/tb"; 7 | 8 | const SocialList: FC = () => { 9 | 10 | return ( 11 |
12 |

13 | 14 |

15 |

16 | 17 |

18 |

19 | 20 |

21 |
22 | ); 23 | }; 24 | 25 | export default SocialList; 26 | -------------------------------------------------------------------------------- /smart contract/lib/util.ts: -------------------------------------------------------------------------------- 1 | 2 | import { 3 | AddressLookupTableAccount, 4 | TransactionInstruction, 5 | VersionedTransaction, 6 | Transaction, 7 | PublicKey, 8 | Connection, 9 | SystemProgram, 10 | SYSVAR_RENT_PUBKEY 11 | } from "@solana/web3.js"; 12 | 13 | import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from "@solana/spl-token"; 14 | import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet"; 15 | 16 | export const getAssociatedTokenAccount = ( 17 | ownerPubkey: PublicKey, 18 | mintPk: PublicKey 19 | ): PublicKey => { 20 | } 21 | 22 | export const execTx = async ( 23 | transaction: Transaction, 24 | connection: Connection, 25 | payer: NodeWallet, 26 | commitment: "confirmed" | "finalized" = 'confirmed' 27 | ) => { 28 | } 29 | 30 | export const createAssociatedTokenAccountInstruction = ( 31 | associatedTokenAddress: PublicKey, 32 | payer: PublicKey, 33 | walletAddress: PublicKey, 34 | splTokenMintAddress: PublicKey 35 | ) => { 36 | }; 37 | 38 | export const getATokenAccountsNeedCreate = async ( 39 | connection: Connection, 40 | walletAddress: PublicKey, 41 | owner: PublicKey, 42 | nfts: PublicKey[], 43 | ) => { 44 | }; 45 | -------------------------------------------------------------------------------- /front-end/src/context/UserContext.ts: -------------------------------------------------------------------------------- 1 | "use client" 2 | import { msgInfo, userInfo } from '@/utils/types'; 3 | import { createContext, useContext, useState, ReactNode } from 'react'; 4 | 5 | // interface WalletContextType { 6 | // user : userInfo; 7 | // setUser: (value: userInfo)=> void; 8 | 9 | 10 | // } 11 | // const walletContext = createContext ; 12 | 13 | // export default walletContext; 14 | 15 | const UserContext = createContext({ 16 | user: {} as userInfo, 17 | setUser: (value: userInfo) => { }, 18 | login: false, 19 | setLogin: (value: boolean) => { }, 20 | isLoading: false, 21 | setIsLoading: (value: boolean) => { }, 22 | imageUrl: '/*.png', 23 | setImageUrl: (value: string) => { }, 24 | isCreated: false, 25 | setIsCreated: (value: boolean) => { }, 26 | messages: [] as msgInfo[], 27 | setMessages: (value: msgInfo[]) => { }, 28 | coinId: "", 29 | setCoinId: (value: string) => { }, 30 | newMsg: {} as msgInfo, 31 | setNewMsg: (value: msgInfo) => { }, 32 | solPrice: 0, 33 | setSolPrice: (value: number) => { }, 34 | profileEditModal: false, 35 | setProfileEditModal: (value: boolean) => { }, 36 | postReplyModal: false, 37 | setPostReplyModal: (value: boolean) => { }, 38 | 39 | }) 40 | 41 | export default UserContext; -------------------------------------------------------------------------------- /front-end/public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /front-end/src/components/MessageForm.tsx: -------------------------------------------------------------------------------- 1 | import { msgInfo, userInfo } from "@/utils/types"; 2 | 3 | interface MessageFormProps { 4 | msg: msgInfo; 5 | } 6 | 7 | export const MessageForm: React.FC = ({ msg }) => { 8 | return ( 9 |
10 |
11 |
12 | Token IMG 19 |
20 | {msg.sender && (msg.sender as userInfo).name} 21 |
22 | {msg.time &&
{msg.time.toString()}
} 23 |
24 |
25 | {msg.img !== undefined && ( 26 | Token IMG 33 | )} 34 |
35 | {msg.msg} 36 |
37 |
38 |
39 |
40 | ); 41 | }; 42 | -------------------------------------------------------------------------------- /front-end/src/config/TextData.tsx: -------------------------------------------------------------------------------- 1 | export const ProfileMenuList = [ 2 | { id: 1, text: "Coins held", }, 3 | { id: 4, text: "Coins created", }, 4 | { id: 5, text: "Followers", }, 5 | { id: 6, text: "Following", }, 6 | ] 7 | 8 | export const StagesData = [ 9 | { id: "one", text: "One" }, 10 | { id: "tow", text: "Tow" }, 11 | { id: "three", text: "Three" }, 12 | { id: "four", text: "Four" }, 13 | ] 14 | 15 | export const StageDurationData = [ 16 | { id: 1, text: "1 Days" }, 17 | { id: 1, text: "2 Days" }, 18 | { id: 3, text: "3 Days" }, 19 | { id: 4, text: "4 Days" }, 20 | { id: 5, text: "5 Days" }, 21 | { id: 6, text: "6 Days" }, 22 | { id: 7, text: "7 Days" }, 23 | ] 24 | 25 | export const SellTaxDecayData = [ 26 | { id: 1, text: "Unitill halfqy throgh - 10%" }, 27 | { id: 2, text: "Unitill halfqy throgh - 20%" }, 28 | { id: 3, text: "Unitill halfqy throgh - 30%" }, 29 | { id: 4, text: "Unitill halfqy throgh - 40%" }, 30 | { id: 5, text: "Unitill halfqy throgh - 50%" }, 31 | { id: 6, text: "Unitill halfqy throgh - 60%" }, 32 | { id: 7, text: "Unitill halfqy throgh - 70%" }, 33 | { id: 8, text: "Unitill halfqy throgh - 80%" }, 34 | { id: 9, text: "Unitill halfqy throgh - 90%" }, 35 | { id: 10, text: "Unitill halfqy throgh - 100%" }, 36 | ] 37 | 38 | export const FinalTokenPoolData = [ 39 | { id: "newlp", text: "NEWLP / SOL" }, 40 | { id: "meteora", text: "Meteora / SOL" }, 41 | { id: "raydium", text: "Raydium / SOL" }, 42 | { id: "uniswap", text: "Uniswap / ETH" }, 43 | ] -------------------------------------------------------------------------------- /front-end/src/components/others/ToastGroup.tsx: -------------------------------------------------------------------------------- 1 | import { toast } from "react-toastify"; 2 | import "react-toastify/dist/ReactToastify.css"; 3 | 4 | export const errorAlert = (text: string) => { 5 | toast.error(text, { 6 | position: "bottom-right", 7 | autoClose: 5000, 8 | hideProgressBar: false, 9 | closeOnClick: true, 10 | pauseOnHover: true, 11 | draggable: true, 12 | theme: "colored", 13 | }); 14 | }; 15 | 16 | export const errorAlertCenter = (text: string) => { 17 | toast.error(text, { 18 | position: "top-center", 19 | autoClose: false, 20 | hideProgressBar: false, 21 | closeOnClick: true, 22 | pauseOnHover: true, 23 | draggable: true, 24 | theme: "colored", 25 | }); 26 | }; 27 | 28 | export const warningAlert = (text: string) => { 29 | toast.warning(text, { 30 | className: "bg-black", 31 | position: "top-right", 32 | autoClose: 5000, 33 | hideProgressBar: false, 34 | closeOnClick: true, 35 | pauseOnHover: true, 36 | draggable: true, 37 | theme: "colored", 38 | }); 39 | }; 40 | 41 | export const successAlert = (text: string) => { 42 | toast.success(text, { 43 | position: "top-right", 44 | autoClose: 5000, 45 | hideProgressBar: false, 46 | closeOnClick: true, 47 | pauseOnHover: true, 48 | draggable: true, 49 | theme: "colored", 50 | }); 51 | }; 52 | 53 | export const infoAlert = (text: string) => { 54 | toast.info(text, { 55 | position: "top-right", 56 | autoClose: 5000, 57 | hideProgressBar: false, 58 | closeOnClick: true, 59 | pauseOnHover: true, 60 | draggable: true, 61 | theme: "colored", 62 | }); 63 | }; 64 | -------------------------------------------------------------------------------- /front-end/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pump-frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@coral-xyz/anchor": "^0.30.0", 13 | "@gainsnetwork/sdk": "^0.2.1", 14 | "@metaplex-foundation/js": "^0.20.1", 15 | "@pinata/sdk": "^2.1.0", 16 | "@project-serum/anchor": "^0.26.0", 17 | "@solana/spl-token": "^0.4.6", 18 | "@solana/wallet-adapter-base": "^0.9.23", 19 | "@solana/wallet-adapter-react": "^0.15.35", 20 | "@solana/wallet-adapter-react-ui": "^0.9.35", 21 | "@solana/wallet-adapter-wallets": "^0.19.32", 22 | "@solana/web3.js": "^1.91.8", 23 | "@types/bn.js": "^5.1.5", 24 | "axios": "^1.7.2", 25 | "bs58": "^5.0.0", 26 | "dotenv": "^16.4.5", 27 | "lightweight-charts": "^4.1.5", 28 | "next": "14.2.3", 29 | "pino-pretty": "^13.0.0", 30 | "react": "^18", 31 | "react-dom": "^18", 32 | "react-icons": "^5.3.0", 33 | "react-loader-spinner": "^6.1.6", 34 | "react-loading": "^2.0.3", 35 | "react-query": "^3.39.3", 36 | "react-range": "^1.10.0", 37 | "react-spinners": "^0.13.8", 38 | "react-toastify": "^10.0.5", 39 | "react-use": "^17.5.0", 40 | "tailwind-merge": "^2.3.0", 41 | "viem": "^2.14.2" 42 | }, 43 | "devDependencies": { 44 | "@types/node": "^20", 45 | "@types/react": "^18", 46 | "@types/react-dom": "^18", 47 | "eslint": "^8", 48 | "eslint-config-next": "14.2.3", 49 | "postcss": "^8", 50 | "tailwindcss": "^3.4.1", 51 | "typescript": "^5" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /front-end/tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "tailwindcss"; 2 | 3 | const config: Config = { 4 | content: [ 5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", 6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}", 7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}", 8 | ], 9 | theme: { 10 | screens: { 11 | '4xs': '280px', 12 | // => @media (min-width: 280px) { ... } 13 | '3.5xs': '320px', 14 | // => @media (min-width: 320px) { ... } 15 | '3xs': '375px', 16 | // => @media (min-width: 375px) { ... } 17 | '2xs': '414px', 18 | // => @media (min-width: 414px) { ... } 19 | xs: '520px', 20 | // => @media (min-width: 414px) { ... } 21 | sm: '640px', 22 | // => @media (min-width: 640px) { ... } 23 | sm2: '724px', 24 | // => @media (min-width: 724px) { ... } 25 | md: '768px', 26 | // => @media (min-width: 768px) { ... } 27 | md2: '896px', 28 | // => @media (min-width: 896px) { ... } 29 | md3: '984px', 30 | // => @media (min-width: 984px) { ... } 31 | lg: '1024px', 32 | // => @media (min-width: 1024px) { ... } 33 | lg2: '1158px', 34 | // => @media (min-width: 1024px) { ... } 35 | xl: '1280px', 36 | // => @media (min-width: 1280px) { ... } 37 | '1.5xl': '1348px', 38 | // => @media (min-width: 1348px) { ... } 39 | '2xl': '1536px', 40 | // => @media (min-width: 1536px) { ... } 41 | '3xl': '1820px' 42 | // => @media (min-width: 1820px) { ... } 43 | }, 44 | extend: { 45 | backgroundImage: { 46 | 'custom-gradient': 'linear-gradient(180deg, #147EDF, #0047CA)', 47 | }, 48 | }, 49 | }, 50 | plugins: [], 51 | }; 52 | export default config; 53 | -------------------------------------------------------------------------------- /front-end/src/contexts/ModalProvider.tsx: -------------------------------------------------------------------------------- 1 | import React, { 2 | createContext, 3 | useContext, 4 | useState, 5 | ReactNode, 6 | useEffect, 7 | } from "react"; 8 | 9 | // Define the type for your modal component props 10 | interface ModalProps { 11 | isOpen: boolean; 12 | closeModal: () => void; 13 | } 14 | 15 | // Define the type for your modal context 16 | interface ModalContextType { 17 | openModal: (content: ReactNode) => void; 18 | closeModal: () => void; 19 | } 20 | 21 | // Create the modal context 22 | const ModalContext = createContext(undefined); 23 | 24 | // Define the modal provider component 25 | export const ModalProvider = ({ children }: { children: ReactNode }) => { 26 | const [modalContent, setModalContent] = useState(null); 27 | 28 | const openModal = (content: ReactNode) => { 29 | setModalContent(content); 30 | document.body.classList.add("modal-open"); 31 | }; 32 | 33 | const closeModal = () => { 34 | setModalContent(null); 35 | document.body.classList.remove("modal-open"); 36 | }; 37 | 38 | useEffect(() => { 39 | return () => { 40 | // Cleanup function to remove class when component unmounts 41 | document.body.classList.remove("modal-open"); 42 | }; 43 | }, []); 44 | 45 | return ( 46 | 47 | {children} 48 | {modalContent && <>{modalContent}} 49 | 50 | ); 51 | }; 52 | 53 | // Custom hook to access the modal context 54 | export const useModal = () => { 55 | const context = useContext(ModalContext); 56 | 57 | if (!context) { 58 | throw new Error("useModal must be used within a ModalProvider"); 59 | } 60 | return context; 61 | }; 62 | -------------------------------------------------------------------------------- /back-end/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pump-backend", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "vitest --run", 7 | "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", 8 | "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check", 9 | "build": "rm -rf ./dist && tsc", 10 | "postinstall": "tsc", 11 | "watch-node": "node --watch dist/index.js", 12 | "watch-ts": "tsc -w", 13 | "start": "tsx --watch src/index.ts" 14 | }, 15 | "keywords": [], 16 | "author": "", 17 | "license": "ISC", 18 | "dependencies": { 19 | 20 | "@coral-xyz/anchor": "^0.30.1", 21 | "@metaplex-foundation/js": "^0.20.1", 22 | "@metaplex-foundation/mpl-token-metadata": "^3.2.1", 23 | "@metaplex-foundation/mpl-toolbox": "^0.9.4", 24 | "@metaplex-foundation/umi": "^0.9.1", 25 | "@metaplex-foundation/umi-bundle-defaults": "^0.9.1", 26 | "@raydium-io/raydium-sdk": "^1.3.1-beta.52", 27 | "@solana/spl-token": "^0.4.6", 28 | "@solana/web3.js": "^1.95.5", 29 | "@types/bn.js": "^5.1.5", 30 | "@types/jsonwebtoken": "^9.0.6", 31 | "axios": "^1.7.2", 32 | "body-parser": "^1.20.2", 33 | "bs58": "^5.0.0", 34 | "cors": "^2.8.5", 35 | "crypto": "^1.0.1", 36 | "dotenv": "^16.4.5", 37 | "express": "^4.21.1", 38 | "joi": "^17.13.1", 39 | "jsonwebtoken": "^9.0.2", 40 | "mongoose": "^8.8.2", 41 | "node-cache": "^5.1.2", 42 | "socket.io": "^4.7.5", 43 | "tsx": "^4.19.2", 44 | "tweetnacl": "^1.0.3", 45 | "winston": "^3.13.0" 46 | }, 47 | "devDependencies": { 48 | "@types/cors": "^2.8.17", 49 | "@types/express": "^4.17.21", 50 | "@types/supertest": "^6.0.2", 51 | "supertest": "^7.0.0", 52 | "typescript": "^5.7.2", 53 | "vitest": "^2.1.6" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /front-end/src/contexts/SolanaWalletProvider.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ConnectionProvider, 3 | WalletProvider, 4 | } from "@solana/wallet-adapter-react"; 5 | import { WalletModalProvider } from "@solana/wallet-adapter-react-ui"; 6 | import { ReactNode, useMemo } from "react"; 7 | import { 8 | LedgerWalletAdapter, 9 | PhantomWalletAdapter, 10 | SolflareWalletAdapter, 11 | TorusWalletAdapter, 12 | } from "@solana/wallet-adapter-wallets"; 13 | import { SOLANA_RPC } from "@/config"; 14 | import { WalletAdapterNetwork } from "@solana/wallet-adapter-base"; 15 | import { clusterApiUrl } from "@solana/web3.js"; 16 | 17 | require("@solana/wallet-adapter-react-ui/styles.css"); 18 | 19 | export const SolanaWalletProvider = ({ children }: { children: ReactNode }) => { 20 | // const network = WalletAdapterNetwork.Mainnet; 21 | 22 | const network = WalletAdapterNetwork.Mainnet; 23 | // You can also provide a custom RPC endpoint. 24 | // const endpoint = SOLANA_RPC; 25 | const endpoint = useMemo(() => clusterApiUrl(network), [network]); 26 | 27 | // @solana/wallet-adapter-wallets includes all the adapters but supports tree shaking and lazy loading -- 28 | // Only the wallets you configure here will be compiled into your application, and only the dependencies 29 | // of wallets that your users connect to will be loaded. 30 | const wallets = useMemo( 31 | () => [ 32 | new PhantomWalletAdapter(), 33 | new SolflareWalletAdapter({ network }), 34 | new TorusWalletAdapter(), 35 | new LedgerWalletAdapter(), 36 | ], 37 | [network] 38 | ); 39 | // const wallets = [new PhantomWalletAdapter(), new SolflareWalletAdapter()]; 40 | return ( 41 | 42 | 43 | {children} 44 | 45 | 46 | ); 47 | }; -------------------------------------------------------------------------------- /smart contract/programs/pump/src/instructions/get_curve_info.rs: -------------------------------------------------------------------------------- 1 | use crate::states::{BondingCurve, Config}; 2 | use anchor_lang::prelude::*; 3 | 4 | #[derive(Accounts)] 5 | pub struct GetCurveInfo<'info> { 6 | #[account( 7 | seeds = [Config::SEED_PREFIX.as_bytes()], 8 | bump, 9 | )] 10 | global_config: Box>, 11 | 12 | #[account( 13 | seeds = [BondingCurve::SEED_PREFIX.as_bytes(), &token_mint.key().to_bytes()], 14 | bump 15 | )] 16 | bonding_curve: Box>, 17 | 18 | /// CHECK: This is just for getting the mint key 19 | token_mint: UncheckedAccount<'info>, 20 | } 21 | 22 | impl<'info> GetCurveInfo<'info> { 23 | pub fn process(&self) -> Result<()> { 24 | let bonding_curve = &self.bonding_curve; 25 | let global_config = &self.global_config; 26 | 27 | // log curve information for easy access 28 | msg!("Curve Info for token: {}", self.token_mint.key()); 29 | msg!("Virtual Token Reserves: {}", bonding_curve.virtual_token_reserves); 30 | msg!("Virtual SOL Reserves: {}", bonding_curve.virtual_sol_reserves); 31 | msg!("Real Token Reserves: {}", bonding_curve.real_token_reserves); 32 | msg!("Real SOL Reserves: {}", bonding_curve.real_sol_reserves); 33 | msg!("Total Token Supply: {}", bonding_curve.token_total_supply); 34 | msg!("Is Completed: {}", bonding_curve.is_completed); 35 | msg!("Curve Limit: {}", global_config.curve_limit); 36 | msg!("Buy Fee: {}%", global_config.buy_fee_percent); 37 | msg!("Sell Fee: {}%", global_config.sell_fee_percent); 38 | 39 | // calculate and log current price 40 | if let Ok(price) = bonding_curve.get_current_price() { 41 | msg!("Current Token Price: {} lamports", price); 42 | } 43 | 44 | Ok(()) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /front-end/src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | 6 | @layer components { 7 | .container { 8 | @apply w-full mx-auto max-w-[1440px]; 9 | } 10 | } 11 | 12 | /* width */ 13 | ::-webkit-scrollbar { 14 | width: 4px; 15 | height: 4px; 16 | background: #0D1524; 17 | } 18 | 19 | /* Track */ 20 | ::-webkit-scrollbar-track { 21 | background: #0D1524; 22 | border-radius: 5px; 23 | } 24 | 25 | /* Handle */ 26 | ::-webkit-scrollbar-thumb { 27 | background: #2b7ee2; 28 | border-radius: 5px; 29 | } 30 | 31 | /* Hide scrollbar for Chrome, Safari and Opera */ 32 | .no-scrollbar::-webkit-scrollbar { 33 | display: none; 34 | } 35 | 36 | /* Hide scrollbar for IE, Edge and Firefox */ 37 | .no-scrollbar { 38 | -ms-overflow-style: none; 39 | /* IE and Edge */ 40 | scrollbar-width: none; 41 | /* Firefox */ 42 | } 43 | 44 | :root { 45 | --foreground-rgb: 0, 0, 0; 46 | --background-start-rgb: 214, 219, 220; 47 | --background-end-rgb: 255, 255, 255; 48 | } 49 | 50 | @media (prefers-color-scheme: dark) { 51 | :root { 52 | --foreground-rgb: 255, 255, 255; 53 | --background-start-rgb: 0, 0, 0; 54 | --background-end-rgb: 0, 0, 0; 55 | } 56 | } 57 | 58 | body { 59 | color: rgb(var(--foreground-rgb)); 60 | background: #0b192f; 61 | } 62 | 63 | @layer utilities { 64 | .text-balance { 65 | text-wrap: balance; 66 | } 67 | } 68 | 69 | input::-webkit-outer-spin-button, 70 | input::-webkit-inner-spin-button { 71 | /* display: none; <- Crashes Chrome on hover */ 72 | -webkit-appearance: none; 73 | margin: 0; 74 | /* <-- Apparently some margin are still there even though it's hidden */ 75 | } 76 | 77 | input[type="number"] { 78 | -moz-appearance: textfield; 79 | /* Firefox */ 80 | } 81 | 82 | .text-gradient { 83 | background: -webkit-linear-gradient(135deg, #2BBAF7, #0047CA); 84 | -webkit-background-clip: text; 85 | -webkit-text-fill-color: transparent; 86 | } -------------------------------------------------------------------------------- /smart contract/tests/utils.ts: -------------------------------------------------------------------------------- 1 | 2 | import { 3 | PublicKey, 4 | } from "@solana/web3.js"; 5 | 6 | import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from "@solana/spl-token"; 7 | 8 | export const sleep = (ms: number) => { 9 | return new Promise((resolve) => { 10 | setTimeout(resolve, ms); 11 | }); 12 | }; 13 | 14 | export const getAssociatedTokenAccount = ( 15 | ownerPubkey: PublicKey, 16 | mintPk: PublicKey 17 | ): PublicKey => { 18 | let associatedTokenAccountPubkey = (PublicKey.findProgramAddressSync( 19 | [ 20 | ownerPubkey.toBytes(), 21 | TOKEN_PROGRAM_ID.toBytes(), 22 | mintPk.toBytes(), // mint address 23 | ], 24 | ASSOCIATED_TOKEN_PROGRAM_ID 25 | ))[0]; 26 | 27 | return associatedTokenAccountPubkey; 28 | } 29 | 30 | export function convertToFloat(value: number, decimals: number): number { 31 | return value / Math.pow(10, decimals); 32 | } 33 | 34 | export function convertFromFloat(value: number, decimals: number): number { 35 | return value * Math.pow(10, decimals); 36 | } 37 | 38 | export function calculateAmountOutBuy( 39 | reserveLamport: number, 40 | adjustedAmount: number, 41 | tokenOneDecimals: number, 42 | reserveToken: number 43 | ): number { 44 | // Calculate the denominator sum which is (y + dy) 45 | const denominatorSum = reserveLamport + adjustedAmount; 46 | 47 | // Convert to float for division 48 | const denominatorSumFloat = convertToFloat(denominatorSum, tokenOneDecimals); 49 | const adjustedAmountFloat = convertToFloat(adjustedAmount, tokenOneDecimals); 50 | 51 | // (y + dy) / dy 52 | const divAmt = denominatorSumFloat / (adjustedAmountFloat); 53 | 54 | // Convert reserveToken to float with 9 decimals 55 | const reserveTokenFloat = convertToFloat(reserveToken, 9); 56 | 57 | // Calculate dx = xdy / (y + dy) 58 | const amountOutInFloat = reserveTokenFloat / (divAmt); 59 | 60 | // Convert the result back to the original decimal format 61 | const amountOut = convertFromFloat(amountOutInFloat, 9); 62 | 63 | return amountOut; 64 | } -------------------------------------------------------------------------------- /back-end/src/index.ts: -------------------------------------------------------------------------------- 1 | 2 | import express from "express"; 3 | import cors from "cors"; 4 | import bodyParser from "body-parser"; 5 | import "dotenv/config"; 6 | import userRoutes from "./routes/user"; 7 | import coinRoutes from "./routes/coin"; 8 | import messageRoutes from "./routes/feedback"; 9 | import coinTradeRoutes from "./routes/coinTradeRoutes"; 10 | import chartRoutes from "./routes/chart"; 11 | import { init } from "./db/dbConncetion"; 12 | import { io, socketio } from "./sockets"; 13 | import { AgentsLandListener } from "./logListeners/AgentsLandListener"; 14 | import { Connection } from "@solana/web3.js"; 15 | import { 16 | // commitmentLevel, 17 | // endpoint, 18 | listenerForEvents, 19 | // wsEndpoint, 20 | } from "./program/web3"; 21 | import CurveConfig from './models/CurveConfig'; 22 | import curveRoutes from './routes/curveRoutes'; 23 | import { PROGRAM_ID } from "./program/programId"; 24 | 25 | const app = express(); 26 | const port = process.env.PORT || 5000; 27 | 28 | const whitelist = ["http://localhost:3000"]; 29 | 30 | const corsOptions = { 31 | origin: "*", 32 | credentials: false, 33 | sameSite: "none", 34 | }; 35 | 36 | app.use(cors(corsOptions)); 37 | app.use(bodyParser.json()); 38 | app.use(bodyParser.urlencoded({ extended: true })); 39 | 40 | init(); 41 | 42 | app.get("/", async (req, res) => { 43 | res.json("Success!!"); 44 | }); 45 | 46 | app.use('/user/', userRoutes); 47 | app.use('/coin/', coinRoutes); 48 | app.use('/feedback/', messageRoutes); 49 | app.use('/cointrade/', coinTradeRoutes); 50 | app.use('/chart/', chartRoutes); 51 | app.use('/curveConfig/', curveRoutes) 52 | 53 | export const server = app.listen(port, async () => { 54 | console.log(`server is listening on ${port}`); 55 | listenerForEvents(); 56 | // const connection = new Connection(endpoint!, { 57 | // commitment: commitmentLevel, 58 | // wsEndpoint, 59 | // }); 60 | // const agentLandListenr = new AgentsLandListener(connection); 61 | // agentLandListenr.listenProgramEvents(PROGRAM_ID.toString()); 62 | // return; 63 | }); 64 | socketio(server); -------------------------------------------------------------------------------- /smart contract/programs/pump/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | pub mod consts; 4 | pub mod errors; 5 | pub mod instructions; 6 | pub mod states; 7 | pub mod utils; 8 | 9 | use crate::instructions::*; 10 | 11 | declare_id!("Cu3ZCXsVh7xC64gWH23vjDeytWC6ZGcMRVYZAka92QTq"); 12 | 13 | #[program] 14 | pub mod pump { 15 | use super::*; 16 | 17 | // called by admin to set global config 18 | // need to check the signer is authority 19 | pub fn configure(ctx: Context, new_config: states::Config) -> Result<()> { 20 | ctx.accounts.process(new_config) 21 | } 22 | 23 | // called by a creator to launch a token on the platform 24 | pub fn launch<'info>( 25 | ctx: Context<'_, '_, '_, 'info, Launch<'info>>, 26 | 27 | // metadata 28 | name: String, 29 | symbol: String, 30 | uri: String, 31 | ) -> Result<()> { 32 | ctx.accounts 33 | .process(name, symbol, uri, ctx.bumps.global_config) 34 | } 35 | 36 | // called by a user to swap token/sol 37 | pub fn swap<'info>( 38 | ctx: Context<'_, '_, '_, 'info, Swap<'info>>, 39 | amount: u64, 40 | direction: u8, 41 | min_out: u64, 42 | ) -> Result<()> { 43 | ctx.accounts 44 | .process(amount, direction, min_out, ctx.bumps.bonding_curve) 45 | } 46 | 47 | //////////////////// DM if you want full implementation //////////////////// 48 | // telegram - https://t.me/microgift88 49 | // discord - https://discord.com/users/1074514238325927956 50 | 51 | // migrate the token to raydium once a curve reaches the limit 52 | pub fn migrate<'info>( 53 | ctx: Context<'_, '_, '_, 'info, Migrate<'info>>, 54 | nonce: u8, 55 | ) -> Result<()> { 56 | ctx.accounts.process(nonce) 57 | } 58 | 59 | // get curve information (view function) 60 | pub fn get_curve_info<'info>( 61 | ctx: Context<'_, '_, '_, 'info, GetCurveInfo<'info>>, 62 | ) -> Result<()> { 63 | ctx.accounts.process() 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /front-end/src/components/upload/ImageUpload.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | import React, { ChangeEvent, useRef, useState } from "react"; 3 | 4 | interface ImageUploadProps { 5 | header: string; 6 | setFilePreview: (filePreview: string | null) => void; 7 | type: string; 8 | setFileUrl: (fileUrl: string) => void; 9 | } 10 | 11 | const ImageUpload: React.FC = ({ header, setFilePreview, setFileUrl, type }) => { 12 | const fileInputRef = useRef(null); 13 | const [selectedFileName, setSelectedFileName] = useState("No file selected"); 14 | 15 | const handleFileChange = (event: ChangeEvent) => { 16 | const file = event.target.files?.[0]; 17 | if (file) { 18 | setSelectedFileName(file.name); 19 | setFilePreview(URL.createObjectURL(file)); // Pass the file name or URL to the parent 20 | setFileUrl(URL.createObjectURL(file)) 21 | } else { 22 | setSelectedFileName("No file selected"); 23 | setFilePreview(null); 24 | setFileUrl(null) 25 | } 26 | }; 27 | 28 | return ( 29 |
30 |
31 | 32 | 39 |
40 |
41 | {selectedFileName} 42 |
43 | 49 |
50 |
51 |
52 | ); 53 | }; 54 | 55 | export default ImageUpload; -------------------------------------------------------------------------------- /front-end/src/components/select/SellTaxRange.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | import * as React from "react"; 3 | import { Range } from "react-range"; 4 | import { BiSolidUpArrow } from "react-icons/bi"; 5 | 6 | interface SellTaxRangeProps { 7 | header: string; 8 | setSelectRange: (tokenNumber: number[]) => void; 9 | } 10 | 11 | const SellTaxRange: React.FC = ({ header, setSelectRange }) => { 12 | const [values, setValues] = React.useState([20, 80]); // Two values for min and max 13 | 14 | const handleChangeRange = (e: number[]) => { 15 | setValues(e) 16 | setSelectRange(e) 17 | } 18 | 19 | return ( 20 |
21 | 24 | handleChangeRange(values)} 30 | renderTrack={({ props, children }) => { 31 | const [min, max] = values; 32 | 33 | return ( 34 |
38 |
47 | {children} 48 |
49 | ); 50 | }} 51 | renderThumb={({ props, index }) => ( 52 |
56 |
57 | {index === 0 ? `${values[0]}%` : `${values[1]}%`} 58 |
59 | 63 |
64 | )} 65 | /> 66 |
67 | ); 68 | }; 69 | 70 | export default SellTaxRange; 71 | -------------------------------------------------------------------------------- /smart contract/programs/pump/src/instructions/configure.rs: -------------------------------------------------------------------------------- 1 | use crate::{errors::PumpError, states::Config, consts::{MAX_FEE_PERCENT, MIN_CURVE_LIMIT, MAX_CURVE_LIMIT}}; 2 | use anchor_lang::{prelude::*, system_program}; 3 | 4 | #[derive(Accounts)] 5 | pub struct Configure<'info> { 6 | #[account(mut)] 7 | admin: Signer<'info>, 8 | 9 | #[account( 10 | init_if_needed, 11 | payer = admin, 12 | seeds = [Config::SEED_PREFIX.as_bytes()], 13 | space = 8 + Config::LEN, 14 | bump, 15 | )] 16 | global_config: Account<'info, Config>, 17 | 18 | #[account(address = system_program::ID)] 19 | system_program: Program<'info, System>, 20 | } 21 | 22 | impl<'info> Configure<'info> { 23 | pub fn process(&mut self, new_config: Config) -> Result<()> { 24 | require!(self.global_config.authority.eq(&Pubkey::default()) 25 | || self.global_config.authority.eq(&self.admin.key()), PumpError::NotAuthorized); 26 | 27 | // validate configuration parameters 28 | require!( 29 | new_config.buy_fee_percent >= 0.0 && new_config.buy_fee_percent <= MAX_FEE_PERCENT, 30 | PumpError::IncorrectValue 31 | ); 32 | require!( 33 | new_config.sell_fee_percent >= 0.0 && new_config.sell_fee_percent <= MAX_FEE_PERCENT, 34 | PumpError::IncorrectValue 35 | ); 36 | require!( 37 | new_config.migration_fee_percent >= 0.0 && new_config.migration_fee_percent <= MAX_FEE_PERCENT, 38 | PumpError::IncorrectValue 39 | ); 40 | require!( 41 | new_config.curve_limit >= MIN_CURVE_LIMIT && new_config.curve_limit <= MAX_CURVE_LIMIT, 42 | PumpError::IncorrectValue 43 | ); 44 | require!( 45 | new_config.initial_virtual_token_reserves > 0, 46 | PumpError::IncorrectValue 47 | ); 48 | require!( 49 | new_config.initial_virtual_sol_reserves > 0, 50 | PumpError::IncorrectValue 51 | ); 52 | require!( 53 | new_config.total_token_supply > 0, 54 | PumpError::IncorrectValue 55 | ); 56 | 57 | self.global_config.set_inner(new_config); 58 | 59 | Ok(()) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /smart contract/programs/pump/src/utils/transfer.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::{ 2 | prelude::*, 3 | solana_program::{ 4 | program::{invoke, invoke_signed}, 5 | system_instruction::transfer, 6 | }, 7 | }; 8 | use anchor_spl::token; 9 | 10 | // transfer sol from user 11 | pub fn sol_transfer_from_user<'info>( 12 | signer: &Signer<'info>, 13 | destination: &AccountInfo<'info>, 14 | system_program: &AccountInfo<'info>, 15 | amount: u64, 16 | ) -> Result<()> { 17 | let ix = transfer(signer.key, destination.key, amount); 18 | invoke( 19 | &ix, 20 | &[ 21 | signer.to_account_info(), 22 | destination.to_account_info(), 23 | system_program.to_account_info(), 24 | ], 25 | )?; 26 | 27 | Ok(()) 28 | } 29 | 30 | // transfer sol from PDA 31 | pub fn sol_transfer_with_signer<'info>( 32 | source: &AccountInfo<'info>, 33 | destination: &AccountInfo<'info>, 34 | system_program: &AccountInfo<'info>, 35 | signers_seeds: &[&[&[u8]]], 36 | amount: u64, 37 | ) -> Result<()> { 38 | let ix = transfer(source.key, destination.key, amount); 39 | invoke_signed( 40 | &ix, 41 | &[ 42 | source.to_account_info(), 43 | destination.to_account_info(), 44 | system_program.to_account_info(), 45 | ], 46 | signers_seeds, 47 | )?; 48 | 49 | Ok(()) 50 | } 51 | 52 | // transfer token from user 53 | pub fn token_transfer_user<'info>( 54 | from: &AccountInfo<'info>, 55 | authority: &AccountInfo<'info>, 56 | to: &AccountInfo<'info>, 57 | token_program: &AccountInfo<'info>, 58 | amount: u64, 59 | ) -> Result<()> { 60 | let cpi_ctx: CpiContext<_> = CpiContext::new( 61 | token_program.to_account_info(), 62 | token::Transfer { 63 | from: from.to_account_info(), 64 | authority: authority.to_account_info(), 65 | to: to.to_account_info(), 66 | }, 67 | ); 68 | token::transfer(cpi_ctx, amount)?; 69 | 70 | Ok(()) 71 | } 72 | 73 | // transfer token from PDA 74 | pub fn token_transfer_with_signer<'info>( 75 | from: &AccountInfo<'info>, 76 | authority: &AccountInfo<'info>, 77 | to: &AccountInfo<'info>, 78 | token_program: &AccountInfo<'info>, 79 | signer_seeds: &[&[&[u8]]], 80 | amount: u64, 81 | ) -> Result<()> { 82 | let cpi_ctx: CpiContext<_> = CpiContext::new_with_signer( 83 | token_program.to_account_info(), 84 | token::Transfer { 85 | from: from.to_account_info(), 86 | authority: authority.to_account_info(), 87 | to: to.to_account_info(), 88 | }, 89 | signer_seeds, 90 | ); 91 | token::transfer(cpi_ctx, amount)?; 92 | 93 | Ok(()) 94 | } 95 | -------------------------------------------------------------------------------- /smart contract/cli/command.ts: -------------------------------------------------------------------------------- 1 | import { program } from 'commander'; 2 | import { PublicKey } from '@solana/web3.js'; 3 | import { configProject, launchToken, migrate, setClusterConfig, swap, withdraw } from './scripts'; 4 | 5 | program.version('0.0.1'); 6 | 7 | programCommand('config').action(async (directory, cmd) => { 8 | const { env, keypair, rpc } = cmd.opts(); 9 | 10 | await setClusterConfig(env, keypair, rpc); 11 | 12 | await configProject(); 13 | }); 14 | 15 | programCommand('launch').action(async (directory, cmd) => { 16 | const { env, keypair, rpc } = cmd.opts(); 17 | 18 | await setClusterConfig(env, keypair, rpc); 19 | 20 | await launchToken(); 21 | }); 22 | 23 | programCommand('swap') 24 | .option('-t, --token ', 'token address') 25 | .option('-a, --amount ', 'swap amount') 26 | .option('-s, --style ', '0: buy token, 1: sell token') 27 | .action(async (directory, cmd) => { 28 | const { env, keypair, rpc, token, amount, style } = cmd.opts(); 29 | 30 | await setClusterConfig(env, keypair, rpc); 31 | 32 | if (token === undefined) { 33 | console.log('Error token address'); 34 | return; 35 | } 36 | 37 | if (amount === undefined) { 38 | console.log('Error swap amount'); 39 | return; 40 | } 41 | 42 | if (style === undefined) { 43 | console.log('Error swap style'); 44 | return; 45 | } 46 | 47 | await swap(new PublicKey(token), amount, style); 48 | }); 49 | 50 | programCommand('migrate') 51 | .option('-t, --token ', 'token address') 52 | .action(async (directory, cmd) => { 53 | const { env, keypair, rpc, token } = cmd.opts(); 54 | 55 | await setClusterConfig(env, keypair, rpc); 56 | 57 | if (token === undefined) { 58 | console.log('Error token address'); 59 | return; 60 | } 61 | 62 | await migrate(new PublicKey(token)); 63 | }); 64 | 65 | programCommand('withdraw') 66 | .option('-t, --token ', 'token address') 67 | .action(async (directory, cmd) => { 68 | const { env, keypair, rpc, token } = cmd.opts(); 69 | 70 | await setClusterConfig(env, keypair, rpc); 71 | 72 | if (token === undefined) { 73 | console.log('Error token address'); 74 | return; 75 | } 76 | 77 | await withdraw(new PublicKey(token)); 78 | }); 79 | 80 | function programCommand(name: string) { 81 | return program 82 | .command(name) 83 | .option( 84 | // mainnet-beta, testnet, devnet 85 | '-e, --env ', 86 | 'Solana cluster env name', 87 | 'devnet' 88 | ) 89 | .option('-r, --rpc ', 'Solana cluster RPC name', 'https://api.devnet.solana.com') 90 | .option('-k, --keypair ', 'Solana wallet Keypair Path', '../key/uu.json'); 91 | } 92 | 93 | program.parse(process.argv); 94 | -------------------------------------------------------------------------------- /front-end/src/provider/providers.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import React, { ReactNode, useState } from "react"; 3 | import { PageProvider } from "@/contexts/PageContext"; 4 | import { SolanaWalletProvider } from "@/contexts/SolanaWalletProvider"; 5 | import { QueryClientProvider, QueryClient } from "react-query"; 6 | import { ToastContainer } from "react-toastify"; 7 | import { ModalProvider } from "@/contexts/ModalProvider"; 8 | import UserContext from "@/context/UserContext"; 9 | import { msgInfo, userInfo } from "@/utils/types"; 10 | import "dotenv/config.js"; 11 | import LoginContext from "@/context/CoinContex"; 12 | import { useWallet } from "@solana/wallet-adapter-react"; 13 | import SocketProvider from "@/contexts/SocketContext"; 14 | 15 | export const queryClient = new QueryClient(); 16 | 17 | export default function Providers({ children }: { children: ReactNode }) { 18 | const wallet = useWallet(); 19 | const [user, setUser] = useState({} as userInfo); 20 | const [login, setLogin] = useState(false); 21 | const [isLoading, setIsLoading] = useState(false); 22 | const [imageUrl, setImageUrl] = useState('/*.png'); 23 | const [isCreated, setIsCreated] = useState(false); 24 | const [messages, setMessages] = useState([]); 25 | const [coinId, setCoinId] = useState(''); 26 | const [newMsg, setNewMsg] = useState({} as msgInfo); 27 | const [solPrice, setSolPrice] = useState(0); 28 | const [profileEditModal, setProfileEditModal] = useState(false); 29 | const [postReplyModal, setPostReplyModal] = useState(false); 30 | 31 | return ( 32 | 33 | 34 | 35 | 36 | 62 | 63 | {children} 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | ); 72 | } 73 | -------------------------------------------------------------------------------- /smart contract/README.md: -------------------------------------------------------------------------------- 1 | # 🧠 Pump.fun Smart Contract – Solana/Anchor Based 2 | 3 | A powerful and customizable smart contract built for **token launches** and **liquidity management** on Solana. 4 | 5 | > **Need custom token launch logic or integrations?** 6 | > Reach out: 7 | > Telegram: [@topsecretagent_007](https://t.me/topsecretagent_007) 8 | > Twitter: [@lendon1114](https://x.com/lendon1114) 9 | 10 | --- 11 | 12 | ## 🚀 Features 13 | 14 | - **Fully on-chain logic** 15 | Token creation and Raydium deposits are handled entirely on-chain. 16 | 17 | - **Presale/Sniping Support** 18 | Enable a `Presale` phase before launch to support early snipers and initial price discovery. 19 | 20 | - **Raydium & Meteora Migration** 21 | Migrate token liquidity to Raydium or Meteora after curve completion with a single instruction. 22 | 23 | - **Market Cap Oracle Integration** 24 | Set a curve limit and use price oracles to calculate market cap in real-time during swaps. 25 | 26 | --- 27 | 28 | ## ⚙️ Prerequisites 29 | 30 | Ensure the following tools are installed on your system: 31 | 32 | ### Rust / Solana / Anchor Setup 33 | 34 | 📦 **Install Instructions**: [anchor-lang.com/docs/installation](https://anchor-lang.com/docs/installation) 35 | 36 | ```bash 37 | # Check versions 38 | rustc --version # Rust 39 | solana --version # Solana CLI 40 | anchor --version # Anchor (should be 0.30.1) 41 | 42 | # Set RPC 43 | solana config set --url devnet 44 | 45 | # Check balance and wallet 46 | solana config get 47 | solana balance 48 | 49 | # Create a new keypair if needed 50 | solana-keygen new 51 | 52 | # Airdrop some test SOL (devnet) 53 | solana airdrop 5 54 | ``` 55 | 56 | ## 📂 Project Setup 57 | ```bash 58 | # Clone the repo 59 | git clone https://github.com/your-username/pumpfun-contract.git 60 | cd pumpfun-contract 61 | 62 | # Install dependencies 63 | yarn 64 | ``` 65 | 66 | --- 67 | 68 | ## 🛠️ Build & Deploy 69 | 70 | ### Build the Program 71 | ```bash 72 | # Build the Anchor program 73 | anchor build 74 | 75 | # Sync keypairs if needed 76 | anchor keys sync 77 | 78 | # After editing `lib.rs` (e.g., changing the program address), rebuild 79 | anchor build 80 | ``` 81 | 82 | --- 83 | 84 | ## Test Locally with Anchor 85 | 86 | In `Anchor.toml`, set: 87 | ``` toml 88 | [provider] 89 | cluster = "Localnet" 90 | ``` 91 | 92 | Then run: 93 | ```bash 94 | anchor test --provider.cluster Localnet 95 | ``` 96 | 97 | --- 98 | 99 | ## Deploy to Devnet 100 | 101 | In `Anchor.toml`: 102 | ```toml 103 | [provider] 104 | cluster = "https://api.devnet.solana.com" 105 | ``` 106 | 107 | Deploy: 108 | ```bash 109 | anchor deploy 110 | ``` 111 | 112 | ## 🧪 CLI Usage 113 | 114 | Use CLI scripts to interact with the deployed smart contract. 115 | 116 | ### 1. Initialize Configuration 117 | ```bash 118 | yarn script config 119 | ``` 120 | 121 | ### 2. Launch a Token 122 | ```bash 123 | yarn script launch 124 | ``` 125 | 126 | ### 3. Swap SOL for Token 127 | ```bash 128 | yarn script swap -t -a -s 129 | 130 | # -t: Token mint address 131 | # -a: Amount to swap 132 | # -s: Direction (0 = Buy, 1 = Sell) 133 | ``` 134 | 135 | ### 4. Migrate to Raydium 136 | ```bash 137 | yarn script migrate -t 138 | 139 | # -t: Token mint address to migrate 140 | ``` 141 | 142 | --- 143 | 144 | ## 🧑‍💻 Contact 145 | 146 | For paid development or integration work, feel free to reach out: 147 | 148 | - Telegram: [@topsecretagent_007](https://t.me/topsecretagent_007) 149 | - Twitter: [@lendon1114](https://x.com/lendon1114) 150 | 151 | Let me know if you also want to include badges (e.g., build passing, devnet status), visuals like demo GIFs, or links to example tokens deployed with this contract! 152 | 153 | -------------------------------------------------------------------------------- /smart contract/programs/pump/src/instructions/swap.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | errors::PumpError, states::{BondingCurve, Config} 3 | }; 4 | use anchor_lang::{prelude::*, system_program}; 5 | use anchor_spl::{ 6 | associated_token::{self, AssociatedToken}, 7 | token::{self, Mint, Token, TokenAccount}, 8 | }; 9 | 10 | #[derive(Accounts)] 11 | pub struct Swap<'info> { 12 | #[account(mut)] 13 | user: Signer<'info>, 14 | #[account( 15 | seeds = [Config::SEED_PREFIX.as_bytes()], 16 | bump, 17 | )] 18 | global_config: Box>, 19 | /// CHECK: should be same with the address in the global_config 20 | #[account( 21 | mut, 22 | constraint = global_config.fee_recipient == fee_recipient.key() @PumpError::IncorrectFeeRecipient 23 | )] 24 | fee_recipient: AccountInfo<'info>, 25 | #[account( 26 | mut, 27 | seeds = [BondingCurve::SEED_PREFIX.as_bytes(), &token_mint.key().to_bytes()], 28 | bump 29 | )] 30 | bonding_curve: Box>, 31 | 32 | token_mint: Box>, 33 | #[account( 34 | mut, 35 | associated_token::mint = token_mint, 36 | associated_token::authority = bonding_curve 37 | )] 38 | curve_token_account: Box>, 39 | #[account( 40 | init_if_needed, 41 | payer = user, 42 | associated_token::mint = token_mint, 43 | associated_token::authority = user 44 | )] 45 | user_token_account: Box>, 46 | 47 | #[account(address = token::ID)] 48 | token_program: Program<'info, Token>, 49 | #[account(address = associated_token::ID)] 50 | associated_token_program: Program<'info, AssociatedToken>, 51 | #[account(address = system_program::ID)] 52 | system_program: Program<'info, System>, 53 | } 54 | 55 | impl<'info> Swap<'info> { 56 | pub fn process( 57 | &mut self, 58 | 59 | amount: u64, 60 | direction: u8, 61 | min_out: u64, 62 | 63 | bump_bonding_curve: u8, 64 | ) -> Result<()> { 65 | let bonding_curve = &mut self.bonding_curve; 66 | 67 | // check curve is not completed 68 | require!( 69 | bonding_curve.is_completed == false, 70 | PumpError::CurveAlreadyCompleted 71 | ); 72 | 73 | let curve_pda = &mut bonding_curve.to_account_info(); 74 | let global_config: &Box> = &self.global_config; 75 | 76 | if direction == 0 { 77 | // buy - swap sol for token 78 | bonding_curve.buy( 79 | &self.token_mint, 80 | global_config.curve_limit, 81 | &self.user, 82 | curve_pda, 83 | &mut self.fee_recipient, 84 | &mut self.user_token_account.to_account_info(), 85 | &mut self.curve_token_account.to_account_info(), 86 | amount, 87 | min_out, 88 | global_config.buy_fee_percent, 89 | bump_bonding_curve, 90 | &self.system_program.to_account_info(), 91 | &self.token_program.to_account_info() 92 | )?; 93 | } else if direction == 1 { 94 | // sell - swap token for sol 95 | bonding_curve.sell( 96 | &self.token_mint, 97 | &self.user, 98 | curve_pda, 99 | &mut self.fee_recipient, 100 | &mut self.user_token_account.to_account_info(), 101 | &mut self.curve_token_account.to_account_info(), 102 | amount, 103 | min_out, 104 | global_config.sell_fee_percent, 105 | bump_bonding_curve, 106 | &self.system_program.to_account_info(), 107 | &self.token_program.to_account_info() 108 | )?; 109 | } 110 | 111 | Ok(()) 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /front-end/src/components/home/FilterList.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import { FC, useContext, useState } from "react"; 3 | import Image from "next/image"; 4 | import { useRouter, useSearchParams } from "next/navigation"; 5 | import UserContext from "@/context/UserContext"; 6 | import TimeTranding from "../buttons/TimeTranding"; 7 | import { CiFilter } from "react-icons/ci"; 8 | import switchOn from "@/../public/assets/images/switch-on.png"; 9 | import switchOff from "@/../public/assets/images/switch-off.png"; 10 | import { BiSearchAlt } from "react-icons/bi"; 11 | import { coinInfo } from "@/utils/types"; 12 | import FilterListButton from "../others/FilterListButton"; 13 | 14 | const FilterList: FC = () => { 15 | // const { 16 | // filterState, 17 | // setFilterState, 18 | // nsfwFilterState, 19 | // setNsfwFilterState, 20 | // } = useContext(UserContext); 21 | 22 | const [filterState, setFilterState] = useState(false) 23 | const [nsfwFilterState, setNsfwFilterState] = useState(false) 24 | 25 | const [token, setToken] = useState(""); 26 | 27 | 28 | 29 | const searchToken = () => { }; 30 | 31 | return ( 32 |
33 |
34 | 35 | 36 |
37 |
38 |
39 |
setFilterState(false)} 41 | className={`border-b-[2px] px-4 py-1 text-base cursor-pointer ${filterState ? "border-b-[#143F72]" : "border-b-[#64ffda]" 42 | }`} 43 | > 44 | Following 45 |
46 |
setFilterState(true)} 48 | className={`border-b-[2px] px-4 py-1 text-base cursor-pointer ${filterState ? "border-b-[#64ffda]" : "border-b-[#143F72]" 49 | }`} 50 | > 51 | Terminal 52 |
53 |
54 |
55 |
56 | Include NSFW 57 | { setNsfwFilterState(!nsfwFilterState)} 61 | className="cursor-pointer" 62 | />} 63 |
64 |
65 | 66 | setToken(e.target.value)} 71 | className=" bg-grey-400 w-full py-1 outline-none bg-transparent" 72 | /> 73 | 79 |
80 |
81 |
82 |
setFilterState(false)} 84 | className={`border-b-[2px] px-4 py-1 text-base cursor-pointer ${filterState ? "border-b-[#143F72]" : "border-b-[#2C8DFE]" 85 | }`} 86 | > 87 | Following 88 |
89 |
setFilterState(true)} 91 | className={`border-b-[2px] px-4 py-1 text-base cursor-pointer ${filterState ? "border-b-[#2C8DFE]" : "border-b-[#143F72]" 92 | }`} 93 | > 94 | Terminal 95 |
96 |
97 |
98 |
99 | ); 100 | }; 101 | 102 | export default FilterList; 103 | -------------------------------------------------------------------------------- /smart contract/cli/scripts.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@coral-xyz/anchor"; 2 | import { BN, Program, web3 } from "@coral-xyz/anchor"; 3 | import fs from "fs"; 4 | 5 | import { Keypair, Connection, PublicKey } from "@solana/web3.js"; 6 | 7 | import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet"; 8 | 9 | import { Pumpfun } from "../target/types/pumpfun"; 10 | import { 11 | createConfigTx, 12 | launchTokenTx, 13 | migrateTx, 14 | swapTx, 15 | withdrawTx, 16 | } from "../lib/scripts"; 17 | import { execTx } from "../lib/util"; 18 | import { 19 | TEST_DECIMALS, 20 | TEST_INIT_BONDING_CURVE, 21 | TEST_NAME, 22 | TEST_SYMBOL, 23 | TEST_TOKEN_SUPPLY, 24 | TEST_URI, 25 | TEST_VIRTUAL_RESERVES, 26 | } from "../lib/constant"; 27 | import { createMarket } from "../lib/create-market"; 28 | 29 | let solConnection: Connection = null; 30 | let program: Program = null; 31 | let payer: NodeWallet = null; 32 | 33 | /** 34 | * Set cluster, provider, program 35 | * If rpc != null use rpc, otherwise use cluster param 36 | * @param cluster - cluster ex. mainnet-beta, devnet ... 37 | * @param keypair - wallet keypair 38 | * @param rpc - rpc 39 | */ 40 | export const setClusterConfig = async ( 41 | cluster: web3.Cluster, 42 | keypair: string, 43 | rpc?: string 44 | ) => { 45 | if (!rpc) { 46 | solConnection = new web3.Connection(web3.clusterApiUrl(cluster)); 47 | } else { 48 | solConnection = new web3.Connection(rpc); 49 | } 50 | 51 | const walletKeypair = Keypair.fromSecretKey( 52 | Uint8Array.from(JSON.parse(fs.readFileSync(keypair, "utf-8"))), 53 | { skipValidation: true } 54 | ); 55 | payer = new NodeWallet(walletKeypair); 56 | 57 | console.log("Wallet Address: ", payer.publicKey.toBase58()); 58 | 59 | anchor.setProvider( 60 | new anchor.AnchorProvider(solConnection, payer, { 61 | skipPreflight: true, 62 | commitment: "confirmed", 63 | }) 64 | ); 65 | 66 | // Generate the program client from IDL. 67 | program = anchor.workspace.Pumpfun as Program; 68 | 69 | console.log("ProgramId: ", program.programId.toBase58()); 70 | }; 71 | 72 | export const configProject = async () => { 73 | // Create a dummy config object to pass as argument. 74 | const newConfig = { 75 | authority: payer.publicKey, 76 | pendingAuthority: PublicKey.default, 77 | 78 | teamWallet: payer.publicKey, 79 | 80 | initBondingCurve: TEST_INIT_BONDING_CURVE, 81 | platformBuyFee: 0.5, // Example fee: 5% 82 | platformSellFee: 0.5, // Example fee: 5% 83 | platformMigrationFee: 0.5, // Example fee: 5% 84 | 85 | curveLimit: new BN(6_000_000_000), // Example limit: 6 SOL 86 | 87 | lamportAmountConfig: new BN(TEST_VIRTUAL_RESERVES), 88 | tokenSupplyConfig: new BN(TEST_TOKEN_SUPPLY), 89 | tokenDecimalsConfig: new BN(TEST_DECIMALS), 90 | }; 91 | 92 | const tx = await createConfigTx( 93 | payer.publicKey, 94 | newConfig, 95 | solConnection, 96 | program 97 | ); 98 | 99 | await execTx(tx, solConnection, payer); 100 | }; 101 | 102 | export const launchToken = async () => { 103 | const tx = await launchTokenTx( 104 | // metadata 105 | TEST_NAME, 106 | TEST_SYMBOL, 107 | TEST_URI, 108 | 109 | payer.publicKey, 110 | 111 | solConnection, 112 | program 113 | ); 114 | 115 | await execTx(tx, solConnection, payer); 116 | }; 117 | 118 | export const swap = async ( 119 | token: PublicKey, 120 | 121 | amount: number, 122 | style: number 123 | ) => { 124 | const tx = await swapTx( 125 | payer.publicKey, 126 | token, 127 | amount, 128 | style, 129 | solConnection, 130 | program 131 | ); 132 | 133 | await execTx(tx, solConnection, payer); 134 | }; 135 | 136 | export const migrate = async (token: PublicKey) => { 137 | const market = await createMarket(payer, token, solConnection); 138 | // const market = new PublicKey("8GrKmcQ6rhCNVW4FoKKVLUayduiuNsf9gJ9G1VN4UEEH"); 139 | 140 | const tx = await migrateTx( 141 | payer.publicKey, 142 | token, 143 | market, 144 | solConnection, 145 | program 146 | ); 147 | 148 | await execTx(tx, solConnection, payer); 149 | }; 150 | 151 | export const withdraw = async (token: PublicKey) => { 152 | const tx = await withdrawTx(payer.publicKey, token, solConnection, program); 153 | 154 | await execTx(tx, solConnection, payer); 155 | }; 156 | -------------------------------------------------------------------------------- /front-end/src/components/trading/Chatting.tsx: -------------------------------------------------------------------------------- 1 | import { coinInfo, tradeInfo } from "@/utils/types"; 2 | import { MessageForm } from "../MessageForm"; 3 | import { ChangeEvent, useContext, useEffect, useMemo, useState } from "react"; 4 | import { Trade } from "./Trade"; 5 | import { getCoinTrade, getMessageByCoin } from "@/utils/util"; 6 | import UserContext from "@/context/UserContext"; 7 | import ReplyModal from "../modals/ReplyModal"; 8 | import { BiSort } from "react-icons/bi"; 9 | 10 | interface ChattingProps { 11 | param: string | null; 12 | coin: coinInfo 13 | } 14 | 15 | export const Chatting: React.FC = ({ param, coin }) => { 16 | const { messages, setMessages, newMsg, coinId, postReplyModal, setPostReplyModal } = useContext(UserContext); 17 | const [trades, setTrades] = useState({} as tradeInfo); 18 | const [currentTable, setCurrentTable] = useState("thread"); 19 | const tempNewMsg = useMemo(() => newMsg, [newMsg]); 20 | 21 | useEffect(() => { 22 | const fetchData = async () => { 23 | if (param) { 24 | if (currentTable === "thread") { 25 | const data = await getCoinTrade(param); 26 | setTrades(data) 27 | } else if (currentTable === "transaction") { 28 | const data = await getMessageByCoin(param); 29 | setMessages(data); 30 | } else { 31 | const data = await getMessageByCoin(param); 32 | setMessages(data); 33 | } 34 | } 35 | } 36 | fetchData(); 37 | }, [currentTable, param]) 38 | 39 | useEffect(() => { 40 | if (coinId == coin._id) { 41 | setMessages([...messages, tempNewMsg]) 42 | } 43 | }, [tempNewMsg]) 44 | 45 | return ( 46 |
47 |
48 |
setCurrentTable("thread")} 50 | className={`border-b-[2px] px-4 py-1 text-base cursor-pointer ${currentTable === "thread" ? "border-b-[#64ffda]" : "border-b-[#143F72]" 51 | }`} 52 | > 53 | Thread 54 |
55 |
setCurrentTable("transaction")} 57 | className={`border-b-[2px] px-4 py-1 text-base cursor-pointer ${currentTable === "transaction" ? "border-b-[#64ffda]" : "border-b-[#143F72]" 58 | }`} 59 | > 60 | Transaction 61 |
62 |
setCurrentTable("top holders")} 64 | className={`border-b-[2px] px-4 py-1 text-base cursor-pointer ${currentTable === "top holders" ? "border-b-[#64ffda]" : "border-b-[#143F72]" 65 | }`} 66 | > 67 | Top Holders 68 |
69 |
70 |
71 | {currentTable ? (coin && 72 |
73 | {messages && messages.map((message, index) => ( 74 | 75 | ))} 76 |
setPostReplyModal(true)} className="w-[200px] flex flex-col justify-center text-center font-semibold bg-custom-gradient rounded-full px-8 py-2 text-xl cursor-pointer text-white mx-auto">Post Reply
77 |
78 | ) : ( 79 |
80 | 81 | 82 | 83 | 84 | 85 | 89 | 90 | 91 | 92 | 93 | 94 | {trades.record && trades.record.map((trade, index) => ( 95 | 96 | ))} 97 | 98 |
AccountType 86 | SOL 87 | 88 | DateTransaction
99 |
100 | )} 101 | {postReplyModal && 102 | 103 | } 104 |
105 |
106 | ); 107 | }; 108 | -------------------------------------------------------------------------------- /smart contract/lib/scripts.ts: -------------------------------------------------------------------------------- 1 | import { BN, Program } from "@coral-xyz/anchor"; 2 | import { 3 | ComputeBudgetProgram, 4 | Connection, 5 | Keypair, 6 | PublicKey, 7 | SystemProgram, 8 | SYSVAR_RENT_PUBKEY, 9 | Transaction, 10 | } from "@solana/web3.js"; 11 | 12 | import { Pumpfun } from "../target/types/pumpfun"; 13 | import { 14 | ammProgram, 15 | feeDestination, 16 | marketProgram, 17 | SEED_BONDING_CURVE, 18 | SEED_CONFIG, 19 | } from "./constant"; 20 | import { 21 | ASSOCIATED_TOKEN_PROGRAM_ID, 22 | NATIVE_MINT, 23 | TOKEN_PROGRAM_ID, 24 | } from "@solana/spl-token"; 25 | 26 | export const createConfigTx = async ( 27 | admin: PublicKey, 28 | 29 | newConfig: any, 30 | 31 | connection: Connection, 32 | program: Program 33 | ) => { 34 | const [configPda, _] = PublicKey.findProgramAddressSync( 35 | [Buffer.from(SEED_CONFIG)], 36 | program.programId 37 | ); 38 | 39 | console.log("configPda: ", configPda.toBase58()); 40 | 41 | const tx = await program.methods 42 | .configure(newConfig) 43 | .accounts({ 44 | payer: admin, 45 | }) 46 | .transaction(); 47 | 48 | tx.feePayer = admin; 49 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; 50 | 51 | return tx; 52 | }; 53 | 54 | export const launchTokenTx = async ( 55 | name: string, 56 | symbol: string, 57 | uri: string, 58 | 59 | user: PublicKey, 60 | 61 | connection: Connection, 62 | program: Program 63 | ) => { 64 | const tokenKp = Keypair.generate(); 65 | 66 | console.log("token address: ", tokenKp.publicKey.toBase58()); 67 | 68 | // Send the transaction to launch a token 69 | const tx = await program.methods 70 | .launch( 71 | // metadata 72 | name, 73 | symbol, 74 | uri 75 | ) 76 | .accounts({ 77 | creator: user, 78 | token: tokenKp.publicKey, 79 | teamWallet: user, 80 | }) 81 | .transaction(); 82 | 83 | tx.feePayer = user; 84 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; 85 | 86 | tx.sign(tokenKp); 87 | 88 | return tx; 89 | }; 90 | 91 | export const swapTx = async ( 92 | user: PublicKey, 93 | token: PublicKey, 94 | 95 | amount: number, 96 | style: number, 97 | 98 | connection: Connection, 99 | program: Program 100 | ) => { 101 | const [configPda, _] = PublicKey.findProgramAddressSync( 102 | [Buffer.from(SEED_CONFIG)], 103 | program.programId 104 | ); 105 | const configAccount = await program.account.config.fetch(configPda); 106 | 107 | const tx = await program.methods 108 | .swap(new BN(amount), style, new BN(amount)) 109 | .accounts({ 110 | teamWallet: configAccount.teamWallet, 111 | user, 112 | tokenMint: token, 113 | }) 114 | .transaction(); 115 | 116 | tx.feePayer = user; 117 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; 118 | 119 | return tx; 120 | }; 121 | 122 | export const withdrawTx = async ( 123 | user: PublicKey, 124 | token: PublicKey, 125 | 126 | connection: Connection, 127 | program: Program 128 | ) => { 129 | const [configPda, _] = PublicKey.findProgramAddressSync( 130 | [Buffer.from(SEED_CONFIG)], 131 | program.programId 132 | ); 133 | const configAccount = await program.account.config.fetch(configPda); 134 | console.log(token); 135 | const tx = await program.methods 136 | .withdraw() 137 | .accounts({ 138 | tokenMint: token, 139 | }) 140 | .transaction(); 141 | 142 | tx.feePayer = user; 143 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; 144 | 145 | return tx; 146 | }; 147 | 148 | export const migrateTx = async ( 149 | payer: PublicKey, 150 | token: PublicKey, 151 | market: PublicKey, 152 | 153 | connection: Connection, 154 | program: Program 155 | ) => { 156 | const configPda = PublicKey.findProgramAddressSync( 157 | [Buffer.from(SEED_CONFIG)], 158 | program.programId 159 | )[0]; 160 | const configAccount = await program.account.config.fetch(configPda); 161 | 162 | const nonce = PublicKey.findProgramAddressSync( 163 | [Buffer.from("amm authority")], 164 | ammProgram 165 | )[1]; 166 | 167 | console.log("nonce: ", nonce); 168 | 169 | const bondingCurve = PublicKey.findProgramAddressSync( 170 | [Buffer.from(SEED_BONDING_CURVE), token.toBytes()], 171 | program.programId 172 | )[0]; 173 | console.log("bondingCurve: ", bondingCurve.toBase58()); 174 | 175 | const globalVault = PublicKey.findProgramAddressSync( 176 | [Buffer.from("global")], 177 | program.programId 178 | )[0]; 179 | console.log("globalVault: ", globalVault.toBase58()); 180 | 181 | const tx = new Transaction() 182 | .add(ComputeBudgetProgram.setComputeUnitLimit({ units: 500_000 })) 183 | .add( 184 | await program.methods 185 | .migrate(nonce) 186 | .accounts({ 187 | teamWallet: configAccount.teamWallet, 188 | ammProgram, 189 | coinMint: token, 190 | pcMint: NATIVE_MINT, 191 | market, 192 | marketProgram, 193 | payer, 194 | feeDestination 195 | }) 196 | .transaction() 197 | ); 198 | 199 | tx.feePayer = payer; 200 | tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; 201 | 202 | return tx; 203 | }; 204 | -------------------------------------------------------------------------------- /front-end/src/components/buttons/ConnectButton.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import { FC, useContext, useEffect, useMemo, useState } from "react"; 3 | import { useWallet } from "@solana/wallet-adapter-react"; 4 | import { useWalletModal } from "@solana/wallet-adapter-react-ui"; 5 | import { successAlert, errorAlert, infoAlert } from "@/components/others/ToastGroup"; 6 | import base58 from "bs58"; 7 | import UserContext from "@/context/UserContext"; 8 | import { confirmWallet, walletConnect } from "@/utils/util"; 9 | import { userInfo } from "@/utils/types"; 10 | import { useRouter } from "next/navigation"; 11 | import { RiExchangeDollarLine } from "react-icons/ri"; 12 | import { VscDebugDisconnect } from "react-icons/vsc"; 13 | import { TbMoodEdit } from "react-icons/tb"; 14 | 15 | export const ConnectButton: FC = () => { 16 | const { user, setUser, login, setLogin, isLoading, setIsLoading } = 17 | useContext(UserContext); 18 | const { publicKey, disconnect, connect, signMessage } = useWallet(); 19 | const { visible, setVisible } = useWalletModal(); 20 | const router = useRouter() 21 | 22 | const tempUser = useMemo(() => user, [user]); 23 | useEffect(() => { 24 | const handleClick = async () => { 25 | if (publicKey && !login) { 26 | const updatedUser: userInfo = { 27 | name: publicKey.toBase58().slice(0, 6), 28 | wallet: publicKey.toBase58(), 29 | isLedger: false, 30 | }; 31 | await sign(updatedUser); 32 | } 33 | }; 34 | handleClick(); 35 | }, [publicKey, login]); // Removed `connect`, `wallet`, and `disconnect` to prevent unnecessary calls 36 | const sign = async (updatedUser: userInfo) => { 37 | try { 38 | const connection = await walletConnect({ data: updatedUser }); 39 | if (!connection) return; 40 | if (connection.nonce === undefined) { 41 | const newUser = { 42 | name: connection.name, 43 | wallet: connection.wallet, 44 | _id: connection._id, 45 | avatar: connection.avatar, 46 | }; 47 | setUser(newUser as userInfo); 48 | setLogin(true); 49 | return; 50 | } 51 | 52 | const msg = new TextEncoder().encode( 53 | `Nonce to confirm: ${connection.nonce}` 54 | ); 55 | 56 | const sig = await signMessage?.(msg); 57 | const res = base58.encode(sig as Uint8Array); 58 | const signedWallet = { ...connection, signature: res }; 59 | const confirm = await confirmWallet({ data: signedWallet }); 60 | 61 | if (confirm) { 62 | setUser(confirm); 63 | setLogin(true); 64 | setIsLoading(false); 65 | } 66 | successAlert("Message signed."); 67 | } catch (error) { 68 | errorAlert("Sign-in failed."); 69 | } 70 | }; 71 | 72 | const logOut = async () => { 73 | if (typeof disconnect === "function") { 74 | await disconnect(); 75 | } 76 | // Initialize `user` state to default value 77 | setUser({} as userInfo); 78 | setLogin(false); 79 | localStorage.clear(); 80 | }; 81 | const handleToProfile = (id: string) => { 82 | router.push(id) 83 | } 84 | return ( 85 |
86 | 135 |
136 | ); 137 | }; 138 | -------------------------------------------------------------------------------- /front-end/src/components/modals/ReplyModal.tsx: -------------------------------------------------------------------------------- 1 | import UserContext from '@/context/UserContext'; 2 | import { coinInfo, replyInfo, tradeInfo, userInfo } from '@/utils/types'; 3 | import { postReply, updateUser, uploadImage } from '@/utils/util'; 4 | import React, { ChangeEvent, useContext, useMemo, useRef, useState } from 'react'; 5 | import { errorAlert, successAlert } from '../others/ToastGroup'; 6 | import ImgIcon from "@/../public/assets/images/imce-logo.jpg"; 7 | 8 | import Image from 'next/image'; 9 | 10 | interface ModalProps { 11 | data: coinInfo; 12 | } 13 | 14 | const ReplyModal: React.FC = ({ data }) => { 15 | const { postReplyModal, setPostReplyModal, user } = useContext(UserContext); 16 | const [fileName, setFileName] = useState(null); 17 | const [imageUrl, setImageUrl] = useState(""); 18 | const [msg, setMsg] = useState(""); 19 | 20 | const fileInputRef = useRef(null); 21 | 22 | const replyPost = async () => { 23 | let reply: replyInfo; 24 | if (imageUrl) { 25 | const url = await uploadImage(imageUrl); 26 | if (url && user._id) { 27 | console.log("user._id: ", user._id) 28 | console.log("url: ", url) 29 | 30 | reply = { 31 | coinId: data._id, 32 | sender: user._id, 33 | msg: msg, 34 | img: url 35 | } 36 | } 37 | } else { 38 | if (user._id) { 39 | reply = { 40 | coinId: data._id, 41 | sender: user._id, 42 | msg: msg, 43 | } 44 | } 45 | } 46 | handleModalToggle(); 47 | await postReply(reply); 48 | } 49 | 50 | const handleModalToggle = () => { 51 | setPostReplyModal(!postReplyModal); 52 | }; 53 | 54 | const handleFileChange = (event: ChangeEvent) => { 55 | const file = event.target.files?.[0]; 56 | if (file) { 57 | if (!file.type.startsWith('image/')) { 58 | successAlert('Please select a valid image file.'); 59 | return; 60 | } 61 | const url = URL.createObjectURL(file); 62 | setFileName(file.name || ''); // Ensure it's always a string 63 | setImageUrl(url); // URL.createObjectURL always returns a string 64 | } 65 | }; 66 | 67 | const uploadImage = async (image: string): Promise => { 68 | // Your logic here 69 | const uploadSuccess = true; // Example logic 70 | return uploadSuccess ? 'uploaded-image-url' : ''; 71 | }; 72 | 73 | 74 | return ( 75 |
76 |
77 |

Post Reply

78 |
79 | 85 |