> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://www.openfort.io/api/mcp` to find what you need.
>
> **Have feedback?** Use `submit_feedback` on the same MCP server.

# Cross-app wallet signers

The Ecosystem SDK is agnostic to the key management solution you choose to use. The signer is the part of your [wallet UI](https://www.openfort.io/docs/products/cross-app-wallet/setup/react/wallet-ui) that holds the keys and produces signatures once a request reaches a `/sign/*` route. Pick one before building those routes: it decides how a user proves ownership of the wallet and what happens on a new device.

* [Social Login](https://www.openfort.io/docs/products/cross-app-wallet/setup/signers/openfort) — Social authentication. Non-custodial signer generated using MPC-SSS with social login compatibility.
* [Passkey](https://www.openfort.io/docs/products/cross-app-wallet/setup/signers/passkey) — WebAuthN validation. Self-custodial signer controlled by onchain Passkey (WebAuthN) validation.

## Comparing the two

|  | [Social login](https://www.openfort.io/docs/products/cross-app-wallet/setup/signers/openfort) | [Passkey](https://www.openfort.io/docs/products/cross-app-wallet/setup/signers/passkey) |
|--|--------------|---------|
| Custody | Non-custodial, key shares generated with MPC-SSS | Self-custodial, controlled by an onchain-validated WebAuthn credential |
| User proves ownership with | An Openfort auth method, such as social login | A passkey on the user's device |
| Wallet UI setup | `OpenfortProvider` from `@openfort/ecosystem-js/react`, configured with `embeddedSignerConfiguration` | A wagmi connector configured with your `rpId`; the sample pairs it with a [Safe](https://safe.global) smart account and the [Safe7579](https://github.com/rhinestonewtf/safe7579) adapter |
| Extra keys required | Shield publishable key, plus an encryption session endpoint for `RecoveryMethod.AUTOMATIC` | None |
| Extra routes required | `/sign/authenticate` and `/sign/recover` for login and recovery | None |

## What stays the same

Both signers sit inside `EcosystemProvider` and serve the same `/sign/*` routes, so the RPC surface your apps consume does not change with the choice. Swap the signer and [`personal_sign`](https://www.openfort.io/docs/products/cross-app-wallet/rpc/personal_sign), [`eth_sendTransaction`](https://www.openfort.io/docs/products/cross-app-wallet/rpc/eth_sendTransaction), and [`wallet_grantPermissions`](https://www.openfort.io/docs/products/cross-app-wallet/rpc/wallet_grantPermissions) keep behaving identically for the integrating app.

Branding, routing, and window strategy are also independent of the signer. See [Wallet design and routing](https://www.openfort.io/docs/products/cross-app-wallet/setup/react/wallet-ui) for the routes each RPC method expects, and [Why cross-app wallets?](https://www.openfort.io/docs/products/cross-app-wallet/setup/why) for how the wallet UI and the client packages fit together.
