Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added DAppBrowser and Navbar #20

Merged
merged 8 commits into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
"bip39": "^3.1.0",
"ed25519-hd-key": "^1.3.0",
"ethers": "^6.13.2",
"lucide-react": "^0.446.0",
"prop-types": "^15.8.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.26.2",
"tweetnacl": "^1.0.3",
"vite-plugin-node-polyfills": "^0.22.0"
},
Expand Down
60 changes: 13 additions & 47 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,20 @@
import { useState } from 'react';
import { generateMnemonic } from 'bip39';
import { SolanaWallet } from './components/SolanaWallet';
import { EthWallet } from './components/ETHWallet';
import MnemonicContainer from './components/MnemonicContainer';
// App.jsx
import { Route, Routes } from 'react-router-dom';
import { Analytics } from '@vercel/analytics/react';
import Home from './pages/Home';
import DAppBrowserPage from './pages/DAppBrowserPage';
import Navbar from './components/Navbar';

function App() {
const [mnemonic, setMnemonic] = useState('');
const [buttonText, setButtonText] = useState('Create Seed Phrase');
const [isMnemonicGenerated, setIsMnemonicGenerated] = useState(false);

const handleGenerateMnemonic = async () => {
const mn = await generateMnemonic();
setMnemonic(mn);

// Only change text and color if it's not already generated
if (!isMnemonicGenerated) {
setButtonText('Phrase Changed!');
setIsMnemonicGenerated(true);

// Reset the button text after 2 seconds
setTimeout(() => {
setButtonText('Create Seed Phrase');
setIsMnemonicGenerated(false);
}, 1000);
}
};

return (
<>
<Analytics />
<div className="bg-neutral-400 rounded-2xl flex flex-col justify-center items-center h-full min-h-screen">
<h1 className="text-6xl font-bold text-center mt-8">Wallet Generator</h1>
<MnemonicContainer mnemonic={mnemonic} />

<button
className={`p-2 rounded-3xl mt-8 transition-all duration-300 ease-in-out ${
isMnemonicGenerated ? 'bg-green-500' : 'bg-rose-500'
} hover:bg-green-600 hover:scale-105`}
onClick={handleGenerateMnemonic}
>
{buttonText}
</button>

<div className="flex lg:justify-between lg:flex-row flex-col items-center pb-5">
{mnemonic && <SolanaWallet mnemonic={mnemonic} />}
{mnemonic && <EthWallet mnemonic={mnemonic} />}
</div>
</div>
</>
<>
<Analytics />
<Navbar/>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/dapp-browser" element={<DAppBrowserPage />} />
</Routes>
</>
);
}

Expand Down
4 changes: 3 additions & 1 deletion src/components/ETHWallet.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useState } from "react";
import { mnemonicToSeed } from "bip39";
import { Wallet, HDNodeWallet } from "ethers";

export const EthWallet = ({ mnemonic }) => {
const EthWallet = ({ mnemonic }) => {
const [currentIndex, setCurrentIndex] = useState(0);
const [addresses, setAddresses] = useState([]);
const [buttonText, setButtonText] = useState('Add Ethereum Wallet');
Expand Down Expand Up @@ -49,3 +49,5 @@ export const EthWallet = ({ mnemonic }) => {
</div>
);
};

export default EthWallet;
32 changes: 32 additions & 0 deletions src/components/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import { Link } from 'react-router-dom'; // Assuming you're using React Router for navigation
import { Globe } from 'lucide-react'; // Optional: Add any icons you want

const Navbar = () => {
return (
<nav className="bg-gray-800 text-white shadow-md">
<div className="max-w-6xl mx-auto px-4 py-3 flex justify-between items-center">
<div className="flex items-center">
<Globe className="mr-2" />
<h1 className="text-2xl font-bold">Web3-Wallet</h1>
</div>
<div className="space-x-4">
<Link to="/" className="hover:text-blue-400 transition duration-300">
Home
</Link>
<Link to="/about" className="hover:text-blue-400 transition duration-300">
About
</Link>
<Link to="/services" className="hover:text-blue-400 transition duration-300">
Services
</Link>
<Link to="/contact" className="hover:text-blue-400 transition duration-300">
Contact
</Link>
</div>
</div>
</nav>
);
};

export default Navbar;
4 changes: 3 additions & 1 deletion src/components/SolanaWallet.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { derivePath } from "ed25519-hd-key";
import { Keypair } from "@solana/web3.js";
import nacl from "tweetnacl";

export function SolanaWallet({ mnemonic }) {
function SolanaWallet({ mnemonic }) {
const [currentIndex, setCurrentIndex] = useState(0);
const [publicKeys, setPublicKeys] = useState([]);
const [buttonText, setButtonText] = useState('Add Solana Wallet');
Expand Down Expand Up @@ -52,3 +52,5 @@ export function SolanaWallet({ mnemonic }) {
</div>
);
}

export default SolanaWallet; // Default export
17 changes: 10 additions & 7 deletions src/main.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.jsx'
import './index.css'
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App.jsx';
import './index.css';

createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>,
)
<BrowserRouter>
<App />
</BrowserRouter>
</StrictMode>
);
84 changes: 84 additions & 0 deletions src/pages/DAppBrowserPage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React, { useState, useRef, Suspense, lazy } from 'react';
import { Globe, Loader } from 'lucide-react';

