From 60de8c8fe5625e598141ff1ec4aadf5b32060357 Mon Sep 17 00:00:00 2001 From: jwinterm Date: Sun, 7 Jun 2026 19:11:05 -0400 Subject: [PATCH] feat: install postMessage transport for v0.3.0+ Smirk wallet iframes Adds a runtime that auto-detects parent-frame context and installs window.smirk via postMessage, so smirk.cash works inside the v0.3.0 Smirk desktop wallet's embedded browser the same way it already works under the v0.2.x browser extension. Extension-injected window.smirk takes precedence, so existing dapps and the v0.2.x flow are unchanged. Local mirror of @smirk/dapp-api's installSmirkPageApi pending that package being published to npm; see the file header for the sync contract. --- src/app/SmirkBridgeBootstrap.tsx | 22 +++++ src/app/layout.tsx | 2 + src/lib/smirk-iframe-bridge.ts | 159 +++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 src/app/SmirkBridgeBootstrap.tsx create mode 100644 src/lib/smirk-iframe-bridge.ts diff --git a/src/app/SmirkBridgeBootstrap.tsx b/src/app/SmirkBridgeBootstrap.tsx new file mode 100644 index 0000000..3cdaea0 --- /dev/null +++ b/src/app/SmirkBridgeBootstrap.tsx @@ -0,0 +1,22 @@ +'use client'; + +/** + * `SmirkBridgeBootstrap` — mounts the `installSmirkPageApi` runtime + * on every page of smirk.cash so the site works both inside the + * v0.2.x browser extension (no-op; extension wins) and inside the + * v0.3.0+ desktop wallet's embedded iframe (postMessage transport). + * + * Lives in the root layout so every route picks it up automatically — + * page.tsx, TipPageClient.tsx, future id/forum subdomains, all of it. + * No other files need to know about the v0.3.0 transport. + */ + +import { useEffect } from 'react'; +import { installSmirkPageApi } from '@/lib/smirk-iframe-bridge'; + +export function SmirkBridgeBootstrap(): null { + useEffect(() => { + installSmirkPageApi(); + }, []); + return null; +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 960a455..fbbcb1e 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,6 +1,7 @@ import type { Metadata } from "next"; import { Geist_Mono } from "next/font/google"; import "./globals.css"; +import { SmirkBridgeBootstrap } from "./SmirkBridgeBootstrap"; const geistMono = Geist_Mono({ variable: "--font-geist-mono", @@ -46,6 +47,7 @@ export default function RootLayout({ return ( +
{children}