Gate built-in Cashu mint wallet to native-only (browser CORS reality)

Browsers block most Cashu mints (no CORS headers), so minting/melting fails unreliably in-browser — and the failed fetches spam the console. Rather than ship a broken browser feature:

- CashuWalletCard: in a browser, render a clear "built-in ecash runs in the app" notice pointing users to zaps (NWC/WebLN/Lightning address) which work fine in-browser; full mint wallet renders only on native (Capacitor)
- useCashu: skip coco/IndexedDB/mint init entirely in the browser (isNativePlatform guard) — stops the recurring "Failed to fetch mint" console errors at the source
- Zaps/tips (the app's real money flow) are unaffected — they never touch a Cashu mint

Native builds get the full wallet with minibits working directly (no CORS jail), per the earlier platform-aware work.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
This commit is contained in:
shakespeare.diy 2026-07-24 17:32:40 +07:00
parent fc7564a6f8
commit 18f32a14bf
2 changed files with 65 additions and 1 deletions

View file

@ -39,8 +39,67 @@ import {
import { useToast } from '@/hooks/useToast'; import { useToast } from '@/hooks/useToast';
import { QRScannerModal } from '@/components/wallet/QRScannerModal'; import { QRScannerModal } from '@/components/wallet/QRScannerModal';
import { MintPrivacyManager } from '@/components/wallet/MintPrivacyManager'; import { MintPrivacyManager } from '@/components/wallet/MintPrivacyManager';
import { isNativePlatform } from '@/lib/platform';
import { Smartphone } from 'lucide-react';
/**
* The built-in Cashu (ecash) mint wallet only works where there's no browser
* CORS jail — i.e. in the native app. In a plain web browser most mints block
* requests (no Access-Control-Allow-Origin), so minting/melting fails. Rather
* than ship a browser feature that unreliably errors, we gate the full wallet
* to native and, in the browser, explain how to transact (zaps via a connected
* Lightning wallet, or use the native app).
*
* Zaps/tips — the app's actual money flow — keep working in the browser via
* NWC / WebLN / Lightning address, none of which touch a Cashu mint.
*/
export function CashuWalletCard() { export function CashuWalletCard() {
if (!isNativePlatform()) {
return <CashuWalletBrowserNotice />;
}
return <CashuWalletCardNative />;
}
function CashuWalletBrowserNotice() {
return (
<Card className="border-orange-500/30 bg-gradient-to-br from-orange-500/5 to-yellow-500/5">
<CardHeader className="p-4">
<CardTitle className="text-base font-bold flex items-center gap-2">
<Wallet className="h-5 w-5 text-orange-500" />
Built-in Ecash Wallet
</CardTitle>
<CardDescription className="text-xs">
The built-in Cashu wallet runs in the SkateSpots app
</CardDescription>
</CardHeader>
<CardContent className="space-y-4 p-4 pt-0">
<div className="flex items-start gap-3 rounded-xl bg-orange-500/10 border border-orange-500/20 p-3">
<Smartphone className="h-5 w-5 text-orange-400 flex-shrink-0 mt-0.5" />
<div className="space-y-1">
<p className="text-sm font-semibold">Open SkateSpots in the app to use ecash</p>
<p className="text-xs text-muted-foreground leading-relaxed">
Web browsers block most Cashu mints for security reasons, so the built-in ecash
wallet is available in the native app. Everything else — sending and receiving
<strong className="text-foreground"> zaps</strong> — works right here in your browser.
</p>
</div>
</div>
<div className="rounded-xl border bg-muted/40 p-3 space-y-2">
<p className="text-sm font-semibold flex items-center gap-2">
<Zap className="h-4 w-4 text-amber-500" /> Zap &amp; tip in the browser
</p>
<p className="text-xs text-muted-foreground leading-relaxed">
Connect a Lightning wallet below (Nostr Wallet Connect or a browser extension like
Alby) to zap spots, events, coaches, and crews. No Cashu mint required.
</p>
</div>
</CardContent>
</Card>
);
}
function CashuWalletCardNative() {
const { const {
coco, coco,
repositories, repositories,

View file

@ -97,7 +97,12 @@ export function useCashu(): UseCashuReturn {
// Initialize the coco manager // Initialize the coco manager
const initializeCocoManager = useCallback(async () => { const initializeCocoManager = useCallback(async () => {
if (isInitialized || isLoading) return; if (isInitialized || isLoading) return;
// The Cashu mint wallet is native-only: browsers block most mints via CORS,
// so there's no point spinning up coco / IndexedDB / mint probing (and the
// failed mint fetches spam the console). Skip init entirely in the browser.
if (!isNativePlatform()) return;
setIsLoading(true); setIsLoading(true);
setError(null); setError(null);