const LazyIframe = lazy(() => new Promise(resolve => {
setTimeout(() => {
resolve({
default: ({ src, title }) => (
<iframe
src={src}
title={title}
style={{ width: '100%', height: '100%', border: 'none' }}
sandbox="allow-scripts allow-same-origin"
/>
)
});
}, 1000);
}));

const DAppBrowser = () => {
const [url, setUrl] = useState('');
const [currentDApp, setCurrentDApp] = useState(null);
const inputRef = useRef(null);

const loadDApp = () => {
if (url) {
setCurrentDApp(url);
}
};

const handleKeyPress = (e) => {
if (e.key === 'Enter') {
loadDApp();
}
};

return (
<div className="dapp-browser bg-gradient-to-br from-purple-900 to-indigo-900 min-h-screen text-white p-4 sm:p-8">
<div className="max-w-7xl mx-auto">
<h1 className="text-3xl sm:text-4xl font-bold mb-4 sm:mb-8 text-center">
<Globe className="inline-block mr-2 mb-1" />
Web3 DApp Browser
</h1>
<div className="dapp-browser-controls bg-gray-800 p-3 sm:p-4 rounded-lg shadow-lg mb-4 sm:mb-8">
<div className="flex items-center">
<input
ref={inputRef}
type="text"
value={url}
onChange={(e) => setUrl(e.target.value)}
onKeyPress={handleKeyPress}
placeholder="Enter DApp URL"
className="flex-grow p-2 sm:p-3 bg-gray-700 text-white rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<button
onClick={loadDApp}
className="p-2 sm:p-3 bg-blue-600 hover:bg-blue-700 text-white rounded-r-md transition duration-300 ease-in-out focus:outline-none focus:ring-2 focus:ring-blue-500"
>
Load DApp
</button>
</div>
</div>
<div className="dapp-browser-content bg-gray-800 rounded-lg shadow-lg" style={{ height: 'calc(100vh - 200px)' }}>
<Suspense fallback={
<div className="flex items-center justify-center h-full">
<Loader className="animate-spin mr-2" />
<span>Loading DApp...</span>
</div>
}>
{currentDApp ? (
<LazyIframe src={currentDApp} title="DApp Browser" />
) : (
<div className="flex flex-col items-center justify-center h-full">
<Globe className="mb-4 text-blue-400" size={64} />
<p className="text-xl text-center">Enter a URL and click 'Load DApp' to interact with a decentralized application.</p>
</div>
)}
</Suspense>
</div>
</div>
</div>
);
};

export default DAppBrowser;
62 changes: 62 additions & 0 deletions src/pages/Home.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { useState } from 'react';
import { generateMnemonic } from 'bip39';
import { useNavigate } from 'react-router-dom'; // Import useNavigate
import SolanaWallet from '../components/SolanaWallet';
import EthWallet from '../components/ETHWallet';
import MnemonicContainer from '../components/MnemonicContainer';

function Home() {
const [mnemonic, setMnemonic] = useState('');
const [buttonText, setButtonText] = useState('Create Seed Phrase');
const [isMnemonicGenerated, setIsMnemonicGenerated] = useState(false);
const navigate = useNavigate(); // Initialize useNavigate

const handleGenerateMnemonic = async () => {
const mn = await generateMnemonic();
setMnemonic(mn);

if (!isMnemonicGenerated) {
setButtonText('Phrase Changed!');
setIsMnemonicGenerated(true);

setTimeout(() => {
setButtonText('Create Seed Phrase');
setIsMnemonicGenerated(false);
}, 1000);
}
};

const handleNavigateToDAppBrowser = () => {
navigate('/dapp-browser'); // Navigate to DAppBrowserPage
};

return (
<div className="bg-neutral-400 rounded-2xl flex flex-col justify-center items-center h-full min-h-screen">
<h1 className="text-6xl font-bold text-center mt-8">Wallet Generator</h1>
<MnemonicContainer mnemonic={mnemonic} />

<button
className={`p-2 rounded-3xl mt-8 transition-all duration-300 ease-in-out ${
isMnemonicGenerated ? 'bg-green-500' : 'bg-rose-500'
} hover:bg-green-600 hover:scale-105`}
onClick={handleGenerateMnemonic}
>
{buttonText}
</button>

<div className="flex lg:justify-between lg:flex-row flex-col items-center pb-5">
{mnemonic && <SolanaWallet mnemonic={mnemonic} />}
{mnemonic && <EthWallet mnemonic={mnemonic} />}
</div>

<button
className="p-2 rounded-3xl mt-8 bg-blue-500 hover:bg-blue-600 transition-all duration-300 ease-in-out"
onClick={handleNavigateToDAppBrowser}
>
Go to DApp Browser
</button>
</div>
);
}

export default Home;