diff --git a/category/code-examples.mdx b/category/code-examples.mdx index dd410567..0376b796 100644 --- a/category/code-examples.mdx +++ b/category/code-examples.mdx @@ -5,10 +5,40 @@ mode: wide --- - - Create a sub-org with a passkey user + + Embedded Consumer Wallet + + Embedded Business Wallet + + + + Embedded Wallet-as-a-Service + + + + Create a sub-org with a passkey user + + - ![Embedded Consumer Wallets architecture: user/service, wallets, policy engine, authenticators, secure enclave infrastructure](/assets/files/Consumer_Wallets.png) + ![Embedded Consumer Wallets architecture: user/service, wallets, policy engine, authenticators, + secure enclave infrastructure](/assets/files/Consumer_Wallets.png) ## Example: Neobank-style embedded consumer wallet @@ -120,6 +176,7 @@ Follow these steps to launch an embedded consumer wallet experience inside your - [Auth Proxy overview](https://docs.turnkey.com/reference/auth-proxy) - [Email authentication (OTP)](https://docs.turnkey.com/authentication/email) - [Passkeys integration](https://docs.turnkey.com/authentication/passkeys/integration) + Install and initialize the Turnkey SDK at app startup so sessions and wallet operations are ready immediately. @@ -128,6 +185,7 @@ Follow these steps to launch an embedded consumer wallet experience inside your - [Embedded Wallet Kit (React)](https://docs.turnkey.com/sdks/react/getting-started) - [Embedded Wallet Kit (React Native)](https://docs.turnkey.com/sdks/react-native/getting-started) + Build your login/signup flow and gate wallet actions until: @@ -139,6 +197,7 @@ Follow these steps to launch an embedded consumer wallet experience inside your - [Wallet authentication guide](/sdks/react/auth) - [OAuth signup helper](https://docs.turnkey.com/generated-docs/react-wallet-kit/client-context-type-add-oauth-provider) + **On first login:** @@ -152,6 +211,7 @@ Follow these steps to launch an embedded consumer wallet experience inside your - [Sub-organization customization](/sdks/react/sub-organization-customization) - [Create wallet](https://docs.turnkey.com/sdks/react/using-embedded-wallets#creating-an-embedded-wallet) - [Create wallet accounts](https://docs.turnkey.com/sdks/react/using-embedded-wallets#creating-wallet-accounts) + Expose wallet functionality directly inside your app. @@ -165,13 +225,18 @@ Follow these steps to launch an embedded consumer wallet experience inside your **Import / Export / Recovery (Optional) Docs** - [Import & Export wallets](https://docs.turnkey.com/wallets/export-wallets) + ## Next steps -Ready to build? You can start with the [Embedded Wallets Quickstart](/getting-started/embedded-wallet-quickstart), explore the [Features overview](/embedded-wallets/features/overview), or browse the [Code Examples Hub](/category/code-examples). +Ready to build? You can start with the +[Embedded Wallets Quickstart](/getting-started/embedded-wallet-quickstart), explore the +[Features overview](/embedded-wallets/features/overview), or browse the +[Code Examples Hub](/category/code-examples). - ![Turnkey in action: Moonshot onboarding — email sign-in, verification, portfolio, and asset view](/assets/files/moonshot_consumerwallet.png) - \ No newline at end of file + ![Turnkey in action: Moonshot onboarding — email sign-in, verification, portfolio, and asset + view](/assets/files/moonshot_consumerwallet.png) + diff --git a/embedded-wallets/embedded-waas.mdx b/embedded-wallets/embedded-waas.mdx new file mode 100644 index 00000000..4f976946 --- /dev/null +++ b/embedded-wallets/embedded-waas.mdx @@ -0,0 +1,276 @@ +--- +title: "Embedded WaaS" +description: + "Build a white-labeled Wallet-as-a-Service product on Turnkey for your developer platform. This + guide covers the step-by-step implementation for embedding non-custodial wallets into your + platform." +--- + +## Why Turnkey for Embedded WaaS? + +Turnkey provides the infrastructure to embed wallets into your developer product. Use it to +provision isolated user wallets within secure enclaves, enforce signing policies and spending +limits, and build white-labeled SDKs and UI components on top of Turnkey's API. + +## Core Principles + +- **Segregated environments per end user:** Each end user's wallets, credentials, policies, and + activity logs are fully isolated from other users and from your platform's management layer. +- **Configurable admin and billing controls:** Every fund-moving transaction requires sign-off from + both the end user and your platform, to enforce billing and compliance at the signing layer, not + only in application code. +- **User-authenticated action:** No transaction executes without the end user’s authentication + (e.g., passkey). +- **Non-custodial by design:** Your platform controls allow you to block transactions but cannot + move funds without user sign-off. +- **User-controlled key export:** End users can [export their wallet](/wallets/export-wallets) + independently, even if your platform goes offline or they choose to leave. + +## Architecture + +The diagram below shows the recommended sub-org structure for a WaaS deployment using 2-of-2 root +quorum signing. + + + typical waas provider and end user co-signing model + + +### Transaction Authorization Flow + +The sequence below describes the default funds-moving flow under the 2-of-2 root quorum model: + +- End user initiates a transaction from the embedded wallet UI. +- End user approves via their authenticator (e.g. passkey). Turnkey records the activity as + partially approved. +- Your platform evaluates on its own backend: billing status, risk/compliance rules, and any other + checks. +- Provider approves via API key. The transaction executes. +- If the provider withholds approval, the transaction does not execute. + + + typical waas negative control for transaction permission + + +Relevant docs: [Activities & approvals](/concepts/overview#activities) | +[Root quorum](/concepts/users/root-quorum) + +## How to Get Started on Embedded WaaS with Turnkey + +### Step 1: Define the Tenant Model and Ownership Boundaries + +Map each end user to a [Turnkey sub-organization](/concepts/sub-organizations). + +- **Isolated tenants:** Each sub-org is a self-contained data boundary, with wallets, policies, + authenticators, and activity logs fully isolated from one another. +- **Scoped parent org permissions:** Your parent organization has read-only access to sub-orgs and + can initiate auth and recovery flows, but cannot sign transactions or modify policies within them. +- **External mapping:** Track the relationship between your platform's user IDs and their + corresponding Turnkey sub-org IDs in your own database. + +### Choose Your Custody Model + +Turnkey's primitives are flexible enough to support a wide range of custody configurations, which +can be combined with other models (e.g., self-custody or custodial) to support your needs. For +embedded WaaS, we recommend a co-managed custody model: + +| Consideration | Co-managed (Recommended) | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------ | +| Transaction control | Both end user and your platform must approve. Cryptographic enforcement of billing, compliance, and risk controls. | +| Custody classification | Non-custodial. Your platform can block but not move funds alone. | +| Setup complexity | Staged sub-org creation (create at 1-of-2, configure policies, raise to 2-of-2). | +| Best fit | Most WaaS products needing billing gates, compliance holds, or service-level transaction approval. | + +Relevant docs: [Sub-organizations](/concepts/sub-organizations) | +[Root quorum](/concepts/users/root-quorum) + +### Step 2: Design the Sub-Organization Control Model + +Define what lives inside each sub-org and how control is shared between the platform and the end +user. + +- **End user (root):** Authenticated via passkey or equivalent user-controlled authenticator. +- **WaaS provider (root):** Authenticated via API key. Used to approve or block transactions based + on your service rules. +- **Delegated Access (optional):** If needed for automation or backend-initiated workflows, add a + scoped non-root API key via [Delegated Access](/concepts/policies/delegated-access-overview). DA + must be tightly policy-scoped and should never have broad signing authority or bypass user + consent. + +**Relevant docs:** [Delegated Access](/concepts/policies/delegated-access-overview) | +[Policy scoping](/concepts/policies/overview) + +### Step 3: Define Default Wallet and Policy Template + +Specify what gets created in every sub-org by default: wallet structure, supported chains/accounts, +and baseline policies. + +For the 2-of-2 quorum model, establish the threshold last so the backend can configure policies +(including export) with only your platform’s approval. Start by creating a sub-org with both root +users and wallets. Then, create the export policy while the platform has sole root access (Step 3b). +Once the 2-of-2 quorum is established (step 3c), the end user can trigger exports via this policy +without needing your platform’s co-signature. + +This keeps the co-managed model non-custodial because end users can always export their keys and +access their funds directly, independent of your platform. + +| Step | Action | Quorum State | +| ---- | --------------------------------------------- | ------------ | +| 3a | Create sub-org with both root users \+ wallet | 1-of-2 | +| 3b | Create export policy for end user | 1-of-2 | +| 3c | Update threshold to 2 | **2-of-2** | + +**3a. Create sub-org with both root users at 1-of-2 threshold** + +```javascript +const subOrg = await turnkeyClient.createSubOrganization({ + parameters: { + subOrganizationName: `User Wallet - ${userId}`, + rootUsers: [ + { userName: "WaaS Provider", apiKeys: [{ publicKey: PROVIDER_KEY }] }, + { + userName: "End User", + authenticators: [ + { + /* passkey */ + }, + ], + }, + ], + rootQuorumThreshold: 1, + wallet: { + walletName: "Primary Wallet", + accounts: [ + { + /* eth account */ + }, + ], + }, + }, +}); +``` + +**3b. Create export policy (user escape hatch)** + +```javascript +await turnkeyClient.createPolicy({ + organizationId: subOrgId, + parameters: { + policyName: "Allow User Wallet Export", + effect: "EFFECT_ALLOW", + consensus: `approvers.any(user, user.id == '${endUserId}')`, + condition: `activity.type == 'ACTIVITY_TYPE_EXPORT_WALLET' + && wallet.id == '${walletId}'`, + }, +}); +``` + +**3c. Raise threshold to 2-of-2** + +```javascript +await turnkeyClient.updateRootQuorum({ + organizationId: subOrgId, + parameters: { + threshold: 2, + userIds: [providerUserId, endUserId], + }, +}); +``` + +Relevant docs: [Export wallets](/wallets/export-wallets) | +[Policy examples](/concepts/policies/examples/access-control) + +### Step 4: Build the Developer-Facing SDK or Integration Surface + +Create the SDK, APIs, or UI components that downstream developers integrate with. Abstract away +Turnkey and expose only your platform's intended wallet, auth, and signing flows. + +- **Embedded Wallet Kit (EWK):** Fork or wrap [Embedded Wallet Kit](/sdks/react/index) components + (e.g. authentication, wallet UI, and approval prompts) with your branding and surface "pending + provider approval" states. +- **Backend service:** Handle provider root approvals (via API key), billing and risk evaluation, + and activity monitoring through your backend. +- **SDK abstraction layer:** Wrap Turnkey's SDK calls behind your own interface for full control + over the developer experience, with flexibility to swap or upgrade infrastructure without breaking + integrations. + +Relevant docs: [Embedded Wallet Kit](/sdks/react/index) | +[SDK reference](/generated-docs/react-wallet-kit/client-context-type-handle-login) + +### Step 5: Incorporate the Embedded Wallet into the Platform Flow + +Wire the wallet into your onboarding and runtime flows so every downstream integration inherits a +working embedded wallet. + +- **Onboarding:** Handle Turnkey org setup, auth configuration, and the staged sub-org creation flow + as part of your user registration. The end user should experience passkey registration (or + equivalent) as a natural part of sign-up. +- **Client initialization:** Initialize the Turnkey client with the user's sub-org context on each + session. Use [sessions](/authentication/sessions) for batched signing workflows to reduce + authentication friction during active use. +- **Transaction flow:** Surface the approval prompt via EWK components, submit the user's approval + to Turnkey, run your backend checks, then co-sign or withhold. +- **Recovery:** Expose the export flow in your settings UI so users can self-serve wallet recovery. + Turnkey's enclave encrypts the mnemonic to a user-generated target key via HPKE. Neither Turnkey + nor your platform can view the exported material. + +## Use Cases + +| Need | Configuration | +| -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Fintech or neobank with card-linked crypto wallets | **Co-managed with billing gates:** Provider co-signs after verifying account standing. Export policy as user escape hatch. Passkey auth for consumer UX. | +| Dev tooling platform reselling embedded wallets | **White-labeled EWK with SDK abstraction:** Downstream developers integrate with your SDK, never touching Turnkey directly. Segregated environments per end user, provider co-sign for compliance. | +| Self-custody consumer wallet | **Self-custody model:** Maximum user sovereignty. Provider handles auth initiation and UX but has no signing authority. Application-layer controls for billing. | +| Institutional or high-value accounts | **Co-managed with policy-based limits:** Transaction-aware policies for amount thresholds, sanctioned address deny-lists, and chain restrictions. | + +## The Result: Non-Custodial Control at the Infrastructure Layer + +Embedded WaaS with Turnkey lets you build wallets into your dev platform without owning custody or +managing key infrastructure. + +- **Tenant isolation:** Isolated user wallets, credentials, and activity logs help protect end + users’ key material and data. +- **Quorum control:** 2-of-2 root quorum guarantees explicit user consent on every transaction. +- **Flexible models:** Customers can evolve custody models over time as needs change. +- **Full auditability:** Every operation is logged and nothing moves unless both the user and your + platform approve. + +## DIMO Case Study + +[DIMO](https://dimo.co/) is a decentralized transportation network connecting over 165,000 vehicles. +Drivers share vehicle data to access apps for insurance, fleet management, and predictive +maintenance. DIMO uses Turnkey to power its embedded wallet infrastructure, replacing a fragmented +onboarding flow that required external wallet apps and seed phrases. + +With Turnkey, DIMO delivered: + +- **Passkey-first onboarding:** DIMO replaced seed phrases and external wallet installs with + Turnkey's passkey authentication, cutting sign-in time from 2 minutes to 10 seconds and boosting + onboarding completion by 30%. +- **Sub-org per user with full ownership:** Each driver gets an independent sub-organization, giving + them complete control of their credentials and transactions while DIMO retains the governance + layer needed for enterprise compliance. +- **On-chain transaction SDK:** DIMO's open-source + [transactions SDK](https://github.com/DIMO-Network/transactions) uses Turnkey's stamper and signer + primitives directly, supporting vehicle registration, data permissions (SACD), staking, and device + pairing, all backed by smart account sessions to minimize signature prompts. +- **2-3 week integration:** Full deployment into DIMO's global login stack completed in under three + weeks using Turnkey's SDKs and responsive support. + +Read the full case study: +[How DIMO is bringing transportation solutions onchain with Turnkey](https://www.turnkey.com/customers/how-dimo-is-bringing-transportation-solutions-onchain-with-turnkey) + +## Resources + +- [Sub-organizations](/concepts/sub-organizations): Tenant isolation and user modeling +- [Root quorum](/concepts/users/root-quorum): Multi-party approval and ownership configuration +- [Policy engine](/concepts/policies/overview): Authorization rules, transaction controls, and + export policies +- [Embedded Wallet Kit](/reference/embedded-wallet-kit): Prebuilt UI components for auth and wallet + flows +- [Export wallets](/products/company-wallets/features/export-wallets): Key export and user recovery diff --git a/images/embedded-wallets/waas-tx-auth.png b/images/embedded-wallets/waas-tx-auth.png new file mode 100644 index 00000000..ae39169a Binary files /dev/null and b/images/embedded-wallets/waas-tx-auth.png differ diff --git a/images/embedded-wallets/waas.png b/images/embedded-wallets/waas.png new file mode 100644 index 00000000..922b5dc3 Binary files /dev/null and b/images/embedded-wallets/waas.png differ