Docs Navigation

Embedded Wallet

Embedded Wallet: Architecture

How 1Shot Wallet isolates passkey custody in OWS iframes, encrypts recoverable data client-side, and enables EIP-7702 gas abstraction without changing the EOA.

Architecture at a glance

1Shot Wallet implements the Open Wallet Standard (OWS) as three browser security contexts with distinct responsibilities. The application integrates with the Host Layer; the Host embeds the Branding Layer; and only the Branding Layer embeds the Signing Layer. This separation keeps application code and most wallet UI outside the context that handles private key material.

The production Branding and Signing Layers are served from wallet.1shotapi.com, with the signer under /signer/. The shared origin gives WebAuthn a stable relying-party ID, while separate nested documents preserve the RPC, lifecycle, and path-scoped policy boundaries. It is not an origin-isolation boundary between Branding and Signing. The Host must never embed /signer/ directly.

Trust boundaries

Host Layer (integrator application origin)
└── Branding Layer (wallet.1shotapi.com)
    ├── consent, account UI, chain logic, relayer and OID4 clients
    └── Signing Layer (wallet.1shotapi.com/signer/)
        └── WebAuthn, key derivation, curve signing and encryption
  • Host Layer — integrates through @1shotapi/ows-provider, exposes EIP-1193 to the application, and controls presentation and product styling.
  • Branding Layer — presents wallet and consent UI, validates wallet RPC requests, marshals chain-specific payloads, and communicates with blockchains, credential issuers, and the 1Shot relayer.
  • Signing Layer — performs WebAuthn ceremonies, derives keys, signs digests, and encrypts or decrypts wallet data. It does not implement chain APIs or make network requests.

Nested iframes and message boundaries

Host↔Branding communication uses Postmate and OWS RPC wrappers. Branding↔Signing uses a smaller versioned postMessage protocol. The signer starts only when it is double-nested, accepts requests only when event.source === window.parent, and sends responses to the requesting parent origin rather than using a wildcard target.

Both iframe factories set the WebAuthn Permissions Policy before navigation (publickey-credentials-get and publickey-credentials-create). The entire ancestor chain must be a secure context, so production Hosts must use HTTPS. Safari/WebKit account creation that cannot run inside a cross-origin iframe is handed to a first-party /create/ page; the resulting account is then unlocked through the normal nested architecture.

Note

The signer authenticates its immediate parent window and enforces double nesting; it does not independently authenticate the top-level Host. Branding is therefore the policy and consent boundary between application requests and signing operations, and the wallet origin is part of the trusted computing base.

Passkey-derived key custody

Normal wallet custody relies on the WebAuthn PRF extension. During an assertion, the authenticator evaluates a credential-bound pseudorandom function after user verification. The signer expands that output with HKDF-SHA-256 and domain-separated labels to derive a valid secp256k1 scalar, an Ed25519 seed, and an AES-256 key. The server receives neither the PRF output nor the derived private keys.

The secp256k1 key controls the EVM account. Ed25519 supports credential proofs and Solana keys, while the AES key protects recoverable wallet records. Derived key material remains inside the signer document and its in-memory session; chain-specific EIP-191, EIP-712, transaction, and EIP-7702 encoding occurs outside the signer, which receives digests to sign.

  • PRF is a requirement, not an optional enhancement. Missing PRF output fails account derivation; the implementation does not silently downgrade to a weaker storage mechanism.
  • Some authenticators do not return PRF bytes during registration. In that case the signer performs a follow-up assertion with prf.eval; this is still PRF-dependent.
  • Passphrase recovery and explicit private-key import can establish a temporary recovery session. They are alternate custody paths, not an automatic LongBlob fallback.
  • A WebAuthn ceremony and user verification are required whenever fresh PRF output is needed; the PRF cannot be evaluated silently by the wallet or relayer.

A deliberately small Signing Layer

The Signing Layer is shipped as plain JavaScript ES modules with no runtime npm dependencies and no build step. Its cryptographic implementations are vendored in source form from Noble rather than fetched as a dependency at runtime. This keeps the custody kernel inspectable, reproducible, and independent of the React application and its dependency graph.

The package is chain-agnostic by design: it signs curve digests and provides key-derived encryption primitives. Wallet SDKs outside the signer are responsible for transaction serialization and protocol-specific validation. This minimizes the code granted access to derived keys and reduces the surface that must remain stable as chain integrations evolve.

Signer Content Security Policy

Production nginx applies a path-scoped CSP to /signer/ and /signer/src/. It defaults every resource class to none, permits only same-origin scripts and styles, blocks normal connection APIs and remote resource loading, and removes common injection surfaces. The Branding application intentionally has a different policy because it must reach RPC endpoints, issuers, and the relayer.

