├── lib ├── cn.ts ├── is-active.ts ├── source.ts ├── mongodb.ts ├── chat │ └── inkeep-qa-schema.ts ├── metadata.ts ├── assets │ └── birdeye │ │ └── wallets.ts └── utils.ts ├── content └── docs │ ├── meta.json │ └── onchainkit │ ├── Metaplex │ ├── Fusion │ │ └── meta.json │ ├── Inscription │ │ └── meta.json │ ├── Token-Auth-Rules │ │ └── meta.json │ ├── Core │ │ ├── meta.json │ │ └── core-asset-launchpad.mdx │ ├── MPL-Hybrid │ │ ├── meta.json │ │ └── mpl-hybrid-form.mdx │ ├── Candy-Machine │ │ └── meta.json │ ├── Bubblegum-v1 │ │ ├── meta.json │ │ └── bubblegum-legacy-form.mdx │ ├── Core-Candy-Machine │ │ └── meta.json │ ├── Hydra │ │ ├── meta.json │ │ └── hydra-fanout-form.mdx │ ├── Bubblegum-v2 │ │ └── meta.json │ ├── Token-Metadata │ │ ├── meta.json │ │ ├── create-collection-form.mdx │ │ ├── tm-launchpad-form.mdx │ │ ├── get-nft-form.mdx │ │ └── mint-nft-form.mdx │ └── meta.json │ ├── pk-input.mdx │ ├── meta.json │ ├── avatar.mdx │ ├── Meteora-DBC │ └── buildCurveAndCreateConfig-form.mdx │ ├── token-icon.mdx │ ├── swap-token-form.mdx │ ├── index.mdx │ ├── token-list.mdx │ ├── ZK-Compression │ ├── mint-cToken.mdx │ ├── claim-cToken.mdx │ └── distribute-cToken.mdx │ ├── txn-settings.mdx │ ├── price-change.mdx │ ├── sparkline.mdx │ ├── token-combobox.mdx │ ├── txn-list.mdx │ └── token-input.mdx ├── app ├── icon.ico ├── favicon-16x16.png ├── favicon-32x32.png ├── apple-touch-icon.png ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── api │ ├── search │ │ └── route.ts │ ├── email │ │ └── route.ts │ ├── feedback │ │ └── route.ts │ ├── stats │ │ ├── copy-command-track │ │ │ └── route.ts │ │ └── route.ts │ ├── chat │ │ └── route.ts │ └── murphy │ │ └── solayer │ │ └── stake │ │ └── route.ts ├── not-found.tsx ├── site.webmanifest ├── robots.ts ├── (home) │ ├── test │ │ └── page.tsx │ ├── page.tsx │ ├── layout.tsx │ └── about │ │ └── page.tsx ├── layout.client.tsx ├── docs │ ├── layout.tsx │ └── [[...slug]] │ │ └── page.tsx └── layout.tsx ├── postcss.config.mjs ├── public ├── murphy │ └── murphy-op.png ├── token-icons │ └── placeholder.jpg ├── brand-logos │ ├── github.svg │ └── passkey-logo.svg ├── crypto-logos │ ├── tether-usdt-logo.svg │ ├── usd-coin-usdc-logo.svg │ └── solana-logo.svg ├── r │ └── token-icon.json └── partner │ └── solana-logo.svg ├── styles └── tailwind.css ├── config └── swap │ └── index.ts ├── types ├── swap │ └── index.ts └── assets │ └── index.ts ├── components ├── murphy-logo.tsx ├── ui │ ├── skeleton.tsx │ ├── sonner.tsx │ ├── label.tsx │ ├── textarea.tsx │ ├── progress.tsx │ ├── murphy │ │ ├── token-icon.tsx │ │ ├── avatar.tsx │ │ ├── price-change.tsx │ │ ├── pk-input.tsx │ │ └── sparkline.tsx │ ├── link-button.tsx │ ├── collapsible.tsx │ ├── input.tsx │ ├── switch.tsx │ ├── popover.tsx │ ├── avatar.tsx │ ├── avatar-circles.tsx │ ├── toggle.tsx │ ├── badge.tsx │ ├── alert.tsx │ ├── tabs.tsx │ ├── toggle-group.tsx │ ├── slider.tsx │ ├── button.tsx │ └── card.tsx ├── docs │ ├── call-action.tsx │ ├── index.tsx │ ├── preview-component.tsx │ └── open-in-v0-button.tsx ├── app │ ├── layout.tsx │ └── page.tsx ├── landding │ ├── call-action-section.tsx │ ├── terminal-demo.tsx │ ├── floating-particles.tsx │ ├── orbiting-circles.tsx │ └── contribute-section.tsx ├── ai-search │ └── index.tsx ├── providers │ └── client-lazorkit-provider.tsx ├── background │ ├── grid-pattern.tsx │ └── ripple.tsx └── layout │ ├── language-toggle.tsx │ ├── search-toggle.tsx │ └── theme-toggle.tsx ├── source.config.ts ├── models ├── Email.ts ├── Feedback.ts └── ComponentCopy.ts ├── .gitignore ├── next.config.mjs ├── components.json ├── .env.example ├── registry └── components │ ├── price-change.json │ ├── token-icon.json │ ├── avatar.json │ ├── pk-input.json │ ├── sparkline.json │ ├── txn-list.json │ ├── mint-cToken.json │ ├── get-nft-form.json │ ├── send-token-form.json │ ├── mint-cnft-form.json │ ├── distribute-cToken.json │ ├── txn-settings.json │ ├── token-card.json │ ├── compressed-nft-viewer.json │ ├── CancelRecurringOrder.json │ ├── transfer-nft-form.json │ ├── RecurringSetupForm.json │ ├── price-chart.json │ ├── RecurringOrderCard.json │ ├── RecurringHistoryList.json │ ├── RecurringActiveOrders.json │ ├── RecurringOrderWidget.json │ ├── mint-nft-form.json │ ├── hydra-fanout-form.json │ ├── claim-cToken.json │ ├── stake-token-form.json │ ├── create-collection-form.json │ ├── tm-launchpad-form.json │ ├── create-merkleTree-form.json │ ├── update-collection-form.json │ ├── candy-machine-form.json │ ├── token-input.json │ ├── token-metadata-viewer.json │ ├── bubblegum-legacy-form.json │ ├── core-candy-machine-form.json │ ├── core-asset-launchpad.json │ ├── improved-cnft-manager.json │ ├── mpl-hybrid-form.json │ ├── createConfig-form.json │ ├── buildCurveAndCreateConfig-form.json │ ├── buildCurveAndCreateConfigByMarketCap-form.json │ ├── token-combobox.json │ ├── connect-wallet-button.json │ ├── token-list.json │ └── swap-token-form.json ├── constants └── swap │ └── jupiter-constants.ts ├── .github └── ISSUE_TEMPLATE │ └── feature_request.md ├── README.md ├── tsconfig.json ├── LICENSE ├── hook └── murphy │ ├── use-walletModal.ts │ └── use-walletMultiButton.ts ├── mdx-components.tsx └── scripts └── build-registry.ts /lib/cn.ts: -------------------------------------------------------------------------------- 1 | export { twMerge as cn } from 'tailwind-merge'; 2 | -------------------------------------------------------------------------------- /content/docs/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": ["onchainkit"] 3 | } 4 | -------------------------------------------------------------------------------- /app/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Murphy-CodeLabs/murphy/HEAD/app/icon.ico -------------------------------------------------------------------------------- /app/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Murphy-CodeLabs/murphy/HEAD/app/favicon-16x16.png -------------------------------------------------------------------------------- /app/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Murphy-CodeLabs/murphy/HEAD/app/favicon-32x32.png -------------------------------------------------------------------------------- /app/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Murphy-CodeLabs/murphy/HEAD/app/apple-touch-icon.png -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | '@tailwindcss/postcss': {}, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /public/murphy/murphy-op.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Murphy-CodeLabs/murphy/HEAD/public/murphy/murphy-op.png -------------------------------------------------------------------------------- /styles/tailwind.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | 3 | 4 | @theme inline { 5 | --color-highlight: #8839ef 6 | } -------------------------------------------------------------------------------- /app/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Murphy-CodeLabs/murphy/HEAD/app/android-chrome-192x192.png -------------------------------------------------------------------------------- /app/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Murphy-CodeLabs/murphy/HEAD/app/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/token-icons/placeholder.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Murphy-CodeLabs/murphy/HEAD/public/token-icons/placeholder.jpg -------------------------------------------------------------------------------- /content/docs/onchainkit/Metaplex/Fusion/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Fusion", 3 | "description": "NFTs inside NFTs", 4 | "icon": "Layers", 5 | "pages": [] 6 | } -------------------------------------------------------------------------------- /config/swap/index.ts: -------------------------------------------------------------------------------- 1 | import { Config } from "../../types/swap"; 2 | 3 | export const config: Config = { 4 | JUPITER_REFERRAL_ACCOUNT: undefined, 5 | JUPITER_FEE_BPS: 0, 6 | }; 7 | -------------------------------------------------------------------------------- /app/api/search/route.ts: -------------------------------------------------------------------------------- 1 | import { source } from '@/lib/source'; 2 | import { createFromSource } from 'fumadocs-core/search/server'; 3 | 4 | export const { GET } = createFromSource(source); 5 | -------------------------------------------------------------------------------- /content/docs/onchainkit/Metaplex/Inscription/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Inscription", 3 | "description": "NFT inscribed on Solana", 4 | "icon": "PenTool", 5 | "pages": [] 6 | } -------------------------------------------------------------------------------- /content/docs/onchainkit/Metaplex/Token-Auth-Rules/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Token Auth Rules", 3 | "description": "NFT permissions", 4 | "icon": "Shield", 5 | "pages": [] 6 | } -------------------------------------------------------------------------------- /content/docs/onchainkit/Metaplex/Core/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Core", 3 | "description": "Next gen NFT standard", 4 | "icon": "Cpu", 5 | "pages": [ 6 | "core-asset-launchpad" 7 | ] 8 | } -------------------------------------------------------------------------------- /content/docs/onchainkit/Metaplex/MPL-Hybrid/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "MPL-Hybrid", 3 | "description": "Hybrid Assets", 4 | "icon": "Shuffle", 5 | "pages": [ 6 | "mpl-hybrid-form" 7 | ] 8 | } -------------------------------------------------------------------------------- /content/docs/onchainkit/Metaplex/Candy-Machine/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Candy Machine", 3 | "description": "TM NFT launchpad", 4 | "icon": "Rocket", 5 | "pages": [ 6 | "candy-machine-form" 7 | ] 8 | } -------------------------------------------------------------------------------- /content/docs/onchainkit/Metaplex/Bubblegum-v1/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Bubblegum v1 (legacy)", 3 | "description": "Legacy Compressed NFTs", 4 | "icon": "Archive", 5 | "pages": [ 6 | "bubblegum-legacy-form" 7 | ] 8 | } -------------------------------------------------------------------------------- /content/docs/onchainkit/Metaplex/Core-Candy-Machine/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Core Candy Machine", 3 | "description": "Core Asset launchpad", 4 | "icon": "Zap", 5 | "pages": [ 6 | "core-candy-machine-form" 7 | ] 8 | } -------------------------------------------------------------------------------- /app/not-found.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function NotFound() { 4 | return ( 5 |
6 |

Not Found

7 |
8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /content/docs/onchainkit/Metaplex/Hydra/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Hydra", 3 | "description": "Metaplex Hydra fanout wallets for multi-recipient distributions", 4 | "icon": "GitBranch", 5 | "pages": [ 6 | "hydra-fanout-form" 7 | ] 8 | } -------------------------------------------------------------------------------- /app/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /types/swap/index.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey, Connection } from "@solana/web3.js"; 2 | 3 | export interface Config { 4 | JUPITER_REFERRAL_ACCOUNT?: string; 5 | JUPITER_FEE_BPS?: number; 6 | } 7 | 8 | declare const _default: { 9 | Config: Config; 10 | }; 11 | 12 | 13 | export default _default; -------------------------------------------------------------------------------- /components/murphy-logo.tsx: -------------------------------------------------------------------------------- 1 | import Image from "next/image"; 2 | export default function MurphisLogo() { 3 | return ( 4 | Murphy Logo 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /lib/is-active.ts: -------------------------------------------------------------------------------- 1 | export function isActive( 2 | url: string, 3 | pathname: string, 4 | nested = true, 5 | ): boolean { 6 | if (url.endsWith('/')) url = url.slice(0, -1); 7 | if (pathname.endsWith('/')) pathname = pathname.slice(0, -1); 8 | 9 | return url === pathname || (nested && pathname.startsWith(`${url}/`)); 10 | } 11 | -------------------------------------------------------------------------------- /source.config.ts: -------------------------------------------------------------------------------- 1 | import { defineDocs, defineConfig } from 'fumadocs-mdx/config'; 2 | 3 | // Options: https://fumadocs.vercel.app/docs/mdx/collections#define-docs 4 | export const docs = defineDocs({ 5 | dir: 'content/docs', 6 | }); 7 | 8 | export default defineConfig({ 9 | mdxOptions: { 10 | // MDX options 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /content/docs/onchainkit/Metaplex/Bubblegum-v2/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Bubblegum v2", 3 | "description": "Improved Compressed NFTs", 4 | "icon": "TreePine", 5 | "pages": [ 6 | "mint-cnft-form", 7 | "create-merkleTree-form", 8 | "compressed-nft-viewer", 9 | "improved-cnft-manager" 10 | ] 11 | } -------------------------------------------------------------------------------- /components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | function Skeleton({ className, ...props }: React.ComponentProps<"div">) { 4 | return ( 5 |
10 | ) 11 | } 12 | 13 | export { Skeleton } 14 | -------------------------------------------------------------------------------- /components/docs/call-action.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from "@/components/ui/button"; 2 | import { Feedback } from "../feadback-card"; 3 | import { LinkTree } from "../community-links"; 4 | 5 | export function CallAction() { 6 | return ( 7 |
8 | 9 | 10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /models/Email.ts: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose'; 2 | 3 | const EmailSchema = new mongoose.Schema({ 4 | email: { 5 | type: String, 6 | required: true, 7 | unique: true 8 | } 9 | }, { 10 | timestamps: true, 11 | collection: process.env.EMAIL_COLLECTION_NAME 12 | }); 13 | 14 | export default mongoose.models.Email || mongoose.model('Email', EmailSchema); -------------------------------------------------------------------------------- /app/robots.ts: -------------------------------------------------------------------------------- 1 | import type { MetadataRoute } from 'next' 2 | 3 | export default function robots(): MetadataRoute.Robots { 4 | return { 5 | rules: [ 6 | { 7 | userAgent: '*', 8 | allow: [ 9 | '/', 10 | '/docs', 11 | '/about', 12 | ], 13 | }, 14 | ], 15 | sitemap: `${process.env.NEXT_PUBLIC_BASE_URL}/sitemap.xml`, 16 | } 17 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # deps 2 | /node_modules 3 | 4 | # generated content 5 | .contentlayer 6 | .content-collections 7 | .source 8 | 9 | # test & build 10 | /coverage 11 | /.next/ 12 | /out/ 13 | /build 14 | *.tsbuildinfo 15 | 16 | # misc 17 | .DS_Store 18 | *.pem 19 | /.pnp 20 | .pnp.js 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | # others 26 | .env 27 | .env*.local 28 | .vercel 29 | next-env.d.ts -------------------------------------------------------------------------------- /types/assets/index.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey,Connection } from "@solana/web3.js"; 2 | 3 | export type SolAsset = { 4 | mint: PublicKey; 5 | name: string; 6 | symbol: string; 7 | image: string; 8 | decimals: number; 9 | price: number; 10 | userTokenAccount?: { 11 | address: PublicKey; 12 | amount: number; 13 | }; 14 | }; 15 | 16 | export type FetchWalletArgs = { 17 | owner: PublicKey; 18 | limit?: number; 19 | }; -------------------------------------------------------------------------------- /content/docs/onchainkit/Metaplex/Token-Metadata/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Token Metadata", 3 | "description": "Digital ownership standard", 4 | "icon": "Coins", 5 | "pages": [ 6 | "create-collection-form", 7 | "mint-nft-form", 8 | "transfer-nft-form", 9 | "update-collection-form", 10 | "view-nft-form", 11 | "tm-launchpad-form", 12 | "token-metadata-viewer" 13 | ] 14 | } -------------------------------------------------------------------------------- /content/docs/onchainkit/Metaplex/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Metaplex", 3 | "description": "Solana NFT and digital asset ecosystem", 4 | "pages": [ 5 | "Token-Metadata", 6 | "Core", 7 | "Bubblegum-v1", 8 | "Bubblegum-v2", 9 | "Candy-Machine", 10 | "Core-Candy-Machine", 11 | "Fusion", 12 | "Hydra", 13 | "Inscription", 14 | "MPL-Hybrid", 15 | "Token-Auth-Rules" 16 | ] 17 | } -------------------------------------------------------------------------------- /models/Feedback.ts: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose'; 2 | 3 | const FeedbackSchema = new mongoose.Schema({ 4 | happiness: { 5 | type: Number, 6 | required: true, 7 | min: 1, 8 | max: 4 9 | }, 10 | feedback: { 11 | type: String, 12 | required: true 13 | }, 14 | }, { 15 | timestamps: true, 16 | collection: process.env.FEEDBACK_COLLECTION_NAME 17 | }); 18 | 19 | export default mongoose.models.Feedback || mongoose.model('Feedback', FeedbackSchema); -------------------------------------------------------------------------------- /components/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type React from "react" 2 | import { ThemeProvider } from 'next-themes' 3 | import "@/app/globals.css" 4 | 5 | export default function RootLayout({ children }: { children: React.ReactNode }) { 6 | return ( 7 | 8 | 9 | 10 | 11 | {children} 12 | 13 | 14 | 15 | ) 16 | } -------------------------------------------------------------------------------- /models/ComponentCopy.ts: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose'; 2 | 3 | const ComponentCopySchema = new mongoose.Schema({ 4 | componentName: { 5 | type: String, 6 | required: true, 7 | unique: true 8 | }, 9 | copyCount: { 10 | type: Number, 11 | default: 0 12 | } 13 | }, { 14 | timestamps: true, 15 | collection: process.env.COPY_COMMAND_TRACK_COLLECTION_NAME 16 | } 17 | ); 18 | 19 | export default mongoose.models.ComponentCopy || mongoose.model('ComponentCopy', ComponentCopySchema); -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | import { createMDX } from "fumadocs-mdx/next"; 2 | 3 | const withMDX = createMDX(); 4 | 5 | /** @type {import('next').NextConfig} */ 6 | const config = { 7 | reactStrictMode: true, 8 | images: { 9 | remotePatterns: [ 10 | { 11 | hostname: "*", 12 | }, 13 | ], 14 | }, 15 | webpack: (config) => { 16 | config.module.rules.push({ 17 | test: /\.json$/, 18 | type: "json", 19 | }); 20 | return config; 21 | }, 22 | }; 23 | export default withMDX(config); 24 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "", 8 | "css": "styles/global.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } 22 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # Use mainnet or devnet 2 | NEXT_PUBLIC_USE_MAINNET=true 3 | 4 | # Alchemy API Key 5 | # Solana RPC URLs , alchemy.com 6 | NEXT_PUBLIC_SOLANA_RPC_URL="https://solana-mainnet.g.alchemy.com/v2/your-alchemy-api-key" 7 | NEXT_PUBLIC_SOLANA_RPC_URL_DEVNET="https://solana-devnet.g.alchemy.com/v2/your-alchemy-api-key" 8 | 9 | NEXT_PUBLIC_BIRDEYE_API_KEY="bird-eye-api-key" 10 | # Base URL 11 | NEXT_PUBLIC_BASE_URL="https://murphy.vercel.app" 12 | 13 | MONGODB_URI="your-key-db" 14 | COPY_COMMAND_TRACK_COLLECTION_NAME = "your-track" 15 | -------------------------------------------------------------------------------- /registry/components/price-change.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "price-change", 3 | "type": "registry:block", 4 | "title": "The PriceChange component displays the change of a price over time.", 5 | "files": [ 6 | { 7 | "path": "components/ui/murphy/price-change.tsx", 8 | "type": "registry:file", 9 | "target": "components/ui/murphy/price-change.tsx" 10 | }, 11 | { 12 | "path": "lib/utils.ts", 13 | "type": "registry:file", 14 | "target": "lib/utils.ts" 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /constants/swap/jupiter-constants.ts: -------------------------------------------------------------------------------- 1 | import { PublicKey } from "@solana/web3.js"; 2 | 3 | export const JUP_API = "https://quote-api.jup.ag/v6"; 4 | export const JUP_REFERRAL_ADDRESS = "JUPTRFXx5qe2wMFBtC7c7s6DvS3weDgAZu7Lr4ZKtoQ"; 5 | 6 | export const DEFAULT_OPTIONS = { 7 | SLIPPAGE_BPS: 50, // 0.5% 8 | }; 9 | 10 | export const TOKENS = { 11 | SOL: new PublicKey("So11111111111111111111111111111111111111112"), 12 | USDC: new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), 13 | USDT: new PublicKey("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB") 14 | }; -------------------------------------------------------------------------------- /registry/components/token-icon.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "token-icon", 3 | "type": "registry:block", 4 | "title": "The Sparkline component is a line chart that displays the price of a token over time.", 5 | "files": [ 6 | { 7 | "path": "components/ui/murphy/token-icon.tsx", 8 | "type": "registry:file", 9 | "target": "components/ui/murphy/token-icon.tsx" 10 | }, 11 | { 12 | "path": "types/assets/index.ts", 13 | "type": "registry:file", 14 | "target": "types/assets/index.ts" 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /registry/components/avatar.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "avatar", 3 | "description": "A simple avatar icon", 4 | "type": "registry:block", 5 | "dependencies":[ 6 | "@solana/web3.js", 7 | "minidenticons" 8 | ], 9 | "files": [ 10 | { 11 | "path": "components/ui/murphy/avatar.tsx", 12 | "type": "registry:component", 13 | "target": "components/ui/murphy/avatar.tsx" 14 | }, 15 | { 16 | "path": "lib/utils.ts", 17 | "type": "registry:file", 18 | "target": "lib/utils.ts" 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /app/(home)/test/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { ConnectWalletButton } from "@/components/ui/murphy"; 4 | import { SendTokenForm } from "@/components/ui/murphy/send-token-form"; 5 | import { Wallet } from "lucide-react"; 6 | 7 | export default function TestPage() { 8 | return ( 9 |
10 |

Connect Your Solana Wallet

11 | 12 | 13 | Connect Wallet 14 | 15 | 16 | 17 |
18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /lib/source.ts: -------------------------------------------------------------------------------- 1 | import { docs } from "@/.source"; 2 | import { loader } from "fumadocs-core/source"; 3 | import { createElement } from "react"; 4 | import { icons } from "lucide-react"; 5 | 6 | // See https://fumadocs.vercel.app/docs/headless/source-api for more info 7 | export const source = loader({ 8 | // it assigns a URL to your pages 9 | baseUrl: "/docs", 10 | source: docs.toFumadocsSource(), 11 | icon(icon) { 12 | if (!icon) { 13 | // You may set a default icon 14 | return; 15 | } 16 | if (icon in icons) return createElement(icons[icon as keyof typeof icons]); 17 | }, 18 | }); 19 | -------------------------------------------------------------------------------- /registry/components/pk-input.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pk-input", 3 | "type": "registry:block", 4 | "title": "The PKInput component is an input field with support for inline public key validation.", 5 | "registryDependencies": ["input"], 6 | "dependencies": ["@solana/web3.js"], 7 | "files": [ 8 | { 9 | "path": "components/ui/murphy/pk-input.tsx", 10 | "type": "registry:component", 11 | "target": "components/ui/murphy/pk-input.tsx" 12 | }, 13 | { 14 | "path": "lib/utils.ts", 15 | "type": "registry:file", 16 | "target": "lib/utils.ts" 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /registry/components/sparkline.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sparkline", 3 | "type": "registry:block", 4 | "title": "The Sparkline component is a line chart that displays the price of a token over time.", 5 | "registryDependencies": ["chart"], 6 | "dependencies": ["recharts"], 7 | "files": [ 8 | { 9 | "path": "components/ui/murphy/price-change.tsx", 10 | "type": "registry:file", 11 | "target": "components/ui/murphy/price-change.tsx" 12 | }, 13 | { 14 | "path": "components/ui/murphy/sparkline.tsx", 15 | "type": "registry:file", 16 | "target": "components/ui/murphy/sparkline.tsx" 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /app/api/email/route.ts: -------------------------------------------------------------------------------- 1 | import { NextResponse } from 'next/server'; 2 | import connectDB from '@/lib/mongodb'; 3 | import Email from '@/models/Email'; 4 | 5 | export async function POST(request: Request) { 6 | try { 7 | await connectDB(); 8 | const { email } = await request.json(); 9 | 10 | const newEmail = await Email.create({ 11 | email 12 | }); 13 | 14 | return NextResponse.json({ success: true, email: newEmail }); 15 | } catch (error) { 16 | console.error("Error subscribing email:", error); 17 | return NextResponse.json( 18 | { success: false, error: "Failed to subscribe email" }, 19 | { status: 500 } 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /components/ui/sonner.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { useTheme } from "next-themes" 4 | import { Toaster as Sonner, ToasterProps } from "sonner" 5 | 6 | const Toaster = ({ ...props }: ToasterProps) => { 7 | const { theme = "system" } = useTheme() 8 | 9 | return ( 10 | 22 | ) 23 | } 24 | 25 | export { Toaster } 26 | -------------------------------------------------------------------------------- /registry/components/txn-list.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "txn-list", 3 | "type": "registry:block", 4 | "title": "The TxnList component is a table of transactions with metadata.", 5 | "registryDependencies": ["table","skeleton"], 6 | "dependencies": [ 7 | "@solana/web3.js", 8 | "date-fns", 9 | "@solana/wallet-adapter-react" 10 | ], 11 | "files": [ 12 | { 13 | "path": "components/ui/murphy/txn-list.tsx", 14 | "type": "registry:file", 15 | "target": "components/ui/murphy/txn-list.tsx" 16 | }, 17 | { 18 | "path": "lib/utils.ts", 19 | "type": "registry:file", 20 | "target": "lib/utils.ts" 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /app/api/feedback/route.ts: -------------------------------------------------------------------------------- 1 | import { NextResponse } from 'next/server'; 2 | import connectDB from '@/lib/mongodb'; 3 | import Feedback from '@/models/Feedback'; 4 | 5 | export async function POST(request: Request) { 6 | try { 7 | await connectDB(); 8 | const { happiness, feedback } = await request.json(); 9 | 10 | const newFeedback = await Feedback.create({ 11 | happiness, 12 | feedback 13 | }); 14 | 15 | return NextResponse.json({ success: true, feedback: newFeedback }); 16 | } catch (error) { 17 | console.error('Error submitting feedback:', error); 18 | return NextResponse.json({ success: false, error: 'Failed to submit feedback' }, { status: 500 }); 19 | } 20 | } -------------------------------------------------------------------------------- /components/landding/call-action-section.tsx: -------------------------------------------------------------------------------- 1 | import { LinkButton } from "../ui/link-button"; 2 | 3 | export function CallActionSection() { 4 | return ( 5 | <> 6 |
7 |

8 | Ready to build your next Dapp? 9 |

10 | 11 | Get Started 12 | 13 |
14 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Murphy 2 | 3 | Murphy is an SDK designed to simplify Web3 and Solana development, allowing developers to build decentralized applications in their own way. 4 | 5 | ## Overview 6 | 7 | Named after Murphy's Law ("Whatever can go wrong, will go wrong"), this project embraces the experimental nature of Web3 development. Muphis provides tools and abstractions that make it easier to interact with Solana's blockchain, allowing both beginners and experienced developers to build powerful decentralized applications. 8 | 9 | ## Contributing 10 | 11 | Contributions are welcome! Whether you're fixing bugs, adding features, or improving documentation, your help is appreciated. 12 | 13 | ## License 14 | 15 | [MIT](LICENSE) 16 | -------------------------------------------------------------------------------- /app/api/stats/copy-command-track/route.ts: -------------------------------------------------------------------------------- 1 | import { NextResponse } from 'next/server'; 2 | import connectDB from '@/lib/mongodb'; 3 | import ComponentCopy from '@/models/ComponentCopy'; 4 | 5 | export async function POST(request: Request) { 6 | try { 7 | await connectDB(); 8 | const { componentName } = await request.json(); 9 | 10 | const component = await ComponentCopy.findOneAndUpdate( 11 | { componentName }, 12 | { $inc: { copyCount: 1 } }, 13 | { upsert: true, new: true } 14 | ); 15 | 16 | return NextResponse.json({ success: true, component }); 17 | } catch (error) { 18 | return NextResponse.json({ success: false, error: 'Failed to track copy' }, { status: 500 }); 19 | } 20 | } -------------------------------------------------------------------------------- /components/docs/index.tsx: -------------------------------------------------------------------------------- 1 | import InstallationCommands from "./installation-commands"; 2 | import DependenciesInstallCommands from "./dependencies-install-commands"; 3 | import OpenInV0Button from "./open-in-v0-button"; 4 | import { PreviewComponent } from "./preview-component"; 5 | import { 6 | ApiTable, 7 | ApiRow, 8 | ApiParam, 9 | ApiTableProperty 10 | } from "./api-table"; 11 | import { ComponentSource, ComponentSourceSimple } from "./component-source"; 12 | 13 | 14 | export { 15 | InstallationCommands, 16 | DependenciesInstallCommands, 17 | OpenInV0Button, 18 | PreviewComponent, 19 | ApiTable, 20 | ApiRow, 21 | ApiParam, 22 | ApiTableProperty, 23 | ComponentSource, 24 | ComponentSourceSimple 25 | }; 26 | -------------------------------------------------------------------------------- /components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as LabelPrimitive from "@radix-ui/react-label" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | function Label({ 9 | className, 10 | ...props 11 | }: React.ComponentProps) { 12 | return ( 13 | 21 | ) 22 | } 23 | 24 | export { Label } 25 | -------------------------------------------------------------------------------- /registry/components/mint-cToken.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mint-cToken", 3 | "type": "registry:block", 4 | "title": "Mint cToken", 5 | "description": "A simple mint cToken form component.", 6 | "registryDependencies": ["input", "button", "form", "card", "sonner", "select", "dialog", "dropdown-menu"], 7 | "dependencies": [ 8 | "@solana/web3.js", 9 | "@solana/spl-token", 10 | "@solana/wallet-adapter-react", 11 | "@lightprotocol/stateless.js", 12 | "@lightprotocol/compressed-token" 13 | ], 14 | "files": [ 15 | { 16 | "path": "components/ui/murphy/mint-cToken.tsx", 17 | "type": "registry:component", 18 | "target": "components/ui/murphy/mint-cToken.tsx" 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /registry/components/get-nft-form.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "get-nft-form", 3 | "type": "registry:block", 4 | "title": "Get NFT Form", 5 | "description": "A simple get NFT form component.", 6 | "registryDependencies": [ 7 | "input", 8 | "button", 9 | "form", 10 | "card", 11 | "sonner", 12 | "select", 13 | "dialog", 14 | "dropdown-menu" 15 | ], 16 | "dependencies": [ 17 | "@solana/web3.js", 18 | "@solana/spl-token", 19 | "@solana/wallet-adapter-react" 20 | ], 21 | "files": [ 22 | { 23 | "path": "components/ui/murphy/get-nft-form.tsx", 24 | "type": "registry:component", 25 | "target": "components/ui/murphy/get-nft-form.tsx" 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /registry/components/send-token-form.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "send-token-form", 3 | "type": "registry:block", 4 | "title": "Send Token Form", 5 | "description": "A simple send token form component.", 6 | "registryDependencies": [ 7 | "input", 8 | "button", 9 | "form", 10 | "card", 11 | "sonner", 12 | "select", 13 | "dialog", 14 | "dropdown-menu", 15 | "collapsible", 16 | "tabs" 17 | ], 18 | "dependencies": [ 19 | "@solana/web3.js", 20 | "@solana/spl-token", 21 | "@solana/wallet-adapter-react" 22 | ], 23 | "files": [ 24 | { 25 | "path": "components/ui/murphy/send-token-form.tsx", 26 | "type": "registry:component", 27 | "target": "components/ui/murphy/send-token-form.tsx" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /registry/components/mint-cnft-form.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mint-cnft-form", 3 | "type": "registry:block", 4 | "title": "Mint CNFT Form", 5 | "description": "A simple mint CNFT form component.", 6 | "registryDependencies": [ 7 | "input", 8 | "button", 9 | "form", 10 | "card", 11 | "sonner", 12 | "select", 13 | "dialog", 14 | "dropdown-menu" 15 | ], 16 | "dependencies": [ 17 | "@solana/web3.js", 18 | "@solana/spl-token", 19 | "@solana/wallet-adapter-react" 20 | ], 21 | "files": [ 22 | { 23 | "path": "components/ui/murphy/mint-cnft-form.tsx", 24 | "type": "registry:component", 25 | "target": "components/ui/murphy/mint-cnft-form.tsx" 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /components/app/page.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { ConnectWalletButton } from "@/components/ui/murphy/connect-wallet-button" 4 | import { WalletProvider } from "@/components/providers/wallet-provider" 5 | import { Wallet } from "lucide-react" 6 | 7 | export default function TestPage() { 8 | return ( 9 | 10 |
11 |
12 |

Connect Your Solana Wallet

13 | 14 | 15 | Connect Wallet 16 | 17 |
18 |
19 |
20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /registry/components/distribute-cToken.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "distribute-cToken", 3 | "type": "registry:block", 4 | "title": "Distribute cToken", 5 | "description": "A simple distribute cToken form component.", 6 | "registryDependencies": ["input", "button", "form", "card", "sonner", "select", "dialog", "dropdown-menu"], 7 | "dependencies": [ 8 | "@solana/web3.js", 9 | "@solana/spl-token", 10 | "@solana/wallet-adapter-react", 11 | "@lightprotocol/stateless.js", 12 | "@lightprotocol/compressed-token" 13 | ], 14 | "files": [ 15 | { 16 | "path": "components/ui/murphy/distribute-cToken.tsx", 17 | "type": "registry:component", 18 | "target": "components/ui/murphy/distribute-cToken.tsx" 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /registry/components/txn-settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "txn-settings", 3 | "type": "registry:block", 4 | "title": "The TxnSettings component is a popover that allows users to set the transaction priority, fee cap, and other transaction settings.", 5 | "description": "The TxnSettings component is a popover that allows users to set the transaction priority, fee cap, and other transaction settings.", 6 | "registryDependencies": [ 7 | "popover", 8 | "toggle-group", 9 | "input", 10 | "button", 11 | "dialog" 12 | ], 13 | "dependencies": [], 14 | "files": [ 15 | { 16 | "path": "components/ui/murphy/txn-settings.tsx", 17 | "type": "registry:component", 18 | "target": "components/ui/murphy/txn-settings.tsx" 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /registry/components/token-card.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "token-card", 3 | "type": "registry:block", 4 | "description": "The TokenCard component is a card that shows a token's metatda, price, and price history.", 5 | "registryDependencies": ["skeleton","card"], 6 | "dependencies": ["@solana/web3.js"], 7 | "files": [ 8 | { 9 | "path": "components/ui/murphy/token-card.tsx", 10 | "type": "registry:component", 11 | "target": "components/ui/murphy/token-card.tsx" 12 | }, 13 | { 14 | "path": "types/assets/index.ts", 15 | "type": "registry:file", 16 | "target": "types/assets/index.ts" 17 | }, 18 | { 19 | "path": "lib/utils.ts", 20 | "type": "registry:file", 21 | "target": "lib/utils.ts" 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /public/brand-logos/github.svg: -------------------------------------------------------------------------------- 1 | GitHub -------------------------------------------------------------------------------- /registry/components/compressed-nft-viewer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "compressed-nft-viewer", 3 | "type": "registry:block", 4 | "title": "Compressed NFT Viewer", 5 | "description": "View and search compressed NFTs on Solana.", 6 | "registryDependencies": [ 7 | "input", 8 | "button", 9 | "form", 10 | "card", 11 | "sonner", 12 | "select", 13 | "dialog", 14 | "dropdown-menu" 15 | ], 16 | "dependencies": [ 17 | "@solana/web3.js", 18 | "@solana/wallet-adapter-react" 19 | ], 20 | "files": [ 21 | { 22 | "path": "components/ui/murphy/compressed-nft-viewer.tsx", 23 | "type": "registry:component", 24 | "target": "components/ui/murphy/compressed-nft-viewer.tsx" 25 | } 26 | ] 27 | } -------------------------------------------------------------------------------- /registry/components/CancelRecurringOrder.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CancelRecurringOrder", 3 | "type": "registry:block", 4 | "description": "Murphy component to cancel Jupiter Recurring DCA Orders on Solana mainnet", 5 | "files": [ 6 | { 7 | "path": "components/ui/murphy/Jupiter-Recurring/CancelRecurringOrder.tsx", 8 | "type": "registry:component", 9 | "target": "components/ui/murphy/Jupiter-Recurring/CancelRecurringOrder.tsx" 10 | } 11 | ], 12 | "dependencies": [ 13 | "@solana/web3.js", 14 | "@solana/wallet-adapter-react", 15 | "sonner" 16 | ], 17 | "category": "Jupiter Recurring", 18 | "keywords": [ 19 | "jupiter", 20 | "recurring", 21 | "dca", 22 | "cancel", 23 | "order", 24 | "solana", 25 | "wallet" 26 | ], 27 | "author": "Murphy", 28 | "license": "MIT" 29 | } 30 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "target": "ESNext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "allowJs": true, 7 | "skipLibCheck": true, 8 | "strict": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "noEmit": true, 11 | "esModuleInterop": true, 12 | "module": "esnext", 13 | "moduleResolution": "bundler", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "jsx": "preserve", 17 | "incremental": true, 18 | "paths": { 19 | "@/.source": ["./.source/index.ts"], 20 | "@/*": ["./*"] 21 | }, 22 | "plugins": [ 23 | { 24 | "name": "next" 25 | } 26 | ] 27 | }, 28 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 29 | "exclude": ["node_modules"] 30 | } 31 | -------------------------------------------------------------------------------- /components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | function Textarea({ className, ...props }: React.ComponentProps<"textarea">) { 6 | return ( 7 |