Skip to content

Commit

Permalink
Added Bundle Checker
Browse files Browse the repository at this point in the history
  • Loading branch information
cryptoduke01 committed Jan 10, 2025
1 parent c806d07 commit f6eb1c2
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 3 deletions.
32 changes: 32 additions & 0 deletions next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,38 @@ const nextConfig: NextConfig = {
});
return config;
},
experimental: {
turbo: {
// Define unsupported webpack loaders
rules: {
'*.svg': {
loaders: ['@svgr/webpack'], // Example loader for SVG files
as: '*.js',
},
},
// Resolve aliases
resolveAlias: {
underscore: 'lodash', // Alias underscore to lodash
mocha: { browser: 'mocha/browser-entry.js' }, // Conditional alias for browser
},
// Resolve custom extensions
resolveExtensions: [
'.mdx',
'.tsx',
'.ts',
'.jsx',
'.js',
'.mjs',
'.json',
],
// Assign module IDs
moduleIdStrategy: 'deterministic', // Use hashed IDs for better caching
// Enable tree shaking
treeShaking: true,
// Set a memory limit for Turbopack
memoryLimit: 1024 * 1024 * 512, // 512MB in bytes
},
},
};

export default nextConfig;
6 changes: 6 additions & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
13 changes: 13 additions & 0 deletions src/app/bundle-checker/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// src/app/bundle-checker/page.tsx
'use client';

import { BundleChecker } from "@/features/bundle-checker/components/BundleChecker";

export default function BundleCheckerPage() {
return (
<div className="container mx-auto p-4">
<h1 className="text-2xl font-bold mb-4">Bundle/Sniper Checker</h1>
<BundleChecker />
</div>
);
}
45 changes: 45 additions & 0 deletions src/features/bundle-checker/components/BundleChecker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// src/features/bundle-checker/components/BundleChecker.tsx
'use client';

import { useState } from 'react';
import { useBundleAnalysis } from '../hooks/useBundleAnalysis';

export function BundleChecker() {
const [mintAddress, setMintAddress] = useState('');
const { bundles, loading, error, analyzeMint } = useBundleAnalysis();

return (
<div className="p-4">
<div className="mb-4">
<input
type="text"
value={mintAddress}
onChange={(e) => setMintAddress(e.target.value)}
placeholder="Enter mint address"
className="w-full p-2 border rounded"
/>
<button
onClick={() => analyzeMint(mintAddress)}
disabled={loading}
className="mt-2 px-4 py-2 bg-blue-500 text-white rounded disabled:opacity-50"
>
{loading ? 'Analyzing...' : 'Analyze Bundles'}
</button>
</div>

{error && (
<div className="text-red-500 mb-4">{error}</div>
)}

{bundles.map((bundle, i) => (
<div key={i} className="mb-4 p-4 border rounded">
<h3 className="font-bold">Bundle {i + 1}</h3>
<div>Unique Wallets: {bundle.stats.uniqueWallets}</div>
<div>SOL Spent: {bundle.stats.solSpent}</div>
<div>Supply %: {bundle.stats.percentageSupply}%</div>
<div>Current Holdings: {bundle.stats.currentHoldings}</div>
</div>
))}
</div>
);
}
29 changes: 29 additions & 0 deletions src/features/bundle-checker/hooks/useBundleAnalysis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// src/features/bundle-checker/hooks/useBundleAnalysis.ts
'use client';

import { useState } from 'react';
import { Connection } from '@solana/web3.js';
import { analyzeTransactions } from '../utils/analyzeTransactions';
import type { Bundle } from '../types';

export function useBundleAnalysis() {
const [bundles, setBundles] = useState<Bundle[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);

async function analyzeMint(mintAddress: string) {
try {
setLoading(true);
setError(null);
const connection = new Connection('https://api.mainnet-beta.solana.com');
const results = await analyzeTransactions(mintAddress, connection);
setBundles(results);
} catch (err) {
setError(err instanceof Error ? err.message : 'An error occurred');
} finally {
setLoading(false);
}
}

return { bundles, loading, error, analyzeMint };
}
14 changes: 14 additions & 0 deletions src/features/bundle-checker/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// src/features/bundle-checker/types/index.ts
export interface BundleStats {
percentageSupply: number;
solSpent: number;
uniqueWallets: number;
currentHoldings: number;
timestamp: number;
}

export interface Bundle {
transactions: string[];
stats: BundleStats;
wallets: string[];
}
64 changes: 64 additions & 0 deletions src/features/bundle-checker/utils/analyzeTransactions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// src/features/bundle-checker/utils/analyzeTransactions.ts
import { Connection, PublicKey } from '@solana/web3.js';
import type { Bundle } from '../types';

export async function analyzeTransactions(
mintAddress: string,
connection: Connection
): Promise<Bundle[]> {
const mint = new PublicKey(mintAddress);
const signatures = await connection.getSignaturesForAddress(mint);

// Group transactions that occurred within a small time window
const timeWindow = 1000; // 1 second window
let currentBundle: string[] = [];
let bundles: string[][] = [];

for (let i = 0; i < signatures.length - 1; i++) {
const currentTx = signatures[i];
const nextTx = signatures[i + 1];

if (!currentTx.blockTime || !nextTx.blockTime) continue;

currentBundle.push(currentTx.signature);

if (Math.abs(currentTx.blockTime - nextTx.blockTime) > timeWindow) {
if (currentBundle.length > 1) {
bundles.push([...currentBundle]);
}
currentBundle = [];
}
}

// Analyze each bundle
const analyzedBundles: Bundle[] = await Promise.all(
bundles.map(async (bundleTxs) => {
const txData = await Promise.all(
bundleTxs.map(sig => connection.getTransaction(sig))
);

const wallets = new Set<string>();
let solSpent = 0;

txData.forEach(tx => {
if (!tx) return;
wallets.add(tx.transaction.message.accountKeys[0].toString());
// Add SOL spent calculation here
});

return {
transactions: bundleTxs,
stats: {
percentageSupply: 0, // Calculate based on mint info
solSpent,
uniqueWallets: wallets.size,
currentHoldings: 0, // Need to fetch current token accounts
timestamp: txData[0]?.blockTime || 0
},
wallets: Array.from(wallets)
};
})
);

return analyzedBundles;
}
9 changes: 9 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [],
theme: {
extend: {},
},
plugins: [],
}

6 changes: 3 additions & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
"plugins": [
{
"name": "next"
}
],
],
"paths": {
"@/*": ["./src/*"]
}
Expand Down

0 comments on commit f6eb1c2

Please sign in to comment.