feat: Basalt Wallet extension integration + perf optimizations#1
Open
feat: Basalt Wallet extension integration + perf optimizations#1
Conversation
- Add BasaltProvider TypeScript declarations (window.basalt) - Detect extension on hydrate, auto-restore previous sessions - Add "Extension" tab in WalletModal with one-click connect - Show green dot badge on WalletButton when connected via extension - Route transactions through window.basalt.sendTransaction() when using extension (DEX ops, contract calls, transfers) - Listen for accountsChanged/disconnect events from extension - Guard hydrate() against duplicate event listener registration - Combine 10 Zustand selectors into single compound selector with useShallow in useWallet hook - Add exponential backoff to receipt polling (2s→4s→8s cap)
- Add optimizePackageImports for @noble/* libraries in next.config - Add immutable cache headers for static assets - Fix tokens.sort() mutation in useTokenBalances cache key - Hoist lightweight-charts dynamic import to module level to avoid re-importing on every chartData change
There was a problem hiding this comment.
Pull request overview
Integrates Basalt Wallet browser extension support across the wallet store/UI and routes transactions through the extension provider, alongside a set of targeted client/perf improvements for Next.js config, SWR key stability, and chart initialization.
Changes:
- Add Basalt extension provider typings + wallet store support (detect/connect/events, source tracking).
- Update wallet UI (modal/tab + button indicator) and transaction submission to use the extension flow.
- Apply perf fixes: Next immutable caching + optimized imports, SWR key immutability, and hoisted chart module import.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
src/stores/wallet.ts |
Adds extension detection/connect, tracks wallet source, and wires extension event handling. |
src/lib/types/basalt-provider.ts |
Introduces window.basalt provider type declarations. |
src/hooks/useWallet.ts |
Reduces Zustand subscriptions via a compound selector with useShallow. |
src/hooks/useTransaction.ts |
Adds extension-based submission path + receipt polling backoff. |
src/hooks/useTokenBalances.ts |
Prevents SWR cache-key mutation by avoiding in-place sort(). |
src/components/wallet/WalletModal.tsx |
Adds an Extension tab and source badge; hides lock for extension wallets. |
src/components/wallet/WalletButton.tsx |
Adds extension connection indicator dot. |
src/components/pool-detail/PriceChart.tsx |
Hoists dynamic import to cache module load across renders. |
next.config.ts |
Adds immutable caching headers and optimizePackageImports. |
Comments suppressed due to low confidence (1)
src/hooks/useTransaction.ts:27
- The
submit(tx, privateKey)API now documents thatprivateKeyis ignored for extension wallets, forcing callers to pass a dummyUint8Arrayjust to satisfy the signature. Consider changing the signature to makeprivateKeyoptional (or overload it) and only require it whensource !== 'extension'to keep the hook’s API clear and harder to misuse.
interface UseTransactionReturn {
/** Submit a transaction. If connected via extension, privateKey is ignored (pass any Uint8Array). */
submit: (
tx: UnsignedTransaction,
privateKey: Uint8Array,
) => Promise<ReceiptResponse | null>;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+83
to
85
| // Check for local keystore | ||
| if (hasKeystore()) { | ||
| set({ isLocked: true }); |
Comment on lines
+88
to
+104
| // Listen for extension events | ||
| const provider = getProvider(); | ||
| if (provider) { | ||
| provider.on('accountsChanged', (accounts) => { | ||
| const { source } = get(); | ||
| if (source === 'extension') { | ||
| const accs = accounts as string[]; | ||
| set({ address: accs[0] ?? null, isConnected: accs.length > 0 }); | ||
| } | ||
| }); | ||
| provider.on('disconnect', () => { | ||
| const { source } = get(); | ||
| if (source === 'extension') { | ||
| set({ address: null, isConnected: false, source: null }); | ||
| } | ||
| }); | ||
| } |
| attempts++; | ||
| if (tryDetect() || attempts >= 10) { | ||
| clearInterval(poll); | ||
| window.removeEventListener('basalt#initialized', handler); |
Comment on lines
+79
to
83
| const timer = setTimeout(resolve, delay); | ||
| controller.signal.addEventListener('abort', () => { | ||
| clearTimeout(timer); | ||
| resolve(); | ||
| }); |
| const [modalOpen, setModalOpen] = useState(false); | ||
| const [mounted, setMounted] = useState(false); | ||
| const { address, isConnected, isLocked, hydrate } = useWalletStore(); | ||
| const { address, isConnected, isLocked, source, extensionDetected, hydrate } = useWalletStore(); |
|
|
||
| return ( | ||
| <Modal open={open} onOpenChange={onOpenChange} title="Wallet"> | ||
| <Tabs.Root defaultValue={defaultTab} className="w-full"> |
| output: 'standalone', | ||
| reactStrictMode: true, | ||
| experimental: { | ||
| optimizePackageImports: ['@noble/ed25519', '@noble/hashes', '@noble/curves'], |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
window.basaltproviderChanges
Wallet Integration (6 files):
BasaltProviderTypeScript declarations forwindow.basaltwindow.basalt.sendTransaction()when using extensionuseShallow(10 subscriptions → 1)Performance (3 files):
optimizePackageImportsfor @noble/*, immutable cache headerstokens.sort()mutation in SWR cache keyimport('lightweight-charts')to module levelTest plan
npm run dev, open/swap, connect via Extension tab