Embedded Wallet
Embedded Wallet: Customization
Brand the 1Shot embedded wallet from your Host with configure — theme tokens, product copy, feature flags, and dark mode via a single partial-merge RPC.
Overview
The 1Shot Wallet Branding Layer (wallet.1shotapi.com) exposes a Host-only custom RPC — configure — for product branding without forking wallet CSS or touching the Signing Layer. Your Host calls it through proxy.rpc("configure", options) after OWSProxy.create().
Each call partially merges into the current style state, so you can set an initial theme at embed time and update colors or copy later (for example when the user toggles light/dark mode in your app). The RPC returns { ok: true, productName: string } with the resolved product name. Unknown top-level keys are rejected (Zod .strict()).
When and how to call configure
Call configure after the proxy handshake completes and before the user sees wallet UI you care about branding — typically before proxy.showWallet() on flyout hosts. Inline embeds (homepage-style previews) call configure immediately after OWSProxy.create(), as in the marketing site `EmbeddedWalletHero`.
Re-call configure whenever your Host theme changes; the playground Design mode applies changes live and re-applies the last payload when the iframe is recreated.
Minimal branding
const proxy = await OWSProxy.create(container, "https://wallet.1shotapi.com/");
await proxy.rpc("configure", {
copy: {
productName: "Acme Wallet",
tagline: "Powered by 1Shot",
},
theme: {
primary: "oklch(0.45 0.18 250)",
radius: "0.625rem",
},
});
proxy.showWallet();Marketing site embed (homepage / wallet page)
await proxy.rpc("configure", {
copy: {
productName: "1Shot Wallet",
tagline: "The ultimate embedded wallet.",
},
theme: {
primary: "#239aaa",
radius: "2rem",
},
});Presentation (showWallet / hideWallet, inline vs flyout) is separate from branding — set shell behavior through OWSProxy.create options, not the configure RPC.
theme tokens
Map Host-provided colors and typography to Branding Layer CSS variables. Values are any valid CSS color or length string (hex, oklch, rem, etc.).
theme.primary→--primarytheme.primaryForeground→--primary-foregroundtheme.background/theme.foreground→ page colorstheme.muted/theme.mutedForeground→ secondary surfaces and texttheme.border,theme.accent,theme.accentForeground→ chrome and highlightstheme.radius→--radius(e.g."0.625rem","2rem")theme.fontSans→--font-sansdark: true→ toggleshtml.darkon the Branding document
features flags
Optional booleans and allowlists that change wallet chrome without hiding Host-driven flows.
features.hideCloseBox— hide the flyout Close (×) control; defaultfalse. Use for inline hosts (browser extension side panel, fixed embeds).features.disableCredentials— hide the Credentials tab; defaultfalse. Host OID4 RPC flows still work.features.disableDelegations— hide the Delegations tab; defaultfalse. Host delegation flows still work.features.allowedChains— hex chain id strings ("0x1","0x2105", …) restricting the Network dropdown; omit or[]for all enabled catalog chains.
destinationUrl (status webhooks)
Optional top-level destinationUrl (HTTPS URL, ≤256 characters) is a URL to receive transaction status update webhooks from the 1Shot Relayer. When set, the Branding Layer includes it on wallet-submitted transactions so the Host backend can learn status before (or without) relying on the wallet UI.
Pass null or "" to clear a previously configured URL. Omit the field to leave the current value unchanged.
Webhook destination
await proxy.rpc("configure", {
destinationUrl: "https://my-app.example.com/relayer-webhook",
});copy overrides
Override user-facing strings across connect, setup, signing consent, credentials, and advanced flows. Keys are grouped by surface — you only need to set the strings your product exposes.
Some credential copy supports template placeholders substituted at runtime: {issuerName}, {issuerId}, {verifierName}, {verifierId}, {credentialType}, {credentialIssuer}, {count}.
Optional nested **copy.passkeyPrompt.*** overrides Signing Layer Confirm/Cancel copy during export/import private key ceremonies (for example copy.passkeyPrompt.exportPrivateKey.title).
For the exhaustive key list (every modal label and error string), see 1shot-wallet SKILL.md.
- Product chrome —
copy.productName,copy.tagline - Connect & setup —
copy.connect.*,copy.walletSetup.*,copy.passkeyName.* - Signing consent —
copy.personalSign.*,copy.typedData.* - Credentials —
copy.credentialOffer.*,copy.credentialPresentation.*,copy.credentials.*(tab, list, detail, errors) - Advanced —
copy.exportPrivateKey.*,copy.importPrivateKey.*,copy.advancedOptions.*
Reference implementations
Marketing site — `EmbeddedWalletHero` on the homepage and 1Shot Wallet solution page sets productName, tagline, theme.primary, and optional theme.radius after create.
Playground Design mode — /playground exposes a live WalletConfigurator backed by styleForm.ts: tweak theme, copy, and features, then export/import JSON for your Host configure payload.
What not to do
- Do not embed
https://wallet.1shotapi.com/signer/from the Host — always Host → Branding → Signing. - Do not inject CSS into the wallet iframe from the Host page — use
configuretokens and copy only. - Do not rely on undocumented keys — they fail validation on strict
configureschemas.
Test before production
Open the wallet playground, switch to Design mode, and iterate on theme and copy with live preview. Export the JSON payload and paste it into your Host integration. Pair with the 1Shot Wallet quickstart for EIP-1193 connect and send flows.