Signing Layer CSP (abridged)

default-src 'none';
script-src 'self';
style-src 'self';
connect-src 'none';
img-src 'none';
object-src 'none';
child-src 'none';
frame-src 'none';
worker-src 'none';
base-uri 'none';
form-action 'none';
  • connect-src 'none' prevents fetch, XHR, WebSocket, and similar network channels from the signer.
  • No child frames, workers, objects, forms, images, fonts, or media are permitted.
  • frame-ancestors is deliberately omitted so permissionless Branding Layers can embed the signer. Runtime double-nesting and immediate-parent checks enforce the OWS relationship instead.
  • WebAuthn and Web Crypto are browser APIs and do not require signer network access.

User data, encryption, and recovery

Wallet records such as verifiable credentials and signed execution delegations are cached in the wallet origin for responsive local use. Recovery copies are serialized and encrypted client-side with AES-256-GCM using a key derived inside the signer, then uploaded as opaque ciphertext to the 1Shot relayer. Recovery requires WebAuthn authentication and signer-side decryption.

This design limits the relayer to ciphertext and availability metadata, but it is important to distinguish remote encryption from browser storage. The current local vault cache, account metadata, tracked assets, and activity data are stored unencrypted under the wallet origin. Derived signing keys are not stored in that Branding cache or intentionally returned through RPC, but compromise of the shared wallet origin must still be treated as compromise of the wallet's trusted computing base.

  • Encrypted remotely — verifiable credentials and delegation records stored for cross-session recovery.
  • Origin-local plaintext — the working vault cache and non-secret wallet metadata in browser storage.
  • Signer-held keys — secp256k1, Ed25519, and AES key material derived from PRF output and retained in memory only for the active signer session.
  • Authenticated recovery — relayer vault operations require a WebAuthn assertion; ciphertext is decrypted only after it returns to the signer.

Gas abstraction without changing the account address

For supported networks, 1Shot uses MetaMask's Delegation Framework and EIP-7702 to give the existing passkey-controlled EOA programmable smart-account behavior. The user keeps the same address and signs a chain- and nonce-bound authorization that points the EOA to MetaMask's EIP7702StatelessDeleGator implementation.

The stateless delegator enables constrained ERC-7710 executions without placing signer data in contract storage. EIP-7715-compatible wallet RPC methods let applications request user-approved permissions; the current wallet implements periodic ERC-20 transfer permissions and stores the resulting signed delegation in the encrypted recovery vault.

Note

Approving an execution permission signs and stores a delegation but does not by itself install the EIP-7702 designator on-chain. The upgrade authorization is attached to a later relayed send or cancellation when needed.

  1. The wallet checks whether the EOA already points to the approved Stateless7702 implementation on the selected chain.
  2. When an upgrade is required, the signer signs an EIP-7702 authorization. The wallet verifies that the authorization recovers to the expected EOA before submission.
  3. For a relayed transaction, the wallet creates exact-calldata delegations for the requested work and the selected ERC-20 fee payment. Caveats bind what the relayer may execute.
  4. The relayer estimates the ERC-7710 transaction, returns the required fee and execution context, and submits the work together with any one-time EIP-7702 authorization.
  5. The wallet polls the relayer task to a terminal transaction hash. On-chain contracts enforce the delegation signatures and caveats during redemption.

Security properties and decision considerations

  • No server-side signing key custody — wallet keys are deterministically derived after passkey verification rather than provisioned by the relayer.
  • Compartmentalized web surface — application, wallet policy/UI, and signing execute in separate documents; signer CSP denies connection APIs and remote resource loads.
  • Explicit user ceremonies — signing and key access are gated by browser-mediated WebAuthn UI and signer-hosted Confirm/Cancel controls.
  • Protocol-level scope — relayer authority is expressed as signed, caveated delegations rather than possession of the user's private key.
  • Platform dependency — normal custody requires browser, OS, and authenticator support for WebAuthn PRF and secure nested-iframe ceremonies.
  • Wallet-origin integrity remains material — Branding mediates consent, can read its origin-local cache, and shares an origin with Signing. Its supply chain, deployment controls, and XSS posture remain part of the trusted computing base.
  • Availability dependencies remain — chain RPCs, the selected authenticator ecosystem, and the relayer affect service availability even though the relayer cannot derive the wallet key.

Open-source implementations

The complete product wallet and its OWS custody foundation are available for architecture review, threat modeling, and independent deployment analysis.