Passkey app
you want users who still have email. they should get a wallet without a seed phrase lecture. moonx does that. pretending otherwise is how you invent support tickets.
stack
@moon-x/react-sdk-MoonXProvider,useMoonX().start(), ethereum wallet hooks- passkey step-up for wallet create / sign (moonx presence tokens)
- optional app session cookie after JWKS verification (k4d pattern:
POST /api/auth/session)
official: moonx getting started
steps
1. keys
create an app in the moonx dashboard. ship moon_pk_* to the browser. keep moon_sk_* on the server. forever.
2. provider
import { MoonXProvider } from "@moon-x/react-sdk";
import "@moon-x/react-sdk/style.css";
export function AppProviders({ children }: { children: React.ReactNode }) {
return (
<MoonXProvider publishableKey={process.env.NEXT_PUBLIC_MOONX_PUBLISHABLE_KEY!}>
{children}
</MoonXProvider>
);
}
3. sign in
import { useMoonX } from "@moon-x/react-sdk";
export function SignIn() {
const { start, user, ready } = useMoonX();
if (!ready) return <span>…</span>;
if (user) return <span>signed in</span>;
return <button onClick={() => start()}>sign in</button>;
}
email OTP or google/apple oauth. the modal is not optional homework.
4. wallet + passkey
import { useCreateWallet } from "@moon-x/react-sdk/ethereum";
import { useSignMessage } from "@moon-x/react-sdk/ethereum";
export function WalletBit() {
const { createWallet } = useCreateWallet();
const { signMessage } = useSignMessage();
return (
<>
<button onClick={() => createWallet()}>create wallet</button>
<button onClick={() => signMessage({ message: "hello" })}>sign</button>
</>
);
}
first sensitive op enrolls a passkey. moonx never holds the raw key material. that is the entire point.
5. backend session (optional, k4d style)
verify moonx access/identity tokens against your app JWKS, then mint your own http-only session. see backend verification. k4d wires this at /api/auth/session.
pitfalls
- missing
NEXT_PUBLIC_MOONX_PUBLISHABLE_KEYmeans a brick wall, not a vibe. - allowed origins in the moonx dashboard must include every host you actually use (gateway, escrow, docs, localhost ports).
- do not name this product "human wallet". that brand is taken. say passkey / embedded / email-in.