Skip to content

Commit 8ec9444

Browse files
Copilot0xrinegade
andcommitted
Add comprehensive GitHub Copilot instructions with validated build and test commands
Co-authored-by: 0xrinegade <[email protected]>
1 parent 1329c17 commit 8ec9444

File tree

41 files changed

+526
-977
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+526
-977
lines changed

.github/copilot-instructions.md

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# SVMSeek Wallet Development Instructions
2+
3+
Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.
4+
5+
## Working Effectively
6+
7+
### Bootstrap and Build
8+
- Install dependencies: `yarn install --frozen-lockfile` -- takes 2.5 minutes. NEVER CANCEL. Set timeout to 10+ minutes.
9+
- Build production: `yarn build` -- takes 1.5 minutes. NEVER CANCEL. Set timeout to 10+ minutes.
10+
- Build extensions: `./scripts/build-extensions.sh` -- takes 2 seconds.
11+
- Format code: `yarn fix:prettier` -- takes 1 second.
12+
13+
### Development Workflow
14+
- Start development server: `yarn start` -- may take 2-3 minutes to fully compile. NEVER CANCEL. Set timeout to 10+ minutes.
15+
- Test production build: `yarn global add serve && serve -s build -p 3001`
16+
- Run unit tests: `yarn test --watchAll=false --coverage=false` -- takes 1.2 minutes. NEVER CANCEL. Set timeout to 5+ minutes.
17+
18+
### Browser Extensions
19+
- Build all extensions: `./scripts/build-extensions.sh`
20+
- Produces ZIP files for Chrome (v3), Firefox (v2), Safari (v2), Edge (v3)
21+
- Extensions are ~3.3MB each and ready for store submission
22+
- Extension builds require successful `yarn build` first
23+
24+
### E2E Testing
25+
- Install browsers: `yarn playwright:install` -- takes 15 seconds. May show dependency warnings (normal in CI).
26+
- Run E2E tests: `yarn test:e2e` -- may fail with localStorage issues in headless mode (known limitation)
27+
- Use `yarn test:e2e-headed` for better compatibility
28+
29+
## Validation
30+
31+
- ALWAYS run through at least one complete end-to-end scenario after making changes.
32+
- ALWAYS validate the production build works: `yarn build && serve -s build`
33+
- Test the wallet interface at `/wallet` route to ensure core functionality works
34+
- Browser extension builds should always succeed if main build succeeds
35+
- Always run `yarn fix:prettier` before committing to maintain code style
36+
37+
## Platform Support
38+
39+
### Web Application
40+
- Node.js v20.18.0+ required (check with `node --version`)
41+
- Yarn v1.22.0+ recommended
42+
- Builds successfully in 1.5 minutes
43+
- Serves on localhost:3000 (dev) or any port with `serve -s build`
44+
45+
### Browser Extensions
46+
- Chrome: Manifest V3, 3.3MB
47+
- Firefox: Manifest V2, 3.3MB
48+
- Safari: Manifest V2, 3.3MB
49+
- Edge: Manifest V3, 3.3MB
50+
- Build time: 2 seconds
51+
52+
### Mobile (Android)
53+
- Requires Java 17+ (current system has Java 17)
54+
- Android build FAILS due to Java 21 requirement conflict
55+
- DO NOT attempt Android builds - requires configuration fixes
56+
- Script: `./scripts/build-mobile.sh` (will fail)
57+
58+
## Common Tasks
59+
60+
### Repository Structure
61+
```
62+
svmseek/
63+
├── src/ # React TypeScript source
64+
│ ├── components/ # React components
65+
│ │ ├── Explorer/ # Blockchain explorer components
66+
│ │ ├── ChatInterface.tsx
67+
│ │ └── GlassContainer.tsx
68+
│ ├── pages/ # Page components
69+
│ ├── utils/ # Utility functions
70+
│ └── context/ # React context providers
71+
├── public/ # Static assets
72+
├── docs/ # Documentation
73+
├── extension/ # Browser extension files
74+
├── scripts/ # Build and utility scripts
75+
├── e2e/ # E2E test files
76+
└── build/ # Production build output
77+
```
78+
79+
### Key Technologies
80+
- React 19 with TypeScript
81+
- Material-UI v7 for components
82+
- Solana Web3.js for blockchain
83+
- Styled Components for CSS-in-JS
84+
- Playwright for E2E testing
85+
- Capacitor for mobile (broken)
86+
87+
### File Listings
88+
89+
#### Root Directory
90+
```
91+
.github/ # GitHub Actions workflows
92+
docs/ # Comprehensive documentation
93+
extension/ # Browser extension source
94+
scripts/ # Build automation scripts
95+
src/ # Application source code
96+
package.json # Dependencies and scripts
97+
yarn.lock # Dependency lock file
98+
.nvmrc # Node version requirement (v20.18.0)
99+
```
100+
101+
#### Package.json Scripts (Key Ones)
102+
```json
103+
{
104+
"start": "craco start",
105+
"build": "craco build",
106+
"test": "craco test",
107+
"test:e2e": "npx playwright test --config=playwright.simple.config.ts",
108+
"fix:prettier": "prettier \"src/**/*.js\" \"extension/src/*.js\" --write",
109+
"build:extension-enhanced": "./scripts/build-extensions.sh"
110+
}
111+
```
112+
113+
## Known Issues
114+
115+
### E2E Tests
116+
- May fail with localStorage access errors in headless mode
117+
- Use `--headed` flag for better compatibility
118+
- Advanced performance tests fail due to security restrictions
119+
120+
### Mobile Builds
121+
- Android build fails due to Java version mismatch (requires Java 21, system has Java 17)
122+
- DO NOT attempt mobile builds until configuration is fixed
123+
124+
### Development Server
125+
- May take 2-3 minutes to fully start and serve content
126+
- Wait for "Compiled successfully" message before testing
127+
- Default port is 3000, may conflict with other services
128+
129+
## Build Outputs
130+
131+
### Successful Build Indicators
132+
- Web build: ~3MB total bundle size, multiple chunk files
133+
- Extension build: 4 ZIP files created (~3.3MB each)
134+
- Unit tests: 93 passed, 17 skipped (normal)
135+
136+
### File Sizes (Typical)
137+
- Main application bundle: ~3MB total
138+
- Extension packages: ~3.3MB each
139+
- Individual chunks: 1KB to 1.2MB range
140+
141+
## Debugging
142+
143+
### TypeScript Warnings
144+
- Version warning for @typescript-eslint is normal (uses TS 5.9.2 vs supported 5.2.0)
145+
- Does not affect functionality
146+
147+
### Bundle Size
148+
- Large bundle size warnings are normal for crypto applications
149+
- Consider code splitting if adding significant features
150+
151+
### Browser Compatibility
152+
- Chrome: Full support
153+
- Firefox: Full support
154+
- Safari: Full support
155+
- Edge: Full support
156+
- Mobile browsers: Supported via PWA
157+
158+
## Documentation References
159+
160+
- Main README: `README.md`
161+
- Developer Guide: `docs/developer-guide.md`
162+
- Build System: `docs/BUILD_SYSTEM.md`
163+
- Mobile Building: `docs/MOBILE_BUILD.md`

extension/extension-build-info.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
SVMSeek Wallet Browser Extensions
22
=================================
3-
Build Date: Thu Jul 24 13:14:00 UTC 2025
3+
Build Date: Mon Aug 11 15:44:03 UTC 2025
44
Extensions Built: Chrome, Firefox, Safari, Edge
55

66
Extension Details:
7-
- chrome: 6.9M (Manifest v3)
8-
- firefox: 6.9M (Manifest v2)
9-
- safari: 6.9M (Manifest v2)
10-
- edge: 6.9M (Manifest v3)
7+
- chrome: 3.3M (Manifest v3)
8+
- firefox: 3.3M (Manifest v2)
9+
- safari: 3.3M (Manifest v2)
10+
- edge: 3.3M (Manifest v3)
1111

1212
Distribution:
1313
- Chrome: Chrome Web Store (Manifest v3)

extension/src/background.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ function handleDisconnect(message, sender, sendResponse) {
5454

5555
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
5656
console.log('extensionChanel');
57-
console.log('message.data', message.data)
57+
console.log('message.data', message.data);
5858
if (message.channel === 'ccai_contentscript_background_channel') {
5959
if (message.data.method === 'connect') {
6060
handleConnect(message, sender, sendResponse);

extension/src/contentscript.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ window.addEventListener('ccai_injected_script_message', (event) => {
2121
);
2222
},
2323
);
24-
});
24+
});

extension/src/script.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
window.ccai = {
32
postMessage: (message) => {
43
const listener = (event) => {

src/components/AddHarwareWalletDialog.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ export default function AddHardwareWalletDialog({ open, onAdd, onClose }) {
2121
await provider.init();
2222
setPubKey(provider.publicKey);
2323
} catch (err) {
24-
devLog(
25-
`received error when attempting to connect ledger: ${err}`,
26-
);
24+
devLog(`received error when attempting to connect ledger: ${err}`);
2725
if (err.statusCode === 0x6804) {
2826
enqueueSnackbar('Unlock ledger device', { variant: 'error' });
2927
}

src/components/AddTokenDialog.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
useWalletTokenAccounts,
1212
} from '../utils/wallet';
1313
import { LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js';
14-
import { TOKENS } from '../utils/tokens/tokens'
14+
import { TOKENS } from '../utils/tokens/tokens';
1515
import { useUpdateTokenName } from '../utils/tokens/names';
1616
import { useAsyncData } from '../utils/fetch-loop';
1717
import LoadingIndicator from './LoadingIndicator';
@@ -125,7 +125,8 @@ export default function AddTokenDialog({ open, onClose }) {
125125
indicatorColor="primary"
126126
sx={{
127127
marginBottom: 1,
128-
borderBottom: (theme) => `1px solid ${theme.palette.background.paper}`,
128+
borderBottom: (theme) =>
129+
`1px solid ${theme.palette.background.paper}`,
129130
}}
130131
onChange={(e, value) => setTab(value)}
131132
>

src/components/BalancesList.js

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import List from '@mui/material/List';
33
import ListItem from '@mui/material/ListItem';
44
import ListItemText from '@mui/material/ListItemText';
55
import Paper from '@mui/material/Paper';
6-
import { logError } from '../utils/logger';
6+
import { logError } from '../utils/logger';
77
import {
88
refreshWalletPublicKeys,
99
useBalanceInfo,
@@ -101,9 +101,8 @@ export default function BalancesList() {
101101
const wallet = useWallet();
102102
const [publicKeys, loaded] = useWalletPublicKeys();
103103
const [showAddTokenDialog, setShowAddTokenDialog] = useState(false);
104-
const [showEditAccountNameDialog, setShowEditAccountNameDialog] = useState(
105-
false,
106-
);
104+
const [showEditAccountNameDialog, setShowEditAccountNameDialog] =
105+
useState(false);
107106
const [showMergeAccounts, setShowMergeAccounts] = useState(false);
108107
const [sortAccounts, setSortAccounts] = useState(SortAccounts.None);
109108
const { accounts, setAccountName } = useWalletSelector();
@@ -297,7 +296,7 @@ const ButtonContainer = styled('div')(({ theme }) => ({
297296
export function BalanceListItem({ publicKey, expandable, setUsdValue }) {
298297
const wallet = useWallet();
299298
const balanceInfo = useBalanceInfo(publicKey);
300-
const theme = useTheme()
299+
const theme = useTheme();
301300
const connection = useConnection();
302301
const [open, setOpen] = useState(false);
303302
const [, setForceUpdate] = useState(false);
@@ -407,16 +406,16 @@ export function BalanceListItem({ publicKey, expandable, setUsdValue }) {
407406
price === undefined // Not yet loaded.
408407
? undefined
409408
: price === null // Loaded and empty.
410-
? null
411-
: ((amount / Math.pow(10, decimals)) * price).toFixed(2); // Loaded.
409+
? null
410+
: ((amount / Math.pow(10, decimals)) * price).toFixed(2); // Loaded.
412411

413412
if (setUsdValue && usdValue !== undefined) {
414413
setUsdValue(publicKey, usdValue === null ? null : parseFloat(usdValue));
415414
}
416415

417416
return (
418417
<>
419-
<ListItem button onClick={() => expandable && setOpen((open) => !open)}>
418+
<ListItem button onClick={() => expandable && setOpen((open) => !open)}>
420419
<ListItemIcon>
421420
<TokenIcon mint={mint} tokenName={tokenName} size={28} />
422421
</ListItemIcon>
@@ -429,9 +428,7 @@ export function BalanceListItem({ publicKey, expandable, setUsdValue }) {
429428
{tokenSymbol ? ` (${tokenSymbol})` : null}
430429
</Title>
431430
}
432-
secondary={
433-
<AddressText>{subtitle}</AddressText>
434-
}
431+
secondary={<AddressText>{subtitle}</AddressText>}
435432
/>
436433
<div
437434
style={{
@@ -466,10 +463,8 @@ function BalanceListItemDetails({ publicKey, serumMarkets, balanceInfo }) {
466463
const [, setDepositDialogOpen] = useState(false);
467464
const [tokenInfoDialogOpen, setTokenInfoDialogOpen] = useState(false);
468465
const [exportAccDialogOpen, setExportAccDialogOpen] = useState(false);
469-
const [
470-
closeTokenAccountDialogOpen,
471-
setCloseTokenAccountDialogOpen,
472-
] = useState(false);
466+
const [closeTokenAccountDialogOpen, setCloseTokenAccountDialogOpen] =
467+
useState(false);
473468
const wallet = useWallet();
474469
const isProdNetwork = useIsProdNetwork();
475470
const [swapInfo] = useAsyncData(async () => {
@@ -558,7 +553,10 @@ function BalanceListItemDetails({ publicKey, serumMarkets, balanceInfo }) {
558553
) : null}
559554
</ButtonContainer>
560555
<Typography variant="body2" component="div">
561-
Deposit Address: <AddressText style={{ display: 'inline' }}>{publicKey.toBase58()}</AddressText>
556+
Deposit Address:{' '}
557+
<AddressText style={{ display: 'inline' }}>
558+
{publicKey.toBase58()}
559+
</AddressText>
562560
</Typography>
563561
<Typography variant="body2">
564562
Token Name: {tokenName ?? 'Unknown'}
@@ -568,7 +566,10 @@ function BalanceListItemDetails({ publicKey, serumMarkets, balanceInfo }) {
568566
</Typography>
569567
{mint ? (
570568
<Typography variant="body2" component="div">
571-
Token Address: <AddressText style={{ display: 'inline' }}>{mint.toBase58()}</AddressText>
569+
Token Address:{' '}
570+
<AddressText style={{ display: 'inline' }}>
571+
{mint.toBase58()}
572+
</AddressText>
572573
</Typography>
573574
) : null}
574575
<div style={{ display: 'flex', justifyContent: 'space-between' }}>

src/components/MergeAccountsDialog.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,11 @@ export default function MergeAccountsDialog({ open, onClose }) {
184184
</div>
185185
</Card>
186186
) : (
187-
<RowContainer justify={'space-between'} height={'100%'} direction={'column'}>
187+
<RowContainer
188+
justify={'space-between'}
189+
height={'100%'}
190+
direction={'column'}
191+
>
188192
<Title
189193
maxFont={'2.1rem'}
190194
fontSize="2.4rem"

src/components/Navbar/NavigationFrame.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,8 @@ export function WalletSelector() {
7272
const { accounts, setWalletSelector, addAccount } = useWalletSelector();
7373
const [anchorEl, setAnchorEl] = useState(null);
7474
const [addAccountOpen, setAddAccountOpen] = useState(false);
75-
const [
76-
addHardwareWalletDialogOpen,
77-
setAddHardwareWalletDialogOpen,
78-
] = useState(false);
75+
const [addHardwareWalletDialogOpen, setAddHardwareWalletDialogOpen] =
76+
useState(false);
7977
const [deleteMnemonicOpen, setDeleteMnemonicOpen] = useState(false);
8078
const [exportMnemonicOpen, setExportMnemonicOpen] = useState(false);
8179

@@ -245,7 +243,7 @@ function Footer() {
245243
const location = useLocation();
246244
devLog('location', location);
247245

248-
if (isConnectPopup) return null
246+
if (isConnectPopup) return null;
249247

250248
return (
251249
<>
@@ -261,8 +259,8 @@ function Footer() {
261259
{location.pathname.includes('restore')
262260
? 'Restore your wallet using seed phrase to get access for SPL assets management and interaction with dApps on the Solana blockchain.'
263261
: location.pathname.includes('create')
264-
? ' Create a cryptocurrency wallet for SPL assets management and secure connection and interaction with dApps on the Solana blockchain.'
265-
: 'Web-based cryptocurrency wallet or browser extension for SPL assets management and securely connect and interact with dApps on the Solana blockchain.'}
262+
? ' Create a cryptocurrency wallet for SPL assets management and secure connection and interaction with dApps on the Solana blockchain.'
263+
: 'Web-based cryptocurrency wallet or browser extension for SPL assets management and securely connect and interact with dApps on the Solana blockchain.'}
266264
</span>{' '}
267265
<Button
268266
variant="outlined"

0 commit comments

Comments
 (0)