diff --git a/.gitignore b/.gitignore
index acecd96c..59cc627e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,5 @@ build
# windsurf rules
.windsurfrules
-CLAUDE.md
\ No newline at end of file
+CLAUDE.md
+.claude/
\ No newline at end of file
diff --git a/.nvmrc b/.nvmrc
index 87ec8842..ccc4c6c7 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-18.18.2
+20.20.2
diff --git a/DESIGN-WORKFLOW.md b/DESIGN-WORKFLOW.md
new file mode 100644
index 00000000..d9294359
--- /dev/null
+++ b/DESIGN-WORKFLOW.md
@@ -0,0 +1,84 @@
+# Docs design workflow
+
+Guide for contributing design changes to the Turnkey Mintlify docs (welcome page revamp and related UI).
+
+## Branch strategy
+
+- Base design work on **`graham/docs-revamp`** (or a short-lived branch from it, e.g. `serge/design-welcome`).
+- Open PRs **into `graham/docs-revamp`** until the revamp merges to `main`.
+- Sync often to avoid drift from the Mintlify preview:
+
+```sh
+git fetch origin
+git merge origin/graham/docs-revamp
+```
+
+Production deploys from **`main`** (see README).
+
+## Files to edit
+
+| Change | Files |
+|--------|--------|
+| Welcome / landing layout | `welcome.mdx` |
+| Welcome / shared UI styles | `styles.css` (`.tk-*` classes) |
+| Site-wide color, nav, fonts | `docs.json` |
+| Illustrations, icons | `images/` (use `/images/...` paths) |
+| Logos / favicon | `logo/`, `favicon.svg` |
+
+Avoid unless intentional:
+
+- `generated-docs/`, `api-reference/` (generated — use `make gen` for API reference)
+- Duplicating content in `snippets/shared/` (update the snippet once; see README)
+
+## Local development
+
+Mintlify CLI requires **Node ≥ 20.17** (`.nvmrc` may list an older version).
+
+```sh
+nvm use 20
+cd docs # directory containing docs.json
+mintlify dev
+```
+
+Preview welcome: http://localhost:3000/welcome
+
+Before opening a PR:
+
+```sh
+mintlify validate
+```
+
+### Common pitfall
+
+Use **straight ASCII quotes** (`'`) in imports and JSX — not curly/smart quotes (`‘` `’`). Smart quotes in `import` paths or `style={{}}` cause MDX parse errors and can blank pages during `mintlify dev`.
+
+## Shipping to the team
+
+1. Make focused commits (e.g. hero spacing, nav labels — not one giant “design” commit).
+2. Push your branch to `tkhq/docs`.
+3. Open a PR **into `graham/docs-revamp`** with:
+ - What changed (welcome vs sitewide)
+ - Before/after screenshots (light and dark if relevant)
+ - Mintlify preview link from the PR checks
+ - Local test steps: `mintlify dev` → `/welcome`
+4. Request review from the revamp owner / docs maintainers.
+5. Merge via team process; do not merge to `main` unless agreed.
+
+## Style conventions
+
+- Prefer **CSS classes in `styles.css`** over large inline `style={{}}` in `welcome.mdx`.
+- Commit image assets in-repo; do not rely only on Mintlify CDN URLs for new art.
+- `welcome.mdx` uses `mode: "custom"` for a full-width landing layout (navbar only).
+
+## Access
+
+- **GitHub:** write access to `tkhq/docs` allows push + PR without a fork.
+- **Mintlify dashboard:** optional (`mintlify login`); not required for local preview.
+
+## Quick checklist
+
+- [ ] Branch is up to date with `origin/graham/docs-revamp`
+- [ ] `mintlify dev` — `/welcome` looks correct (light + dark)
+- [ ] `mintlify validate` passes
+- [ ] No smart quotes in imports / JSX
+- [ ] PR targets `graham/docs-revamp` with screenshots
diff --git a/api-overview.mdx b/api-overview.mdx
deleted file mode 100644
index cd5c6d86..00000000
--- a/api-overview.mdx
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: API overview
-mode: wide
-sidebarTitle: Overview
----
-
-
-
- Getting started with the Turnkey API
-
-
-
- Creating your first signed request
-
-
-
- Fetching data from Turnkey
-
-
-
- Secure execution with Turnkey
-
-
-
- Enumerating all errors received using the Turnkey API
-
-
diff --git a/api-reference/activities/overview.mdx b/api-reference/activities/overview.mdx
index 153fcc3c..3dd69f40 100644
--- a/api-reference/activities/overview.mdx
+++ b/api-reference/activities/overview.mdx
@@ -1,24 +1,21 @@
---
title: "Activities"
-description: "Activities are requests to securely execute a workload in Turnkey."
+description: "Activities are requests to securely execute a workload in Turnkey. Submission endpoints are always prefixed with `/public/v1/submit`."
sidebarTitle: "Overview"
mode: wide
---
# What are activities?
-Activities (also called [submissions](/developer-reference/api-overview/submissions)) are requests to create, modify, or use resources within Turnkey.
+Activities are requests to create, modify, or use resources within Turnkey.
Submission endpoints are always prefixed with `/public/v1/submit`.
-- **Policy Enforcement:** Activities are subject to consensus or condition enforcement via the policy engine.
-- **Optimistic Execution:** Activities are executed optimistically synchronous—if possible, the request completes synchronously; otherwise, it falls back to asynchronous processing.
-- **Activity Status:**
- - `COMPLETED`: The activity was successful and the `result` field is populated.
- - `FAILED`: The activity failed and the `failure` field contains the reason.
- - `CONSENSUS_NEEDED`: More signatures are required to process the request.
- - `PENDING`: The request is processing asynchronously.
-- **Approval expiration:** Activities do not expire. However, approvals expire 24 hours after the first vote if consensus is not reached, and must be re-submitted while the activity remains in ACTIVITY_STATUS_CONSENSUS_NEEDED.
-- **Status Updates:** You can get updates by re-submitting the request (idempotent) or polling `get_activity` with the activity ID.
-- **Idempotency:** The API is idempotent—identical requests (same POST body) return the same activity. To generate a new activity, change the `timestampMs` value in your request.
-
-
+- **Policy enforcement:** Activities are subject to consensus or condition enforcement via the policy engine.
+- **Optimistic execution:** Activities execute optimistically synchronous — if possible, the request completes synchronously; otherwise it falls back to asynchronous processing. Your services should account for this by checking the activity status in the response:
+ - `ACTIVITY_STATUS_COMPLETED`: The activity succeeded and the `result` field is populated.
+ - `ACTIVITY_STATUS_FAILED`: The activity failed and the `failure` field contains the reason.
+ - `ACTIVITY_STATUS_CONSENSUS_NEEDED`: More signatures (votes) are required to process the request.
+ - `ACTIVITY_STATUS_PENDING`: The request is processing asynchronously.
+- **Approval expiration:** Activities do not expire. However, when an activity is submitted, the requester's submission counts as the first approval and starts a 24-hour window. If consensus is not reached within that window, existing approvals expire and must be re-submitted while the activity remains in `ACTIVITY_STATUS_CONSENSUS_NEEDED`.
+- **Status updates:** Poll `get_activity` with the `activity.id`, or re-submit the original request (see idempotency below).
+- **Idempotency:** The submission API is idempotent. Each request's POST body is hashed into a fingerprint — any two requests with the same fingerprint return the same activity. To generate a new activity, change the `timestampMs` value in your request.
diff --git a/api-reference/activities/submit-a-raw-transaction-for-broadcasting.mdx b/api-reference/activities/submit-a-raw-transaction-for-broadcasting.mdx
deleted file mode 100644
index 027bf774..00000000
--- a/api-reference/activities/submit-a-raw-transaction-for-broadcasting.mdx
+++ /dev/null
@@ -1,202 +0,0 @@
----
-title: "Submit a raw transaction for broadcasting."
-description: "Submit a raw transaction (serialized and signed) for broadcasting to the network."
----
-
-import { Authorizations } from "/snippets/api/authorizations.mdx";
-import { H3Bordered } from "/snippets/h3-bordered.mdx";
-import { NestedParam } from "/snippets/nested-param.mdx";
-import { EndpointPath } from "/snippets/api/endpoint.mdx";
-
-
-
-
-
-
-
-
-
-Enum options: `ACTIVITY_TYPE_ETH_SEND_RAW_TRANSACTION`
-
-
-
-
-Timestamp (in milliseconds) of the request, used to verify liveness of user requests.
-
-
-
-
-Unique identifier for a given Organization.
-
-
-
-
The parameters object containing the specific intent data for this activity.
-
-
- The raw, signed transaction to be sent.
-
-
-
- Enum options: `eip155:1`, `eip155:11155111`, `eip155:8453`, `eip155:84532`, `eip155:42161`, `eip155:421614`
-
-
-
-
-
-Enable to have your activity generate and return App Proofs, enabling verifiability.
-
-
-
-
-A successful response returns the following fields:
-
-
- The activity object containing type, intent, and result
-
-
-Unique identifier for a given Activity object.
-
-
-Unique identifier for a given Organization.
-
-
-The activity status
-
-
-The activity type
-
-
- The intent of the activity
-
-
- The ethSendRawTransactionIntent object
-
-
-The raw, signed transaction to be sent.
-
-
-CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet).
-
-Enum options: `eip155:1`, `eip155:11155111`, `eip155:8453`, `eip155:84532`, `eip155:42161`, `eip155:421614`
-
-
-
-
-
-
-
-
-
- The result of the activity
-
-
- The ethSendRawTransactionResult object
-
-
-The transaction hash of the sent transaction
-
-
-
-
-
-
-
-
-A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata.
-
-
-An artifact verifying a User's action.
-
-
-Whether the activity can be approved.
-
-
-Whether the activity can be rejected.
-
-
-The creation timestamp.
-
-
-The last update timestamp.
-
-
-
-
-
-
-
-```bash title="cURL"
-curl --request POST \
- --url https://api.turnkey.com/public/v1/submit/eth_send_raw_transaction \
- --header 'Accept: application/json' \
- --header 'Content-Type: application/json' \
- --header "X-Stamp: (see Authorizations)" \
- --data '{
- "type": "ACTIVITY_TYPE_ETH_SEND_RAW_TRANSACTION",
- "timestampMs": " (e.g. 1746736509954)",
- "organizationId": " (Your Organization ID)",
- "parameters": {
- "signedTransaction": "",
- "caip2": ""
- }
-}'
-```
-
-```javascript title="JavaScript"
-import { Turnkey } from "@turnkey/sdk-server";
-
-const turnkeyClient = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPublicKey: process.env.API_PUBLIC_KEY!,
- apiPrivateKey: process.env.API_PRIVATE_KEY!,
- defaultOrganizationId: process.env.ORGANIZATION_ID!,
-});
-
-const response = await turnkeyClient.apiClient().ethSendRawTransaction({
- signedTransaction: " (The raw, signed transaction to be sent.)",
- caip2: "" // CAIP-2 chain ID (e.g., 'eip155:1' for Ethereum mainnet).
-});
-```
-
-
-
-
-
-```json 200
-{
- "activity": {
- "id": "",
- "status": "ACTIVITY_STATUS_COMPLETED",
- "type": "ACTIVITY_TYPE_ETH_SEND_RAW_TRANSACTION",
- "organizationId": "",
- "timestampMs": " (e.g. 1746736509954)",
- "result": {
- "activity": {
- "id": "",
- "organizationId": "",
- "status": "",
- "type": "",
- "intent": {
- "ethSendRawTransactionIntent": {
- "signedTransaction": "",
- "caip2": ""
- }
- },
- "result": {
- "ethSendRawTransactionResult": {
- "transactionHash": ""
- }
- },
- "votes": "",
- "fingerprint": "",
- "canApprove": "",
- "canReject": "",
- "createdAt": "",
- "updatedAt": ""
- }
- }
- }
-}
-```
-
-
diff --git a/api-reference/activities/submit-a-transaction-intent-for-broadcasting.mdx b/api-reference/activities/submit-a-transaction-intent-for-broadcasting.mdx
deleted file mode 100644
index 571042c4..00000000
--- a/api-reference/activities/submit-a-transaction-intent-for-broadcasting.mdx
+++ /dev/null
@@ -1,232 +0,0 @@
----
-title: "Submit a transaction intent for broadcasting."
-description: "Submit a transaction intent describing a transaction you would like to broadcast."
----
-
-import { Authorizations } from "/snippets/api/authorizations.mdx";
-import { H3Bordered } from "/snippets/h3-bordered.mdx";
-import { NestedParam } from "/snippets/nested-param.mdx";
-import { EndpointPath } from "/snippets/api/endpoint.mdx";
-
-
-
-
-
-
-
-
-
-Enum options: `ACTIVITY_TYPE_SOL_SEND_TRANSACTION`
-
-
-
-
-Timestamp (in milliseconds) of the request, used to verify liveness of user requests.
-
-
-
-
-Unique identifier for a given Organization.
-
-
-
-
The parameters object containing the specific intent data for this activity.
-
-
- Base64-encoded serialized unsigned Solana transaction
-
-
-
- A wallet or private key address to sign with. This does not support private key IDs.
-
-
-
- Whether to sponsor this transaction via Gas Station.
-
-
-
- Enum options: `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`, `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG`, `solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY`
-
-
-
- user-provided blockhash for replay protection / deadline control. If omitted and sponsor=true, we fetch a fresh blockhash during execution
-
-
-
-
-
-Enable to have your activity generate and return App Proofs, enabling verifiability.
-
-
-
-
-A successful response returns the following fields:
-
-
- The activity object containing type, intent, and result
-
-
-Unique identifier for a given Activity object.
-
-
-Unique identifier for a given Organization.
-
-
-The activity status
-
-
-The activity type
-
-
- The intent of the activity
-
-
- The solSendTransactionIntent object
-
-
-Base64-encoded serialized unsigned Solana transaction
-
-
-A wallet or private key address to sign with. This does not support private key IDs.
-
-
-Whether to sponsor this transaction via Gas Station.
-
-
-CAIP-2 chain ID (e.g., 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp' for Solana mainnet).
-
-Enum options: `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`, `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG`, `solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY`
-
-
-
-user-provided blockhash for replay protection / deadline control. If omitted and sponsor=true, we fetch a fresh blockhash during execution
-
-
-
-
-
-
-
-
- The result of the activity
-
-
- The solSendTransactionResult object
-
-
-The send_transaction_status ID associated with the transaction submission
-
-
-
-
-
-
-
-
-A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata.
-
-
-An artifact verifying a User's action.
-
-
-Whether the activity can be approved.
-
-
-Whether the activity can be rejected.
-
-
-The creation timestamp.
-
-
-The last update timestamp.
-
-
-
-
-
-
-
-```bash title="cURL"
-curl --request POST \
- --url https://api.turnkey.com/public/v1/submit/sol_send_transaction \
- --header 'Accept: application/json' \
- --header 'Content-Type: application/json' \
- --header "X-Stamp: (see Authorizations)" \
- --data '{
- "type": "ACTIVITY_TYPE_SOL_SEND_TRANSACTION",
- "timestampMs": " (e.g. 1746736509954)",
- "organizationId": " (Your Organization ID)",
- "parameters": {
- "unsignedTransaction": "",
- "signWith": "",
- "sponsor": "",
- "caip2": "",
- "recentBlockhash": ""
- }
-}'
-```
-
-```javascript title="JavaScript"
-import { Turnkey } from "@turnkey/sdk-server";
-
-const turnkeyClient = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPublicKey: process.env.API_PUBLIC_KEY!,
- apiPrivateKey: process.env.API_PRIVATE_KEY!,
- defaultOrganizationId: process.env.ORGANIZATION_ID!,
-});
-
-const response = await turnkeyClient.apiClient().solSendTransaction({
- unsignedTransaction: " (Base64-encoded serialized unsigned Solana transaction)",
- signWith: " (A wallet or private key address to sign with. This does not support private key IDs.)",
- sponsor: true // Whether to sponsor this transaction via Gas Station.,
- caip2: "" // CAIP-2 chain ID (e.g., 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp' for Solana mainnet).,
- recentBlockhash: " (user-provided blockhash for replay protection / deadline control. If omitted and sponsor=true, we fetch a fresh blockhash during execution)"
-});
-```
-
-
-
-
-
-```json 200
-{
- "activity": {
- "id": "",
- "status": "ACTIVITY_STATUS_COMPLETED",
- "type": "ACTIVITY_TYPE_SOL_SEND_TRANSACTION",
- "organizationId": "",
- "timestampMs": " (e.g. 1746736509954)",
- "result": {
- "activity": {
- "id": "",
- "organizationId": "",
- "status": "",
- "type": "",
- "intent": {
- "solSendTransactionIntent": {
- "unsignedTransaction": "",
- "signWith": "",
- "sponsor": "",
- "caip2": "",
- "recentBlockhash": ""
- }
- },
- "result": {
- "solSendTransactionResult": {
- "sendTransactionStatusId": ""
- }
- },
- "votes": "",
- "fingerprint": "",
- "canApprove": "",
- "canReject": "",
- "createdAt": "",
- "updatedAt": ""
- }
- }
- }
-}
-```
-
-
diff --git a/api-reference/auth-proxy/account.mdx b/api-reference/auth-proxy/account.mdx
index 57ccb30c..f992c6b5 100644
--- a/api-reference/auth-proxy/account.mdx
+++ b/api-reference/auth-proxy/account.mdx
@@ -18,7 +18,7 @@ import { NestedParam } from "/snippets/nested-param.mdx";
- Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup.
+ Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/features/authentication/auth-proxy) for setup.
diff --git a/api-reference/auth-proxy/oauth-login.mdx b/api-reference/auth-proxy/oauth-login.mdx
index ac9d0160..1877d071 100644
--- a/api-reference/auth-proxy/oauth-login.mdx
+++ b/api-reference/auth-proxy/oauth-login.mdx
@@ -18,7 +18,7 @@ import { NestedParam } from "/snippets/nested-param.mdx";
- Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup.
+ Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/features/authentication/auth-proxy) for setup.
diff --git a/api-reference/auth-proxy/oauth2-authenticate.mdx b/api-reference/auth-proxy/oauth2-authenticate.mdx
index 5787f9cb..99fc36cd 100644
--- a/api-reference/auth-proxy/oauth2-authenticate.mdx
+++ b/api-reference/auth-proxy/oauth2-authenticate.mdx
@@ -18,7 +18,7 @@ import { NestedParam } from "/snippets/nested-param.mdx";
- Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup.
+ Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/features/authentication/auth-proxy) for setup.
diff --git a/api-reference/auth-proxy/otp-init.mdx b/api-reference/auth-proxy/otp-init.mdx
index 24cee15d..18be9c77 100644
--- a/api-reference/auth-proxy/otp-init.mdx
+++ b/api-reference/auth-proxy/otp-init.mdx
@@ -18,7 +18,7 @@ import { NestedParam } from "/snippets/nested-param.mdx";
- Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup.
+ Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/features/authentication/auth-proxy) for setup.
diff --git a/api-reference/auth-proxy/otp-login.mdx b/api-reference/auth-proxy/otp-login.mdx
index 2c603d9a..ca7145c5 100644
--- a/api-reference/auth-proxy/otp-login.mdx
+++ b/api-reference/auth-proxy/otp-login.mdx
@@ -18,7 +18,7 @@ import { NestedParam } from "/snippets/nested-param.mdx";
- Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup.
+ Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/features/authentication/auth-proxy) for setup.
diff --git a/api-reference/auth-proxy/otp-verify.mdx b/api-reference/auth-proxy/otp-verify.mdx
index a4386a2e..135a1c9c 100644
--- a/api-reference/auth-proxy/otp-verify.mdx
+++ b/api-reference/auth-proxy/otp-verify.mdx
@@ -18,7 +18,7 @@ import { NestedParam } from "/snippets/nested-param.mdx";
- Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup.
+ Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/features/authentication/auth-proxy) for setup.
diff --git a/api-reference/auth-proxy/signup.mdx b/api-reference/auth-proxy/signup.mdx
index 58d6228b..5eba4550 100644
--- a/api-reference/auth-proxy/signup.mdx
+++ b/api-reference/auth-proxy/signup.mdx
@@ -18,7 +18,7 @@ import { NestedParam } from "/snippets/nested-param.mdx";
- Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup.
+ Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/features/authentication/auth-proxy) for setup.
diff --git a/api-reference/auth-proxy/wallet-kit-config.mdx b/api-reference/auth-proxy/wallet-kit-config.mdx
index cea380c6..b95f504d 100644
--- a/api-reference/auth-proxy/wallet-kit-config.mdx
+++ b/api-reference/auth-proxy/wallet-kit-config.mdx
@@ -18,7 +18,7 @@ import { NestedParam } from "/snippets/nested-param.mdx";
- Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup.
+ Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/features/authentication/auth-proxy) for setup.
diff --git a/api-reference/overview.mdx b/api-reference/overview.mdx
deleted file mode 100644
index b8fdb80b..00000000
--- a/api-reference/overview.mdx
+++ /dev/null
@@ -1,11 +0,0 @@
----
-title: "API reference"
-description: "Review our [API Introduction](/developer-reference/api-overview/intro) to get started."
-sidebarTitle: "Overview"
-mode: wide
----
-
-import { EndpointFilter } from "/snippets/api/endpoint-filter.mdx";
-import { endpoints, tags } from "/snippets/data/endpoint-tags.mdx";
-
-
diff --git a/developer-reference/api-overview/errors.mdx b/api-reference/overview/errors.mdx
similarity index 96%
rename from developer-reference/api-overview/errors.mdx
rename to api-reference/overview/errors.mdx
index 69aa2133..03bb160b 100644
--- a/developer-reference/api-overview/errors.mdx
+++ b/api-reference/overview/errors.mdx
@@ -258,7 +258,7 @@ Troubleshooting tips:
Common causes:
- You have exceeded your monthly signing quota. The first 25 signatures a month are free for "free" users.
-- You have reached a resource limit on a particular resource. You can find out about our resource limits [here](/concepts/resource-limits).
+- You have reached a resource limit on a particular resource. You can find out about our resource limits [here](/reference/resource-limits).
Troubleshooting tips:
@@ -270,7 +270,7 @@ Troubleshooting tips:
Common causes:
- You have exceeded your monthly signing quota. The first 25 signatures a month are free for "free" users.
-- You have reached a resource limit on a particular resource. You can find out about our resource limits [here](/concepts/resource-limits).
+- You have reached a resource limit on a particular resource. You can find out about our resource limits [here](/reference/resource-limits).
Troubleshooting tips:
@@ -307,17 +307,17 @@ Common causes:
Troubleshooting tips:
- Confirm that you are using the correct credentials for the request you are making.
-- Confirm that all necessary [policies](/concepts/policies/overview) are in place so that the action that is requested can be performed.
+- Confirm that all necessary [policies](/features/policies/overview) are in place so that the action that is requested can be performed.
### no valid authentication signature found for request
Common causes:
-- No signature, or [stamp](/developer-reference/api-overview/stamps), is attached to a request. All requests made to Turnkey's api must be stamped so that Turnkey can authenticate and authorize the user who performed the request.
+- No signature, or [stamp](/api-reference/overview/stamps), is attached to a request. All requests made to Turnkey's api must be stamped so that Turnkey can authenticate and authorize the user who performed the request.
Troubleshooting tips:
-- Take a look at the page on [stamps](/developer-reference/api-overview/stamps) to get some information about stamps, what they are, and how they are created.
+- Take a look at the page on [stamps](/api-reference/overview/stamps) to get some information about stamps, what they are, and how they are created.
- At a base level our SDK's abstract away the complicated stamping process for you. [Here](https://github.com/tkhq/sdk/tree/main/examples) are some example projects with our JS/TS SDK to get you started!
### could not find public key in organization
@@ -438,7 +438,7 @@ Common causes:
Troubleshooting tips:
-- Take a look at the page on [stamps](/developer-reference/api-overview/stamps) to get some information about stamps, what they are, and how they are created.
+- Take a look at the page on [stamps](/api-reference/overview/stamps) to get some information about stamps, what they are, and how they are created.
- At a base level our SDK's abstract away the complicated stamping process for you. [Here](https://github.com/tkhq/sdk/tree/main/examples) are some example projects with our JS/TS SDK to get you started!
### could not extract webauthn stamp
@@ -449,7 +449,7 @@ Common causes:
Troubleshooting tips:
-- Take a look at the page on [stamps](/developer-reference/api-overview/stamps) to get some information about stamps, what they are, and how they are created.
+- Take a look at the page on [stamps](/api-reference/overview/stamps) to get some information about stamps, what they are, and how they are created.
- At a base level our SDK's abstract away the complicated stamping process for you. [Here](https://github.com/tkhq/sdk/tree/main/examples) are some example projects with our JS/TS SDK to get you started!
### could not extract api key stamp
@@ -460,7 +460,7 @@ Common causes:
Troubleshooting tips:
-- Take a look at the page on [stamps](/developer-reference/api-overview/stamps) to get some information about stamps, what they are, and how they are created.
+- Take a look at the page on [stamps](/api-reference/overview/stamps) to get some information about stamps, what they are, and how they are created.
- At a base level our SDK's abstract away the complicated stamping process for you. [Here](https://github.com/tkhq/sdk/tree/main/examples) are some example projects with our JS/TS SDK to get you started!
### cannot authenticate public API activity request without a stamp (X-Stamp/X-Stamp-Webauthn header)
@@ -471,7 +471,7 @@ Common causes:
Troubleshooting tips:
-- Take a look at the page on [stamps](/developer-reference/api-overview/stamps) to get some information about stamps, what they are, and how they are created.
+- Take a look at the page on [stamps](/api-reference/overview/stamps) to get some information about stamps, what they are, and how they are created.
- At a base level our SDK's abstract away the complicated stamping process for you. [Here](https://github.com/tkhq/sdk/tree/main/examples) are some example projects with our JS/TS SDK to get you started!
### webauthn authenticator not found in organization
@@ -515,8 +515,8 @@ Common causes:
Troubleshooting tips:
- Use a valid hash function scheme from the following: `HASH_FUNCTION_NO_OP`, `HASH_FUNCTION_SHA256`, `HASH_FUNCTION_KECCAK256`, `HASH_FUNCTION_NOT_APPLICABLE`
-- More information about `HASH_FUNCTION_NO_OP` [here](/faq#what-does-hash_function_no_op-mean)
-- More information about `HASH_FUNCTION_NOT_APPLICABLE` [here](/faq#what-is-hash_function_not_applicable-and-how-does-it-differ-from-hash_function_no_op)
+- More information about `HASH_FUNCTION_NO_OP` [here](/reference/faq#what-does-hash_function_no_op-mean)
+- More information about `HASH_FUNCTION_NOT_APPLICABLE` [here](/reference/faq#what-is-hash_function_not_applicable-and-how-does-it-differ-from-hash_function_no_op)
### invalid magic link template
@@ -526,7 +526,7 @@ Common causes:
Troubleshooting tips:
-- Read more about [bespoke email templates](/embedded-wallets/sub-organization-auth#bespoke-email-templates)
+- Read more about [bespoke email templates](/features/authentication/email#bespoke-email-templates)
- Reach out to Turnkey at [help@turnkey.com](mailto:help@turnkey.com)!
### failed to get email template contents
@@ -547,7 +547,7 @@ Common causes:
Troubleshooting tips:
-- Read more about [bespoke email templates](/embedded-wallets/sub-organization-auth#bespoke-email-templates)
+- Read more about [bespoke email templates](/features/authentication/email#bespoke-email-templates)
- Reach out to Turnkey at [help@turnkey.com](mailto:help@turnkey.com)!
### authentication failed
@@ -559,7 +559,7 @@ Common causes:
Troubleshooting tips:
- Ensure that all proper authenticators and api-keys have been added to the organization.
-- Read more about how to create a stamp for a request [here](/developer-reference/api-overview/stamps)
+- Read more about how to create a stamp for a request [here](/api-reference/overview/stamps)
### failed to load organizations
@@ -591,7 +591,7 @@ Common causes:
Troubleshooting tips:
-- Read more about policy structure [here](/concepts/policies/overview#policy-structure)
+- Read more about policy structure [here](/features/policies/overview#policy-structure)
### invalid policy condition
@@ -601,13 +601,13 @@ Common causes:
Troubleshooting tips:
-- Read more about policy structure [here](/concepts/policies/overview#policy-structure)
+- Read more about policy structure [here](/features/policies/overview#policy-structure)
### quorum threshold must be non-zero integer
Common causes:
-- Quorum is the required amount of approvals by [root quorum members](/concepts/users/root-quorum) needed for an action to take place within an organization.
+- Quorum is the required amount of approvals by [root quorum members](/features/users/root-quorum) needed for an action to take place within an organization.
Troubleshooting tips:
@@ -669,7 +669,7 @@ Troubleshooting tips:
Common causes:
-- Turnkey allows up to 10 authenticators per user. This is a hard resource limit. More information on resource limits [here](/concepts/resource-limits).
+- Turnkey allows up to 10 authenticators per user. This is a hard resource limit. More information on resource limits [here](/reference/resource-limits).
Troubleshooting Tips:
@@ -680,7 +680,7 @@ Troubleshooting Tips:
Common causes:
-- Turnkey allows up to 10 long-lived api keys per user. This is a hard resource limit. More information on resource limits [here](/concepts/resource-limits).
+- Turnkey allows up to 10 long-lived api keys per user. This is a hard resource limit. More information on resource limits [here](/reference/resource-limits).
Troubleshooting Tips:
@@ -691,7 +691,7 @@ Troubleshooting Tips:
Common causes:
-- Turnkey allows up to 10 short-lived api keys per user. This is a hard resource limit. More information on resource limits [here](/concepts/resource-limits). Short-lived API keys will automatically be deleted from an organization when they are expired.
+- Turnkey allows up to 10 short-lived api keys per user. This is a hard resource limit. More information on resource limits [here](/reference/resource-limits). Short-lived API keys will automatically be deleted from an organization when they are expired.
Troubleshooting Tips:
@@ -726,7 +726,7 @@ Common causes:
Troubleshooting tips:
-- The path is a string that is used to derive a new account within an HD wallet. A list of default paths per address format can be found [here](/concepts/wallets#hd-wallet-default-paths)
+- The path is a string that is used to derive a new account within an HD wallet. A list of default paths per address format can be found [here](/features/wallets#hd-wallet-default-paths)
- Paths cannot be reused within the same HD wallet.
### invalid address format
@@ -737,8 +737,8 @@ Common causes:
Troubleshooting tips:
-- Turnkey offers a wide range of support for many ecosystems. A list of valid address formats can be found in the table [here](/concepts/wallets#address-formats-and-curves).
-- More about Turnkey and general ecosystem support can be found [here](/networks/overview).
+- Turnkey offers a wide range of support for many ecosystems. A list of valid address formats can be found in the table [here](/features/wallets#address-formats-and-curves).
+- More about Turnkey and general ecosystem support can be found [here](/features/networks/overview).
### invalid curve
@@ -748,8 +748,8 @@ Common causes:
Troubleshooting tips:
-- Before ecosystem level integrations Turnkey offers support on a curve level. This makes us extendable to any ecosystem that is based on a curve we support. A list of valid curve parameters can be found in the table [here](/concepts/wallets#address-formats-and-curves).
-- More about Turnkey and general ecosystem support can be found [here](/networks/overview).
+- Before ecosystem level integrations Turnkey offers support on a curve level. This makes us extendable to any ecosystem that is based on a curve we support. A list of valid curve parameters can be found in the table [here](/features/wallets#address-formats-and-curves).
+- More about Turnkey and general ecosystem support can be found [here](/features/networks/overview).
### curve required
@@ -759,8 +759,8 @@ Common causes:
Troubleshooting tips:
-- Before ecosystem level integrations Turnkey offers support on a curve level. This makes us extendable to any ecosystem that is based on a curve we support. A list of valid curve parameters can be found in the table [here](/concepts/wallets#address-formats-and-curves).
-- More about Turnkey and general ecosystem support can be found [here](/networks/overview).
+- Before ecosystem level integrations Turnkey offers support on a curve level. This makes us extendable to any ecosystem that is based on a curve we support. A list of valid curve parameters can be found in the table [here](/features/wallets#address-formats-and-curves).
+- More about Turnkey and general ecosystem support can be found [here](/features/networks/overview).
### failed to parse transaction
diff --git a/developer-reference/api-overview/intro.mdx b/api-reference/overview/intro.mdx
similarity index 67%
rename from developer-reference/api-overview/intro.mdx
rename to api-reference/overview/intro.mdx
index ca3a918c..b3794264 100644
--- a/developer-reference/api-overview/intro.mdx
+++ b/api-reference/overview/intro.mdx
@@ -11,7 +11,7 @@ Many client libraries are available to make requests to a RPC/HTTP API, across m
## POST-only
-If you look at the [API reference](/api-reference/overview) you'll notice that all API calls to Turnkey are HTTP POST requests. Requests contain a POST body and a header with a digital signature over the POST body. We call this digital signature a [Stamp](/developer-reference/api-overview/stamps).
+If you look at the [API reference](/api-reference/overview/intro) you'll notice that all API calls to Turnkey are HTTP POST requests. Requests contain a POST body and a header with a digital signature over the POST body. We call this digital signature a [Stamp](/api-reference/overview/stamps).
Requests must be stamped by registered user credentials and verified by Turnkey's secure enclaves before they are processed. This ensures cryptographic integrity end-to-end which eliminates the ability for any party to modify a user's request.
@@ -24,6 +24,6 @@ Turnkey's API is divided into 2 broad categories: queries and submissions.
## Dive deeper
-* Creating your first [Stamp](/developer-reference/api-overview/stamps)
-* Fetching data with [Queries](/developer-reference/api-overview/queries)
-* Executing workloads with [Submissions](/developer-reference/api-overview/submissions)
+* Creating your first [Stamp](/api-reference/overview/stamps)
+* Fetching data with [Queries](/api-reference/queries/overview)
+* Executing workloads with [Submissions](/api-reference/activities/overview)
diff --git a/developer-reference/api-overview/stamps.mdx b/api-reference/overview/stamps.mdx
similarity index 75%
rename from developer-reference/api-overview/stamps.mdx
rename to api-reference/overview/stamps.mdx
index 3d0480cc..2611c543 100644
--- a/developer-reference/api-overview/stamps.mdx
+++ b/api-reference/overview/stamps.mdx
@@ -66,7 +66,7 @@ To create a valid, Webauthn authenticator stamped request follow these steps:
- Submit the stamped request to Turnkey's API. If you would like your client request to be proxied through a backend, refer to the patterns mentioned [here](/authentication/passkeys/integration#proxying-signed-requests). An example application that uses this pattern can be found at wallet.tx.xyz (code [here](https://github.com/tkhq/demo-embedded-wallet/))
+ Submit the stamped request to Turnkey's API. If you would like your client request to be proxied through a backend, refer to the patterns mentioned [here](/features/authentication/passkeys/integration#proxying-signed-requests). An example application that uses this pattern can be found at wallet.tx.xyz (code [here](https://github.com/tkhq/demo-embedded-wallet/))
@@ -74,23 +74,15 @@ To create a valid, Webauthn authenticator stamped request follow these steps:
Our [JS SDK](https://github.com/tkhq/sdk) and [CLI](https://github.com/tkhq/tkcli) abstract request stamping for you. If you choose to use an independent client, you will need to implement this yourself. For reference, check out our implementations:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
Our CLI has a `--no-post` option to generate stamps without sending anything over the network. This is a useful tool should you have trouble with debugging stamping-related logic. A sample command might look something like:
diff --git a/api-reference/queries/get-gas-usage-and-limits.mdx b/api-reference/queries/get-gas-usage-and-limits.mdx
deleted file mode 100644
index 185f94b3..00000000
--- a/api-reference/queries/get-gas-usage-and-limits.mdx
+++ /dev/null
@@ -1,70 +0,0 @@
----
-title: "Get gas usage and limits."
-description: "Get gas usage and gas limits for either the parent organization or a sub-organization."
----
-
-import { Authorizations } from "/snippets/api/authorizations.mdx";
-import { H3Bordered } from "/snippets/h3-bordered.mdx";
-import { NestedParam } from "/snippets/nested-param.mdx";
-import { EndpointPath } from "/snippets/api/endpoint.mdx";
-
-
-
-
-
-
-
-
-
-Unique identifier for a given Organization.
-
-
-
-
-A successful response returns the following fields:
-
-The window duration (in minutes) for the organization or sub-organization.
-The window limit (in USD) for the organization or sub-organization.
-The total gas usage (in USD) of all sponsored transactions processed over the last `window_duration_minutes`
-
-
-
-```bash title="cURL"
-curl --request POST \
- --url https://api.turnkey.com/public/v1/query/get_gas_usage \
- --header 'Accept: application/json' \
- --header 'Content-Type: application/json' \
- --header "X-Stamp: (see Authorizations)" \
- --data '{
- "organizationId": ""
-}'
-```
-
-```javascript title="JavaScript"
-import { Turnkey } from "@turnkey/sdk-server";
-
-const turnkeyClient = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPublicKey: process.env.API_PUBLIC_KEY!,
- apiPrivateKey: process.env.API_PRIVATE_KEY!,
- defaultOrganizationId: process.env.ORGANIZATION_ID!,
-});
-
-const response = await turnkeyClient.apiClient().getGasUsage({
- organizationId: " (Unique identifier for a given Organization.)"
-});
-```
-
-
-
-
-
-```json 200
-{
- "windowDurationMinutes": "",
- "windowLimitUsd": "",
- "usageUsd": ""
-}
-```
-
-
diff --git a/api-reference/queries/get-nonces-for-an-address.mdx b/api-reference/queries/get-nonces-for-an-address.mdx
deleted file mode 100644
index 2528046b..00000000
--- a/api-reference/queries/get-nonces-for-an-address.mdx
+++ /dev/null
@@ -1,96 +0,0 @@
----
-title: "Get nonces for an address."
-description: "Get nonce values for an address on a given network. Can fetch the standard on-chain nonce and/or the gas station nonce used for sponsored transactions."
----
-
-import { Authorizations } from "/snippets/api/authorizations.mdx";
-import { H3Bordered } from "/snippets/h3-bordered.mdx";
-import { NestedParam } from "/snippets/nested-param.mdx";
-import { EndpointPath } from "/snippets/api/endpoint.mdx";
-
-
-
-
-
-
-
-
-
-Unique identifier for a given Organization.
-
-
-
-
-The Ethereum address to query nonces for.
-
-
-
-
-The network identifier in CAIP-2 format (e.g., 'eip155:1' for Ethereum mainnet).
-
-
-
-
-Whether to fetch the standard on-chain nonce.
-
-
-
-
-Whether to fetch the gas station nonce used for sponsored transactions.
-
-
-
-
-A successful response returns the following fields:
-
-The standard on-chain nonce for the address, if requested.
-The gas station nonce for sponsored transactions, if requested.
-
-
-
-```bash title="cURL"
-curl --request POST \
- --url https://api.turnkey.com/public/v1/query/get_nonces \
- --header 'Accept: application/json' \
- --header 'Content-Type: application/json' \
- --header "X-Stamp: (see Authorizations)" \
- --data '{
- "organizationId": "",
- "address": "",
- "caip2": "",
- "nonce": "",
- "gasStationNonce": ""
-}'
-```
-
-```javascript title="JavaScript"
-import { Turnkey } from "@turnkey/sdk-server";
-
-const turnkeyClient = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPublicKey: process.env.API_PUBLIC_KEY!,
- apiPrivateKey: process.env.API_PRIVATE_KEY!,
- defaultOrganizationId: process.env.ORGANIZATION_ID!,
-});
-
-const response = await turnkeyClient.apiClient().getNonces({
- organizationId: " (Unique identifier for a given Organization.)",
- address: " (The Ethereum address to query nonces for.)",
- caip2: " (The network identifier in CAIP-2 format (e.g., 'eip155:1' for Ethereum mainnet).)",
- nonce: true // Whether to fetch the standard on-chain nonce.,
- gasStationNonce: true // Whether to fetch the gas station nonce used for sponsored transactions.
-});
-```
-
-
-
-
-
-```json 200
-{
- "nonce": "",
- "gasStationNonce": ""
-}
-```
-
-
diff --git a/api-reference/queries/get-suborgs.mdx b/api-reference/queries/get-suborgs.mdx
deleted file mode 100644
index 307bc3b2..00000000
--- a/api-reference/queries/get-suborgs.mdx
+++ /dev/null
@@ -1,116 +0,0 @@
----
-title: "Get Suborgs"
-description: "Get all suborg IDs associated given a parent org ID and an optional filter."
----
-
-import { Authorizations } from "/snippets/api/authorizations.mdx";
-import { H3Bordered } from "/snippets/h3-bordered.mdx";
-import { NestedParam } from "/snippets/nested-param.mdx";
-import { EndpointPath } from "/snippets/api/endpoint.mdx";
-
-
-
-
-
-
-
-
-
-Unique identifier for the parent Organization. This is used to find sub-organizations within it.
-
-
-
-
-Specifies the type of filter to apply, i.e 'CREDENTIAL_ID', 'NAME', 'USERNAME', 'EMAIL', 'PHONE_NUMBER', 'OIDC_TOKEN' or 'PUBLIC_KEY'
-
-
-
-
-The value of the filter to apply for the specified type. For example, a specific email or name string.
-
-
-
-
paginationOptions field
-
-
- A limit of the number of object to be returned, between 1 and 100. Defaults to 10.
-
-
-
- A pagination cursor. This is an object ID that enables you to fetch all objects before this ID.
-
-
-
- A pagination cursor. This is an object ID that enables you to fetch all objects after this ID.
-
-
-
-
-
-A successful response returns the following fields:
-
-
- List of unique identifiers for the matching sub-organizations.
-
-
-item field
-
-
-
-
-
-
-
-```bash title="cURL"
-curl --request POST \
- --url https://api.turnkey.com/public/v1/query/list_suborgs \
- --header 'Accept: application/json' \
- --header 'Content-Type: application/json' \
- --header "X-Stamp: (see Authorizations)" \
- --data '{
- "organizationId": "",
- "filterType": "",
- "filterValue": "",
- "paginationOptions": {
- "limit": "",
- "before": "",
- "after": ""
- }
-}'
-```
-
-```javascript title="JavaScript"
-import { Turnkey } from "@turnkey/sdk-server";
-
-const turnkeyClient = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPublicKey: process.env.API_PUBLIC_KEY!,
- apiPrivateKey: process.env.API_PRIVATE_KEY!,
- defaultOrganizationId: process.env.ORGANIZATION_ID!,
-});
-
-const response = await turnkeyClient.apiClient().listSuborgs({
- organizationId: " (Unique identifier for the parent Organization. This is used to find sub-organizations within it.)",
- filterType: " (Specifies the type of filter to apply, i.e 'CREDENTIAL_ID', 'NAME', 'USERNAME', 'EMAIL', 'PHONE_NUMBER', 'OIDC_TOKEN' or 'PUBLIC_KEY')",
- filterValue: " (The value of the filter to apply for the specified type. For example, a specific email or name string.)",
- paginationOptions: { // paginationOptions field,
- limit: " (A limit of the number of object to be returned, between 1 and 100. Defaults to 10.)",
- before: " (A pagination cursor. This is an object ID that enables you to fetch all objects before this ID.)",
- after: " (A pagination cursor. This is an object ID that enables you to fetch all objects after this ID.)",
- }
-});
-```
-
-
-
-
-
-```json 200
-{
- "organizationIds": [
- ""
- ]
-}
-```
-
-
diff --git a/api-reference/queries/get-verified-suborgs.mdx b/api-reference/queries/get-verified-suborgs.mdx
deleted file mode 100644
index d2005d5a..00000000
--- a/api-reference/queries/get-verified-suborgs.mdx
+++ /dev/null
@@ -1,116 +0,0 @@
----
-title: "Get Verified Suborgs"
-description: "Get all email or phone verified suborg IDs associated given a parent org ID."
----
-
-import { Authorizations } from "/snippets/api/authorizations.mdx";
-import { H3Bordered } from "/snippets/h3-bordered.mdx";
-import { NestedParam } from "/snippets/nested-param.mdx";
-import { EndpointPath } from "/snippets/api/endpoint.mdx";
-
-
-
-
-
-
-
-
-
-Unique identifier for the parent Organization. This is used to find sub-organizations within it.
-
-
-
-
-Specifies the type of filter to apply, i.e 'EMAIL', 'PHONE_NUMBER'
-
-
-
-
-The value of the filter to apply for the specified type. For example, a specific email or phone number string.
-
-
-
-
paginationOptions field
-
-
- A limit of the number of object to be returned, between 1 and 100. Defaults to 10.
-
-
-
- A pagination cursor. This is an object ID that enables you to fetch all objects before this ID.
-
-
-
- A pagination cursor. This is an object ID that enables you to fetch all objects after this ID.
-
-
-
-
-
-A successful response returns the following fields:
-
-
- List of unique identifiers for the matching sub-organizations.
-
-
-item field
-
-
-
-
-
-
-
-```bash title="cURL"
-curl --request POST \
- --url https://api.turnkey.com/public/v1/query/list_verified_suborgs \
- --header 'Accept: application/json' \
- --header 'Content-Type: application/json' \
- --header "X-Stamp: (see Authorizations)" \
- --data '{
- "organizationId": "",
- "filterType": "",
- "filterValue": "",
- "paginationOptions": {
- "limit": "",
- "before": "",
- "after": ""
- }
-}'
-```
-
-```javascript title="JavaScript"
-import { Turnkey } from "@turnkey/sdk-server";
-
-const turnkeyClient = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPublicKey: process.env.API_PUBLIC_KEY!,
- apiPrivateKey: process.env.API_PRIVATE_KEY!,
- defaultOrganizationId: process.env.ORGANIZATION_ID!,
-});
-
-const response = await turnkeyClient.apiClient().listVerifiedSuborgs({
- organizationId: " (Unique identifier for the parent Organization. This is used to find sub-organizations within it.)",
- filterType: " (Specifies the type of filter to apply, i.e 'EMAIL', 'PHONE_NUMBER')",
- filterValue: " (The value of the filter to apply for the specified type. For example, a specific email or phone number string.)",
- paginationOptions: { // paginationOptions field,
- limit: " (A limit of the number of object to be returned, between 1 and 100. Defaults to 10.)",
- before: " (A pagination cursor. This is an object ID that enables you to fetch all objects before this ID.)",
- after: " (A pagination cursor. This is an object ID that enables you to fetch all objects after this ID.)",
- }
-});
-```
-
-
-
-
-
-```json 200
-{
- "organizationIds": [
- ""
- ]
-}
-```
-
-
diff --git a/api-reference/queries/overview.mdx b/api-reference/queries/overview.mdx
index 0466d0ea..e01be2d9 100644
--- a/api-reference/queries/overview.mdx
+++ b/api-reference/queries/overview.mdx
@@ -5,8 +5,6 @@ sidebarTitle: "Overview"
mode: wide
---
-# What are queries?
-
Queries are read-only operations that let you fetch information from Turnkey's API without modifying any resources. Query endpoints are always prefixed with `/public/v1/query`.
- **No Policy Enforcement:** Queries are not subject to the policy engine, so any authenticated user in your organization can perform them.
diff --git a/authentication/credentials.mdx b/authentication/credentials.mdx
deleted file mode 100644
index 112cf71e..00000000
--- a/authentication/credentials.mdx
+++ /dev/null
@@ -1,51 +0,0 @@
----
-title: "Credentials"
-description: "An overview of credentials and how they're used with various authentication methods"
----
-
-## Introduction
-
-After authenticating using frequently-used methods like [SMS OTP](/authentication/sms), [Email Authentication](/authentication/email), or [OAuth](/authentication/social-logins) (e.g., Google), users will make requests to Turnkey with a resulting API key. Each API key includes a `Credential` field specifying its type and public key. This Credential type can be used to identify how the API key was issued and which specific authentication method was used.
-
-[Passkeys](/authentication/passkeys/introduction), known as Authenticators within the context of Turnkey, also have the same `Credential` field and are equally distinguished by the credential type.
-
-## Obtaining an API key's credential type and public key
-
-To obtain an API key's credential type and public key you can use the [GetAPIKey](/api-reference/queries/get-api-key) query. The API Key fields will be returned from this call and the credential `type` and `public_key` fields will be in the response. This will return an object that looks like:
-```sh
-{
- "apiKey": {
- "apiKeyId": "",
- "apiKeyName": "",
- "createdAt": {
- "nanos": "0",
- "seconds": "1752105687"
- },
- "credential": {
- "publicKey": "",
- "type": "CREDENTIAL_TYPE_API_KEY_P256"
- },
- "updatedAt": {
- "nanos": "0",
- "seconds": "1752105687"
- }
- }
-}
-```
-
-## Credential types
-
-The table below describes all of the different credential types and what authentication methods correspond to that credential type
-
-| Type | Authentication Method(s) |
-| --------------------------------------------| ---------------------------------------------------------------- |
-| **CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR** | [Passkey/Authenticator Authentication](/authentication/passkeys/introduction) |
-| **CREDENTIAL_TYPE_API_KEY_P256** | [CreateAPIKeys](/api-reference/activities/create-api-keys) - curveType API_KEY_CURVE_P256 |
-| **CREDENTIAL_TYPE_RECOVER_USER_KEY_P256** | [Email Recovery](/authentication/email#recovery-flow) |
-| **CREDENTIAL_TYPE_API_KEY_SECP256K1** | Used for Ethereum and SECP256K1 chainS [Wallet Authentication](/embedded-wallets/code-examples/wallet-auth) |
-| **CREDENTIAL_TYPE_EMAIL_AUTH_KEY_P256** | [Credential Bundle based Email Authentication](/authentication/email#credential-bundle-method) |
-| **CREDENTIAL_TYPE_API_KEY_ED25519** | Solana and ED25519 chains [Wallet Authentication](/embedded-wallets/code-examples/wallet-auth) |
-| **CREDENTIAL_TYPE_OTP_AUTH_KEY_P256** | OTP based [Email](/authentication/email#otp-based-method) or [SMS](/authentication/sms) Authentication |
-| **CREDENTIAL_TYPE_READ_WRITE_SESSION_KEY_P256** | [CreateReadWriteSession](/api-reference/activities/create-read-write-session) |
-| **CREDENTIAL_TYPE_OAUTH_KEY_P256** | [Social Logins](/authentication/social-logins) |
-| **CREDENTIAL_TYPE_LOGIN** | [IndexedDB Authentication](/sdks/javascript-browser#indexeddbclient); OTP, Passkey, or OAuth |
\ No newline at end of file
diff --git a/authentication/otp-migration-guide.mdx b/authentication/otp-migration-guide.mdx
deleted file mode 100644
index 530294ba..00000000
--- a/authentication/otp-migration-guide.mdx
+++ /dev/null
@@ -1,40 +0,0 @@
----
-title: "Updated OTP login and signup flow"
-sidebarTitle: "OTP login and signup"
-description: "How to migrate to Turnkey's new security-upgraded OTP authentication flows."
----
-
-Turnkey's OTP authentication flows (email and SMS) have been upgraded to pass OTP code attempts as encrypted bundles rather than in plaintext — raising the bar for security and ensuring that server compromises can no longer be leveraged to compromise an OTP login process. The new flow is recommended for its security improvements, and we've included a migration guide from legacy flows to the new flow below.
-
-## Migration guide
-
-For implementations using Turnkey's legacy OTP flows, migrating to the updated OTP flows is a breaking change and will require some tweaks to implementations beyond just upgrading SDK versions.
-
-
- If you have policies written against specific versions of the activities mentioned below, you will need to update those policies to reference the new activity versions.
-
-
-### Updated OTP flow activity types
-
-The following activities (and any subsequent versions) use the updated OTP flow:
-
-| Activity | Description |
-|---|---|
-| `ACTIVITY_TYPE_INIT_OTP_V3` | Initiates an OTP flow via email or SMS, returns an encryption bundle to be used during OTP verification |
-| `ACTIVITY_TYPE_VERIFY_OTP_V2` | Verifies OTP attempt securely, returns a verification token (JWT) |
-| `ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7` | Used to sign up; consumes verification token received after successful `VERIFY_OTP_V2` activity |
-| `ACTIVITY_TYPE_OTP_LOGIN_V2` | Used to log in and generate a session; consumes verification token received after successful `VERIFY_OTP_V2` activity |
-
-NOTE: Older activity versions such as `ACTIVITY_TYPE_INIT_OTP_V2`, `ACTIVITY_TYPE_VERIFY_OTP` use our legacy OTP flow and are not interchangeable with the new ones due to the new encryption protocol. Notably, for sub organization creation, which accepts OTP verification tokens, `ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7` can be used as part of the legacy flow and the new updated flow, while `ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V8` onwards will no longer be compatible with legacy OTP verification tokens.
-
-### Required updates to implementations
-
-The following updates are required to legacy OTP implementations to migrate to the updated OTP flow, after bumping SDK versions:
-
-- The response shape for `ACTIVITY_TYPE_INIT_OTP_V3` now includes an `otpEncryptionTargetBundle` which is to be used during otp verification. This requires persisting state between `INIT_OTP` and `VERIFY_OTP` which means OTP flows need to be initiated and verified by the same service, or the service initiating OTP needs to pass the encryption bundle received in the response to the app client which will verify the OTP code.
-- The request shape for `ACTIVITY_TYPE_VERIFY_OTP_V2` now includes an `encryptedOtpBundle` which is generated using the `otpEncryptionTargetBundle` received from `ACTIVITY_TYPE_INIT_OTP_V3`. This bundle will include a client-generated public key and the OTP code attempt. The `encryptOtpCodeToBundle` helper function from [@turnkey/crypto](https://www.npmjs.com/package/@turnkey/crypto) is used to generate the `encryptedOtpBundle` used during OTP verification.
-- The verification token received in the response of `ACTIVITY_TYPE_VERIFY_OTP_V2` is signed by a different key than legacy OTP verification tokens. This key is included in our updated SDKs.
-- Login and signup flows initiated using OTP verification tokens now require client signature objects, generated using the client generated keypair whose public key was used during OTP verification. This process is handled by our updated SDKs.
-- Finally, users managing OTP flows with policies will need to update any policies referencing a specific OTP-related activity type so they point to the new activity versions.
-
-For more information and a diagram of the new OTP flow, please refer to additional documentation [here](../security/enclave-secure-channels#otp-login-flow).
\ No newline at end of file
diff --git a/category/advanced.mdx b/category/advanced.mdx
deleted file mode 100644
index 45fba0b5..00000000
--- a/category/advanced.mdx
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "Advanced"
-description: "Use Turnkey's low-level http libraries directly"
-sidebarTitle: "Overview"
----
-
-
-
- Detailed guide on installing and initializing the TurnkeyClient
-
-
- Guide on using the ApiKeyStamper
-
-
-
- Guide on using the WalletStamper
-
-
- Guide on using the WebauthnStamper
-
-
- Guide on using the IframeStamper
-
-
- Guide on using the IndexedDbStamper
-
-
diff --git a/category/code-examples-1.mdx b/category/code-examples-1.mdx
deleted file mode 100644
index 0730b735..00000000
--- a/category/code-examples-1.mdx
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "Code examples"
-sidebarTitle: "Overview"
-mode: wide
----
-
-
-
- Signing transactions
-
-
- Smart contract management
-
-
- Payment orchestration
-
-
diff --git a/category/code-examples.mdx b/category/code-examples.mdx
deleted file mode 100644
index 0376b796..00000000
--- a/category/code-examples.mdx
+++ /dev/null
@@ -1,90 +0,0 @@
----
-title: "Code examples"
-sidebarTitle: "Overview"
-mode: wide
----
-
-
-
- Embedded Consumer Wallet
-
-
-
- Embedded Business Wallet
-
-
-
- Embedded Wallet-as-a-Service
-
-
-
- Create a sub-org with a passkey user
-
-
-
- Authenticate a user with a passkey credential
-
-
-
- Create a user passkey session
-
-
-
- Create a user with email only
-
-
- Authenticate a user with email
-
-
- Add an additional passkey
-
-
- Authenticate a user with an Ethereum wallet
-
-
- Signing transactions
-
-
- Sending sponsored transactions
-
-
- Import wallet or private key
-
-
- Export wallet or private key
-
-
- Social linking
-
-
-
diff --git a/category/security.mdx b/category/security.mdx
deleted file mode 100644
index fe302332..00000000
--- a/category/security.mdx
+++ /dev/null
@@ -1,106 +0,0 @@
----
-title: Security & architecture
-sidebarTitle: Overview
-description: "Learn how Turnkey achieves innovative, cloud scale, no single point of failure security."
----
-
-Turnkey is the first verifiable key management system of its kind, securing millions of wallets and private keys for a wide variety of use cases.
-Turnkey's security architecture ensures that raw private keys are never exposed to Turnkey, your software, or your team.
-We provide end-to-end private key generation and access control within secure enclaves, with strong isolation guarantees and
-cryptographic attestation proving that only authorized code is running. Our custom-built operating system, QuorumOS,
-minimizes attack surface and enables reproducible, auditable deployments. From hardware-backed trust to multi-factor access controls,
-every layer of Turnkey's architecture is designed to be secure, verifiable, and developer-friendly by default. Our whitepaper covers our
-holistic security model in-depth, and speaks to our vision for building verifiable key management infrastructure. Learn more about our approach to security here.
-
-
-
-
- Learn about Turnkey's unique security framework
-
-
-
- Learn how Turnkey handles private keys
-
-
-
- Overview of secure enclaves and how we use them
-
-
-
- Learn how we deploy our secure applications
-
-
-
- Learn how we ensure an end-to-end audit trail
-
-
- Turnkey's disaster recovery process
-
-
-
- Learn about Turnkey's enclave to end-user secure channels
-
-
-
- Read about Turnkey's ambitious foundations with the Turnkey Whitepaper
-
-
-
- Overview of Turnkey's responsible disclosure program
-
-
-
diff --git a/category/web3-libraries.mdx b/category/web3-libraries.mdx
deleted file mode 100644
index 554085c5..00000000
--- a/category/web3-libraries.mdx
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "Web3 libraries"
-description: "Turnkey Web3 libraries"
-mode: wide
-sidebarTitle: "Overview"
----
-
-
-
- Ethers wrapper
-
-
-
- Viem wrapper
-
-
-
- CosmJS wrapper
-
-
-
- EIP 1193 provider
-
-
-
- Solana Web3 wrapper
-
-
diff --git a/changelogs/api-changelog/readme.mdx b/changelogs/api-changelog/readme.mdx
new file mode 100644
index 00000000..6a78f815
--- /dev/null
+++ b/changelogs/api-changelog/readme.mdx
@@ -0,0 +1,8 @@
+---
+title: "API changelog"
+description: "PLACEHOLDER -- Version history and breaking changes for the Turnkey API."
+---
+
+# API changelog
+
+> **This is a placeholder page.** API changelog entries will be added in a future phase.
diff --git a/changelogs/tvc-changelog/readme.mdx b/changelogs/tvc-changelog/readme.mdx
new file mode 100644
index 00000000..ce2f4161
--- /dev/null
+++ b/changelogs/tvc-changelog/readme.mdx
@@ -0,0 +1,8 @@
+---
+title: "TVC changelog"
+description: "PLACEHOLDER -- Version history for Turnkey's Verifiable Cloud."
+---
+
+# TVC changelog
+
+> **This is a placeholder page.** TVC changelog entries will be added in a future phase.
diff --git a/company-wallets/code-examples/balance-sweeper.mdx b/company-wallets/code-examples/balance-sweeper.mdx
deleted file mode 100644
index 21b38e8f..00000000
--- a/company-wallets/code-examples/balance-sweeper.mdx
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: "Balance sweeper"
-description: "This example shows how to sweep funds (tokens + native ETH) from one address to another, built on top of Ethers with Turnkey.
-
-It features abstractions for managing transaction construction, gas sponsorship, broadcasting and nonce management, all contained within a single API."
----
-
-See the [**main SDK documentation**](https://github.com/tkhq/sdk/tree/main/examples/sweeper) for detailed API reference and implementation guides.
\ No newline at end of file
diff --git a/company-wallets/code-examples/payment-orchestration.mdx b/company-wallets/code-examples/payment-orchestration.mdx
deleted file mode 100644
index 1e31a5ce..00000000
--- a/company-wallets/code-examples/payment-orchestration.mdx
+++ /dev/null
@@ -1,206 +0,0 @@
----
-title: "Payment Orchestration"
-description: "Programmatically move funds across wallet types including hot wallets, omnibus wallets, and payout wallets
-with role-based access controls defining which users or wallets can execute transfers, sweeps, swaps, mints, and redemptions."
-mode: wide
----
-
-## Why Turnkey for Payment Orchestration?
-
-Turnkey automates treasury operations, internal transfers, and crosschain routing through a single integration with sub-100ms
-signing and role-based-access-controls (RBAC) at every transaction. Keys stay secure in hardware-backed enclaves while your team
-gets full visibility into every fund movement.
-
-## Core security principles
-
-Turnkey's solution is engineered to meet the operational and security needs of high-value, high-volume payment flows:
-
-* **Zero exposure of private keys:** Private keys are default-generated and isolated within [Turnkey’s secure enclave](/security/secure-enclaves), ensuring raw private keys are never exposed to employees, automated systems, or even to Turnkey itself.
-* **Strict access control (RBAC):** Every action is explicitly permissioned in [Turnkey’s Policy Engine](/concepts/policies/quickstart). If an employee or automated system is not explicitly allowed to perform an action, they cannot.
-* **Predictable and flexible workflows:** Policies allow for granular control over permissions based on transaction type, value, wallet properties, smart contract interactions, and more. This flexibility allows businesses to meet both automated and human-operator review requirements.
-* **Enhanced operational security:** Workflows ensure that all transfers and actions come from known, authorized addresses, adding a layer of transparency and accountability to activity.
-
-Leading platforms like [Squads](https://www.turnkey.com/customers/how-squads-improves-ux-and-accounting-efficiency-with-turnkey)
-and [Flutterwave](https://flutterwave.com/us/blog/flutterwave-partners-with-turnkey-to-power-secure-stablecoin-wallets-for-customers)
-leverage Turnkey, to deliver web3 payment rails at scale.
-
-## Example
-
-Exchanges and custodial payment processors are common examples requiring highly scalable, highly secure onchain systems.
-
-
-
-**Typical needs in custodial payment processing:**
-
-| Need | Solution |
-| :---- | :---- |
-| All users have a unique deposit address | Wallet accounts are efficiently created and controlled within a Turnkey organization |
-| Access to all wallets must be strictly permissioned | Policies enforce RBAC and least-privilege for all signing actions |
-| Keys must never be exposed | Keys remain secure in secure enclave; only signatures are provided |
-| Must support automation and human review | Policies can be written to allow automation for common tasks, or require multi-party consensus for sensitive ones |
-| Must move funds efficiently | Transaction sponsorship makes it trivial to pay for only gas used on thousands of wallets |
-
-
-## How Turnkey smooths payment flows
-
-Turnkey can help at every step to remove friction, accelerate time-to-value, and meet sophisticated requirements:
-
-
-
-
-The first step is to create a Turnkey Organization and populate it with users representing your team and automated workflows.
-These users (human and machine) are assigned specific Policies dictating their access patterns to different wallets and onchain functions.
-
-Among these users, the [Root Quorum](/concepts/users/root-quorum) holds the highest level of access as a group that
-can execute any action and bypass the policy engine. By default, your initial user is the sole member. To prevent a single point
-of failure, we recommend raising the Root Quorum to require multiple root users to approve the most sensitive organizational changes.
-
-
-
-
-
-Turnkey allows you to create numerous wallet accounts at no cost, each with a unique address belonging to the same
-underlying [wallet](/concepts/wallets) resource. Before we can programmatically create an unlimited number of wallet accounts,
-let's create a “Deposits wallet” using the [@turnkey/sdk-server](https://www.npmjs.com/package/@turnkey/sdk-server) Typescript SDK.
-
-```ts
-import { Turnkey } from "@turnkey/sdk-server";
-
-const turnkeyClient = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPublicKey: process.env.API_PUBLIC_KEY!,
- apiPrivateKey: process.env.API_PRIVATE_KEY!,
- defaultOrganizationId: process.env.ORGANIZATION_ID!,
-});
-
-const { walletId, addresses } = await turnkeyClient.apiClient().createWallet({
- walletName: "Deposits wallet",
- accounts: [
- {
- curve: "CURVE_SECP256K1",
- pathFormat: "PATH_FORMAT_BIP32",
- path: "m/44'/60'/0'/0/0",
- addressFormat: "ADDRESS_FORMAT_ETHEREUM",
- },
- {
- curve: "CURVE_ED25519",
- pathFormat: "PATH_FORMAT_BIP32",
- path: "m/44'/501'/0'/0'",
- addressFormat: "ADDRESS_FORMAT_SOLANA",
- }
- ],
-});
-```
-
-Now we can create a function that produces a fresh EVM and SVM deposit address each time it's called.
-
-```ts
-async function createDepositAddresses(
- turnkeyClient: Turnkey,
- walletId: string // Deposits wallet
- ): Promise {
- const addresses = await turnkeyClient.apiClient().createWalletAccounts({
- walletId,
- accounts: ["ADDRESS_FORMAT_ETHEREUM", "ADDRESS_FORMAT_SOLANA"]
- });
-
- return addresses.addresses;
-}
-```
-
-Such a function could be connected to end-user action, or kicked off by some internal flow.
-
-
-
-
-
-Creating deposit addresses on demand is straightforward, but traditionally, the complexity begins after something is deposited.
-Moving these funds to a company wallet after deposit (a “sweep”) is subject to major security and cost considerations. With Turnkey, we can:
-
-* Enforce that all transfers from deposit addresses are into a centrally controlled omnibus address.
-* Forgo sending additional funds to every deposit address to cover transaction fees (gas).
-
-Assume you have created an omnibus wallet for your organization, either as shown above or in the Web Dashboard.
-This is a new hot wallet collecting the funds initially deposited across thousands of deposit addresses.
-
-Let's first create a policy that only allows transactions from deposit addresses to the omnibus address.
-EVM and SVM will require similar yet distinct policies due to their distinct transaction types. These policies can also vary
-by chain, and in production, they likely will need to.
-
-
-```json
-{
- "policyName": "(EVM) Allow API Key User to sign transactions with Deposits wallet",
- "effect": "EFFECT_ALLOW",
- "consensus": "approvers.any(user, user.id == '')",
- "condition": "activity.action == 'SIGN' && wallet.id == '' && eth.tx.to == ''"
-},
-{
- "policyName": "(SVM) Allow API Key User to sign transactions with Deposits wallet",
- "effect": "EFFECT_ALLOW",
- "consensus": "approvers.any(user, user.id == '')",
- "condition": "activity.action == 'SIGN' && wallet.id == '' && solana.tx.transfers.count == 1 && solana.tx.transfers[0].to == ''"
-}
-```
-
-Turnkey's Policy Engine is default-deny, so you only need to specify the exact conditions to allow.
-Transactions must be fully parsed and validated against your policy parameters. Any **raw or obfuscated payloads are rejected** unless otherwise specified.
-
-A costly component of deposit wallet operations is funding each address with enough gas to cover the network fee for sweeping into
-your central wallet. This funding transaction itself incurs a second fee.
-
-Thankfully, with a single line, we can enable Turnkey’s sponsored transaction feature and bypass this entirely, executing a single
-optimized externally sponsored transaction.
-
-
-```ts
-const sendTransactionStatusId = await turnkeyClient.apiClient().ethSendTransaction({
- transaction: {
- from: depositAddress,
- to: "OMNIBUS_ADDRESS",
- caip2: "eip155:8453",
- sponsor: true,
- value: "0",
- data: "0x",
- nonce: "0",
- },
-});
-```
-
-A more complete guide to gas sponsorship can be [found here](/company-wallets/code-examples/sending-sponsored-transactions).
-
-
-
-
-At this point, we've covered creating deposit addresses on demand and securely sweeping funds to a treasury address.
-
-The next step is managing a wallet that likely requires human-operator approval and may need more sophisticated automations like asset rebalancing.
-
-To set multi-user approval in policies, create a user tag (e.g., 'ops-team') and apply it to your teammates. You can then set a policy requiring
-their approval for transfers to a company cold wallet.
-
-
-```json
-{
- "policyName": "Require 2 ops-team for cold wallet deposits",
- "effect": "EFFECT_ALLOW",
- "consensus": "approvers.filter(user, user.tags.contains('')).count() > 1",
- "condition": "activity.action == 'SIGN' && wallet.id == '' && (eth.tx.to == '' || (eth.tx.data[0..10] == '0xa9059cbb' && eth.tx.data[34..74] == ''))"
-}
-```
-
-When transferring tokens rather than native funds, the transaction data can be parsed for known function signatures (e.g., an ERC-20 transfer),
-but the recommended approach is to [upload the contract ABI](/concepts/policies/smart-contract-interfaces) for supported assets and act
-on fully parsed transactions.
-
-Managing real assets at scale introduces security complexity. Balancing risk management, regulatory compliance, and maintaining enough
-liquidity to meet ongoing withdrawal demand makes fund movement one of the hardest problems to engineer. While there's no universal solution,
-pairing application-specific users with tailored policies is the security posture adopted by leading Web3 teams.
-
-
-
-## The result: security as code
-
-Turnkey makes onchain movement easy, scaling to meet high-value and high-volume workflows where access and actions are defined by code.
-This "Security as Code" approach allows businesses to scale Web3 operations with confidence, knowing their mission-critical payment
-flows are protected by cryptographically enforced security and least-privilege access control.
diff --git a/company-wallets/code-examples/signing-transactions.mdx b/company-wallets/code-examples/signing-transactions.mdx
deleted file mode 100644
index 545d117c..00000000
--- a/company-wallets/code-examples/signing-transactions.mdx
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: "Signing transactions"
-description: "This is a guide to signing transactions in a server context. While these snippets leverage Ethers, it can be swapped out for other signers in the Viem or Solana contexts. An example for Ethers can be found , and for Viem in the server context. A similar example with Solana can be found ."
-mode: wide
----
-
-
-
-
-```ts
-import { Turnkey } from "@turnkey/sdk-server";
-
-const turnkeyClient = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
- apiPrivateKey: process.env.API_PRIVATE_KEY,
- apiPublicKey: process.env.API_PUBLIC_KEY,
-});
-```
-
-
-
-
-```ts
-import { ethers } from "ethers";
-import { TurnkeySigner } from "@turnkey/ethers";
-
-const provider = new ethers.JsonRpcProvider();
-const turnkeySigner = new TurnkeySigner({
- client: turnkeyClient.apiClient(),
- organizationId: process.env.ORGANIZATION_ID!,
- signWith: process.env.SIGN_WITH!,
- });
-```
-
-
-
-
-```ts
-const transactionRequest = {
- to: "",
- value: ethers.parseEther(""),
- type: 2,
-};
-const sendTransaction =
- await connectedSigner.sendTransaction(transactionRequest);
-```
-
-
diff --git a/company-wallets/code-examples/smart-contract-management.mdx b/company-wallets/code-examples/smart-contract-management.mdx
deleted file mode 100644
index 90ca91d6..00000000
--- a/company-wallets/code-examples/smart-contract-management.mdx
+++ /dev/null
@@ -1,95 +0,0 @@
----
-title: "Smart Contract Management"
-description: "This is a guide to Smart Contract Management. Our approach is built on a chain-agnostic, primitive-first foundation,
-providing consistent security and workflow management regardless of the blockchain, development tools, or specific use case."
-mode: wide
----
-
-## Why Turnkey for Smart Contract Management?
-
-Turnkey provides a highly secure, predictable, and flexible solution for managing onchain assets. Our approach combines mature,
-cryptographic security with Role-Based Access Control (RBAC) to implement least privilege access and programmatically sign critical
-smart contract operations, such as minting, burning, and pausing.
-
-## Core security principles
-
-Turnkey's solution is engineered to meet the operational and security needs of high-value, high-scrutiny contracts:
-
-* **Zero exposure of private keys:** Private and signing keys are default generated and kept within [Turnkey’s secure enclave](/security/secure-enclaves), never directly exposed or handled by users or automated systems.
-* **Strict access control (RBAC):** Every action – from deployment to token minting to upgrades – is explicitly permissioned via [Policies](/concepts/policies/quickstart). If a user or automated system is not explicitly allowed to perform an action, they cannot.
-* **Predictable and flexible workflows:** Policies allow for granular control over permissions based on transaction type, chain ID, contract address, function hash, and even transaction values. This flexibility allows businesses to meet both automated and human-operator review requirements.
-* **Enhanced operational security:** Workflows ensure that all contract deployments and actions come from known, authorized addresses, adding a layer of transparency and accountability to all onchain activity.
-
-
-
-The above features can also fit **existing** smart contract deployments and management setups; many of the largest teams in Web3 (like Polymarket) have successfully transitioned.
-
-## A high-stakes example: stablecoins and RWAs
-
-Consider the management of Stablecoins or tokenized Real-World Assets, which often secure billions of dollars in value. These high-value contracts require workflows that demand absolute control and accountability.
-
-**Typical needs for high-value contracts:**
-
-| Need | Solution |
-| :---- | :---- |
-| All actions must come from known addresses | Wallets are created and controlled within a Turnkey organization |
-| Access must be strictly permissioned | Policies enforce RBAC and least-privilege for all signing actions |
-| Keys must never be exposed | Keys remain secure in secure enclave; only signatures are provided |
-| Must support automation and human review | Policies can be written to allow automation for common tasks, or require multi-party consensus for sensitive ones |
-
-## How Turnkey secures the lifecycle
-
-Turnkey provides secure, granular control across the entire contract lifecycle:
-
-
-
-
-The first step involves creating a Turnkey Organization and populating it with users (both human and machine). These users are assigned specific Policies that dictate their access patterns to different wallets and on-chain functions.
-
-Crucially, the organization’s highest security threshold, the [**Root Quorum**](/concepts/users/root-quorum),
-is secured. To prevent a single point of failure, we recommend raising the root quorum to require multiple root users to approve the
-most sensitive organizational changes, ensuring operational continuity even in the event of credential loss.
-
-
-
-
-Deployment is strictly permissioned. A designated 'deployer' user must have a policy that explicitly grants them permission to sign the
-deployment transaction for a specific wallet and network.
-
-
-
-
-
-Once deployed, interactions like minting new token supply are governed by precise policies.
-
-For example, a policy can be configured to:
-
-* Allow a 'token owner' user to sign a transaction
-* Require the transaction to originate from a specific wallet
-* Target the deployed contract's exact address
-* Call a specific function (e.g., `mint`)
-
-Policies can also bound [minting amounts](/concepts/policies/smart-contract-interfaces), requiring an additional human review and approval for large transactions.
-
-
-
-
-Upgrading a contract is one of the most sensitive operations, as it redirects the underlying implementation logic – a process that can be exploited if unsecured.
-
-Turnkey ensures this process is secure:
-
-* The contract is designed to be upgradeable from the start (e.g., using a proxy pattern).
-* A specific 'upgrade owner' wallet is designated.
-* A temporary, highly restrictive policy is created **only when an upgrade is needed**. This policy grants an 'upgrade owner' permission to sign the upgrade transaction.
-* Once the upgrade is complete, the policy is removed, and the wallet remains dormant and secured until the next required upgrade, minimizing the window of risk.
-
-
-
-
-> This process is further explored in our [GitHub 'Smart Contract Management' demo](https://github.com/tkhq/solutions/tree/main/smart-contract-mgmt)
-
-## The result: security as code
-
-Turnkey transforms Smart Contract Management from a high-risk, manual operation into a secure, predictable workflow where access is defined
-by code. This "Security as Code" approach allows businesses to scale their Web3 operations with confidence, knowing their mission-critical
-smart contracts are protected by cryptographically enforced security and least-privilege access control.
diff --git a/company-wallets/overview.mdx b/company-wallets/overview.mdx
deleted file mode 100644
index 96c0f860..00000000
--- a/company-wallets/overview.mdx
+++ /dev/null
@@ -1,76 +0,0 @@
----
-title: "Overview"
----
-
-import { SquareCard } from "/snippets/square-card.mdx";
-import { Logo } from "/snippets/logo.mdx";
-
-Turnkey empowers teams to automate complex signing workflows at scale without compromising on security or flexibility. Company Wallets provide the building blocks for creating custom solutions that make your product more secure, from role-based access controls to privacy-preserving smart contracts.
-
-With Company Wallets, you can:
-
-- Automate millions of signatures with customizable security controls
-- Implement role-based access controls and multi-party approvals
-- Support any blockchain or asset type with our chain-agnostic, arbitrary signing capabilities
-- Minimize attack surface area with our paranoid security model
-- Easily migrate existing wallets and keys in and out of Turnkey
-
-## Policy engine
-
-At the foundation of Company Wallets are our policy engine.
-Policies offer flexible controls and permissions within your organization
-and enable a variety of use cases, including cross-border stablecoin payments,
-treasury management, and more.
-
-## What kind of policies can you create?
-
-| Example | Description |
-| ---------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
-| [`deployer`](https://github.com/tkhq/sdk/tree/main/examples/deployer/) | Compile and deploy a smart contract |
-| [`rebalancer`](https://github.com/tkhq/sdk/tree/main/examples/rebalancer/) | A demo application which showcases an example of how to use Turnkey for managing multiple types of keys & users |
-| [`sweeper`](https://github.com/tkhq/sdk/tree/main/examples/sweeper/) | Sweep funds from one address to a different address |
-| [`trading-runner`](https://github.com/tkhq/sdk/tree/main/examples/trading-runner/) | A sample application demonstrating a trading operation, using various private keys, users, and policies, powered by Uniswap |
-
-Almost all actions on Turnkey are implicitly denied by default.
-See our [Policy Overview](/products/company-wallets/policy-engine) for exceptions.
-
-## Other use cases
-
-### Staking operations
-
-Staking teams can use Turnkey to streamline their operations and secure their keys. Automate critical workflows like:
-
-- Mnemonic and key generation
-- Rewards claiming and distribution
-- Network voting and governance actions
-
-## SDKs
-
-
-
-## Next steps
-
-Dig into Company Wallet features like multichain support, scoped API keys, multi-signature approvals, and [more](/products/company-wallets/features/multi-chain-support).
diff --git a/concepts/broadcasting.mdx b/concepts/broadcasting.mdx
deleted file mode 100644
index 4dc1084d..00000000
--- a/concepts/broadcasting.mdx
+++ /dev/null
@@ -1,72 +0,0 @@
----
-title: "Broadcasting"
-description: "Transaction construction, broadcast, and status monitoring for EVM and Solana."
----
-
-## Construction and Broadcast
-
-### EVM
-
-A successful EVM transaction requires:
-
-- **Transaction construction**: assembling the payload (recipient, value, calldata)
-- **Nonce**: set correctly to order transactions and prevent conflicts
-- **Gas and tip fee**: estimated to ensure inclusion even during network congestion
-- **Signature**: cryptographically signing the transaction with the sender's private key
-- **Broadcast**: submitting the signed transaction to the network and monitoring for inclusion
-
-Turnkey handles all of this for you via `ethSendTransaction`. Whether or not you use sponsorship, you pass through minimal payloads and we take care of the rest. We auto-fill any fields you omit.
-
-This endpoint supports arbitrary EVM transactions — not just simple sends. You can interact with smart contracts, deploy contracts, or execute any valid EVM operation.
-
-### Solana
-
-A successful Solana transaction requires:
-
-- **Transaction construction**: assembling the list of instructions (program, accounts, data)
-- **Recent blockhash**: fetched and attached at broadcast time to ensure the transaction is valid
-- **Compute unit limit**: estimated and set to prevent failed transactions due to insufficient compute
-- **Priority fee**: set to ensure timely inclusion under current network conditions
-- **Signature**: cryptographically signing the transaction with the sender's private key
-- **Broadcast**: submitting the signed transaction to the network and monitoring for confirmation
-
-Turnkey handles all of this for you via `solSendTransaction`. Whether or not you use sponsorship, you pass through a minimal payload and we manage the rest.
-
-
- On Solana, fee sponsorship and rent sponsorship are separate. `Sponsor Solana
- Rent` is disabled by default and must be enabled in the dashboard before
- Turnkey will pre-fund rent for account creation. If created accounts are later
- closed, refunded rent can go back to the signer rather than the sponsor. See
- [Solana Rent Sponsorship](/networks/solana-rent-refunds). For payer behavior,
- static-key requirements, and account-creation caveats in sponsored flows, see
- [Solana transaction construction for sponsored flows](/networks/solana-transaction-construction).
-
-
-## Transaction status and enriched errors
-
-After you send a transaction, Turnkey monitors its status until it fails or is confirmed on-chain.
-
-### Transaction Statuses
-
-The following statuses apply to both EVM and Solana transactions:
-
-| **Status** | **Description** |
-| ------------ | -------------------------------------------------------------------------------------------------------- |
-| INITIALIZED | Turnkey has constructed and signed the transaction and prepared fees, but it has not yet been broadcast. |
-| BROADCASTING | Turnkey is actively broadcasting the transaction to the network and awaiting inclusion. |
-| INCLUDED | The transaction has been included in a block (EVM) or confirmed on-chain (Solana). |
-| FAILED | The transaction could not be included on-chain and will not be retried automatically. |
-
-### EVM Smart Contract Transaction Errors
-
-For EVM transactions that revert, Turnkey runs a simulation to produce structured execution traces and decode common revert reasons — giving you actionable error messages instead of opaque hex data.
-
-| **Error type** | **Description** |
-| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| UNKNOWN | The transaction reverted during on-chain execution or simulation, but the revert reason could not be decoded (e.g. missing ABI or unverified contract). |
-| NATIVE | The transaction reverted due to a built-in Solidity error, such as `require()`, `assert()`, or a plain `revert()`. |
-| CUSTOM | The transaction reverted due to a contract-defined custom error declared using Solidity's `error` keyword. |
-
-
- These error types describe how an EVM smart contract reverted during on-chain execution or pre-flight simulation. Turnkey application-level errors (e.g. signing failures, policy rejections) are not classified here and are instead surfaced via `Error.Message`.
-
\ No newline at end of file
diff --git a/concepts/overview.mdx b/concepts/overview.mdx
deleted file mode 100644
index bc0777bb..00000000
--- a/concepts/overview.mdx
+++ /dev/null
@@ -1,156 +0,0 @@
----
-title: "Overview"
-description: "Turnkey is flexible, scalable, and secure wallet infrastructure that can be used for transaction automation (e.g., payments flows, smart contract management), or non-custodial embedded wallets. Turnkey offers low-level primitives that can be combined to accomplish a variety of goals."
----
-
-Turnkey’s security and flexibility enables you to build cutting-edge user experiences, whether you’re using our bare-bones API or pre-built UI components. To make the most out of your implementation, we recommend reading through the following Concepts page for a better understanding of how our products work, and how to best utilize all of Turnkey’s features.
-
-### How Turnkey works
-
-At the core of Turnkey is an important concept: instead of directly managing private keys, wallets are accessed through authenticators like passkeys, social logins, or API keys:
-
-
-
-
-
-- **Organizations (parent orgs)** in Turnkey are top-level entities that contain users, wallets, and policies for a business, with the initial “parent organization” typically representing an entire Turnkey-powered application.
-- Parent organizations can create **sub-organizations (sub-orgs)**, which are fully segregated organizations nested under the parent organization. Parent orgs cannot modify the contents of a sub-org, and sub-orgs typically represent an end user.
-- Both parent organizations and sub-organizations contain a set of **resources and authenticators** that you can configure, including their own users, wallets, API keys, private keys, and policies.
-- **Activities** (like signing transactions or creating users) are governed by **policies** created via Turnkey’s policy engine, though root users can bypass the policy engine when meeting root quorum requirements.
-- **Wallets** in Turnkey are HD seed phrases that can generate multiple wallet accounts (addresses) for signing operations.
-
-### Managing Turnkey interactions and organizations
-
-There are two primary ways for users to interact with Turnkey — via the Turnkey Dashboard, and by submitting activity requests via our public API.
-
-The Turnkey Dashboard, which is where you’ll first create your Turnkey parent organization, is where root users of your parent organization will typically manage administrative activities. It supports passkey authentication only.
-
-On the other hand, interactions with Turnkey at scale (primarily, interactions initiated by end users) can be done via programmatically calling the Turnkey public API and submitting activity requests, with a variety of authentication methods supported.
-
-## Concepts dictionary
-
-For more details on individual concepts, feel free to explore our concept-specific documentation (also accessible through the left navbar).
-
-### Organizations
-
-An organization is a logical grouping of resources like users, policies, and wallets. There are two types of organizations:
-
-| Organization type | Description |
-| :------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| Parent Organization | When you first setup your implementation of Turnkey by signing up on the dashboard you create a parent organization controlled by your business. In most implementations, a top-level organization represents an entire Turnkey-powered implementation. For more information on Turnkey parent organizations [look here](/concepts/organizations). |
-| Sub-Organization | A fully segregated organization nested under the parent organization. Parent organizations have read access to all their sub-organizations, but do not have write access. Each sub-organization typically maps to an individual end user in a Turnkey-powered application. Parent organizations can initiate limited actions for sub-organizations that then must be completed by the sub-organization (e.g. `INIT_OTP`). For more information on Turnkey sub-organizations [look here](/concepts/sub-organizations). |
-
-### Users
-
-Turnkey users are resources within organizations or sub-organizations that can submit activities to Turnkey via a valid credential (e.g., API key, passkey). These requests can be made either by making direct API calls or through the Turnkey Dashboard. Users must be set up to authenticate to Turnkey with credentials (API keys, passkeys), or via other authentication methods such as OAuth, or email auth, with upper limits on credentials defined here in our [resource limits](/concepts/resource-limits). Users can also have associated “tags” which are logical groupings that can be referenced in policies. Users can only submit activities within their given organization — they cannot take action across organizations.
-
-There are two main types of users:
-
-| User type | Description |
-| :----------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| Root Users | The first user(s) created in an organization will have root permissions, meaning they can bypass the policy engine to take any action within that specific organization. This ability can be limited via root quorum, which requires a threshold of root users to access root permissions. For example, if there are five root users and the threshold is three, at least three users must approve an activity for the root quorum threshold to be reached. When you first create a Turnkey organization, your user is automatically created as the sole member of the root quorum by default. |
-| Normal Users | Other than managing their own credentials, non-root users have no permissions unless explicitly granted by [policies](/concepts/policies/overview). By combining non-root users with policies granting permission for specific actions, you can build support for experiences providing [delegated access](/concepts/policies/delegated-access) to business controlled service account. |
-
-In parent organizations, a user often maps to an individual from your team with administrative privileges and responsibilities. In sub-organizations, which are often used to manage an end user's resources, a user can represent an end user and their credentials. If there is only one user representing the end user with only end-user controlled credentials then this would be more akin to a standard non-custodial setup. However, this flexible primitive can often represent other aspects of your backend or application. For example, a Turnkey user might map to a:
-
-- Backend service used to automate certain transactions
-- Service with delegated access to take action on behalf of an end user
-- Required co-signer for all end user transactions
-
-For more information on Turnkey users [look here](/concepts/users/introduction).
-
-### Credentials
-
-Interacting with the Turnkey API requires each API call to be authenticated by cryptographically stamping it with a credential. This process is abstracted away in our SDKs and ensures that the request cannot be tampered with as it travels to the secure enclave. Credentials include API keys and passkeys / Webauthn devices for all Users, while sub-organization users can also use email or OAuth to authenticate. Email and OAuth leverage API keys under the hood.
-
-For more information on Turnkey user credentials [look here](/concepts/users/credentials).
-
-### Activities
-
-Activities are specific actions taken by users, such as signing a transaction, adding a new user, or creating a sub-organization. Activity requests are always evaluated through our policy engine, and can evaluate to ALLOW, DENY, or REQUIRES_CONSENSUS (i.e., requires additional approvals before being allowed).
-
-For more information on Turnkey activities [look here](/developer-reference/api-overview/submissions).
-
-### Policies
-
-Policies, enforced by Turnkey’s policy engine, grant users permissions to perform activities. These policies are a series of logical statements (e.g., User ID == 123 or ETH address == 0x543…9b34) that evaluate to either “ALLOW” or “DENY.” Through these policies you can set granular controls on which users can take which actions with which wallets. Policies can also require multi-party approval / consensus, meaning a threshold of certain users will be required to approve the activity. As mentioned above, the root quorum will bypass the policy engine.
-
-For more information on Turnkey policies [look here](/concepts/policies/overview).
-
-### Wallets and private keys
-
-Resources used to generate crypto addresses and sign transactions or messages. We currently support secp256k1, ed25519, and P256 curves and have two main types:
-
-| Resource type | Description |
-| :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| Wallets (preferred) | A hierarchical deterministic (HD) wallet, which is a collection of cryptographic key pairs derived from a common seed phrase. A wallet (i.e., a single seed phrase) can have many wallet accounts (i.e., a set of derived addresses). Wallets support various cryptographic curves and can be represented by a checksummed mnemonic phrase, making them easier to back up and recover. We limit each organization to 100 Wallets, but there is no limit on the total number of wallet accounts. For more information on Turnkey HD wallets [look here](/concepts/wallets). |
-| Private Keys | Raw private keys represented by an alphanumeric string. We limit each organization to 1,000 private keys, therefore we recommend using wallets instead of private keys for better scalability. |
-
-Learn more about leveraging Wallets across different crypto ecosystems on our [Ecosystem Support](/networks/overview) page.
-
-
-
- Understand Turnkey's core features and fundamentals.
-
-
-{" "}
-
-
- Learn about Organizations on Turnkey
-
-
- Learn about sub-organizations on Turnkey
-
-
-{" "}
-
-
- 3 items
-
-
-{" "}
-
-
- Learn about Wallets on Turnkey
-
-
-{" "}
-
-
- Organization resource limits
-
-
-
- 5 items
-
-
diff --git a/concepts/transaction-management.mdx b/concepts/transaction-management.mdx
deleted file mode 100644
index 90774d14..00000000
--- a/concepts/transaction-management.mdx
+++ /dev/null
@@ -1,15 +0,0 @@
----
-description: "Learn about Turnkey's gas sponsorship, transaction construction, broadcast, nonce management and monitoring capabilities."
----
-
-import SendTxConcepts from "/snippets/shared/send-tx-concepts.mdx";
-
-
-
-## Next steps
-
-For implementation guides, see:
-
-- [Sending Sponsored EVM Transactions (React)](/embedded-wallets/code-examples/sending-sponsored-transactions) - Using `@turnkey/react-wallet-kit`
-- [Sending Sponsored Solana Transactions (React)](/embedded-wallets/code-examples/sending-sponsored-solana-transactions) - Using `@turnkey/react-wallet-kit`
-- [Sending Sponsored Transactions](/company-wallets/code-examples/sending-sponsored-transactions) - Using `@turnkey/core` directly
\ No newline at end of file
diff --git a/concepts/users/credentials.mdx b/concepts/users/credentials.mdx
deleted file mode 100644
index 48bc146a..00000000
--- a/concepts/users/credentials.mdx
+++ /dev/null
@@ -1,24 +0,0 @@
----
-title: "Credentials"
-description: "Credentials represent ways for Users to authenticate to Turnkey. All Turnkey Credentials are held by you, the end-user. Turnkey only keeps **public keys**."
----
-At the moment, Turnkey supports 2 types of Credentials:
-
-* Authenticators
-* API Keys
-
-Note that every Turnkey user needs at least one long-lived credential (a passkey, or non-expiring API key). This is to prevent users from getting locked out of their accounts. The exception is if the user belongs to a suborg, and [Email Auth](/authentication/email) is enabled for that sub-organization.
-
-### Authenticators
-
-Turnkey uses [Webauthn](https://www.w3.org/TR/webauthn-2/) for authentication into its dashboard (no passwords!). Authenticators on Turnkey represent a Webauthn device registered on Turnkey.
-
-When logging into Turnkey, you'll be prompted for a signature with a registered device. This signature is then verified to grant dashboard access. To avoid repeated signatures, Turnkey's dashboard uses session cookies for read traffic. However, all write actions require an authenticator signature.
-
-### API keys
-
-Turnkey API requests are authenticated with API key signatures. When you generate an API key (either through our CLI or through our dashboard), you generate a P-256 key pair. Turnkey keeps the public key, and you hold the private key.
-
-Requests made via SDK or CLI use the private API key to sign requests. Turnkey's public API expects all requests (e.g. to get data or to submit activities) to be signed.
-
-See our [API reference](/api-reference/activities/create-api-keys) for how to programmatically create API keys.
diff --git a/cookbook/landing.mdx b/cookbook/landing.mdx
deleted file mode 100644
index 1374b971..00000000
--- a/cookbook/landing.mdx
+++ /dev/null
@@ -1,67 +0,0 @@
----
-title: "Cookbooks"
-description: "Step-by-step guides for integrating Turnkey with protocols, platforms, and services."
-sidebarTitle: "Overview"
-slug: "cookbook/landing"
----
-
-
-
- Lend and earn yield through Morpho's vaults, scoping wallet permissions to specific contracts
- with Turnkey's policy engine.
-
-
- Supply and borrow assets through Aave's lending markets, with Turnkey's policy engine enforcing
- contract-level access controls.
-
-
- Deposit and earn yield on Breeze using Turnkey-powered Solana wallets.
-
-
- Swap tokens on Solana through Jupiter's aggregated liquidity, signing transactions with Turnkey.
-
-
- Bridge and swap tokens across chains with Li.Fi, using Turnkey to sign across networks.
-
-
- Swap tokens across chains using 0x's swap platform, with Turnkey handling signing and allowance
- management.
-
-
- Discover and manage yield opportunities across 75+ networks, with Turnkey providing
- policy-controlled signing.
-
-
- Enable gasless trading with builder attribution on Polymarket, including Safe deployment and
- token approvals.
-
-
- Attribute onchain activity on Base to your app using builder codes, carried in Turnkey-signed
- transactions.
-
-
- Bridge and swap tokens across chains with Relay, signed by Turnkey wallets.
-
-
- Onramp USD, mint stablecoins, and send payouts via Brale, using Turnkey's policy engine to
- secure signing authority.
-
-
diff --git a/developer-reference/api-overview/queries.mdx b/developer-reference/api-overview/queries.mdx
deleted file mode 100644
index a70479f3..00000000
--- a/developer-reference/api-overview/queries.mdx
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: "Queries"
-description: "Queries are read requests to Turnkey's API. Query URL paths are prefixed with `/public/v1/query`. Queries are not subject to enforcement of the policy engine. All users within an organization can read any data within the organization."
-mode: wide
----
-
-Additionally, parent organizations have the ability to query data for all of their sub-organizations.
diff --git a/developer-reference/api-overview/submissions.mdx b/developer-reference/api-overview/submissions.mdx
deleted file mode 100644
index cd0a7d24..00000000
--- a/developer-reference/api-overview/submissions.mdx
+++ /dev/null
@@ -1,24 +0,0 @@
----
-title: "Submissions"
-description: "Submissions are requests to securely execute a workload. Submission URL paths are prefixed with `/public/v1/submit`. Submissions requests, if valid, produce an `Activity`."
----
-
-### Activities
-
-Activities typically create, modify, or utilize a resource within Turnkey and are subject to consensus or condition enforcement via the policy engine. Activities are executed optimistically synchronous. This means that if we can process the request synchronously, we will. Otherwise, we'll fallback to asynchronous processing. Your services or applications should account for this by checking the response for the activity state:
-
-* If `activity.status == ACTIVITY_STATUS_COMPLETED`, `activity.result` field will be populated with a successful response.
-* If `activity.status == ACTIVITY_STATUS_FAILED`, `activity.failure` field will be populated with a failure reason.
-* If `activity.status == ACTIVITY_STATUS_CONSENSUS_NEEDED`, additional signatures (votes) are required to process the request.
-* If `activity.status == ACTIVITY_STATUS_PENDING`, the request is processing asynchronously.
-
-Activities do not expire but approvals (votes) do. When an activity is submitted, the requester’s submission counts as the first approval, which starts a 24-hour window. If consensus is not reached within that window, existing approvals expire and must be re-submitted while the activity remains in `ACTIVITY_STATUS_CONSENSUS_NEEDED`.
-
-You can get activity status updates by:
-
-* Re-submitting the request. See the notes on idempotency below.
-* Polling `get_activity` with the `activity.id`
-
-### Idempotency
-
-The submission API is idempotent. For each request, the POST body is hashed into a fingerprint. Any two requests with the same fingerprint are considered the same request. If you resubmit the request, you'll get the same activity. If you want a new activity, you should modify the request timestamp `timestampMs` to produce a new fingerprint.
diff --git a/docs.json b/docs.json
index 0f0ce716..37bfd2e7 100644
--- a/docs.json
+++ b/docs.json
@@ -3,8 +3,8 @@
"theme": "mint",
"name": "Turnkey",
"colors": {
- "primary": "#6a5bf5",
- "light": "#6a5bf5",
+ "primary": "#4C48FF",
+ "light": "#4C48FF",
"dark": "#050a0b"
},
"contextual": {
@@ -25,940 +25,878 @@
},
"favicon": "/favicon.svg",
"navigation": {
- "global": {
- "anchors": [
- {
- "anchor": "Support",
- "icon": "slack",
- "href": "https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ"
- },
- {
- "anchor": "Blog",
- "icon": "newspaper",
- "href": "https://www.turnkey.com/blog"
- },
- {
- "anchor": "Contact us",
- "icon": "headset",
- "href": "https://www.turnkey.com/contact-us"
- }
- ]
- },
+ "global": {},
"tabs": [
{
- "tab": "Documentation",
+ "tab": "Home",
+ "icon": "/images/icons/home-02.svg",
"groups": [
{
- "group": "Get started",
+ "group": "Welcome",
"pages": [
- "home",
- {
- "group": "Concepts",
- "pages": [
- "concepts/overview",
- "concepts/organizations",
- "concepts/sub-organizations",
- {
- "group": "Users",
- "pages": [
- "concepts/users/introduction",
- "concepts/users/credentials",
- "concepts/users/root-quorum"
- ]
- },
- "concepts/wallets",
- "concepts/resource-limits",
- "concepts/policies/overview"
- ]
- },
- {
- "group": "Architecture",
- "pages": [
- "products/company-wallets/features/security/quorum-os",
- "products/company-wallets/features/security/remote-attestation",
- "products/company-wallets/features/security/secure-hardware",
- "sdks/cli"
- ]
- },
- "getting-started/quickstart",
- {
- "group": "Quickstarts",
- "pages": [
- "getting-started/embedded-wallet-quickstart",
- "getting-started/migration-guide",
- "getting-started/company-wallets-quickstart",
- "getting-started/verifiable-cloud-quickstart"
- ]
- },
- {
- "group": "Production checklist",
- "pages": [
- "production-checklist/production-checklist",
- "production-checklist/backup-recovery",
- "production-checklist/embedded-wallet",
- "production-checklist/company-wallet"
- ]
- }
+ "welcome"
+ ]
+ }
+ ]
+ },
+ {
+ "tab": "Solutions",
+ "groups": [
+ {
+ "group": "Overview",
+ "pages": [
+ "solutions/overview"
]
},
{
- "group": "Products",
+ "group": "Embedded Wallets",
"pages": [
+ "solutions/embedded-wallets/overview",
+ {
+ "group": "Solution",
+ "pages": [
+ "solutions/embedded-wallets/embedded-consumer-wallet",
+ "solutions/embedded-wallets/embedded-business-wallets",
+ "solutions/embedded-wallets/embedded-waas"
+ ]
+ },
+ "solutions/embedded-wallets/quickstart",
{
- "group": "Embedded Wallets",
+ "group": "Integration guide",
"pages": [
- "embedded-wallets/overview",
+ "solutions/embedded-wallets/integration-guide/overview",
{
- "group": "Features",
+ "group": "React",
"pages": [
- "embedded-wallets/features/overview",
- "products/embedded-wallets/features/agentic-wallets",
- "reference/embedded-wallet-kit",
- "reference/auth-proxy",
+ "solutions/embedded-wallets/integration-guide/react/index",
+ "solutions/embedded-wallets/integration-guide/react/getting-started",
+ "solutions/embedded-wallets/integration-guide/react/auth",
+ "solutions/embedded-wallets/integration-guide/react/using-embedded-wallets",
{
- "group": "Transaction Management",
+ "group": "Using external wallets",
"pages": [
- "concepts/transaction-management",
- "concepts/broadcasting",
- "concepts/balances"
+ "solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview",
+ "solutions/embedded-wallets/integration-guide/react/using-external-wallets/authentication",
+ "solutions/embedded-wallets/integration-guide/react/using-external-wallets/connecting"
]
},
+ "solutions/embedded-wallets/integration-guide/react/signing",
+ "solutions/embedded-wallets/integration-guide/react/ui-customization",
+ "solutions/embedded-wallets/integration-guide/react/sub-organization-customization",
+ "solutions/embedded-wallets/integration-guide/react/advanced-api-requests",
+ "solutions/embedded-wallets/integration-guide/react/advanced-backend-authentication",
+ "solutions/embedded-wallets/integration-guide/react/migrating-sdk-react",
+ "solutions/embedded-wallets/integration-guide/react/troubleshooting",
+ "solutions/embedded-wallets/integration-guide/react/legacy"
+ ]
+ },
+ {
+ "group": "React Native",
+ "pages": [
+ "solutions/embedded-wallets/integration-guide/react-native/overview",
+ "solutions/embedded-wallets/integration-guide/react-native/getting-started",
{
"group": "Authentication",
"pages": [
- "authentication/overview",
- "authentication/email",
- "authentication/social-logins",
- "authentication/sms",
- "authentication/otp-migration-guide",
- {
- "group": "Passkeys",
- "pages": [
- "authentication/passkeys/introduction",
- "authentication/passkeys/integration",
- "authentication/passkeys/options",
- "authentication/passkeys/native",
- "authentication/passkeys/discoverable-vs-non-discoverable"
- ]
- },
- "authentication/backend-setup",
- "authentication/proxying-signed-requests",
- "authentication/bring-your-own-auth",
- "authentication/credentials"
+ "solutions/embedded-wallets/integration-guide/react-native/authentication/overview",
+ "solutions/embedded-wallets/integration-guide/react-native/authentication/email-sms",
+ "solutions/embedded-wallets/integration-guide/react-native/authentication/passkey",
+ "solutions/embedded-wallets/integration-guide/react-native/authentication/social-logins"
]
},
- "products/embedded-wallets/features/multi-chain-support",
- "products/embedded-wallets/features/fiat-on-ramp",
- "authentication/sessions",
- {
- "group": "Wallets",
- "pages": [
- "wallets/pregenerated-wallets",
- "wallets/claim-links",
- "reference/aa-wallets",
- "wallets/import-wallets",
- "wallets/export-wallets",
- "wallets/wagmi",
- "wallets/fiat-on-ramp"
- ]
- }
+ "solutions/embedded-wallets/integration-guide/react-native/sub-organization-customization",
+ "solutions/embedded-wallets/integration-guide/react-native/using-embedded-wallets",
+ "solutions/embedded-wallets/integration-guide/react-native/signing",
+ "solutions/embedded-wallets/integration-guide/react-native/advanced-api-requests"
]
},
{
- "group": "SDKs",
+ "group": "TypeScript",
"pages": [
- "sdks/react/landing",
- "sdks/react-native",
- "sdks/flutter/landing",
- "sdks/swift/landing",
- "sdks/kotlin/landing",
- "sdks/typescript-frontend/landing",
- "sdks/javascript-server"
+ "solutions/embedded-wallets/integration-guide/typescript/index",
+ "solutions/embedded-wallets/integration-guide/typescript/getting-started",
+ "solutions/embedded-wallets/integration-guide/typescript/auth",
+ "solutions/embedded-wallets/integration-guide/typescript/advanced-backend-authentication",
+ "solutions/embedded-wallets/integration-guide/typescript/advanced-api-requests",
+ "solutions/embedded-wallets/integration-guide/typescript/legacy"
]
},
{
- "group": "Examples",
- "pages": [
- "category/code-examples",
- "embedded-wallets/code-examples/embedded-consumer-wallet",
- "products/embedded-business-wallets/overview",
- "embedded-wallets/embedded-waas",
- "embedded-wallets/code-examples/create-sub-org-passkey",
- "embedded-wallets/code-examples/authenticate-user-passkey",
- "embedded-wallets/code-examples/create-passkey-session",
- "embedded-wallets/code-examples/sending-sponsored-transactions",
- "embedded-wallets/code-examples/sending-sponsored-solana-transactions",
- "reference/tron-gasless-transactions",
- "embedded-wallets/code-examples/client-side-signing",
- "embedded-wallets/code-examples/create-user-email",
- "embedded-wallets/code-examples/authenticate-user-email",
- "embedded-wallets/code-examples/add-credential",
- "embedded-wallets/code-examples/wallet-auth",
- "embedded-wallets/code-examples/signing-transactions",
- "embedded-wallets/code-examples/import",
- "embedded-wallets/code-examples/export"
- ]
- }
- ]
- },
- {
- "group": "Company Wallets",
- "pages": [
- "company-wallets/overview",
- {
- "group": "Features",
+ "group": "Flutter",
"pages": [
- "products/company-wallets/features/multi-chain-support",
- "company-wallets/co-signing-transactions",
+ "solutions/embedded-wallets/integration-guide/flutter/index",
+ "solutions/embedded-wallets/integration-guide/flutter/getting-started",
{
- "group": "Transaction Management",
+ "group": "Authentication",
"pages": [
- "company-wallets/code-examples/sending-sponsored-transactions",
- "concepts/balances"
+ "solutions/embedded-wallets/integration-guide/flutter/authentication/overview",
+ "solutions/embedded-wallets/integration-guide/flutter/authentication/email-sms",
+ "solutions/embedded-wallets/integration-guide/flutter/authentication/passkey",
+ "solutions/embedded-wallets/integration-guide/flutter/authentication/social-logins"
]
},
- "products/company-wallets/features/import-wallets",
- "products/company-wallets/features/export-wallets",
- "developer-reference/webhooks"
+ "solutions/embedded-wallets/integration-guide/flutter/sub-organization-customization",
+ "solutions/embedded-wallets/integration-guide/flutter/using-embedded-wallets",
+ "solutions/embedded-wallets/integration-guide/flutter/signing",
+ "solutions/embedded-wallets/integration-guide/flutter/advanced-api-requests"
]
},
{
- "group": "SDKs",
+ "group": "Swift",
"pages": [
- "sdks/golang",
- "sdks/ruby",
- "sdks/rust",
- "sdks/python",
- "sdks/javascript-server",
- "sdks/foundry"
+ "solutions/embedded-wallets/integration-guide/swift/overview",
+ "solutions/embedded-wallets/integration-guide/swift/getting-started",
+ {
+ "group": "Authentication",
+ "pages": [
+ "solutions/embedded-wallets/integration-guide/swift/authentication/overview",
+ "solutions/embedded-wallets/integration-guide/swift/authentication/email-sms",
+ "solutions/embedded-wallets/integration-guide/swift/authentication/passkey",
+ "solutions/embedded-wallets/integration-guide/swift/authentication/social-logins"
+ ]
+ },
+ "solutions/embedded-wallets/integration-guide/swift/signing",
+ "solutions/embedded-wallets/integration-guide/swift/sub-organization-customization",
+ "solutions/embedded-wallets/integration-guide/swift/advanced-api-requests",
+ "solutions/embedded-wallets/integration-guide/swift/using-embedded-wallets",
+ "solutions/embedded-wallets/integration-guide/swift/advanced-backend-authentication"
]
},
{
- "group": "Examples",
+ "group": "Kotlin",
"pages": [
- "category/code-examples-1",
- "company-wallets/code-examples/signing-transactions",
- "company-wallets/code-examples/smart-contract-management",
- "company-wallets/code-examples/payment-orchestration"
+ "solutions/embedded-wallets/integration-guide/kotlin/overview",
+ "solutions/embedded-wallets/integration-guide/kotlin/getting-started",
+ {
+ "group": "Authentication",
+ "pages": [
+ "solutions/embedded-wallets/integration-guide/kotlin/authentication/overview",
+ "solutions/embedded-wallets/integration-guide/kotlin/authentication/email-sms",
+ "solutions/embedded-wallets/integration-guide/kotlin/authentication/passkey",
+ "solutions/embedded-wallets/integration-guide/kotlin/authentication/social-logins",
+ "solutions/embedded-wallets/integration-guide/kotlin/authentication/rp-id-setup"
+ ]
+ },
+ "solutions/embedded-wallets/integration-guide/kotlin/sub-organization-customization",
+ "solutions/embedded-wallets/integration-guide/kotlin/using-embedded-wallets",
+ "solutions/embedded-wallets/integration-guide/kotlin/signing",
+ "solutions/embedded-wallets/integration-guide/kotlin/advanced-api-requests"
]
}
]
- },
+ }
+ ]
+ },
+ {
+ "group": "Company Wallets",
+ "pages": [
+ "solutions/company-wallets/overview",
{
- "group": "Key Management",
+ "group": "Solution",
"pages": [
- "products/key-management/overview",
- {
- "group": "Examples",
- "pages": [
- "products/key-management/examples/overview",
- "products/key-management/examples/encryption-key-storage",
- "products/key-management/examples/enterprise-disaster-recovery"
- ]
- }
+ "solutions/company-wallets/payment-orchestration",
+ "solutions/company-wallets/smart-contract-management",
+ "solutions/company-wallets/agentic-wallets"
]
},
+ "solutions/company-wallets/quickstart",
{
- "group": "Verifiable Cloud",
- "tag": "Beta",
+ "group": "Integration guide",
"pages": [
- "products/verifiable-cloud/overview",
- "products/verifiable-cloud/lifecycle",
- "products/verifiable-cloud/onboarding"
+ "solutions/company-wallets/integration-guide/overview",
+ "solutions/company-wallets/integration-guide/javascript-server",
+ "solutions/company-wallets/integration-guide/golang",
+ "solutions/company-wallets/integration-guide/ruby",
+ "solutions/company-wallets/integration-guide/rust",
+ "solutions/company-wallets/integration-guide/python"
]
}
]
},
{
- "group": "Crypto ecosystems",
+ "group": "Key Management",
"pages": [
- "networks/overview",
- {
- "group": "Supported networks",
- "pages": [
- "networks/ethereum",
- {
- "group": "Solana (SVM)",
- "pages": [
- "networks/solana",
- "networks/solana-transaction-construction",
- "networks/solana-rent-refunds"
- ]
- },
- "networks/bitcoin",
- "networks/spark",
- "networks/hyperliquid",
- "networks/cosmos",
- "networks/tron",
- "networks/sui",
- "networks/sei",
- "networks/stacks",
- "networks/aptos",
- "networks/tempo",
- "networks/movement",
- "networks/iota",
- "networks/doge",
- "networks/others"
- ]
- },
+ "solutions/key-management/overview",
{
- "group": "Cookbook",
+ "group": "Solution",
"pages": [
- "cookbook/landing",
- "cookbook/morpho",
- "cookbook/aave",
- "cookbook/breeze",
- "cookbook/jupiter",
- "cookbook/lifi",
- "cookbook/0x",
- "cookbook/yieldxyz",
- "cookbook/polymarket-builders",
- "cookbook/base-builder-codes",
- "cookbook/relay",
- "cookbook/brale"
+ "solutions/key-management/encryption-key-storage",
+ "solutions/key-management/enterprise-disaster-recovery"
]
}
]
},
{
- "group": "Developers",
+ "group": "Cookbooks",
"pages": [
- "getting-started/examples",
+ "solutions/cookbooks/landing",
{
- "group": "Using LLMs",
+ "group": "Yield",
"pages": [
- "developer-reference/using-llms",
- "ai/skills"
+ "solutions/cookbooks/morpho",
+ "solutions/cookbooks/aave",
+ "solutions/cookbooks/breeze",
+ "solutions/cookbooks/yieldxyz"
]
},
{
- "group": "API overview",
+ "group": "Swaps & bridges",
"pages": [
- "developer-reference/api-overview/intro",
- "developer-reference/api-overview/stamps",
- "developer-reference/api-overview/queries",
- "developer-reference/api-overview/submissions",
- "developer-reference/api-overview/errors"
+ "solutions/cookbooks/jupiter",
+ "solutions/cookbooks/lifi",
+ "solutions/cookbooks/0x",
+ "solutions/cookbooks/relay"
]
},
{
- "group": "Policies",
+ "group": "Payments & infrastructure",
"pages": [
- "concepts/policies/quickstart",
- "concepts/policies/language",
- {
- "group": "Examples",
- "pages": [
- "concepts/policies/examples/access-control",
- "concepts/policies/examples/signing-control",
- "concepts/policies/examples/ethereum",
- "concepts/policies/examples/solana",
- "concepts/policies/examples/tron",
- "concepts/policies/examples/bitcoin",
- "concepts/policies/examples/tempo"
- ]
- },
- {
- "group": "Delegated access",
- "pages": [
- "concepts/policies/delegated-access-overview",
- "concepts/policies/delegated-access-frontend",
- "concepts/policies/delegated-access-backend"
- ]
- },
- "concepts/policies/smart-contract-interfaces"
+ "solutions/cookbooks/polymarket-builders",
+ "solutions/cookbooks/base-builder-codes",
+ "solutions/cookbooks/brale",
+ "solutions/cookbooks/tron-gasless-transactions"
]
- },
- "faq"
+ }
]
- },
- {
- "group": "Community Examples",
- "pages": []
}
]
},
{
- "tab": "SDK reference",
+ "tab": "Documentation",
"groups": [
{
- "group": "SDK reference",
+ "group": "Get started",
"pages": [
- "sdks/introduction",
+ "get-started/about-turnkey",
+ "get-started/quickstart",
+ {
+ "group": "Using LLMs",
+ "pages": [
+ "get-started/using-llms",
+ "get-started/ai-skills"
+ ]
+ },
+ "get-started/examples",
+ {
+ "group": "Going live",
+ "pages": [
+ "get-started/production-checklist",
+ "get-started/backup-recovery"
+ ]
+ }
+ ]
+ },
+ {
+ "group": "Features",
+ "pages": [
+ {
+ "group": "Organizations",
+ "pages": [
+ "features/organizations",
+ "features/sub-organizations"
+ ]
+ },
+ {
+ "group": "Users",
+ "pages": [
+ "features/users/introduction",
+ "features/users/credentials",
+ "features/users/root-quorum",
+ "features/users/best-practices"
+ ]
+ },
{
- "group": "React",
+ "group": "Authentication",
"pages": [
- "sdks/react/index",
- "sdks/react/getting-started",
- "sdks/react/auth",
- "sdks/react/using-embedded-wallets",
+ "features/authentication/overview",
{
- "group": "Using external wallets",
+ "group": "Auth methods",
"pages": [
- "sdks/react/using-external-wallets/overview",
- "sdks/react/using-external-wallets/authentication",
- "sdks/react/using-external-wallets/connecting"
+ "features/authentication/email",
+ "features/authentication/social-logins",
+ "features/authentication/sms",
+ {
+ "group": "Passkeys",
+ "pages": [
+ "features/authentication/passkeys/introduction",
+ "features/authentication/passkeys/integration",
+ "features/authentication/passkeys/options",
+ "features/authentication/passkeys/native",
+ "features/authentication/passkeys/discoverable-vs-non-discoverable"
+ ]
+ },
+ "features/authentication/backend-setup",
+ "features/authentication/bring-your-own-auth"
]
},
- "sdks/react/signing",
- "sdks/react/ui-customization",
- "sdks/react/sub-organization-customization",
- "sdks/react/advanced-api-requests",
- "sdks/react/advanced-backend-authentication",
- "sdks/react/migrating-sdk-react",
- "sdks/react/troubleshooting",
- "sdks/react/legacy",
+ "features/authentication/auth-proxy",
+ "features/authentication/sessions",
{
- "group": "SDK reference",
+ "group": "Advanced",
"pages": [
- "generated-docs/react-wallet-kit/client-context-type-add-oauth-provider",
- "generated-docs/react-wallet-kit/client-context-type-add-passkey",
- "generated-docs/react-wallet-kit/client-context-type-build-wallet-login-request",
- "generated-docs/react-wallet-kit/client-context-type-clear-all-sessions",
- "generated-docs/react-wallet-kit/client-context-type-clear-session",
- "generated-docs/react-wallet-kit/client-context-type-clear-unused-key-pairs",
- "generated-docs/react-wallet-kit/client-context-type-complete-oauth",
- "generated-docs/react-wallet-kit/client-context-type-complete-otp",
- "generated-docs/react-wallet-kit/client-context-type-connect-wallet-account",
- "generated-docs/react-wallet-kit/client-context-type-create-api-key-pair",
- "generated-docs/react-wallet-kit/client-context-type-create-http-client",
- "generated-docs/react-wallet-kit/client-context-type-create-passkey",
- "generated-docs/react-wallet-kit/client-context-type-create-wallet",
- "generated-docs/react-wallet-kit/client-context-type-create-wallet-accounts",
- "generated-docs/react-wallet-kit/client-context-type-delete-sub-organization",
- "generated-docs/react-wallet-kit/client-context-type-disconnect-wallet-account",
- "generated-docs/react-wallet-kit/client-context-type-eth-send-erc20-transfer",
- "generated-docs/react-wallet-kit/client-context-type-eth-send-transaction",
- "generated-docs/react-wallet-kit/client-context-type-export-private-key",
- "generated-docs/react-wallet-kit/client-context-type-export-wallet",
- "generated-docs/react-wallet-kit/client-context-type-export-wallet-account",
- "generated-docs/react-wallet-kit/client-context-type-fetch-boot-proof-for-app-proof",
- "generated-docs/react-wallet-kit/client-context-type-fetch-or-create-p256-api-key-user",
- "generated-docs/react-wallet-kit/client-context-type-fetch-or-create-policies",
- "generated-docs/react-wallet-kit/client-context-type-fetch-private-keys",
- "generated-docs/react-wallet-kit/client-context-type-fetch-user",
- "generated-docs/react-wallet-kit/client-context-type-fetch-wallet-accounts",
- "generated-docs/react-wallet-kit/client-context-type-fetch-wallet-providers",
- "generated-docs/react-wallet-kit/client-context-type-fetch-wallets",
- "generated-docs/react-wallet-kit/client-context-type-get-active-session-key",
- "generated-docs/react-wallet-kit/client-context-type-get-all-sessions",
- "generated-docs/react-wallet-kit/client-context-type-get-proxy-auth-config",
- "generated-docs/react-wallet-kit/client-context-type-get-session",
- "generated-docs/react-wallet-kit/client-context-type-handle-add-email",
- "generated-docs/react-wallet-kit/client-context-type-handle-add-oauth-provider",
- "generated-docs/react-wallet-kit/client-context-type-handle-add-passkey",
- "generated-docs/react-wallet-kit/client-context-type-handle-add-phone-number",
- "generated-docs/react-wallet-kit/client-context-type-handle-apple-oauth",
- "generated-docs/react-wallet-kit/client-context-type-handle-connect-external-wallet",
- "generated-docs/react-wallet-kit/client-context-type-handle-discord-oauth",
- "generated-docs/react-wallet-kit/client-context-type-handle-export-private-key",
- "generated-docs/react-wallet-kit/client-context-type-handle-export-wallet",
- "generated-docs/react-wallet-kit/client-context-type-handle-export-wallet-account",
- "generated-docs/react-wallet-kit/client-context-type-handle-facebook-oauth",
- "generated-docs/react-wallet-kit/client-context-type-handle-google-oauth",
- "generated-docs/react-wallet-kit/client-context-type-handle-import-private-key",
- "generated-docs/react-wallet-kit/client-context-type-handle-import-wallet",
- "generated-docs/react-wallet-kit/client-context-type-handle-login",
- "generated-docs/react-wallet-kit/client-context-type-handle-on-ramp",
- "generated-docs/react-wallet-kit/client-context-type-handle-remove-oauth-provider",
- "generated-docs/react-wallet-kit/client-context-type-handle-remove-passkey",
- "generated-docs/react-wallet-kit/client-context-type-handle-remove-user-email",
- "generated-docs/react-wallet-kit/client-context-type-handle-remove-user-phone-number",
- "generated-docs/react-wallet-kit/client-context-type-handle-send-erc20-transfer",
- "generated-docs/react-wallet-kit/client-context-type-handle-send-transaction",
- "generated-docs/react-wallet-kit/client-context-type-handle-sign-message",
- "generated-docs/react-wallet-kit/client-context-type-handle-update-user-email",
- "generated-docs/react-wallet-kit/client-context-type-handle-update-user-name",
- "generated-docs/react-wallet-kit/client-context-type-handle-update-user-phone-number",
- "generated-docs/react-wallet-kit/client-context-type-handle-verify-app-proofs",
- "generated-docs/react-wallet-kit/client-context-type-handle-xoauth",
- "generated-docs/react-wallet-kit/client-context-type-import-private-key",
- "generated-docs/react-wallet-kit/client-context-type-import-wallet",
- "generated-docs/react-wallet-kit/client-context-type-init-otp",
- "generated-docs/react-wallet-kit/client-context-type-login-or-signup-with-wallet",
- "generated-docs/react-wallet-kit/client-context-type-login-with-oauth",
- "generated-docs/react-wallet-kit/client-context-type-login-with-otp",
- "generated-docs/react-wallet-kit/client-context-type-login-with-passkey",
- "generated-docs/react-wallet-kit/client-context-type-login-with-wallet",
- "generated-docs/react-wallet-kit/client-context-type-logout",
- "generated-docs/react-wallet-kit/client-context-type-refresh-session",
- "generated-docs/react-wallet-kit/client-context-type-refresh-user",
- "generated-docs/react-wallet-kit/client-context-type-refresh-wallets",
- "generated-docs/react-wallet-kit/client-context-type-remove-oauth-providers",
- "generated-docs/react-wallet-kit/client-context-type-remove-passkeys",
- "generated-docs/react-wallet-kit/client-context-type-remove-user-email",
- "generated-docs/react-wallet-kit/client-context-type-remove-user-phone-number",
- "generated-docs/react-wallet-kit/client-context-type-set-active-session",
- "generated-docs/react-wallet-kit/client-context-type-sign-and-send-transaction",
- "generated-docs/react-wallet-kit/client-context-type-sign-message",
- "generated-docs/react-wallet-kit/client-context-type-sign-transaction",
- "generated-docs/react-wallet-kit/client-context-type-sign-up-with-oauth",
- "generated-docs/react-wallet-kit/client-context-type-sign-up-with-otp",
- "generated-docs/react-wallet-kit/client-context-type-sign-up-with-passkey",
- "generated-docs/react-wallet-kit/client-context-type-sign-up-with-wallet",
- "generated-docs/react-wallet-kit/client-context-type-sol-send-transaction",
- "generated-docs/react-wallet-kit/client-context-type-store-session",
- "generated-docs/react-wallet-kit/client-context-type-switch-wallet-account-chain",
- "generated-docs/react-wallet-kit/client-context-type-update-user-email",
- "generated-docs/react-wallet-kit/client-context-type-update-user-name",
- "generated-docs/react-wallet-kit/client-context-type-update-user-phone-number",
- "generated-docs/react-wallet-kit/client-context-type-verify-app-proofs",
- "generated-docs/react-wallet-kit/client-context-type-verify-otp",
- "generated-docs/react-wallet-kit/turnkey-provider-config"
+ "features/authentication/proxying-signed-requests"
]
}
]
},
{
- "group": "React Native",
+ "group": "Wallet and key management",
"pages": [
- "sdks/react-native/overview",
- "sdks/react-native/getting-started",
+ "features/wallets",
{
- "group": "Authentication",
+ "group": "Import & export",
"pages": [
- "sdks/react-native/authentication/overview",
- "sdks/react-native/authentication/email-sms",
- "sdks/react-native/authentication/passkey",
- "sdks/react-native/authentication/social-logins"
+ "features/wallets/import-wallets",
+ "features/wallets/export-wallets"
]
},
- "sdks/react-native/sub-organization-customization",
- "sdks/react-native/using-embedded-wallets",
- "sdks/react-native/signing",
- "sdks/react-native/advanced-api-requests",
+ "features/wallets/pregenerated-wallets",
{
- "group": "SDK reference",
+ "group": "Claim links",
"pages": [
- "generated-docs/react-native-wallet-kit/client-context-type-add-oauth-provider",
- "generated-docs/react-native-wallet-kit/client-context-type-add-passkey",
- "generated-docs/react-native-wallet-kit/client-context-type-clear-all-sessions",
- "generated-docs/react-native-wallet-kit/client-context-type-clear-session",
- "generated-docs/react-native-wallet-kit/client-context-type-clear-unused-key-pairs",
- "generated-docs/react-native-wallet-kit/client-context-type-complete-oauth",
- "generated-docs/react-native-wallet-kit/client-context-type-complete-otp",
- "generated-docs/react-native-wallet-kit/client-context-type-create-api-key-pair",
- "generated-docs/react-native-wallet-kit/client-context-type-create-http-client",
- "generated-docs/react-native-wallet-kit/client-context-type-create-passkey",
- "generated-docs/react-native-wallet-kit/client-context-type-create-wallet",
- "generated-docs/react-native-wallet-kit/client-context-type-create-wallet-accounts",
- "generated-docs/react-native-wallet-kit/client-context-type-delete-sub-organization",
- "generated-docs/react-native-wallet-kit/client-context-type-eth-send-erc20-transfer",
- "generated-docs/react-native-wallet-kit/client-context-type-eth-send-transaction",
- "generated-docs/react-native-wallet-kit/client-context-type-fetch-boot-proof-for-app-proof",
- "generated-docs/react-native-wallet-kit/client-context-type-fetch-or-create-p256-api-key-user",
- "generated-docs/react-native-wallet-kit/client-context-type-fetch-or-create-policies",
- "generated-docs/react-native-wallet-kit/client-context-type-fetch-private-keys",
- "generated-docs/react-native-wallet-kit/client-context-type-fetch-user",
- "generated-docs/react-native-wallet-kit/client-context-type-fetch-wallet-accounts",
- "generated-docs/react-native-wallet-kit/client-context-type-fetch-wallets",
- "generated-docs/react-native-wallet-kit/client-context-type-get-active-session-key",
- "generated-docs/react-native-wallet-kit/client-context-type-get-all-sessions",
- "generated-docs/react-native-wallet-kit/client-context-type-get-proxy-auth-config",
- "generated-docs/react-native-wallet-kit/client-context-type-get-session",
- "generated-docs/react-native-wallet-kit/client-context-type-handle-apple-oauth",
- "generated-docs/react-native-wallet-kit/client-context-type-handle-discord-oauth",
- "generated-docs/react-native-wallet-kit/client-context-type-handle-facebook-oauth",
- "generated-docs/react-native-wallet-kit/client-context-type-handle-google-oauth",
- "generated-docs/react-native-wallet-kit/client-context-type-handle-xoauth",
- "generated-docs/react-native-wallet-kit/client-context-type-init-otp",
- "generated-docs/react-native-wallet-kit/client-context-type-login-with-oauth",
- "generated-docs/react-native-wallet-kit/client-context-type-login-with-otp",
- "generated-docs/react-native-wallet-kit/client-context-type-login-with-passkey",
- "generated-docs/react-native-wallet-kit/client-context-type-logout",
- "generated-docs/react-native-wallet-kit/client-context-type-refresh-session",
- "generated-docs/react-native-wallet-kit/client-context-type-refresh-user",
- "generated-docs/react-native-wallet-kit/client-context-type-refresh-wallets",
- "generated-docs/react-native-wallet-kit/client-context-type-remove-oauth-providers",
- "generated-docs/react-native-wallet-kit/client-context-type-remove-passkeys",
- "generated-docs/react-native-wallet-kit/client-context-type-remove-user-email",
- "generated-docs/react-native-wallet-kit/client-context-type-remove-user-phone-number",
- "generated-docs/react-native-wallet-kit/client-context-type-set-active-session",
- "generated-docs/react-native-wallet-kit/client-context-type-sign-and-send-transaction",
- "generated-docs/react-native-wallet-kit/client-context-type-sign-message",
- "generated-docs/react-native-wallet-kit/client-context-type-sign-transaction",
- "generated-docs/react-native-wallet-kit/client-context-type-sign-up-with-oauth",
- "generated-docs/react-native-wallet-kit/client-context-type-sign-up-with-otp",
- "generated-docs/react-native-wallet-kit/client-context-type-sign-up-with-passkey",
- "generated-docs/react-native-wallet-kit/client-context-type-sol-send-transaction",
- "generated-docs/react-native-wallet-kit/client-context-type-store-session",
- "generated-docs/react-native-wallet-kit/client-context-type-update-user-email",
- "generated-docs/react-native-wallet-kit/client-context-type-update-user-name",
- "generated-docs/react-native-wallet-kit/client-context-type-update-user-phone-number",
- "generated-docs/react-native-wallet-kit/client-context-type-verify-app-proofs",
- "generated-docs/react-native-wallet-kit/client-context-type-verify-otp",
- "generated-docs/react-native-wallet-kit/turnkey-provider-config"
+ "features/wallets/claim-links",
+ "features/wallets/send-crypto-via-url"
]
- }
+ },
+ "features/wallets/aa-wallets"
]
},
{
- "group": "Flutter",
+ "group": "Chain support",
"pages": [
- "sdks/flutter/index",
- "sdks/flutter/getting-started",
+ "features/networks/overview",
{
- "group": "Authentication",
+ "group": "Supported networks",
"pages": [
- "sdks/flutter/authentication/overview",
- "sdks/flutter/authentication/email-sms",
- "sdks/flutter/authentication/passkey",
- "sdks/flutter/authentication/social-logins"
+ "features/networks/ethereum",
+ {
+ "group": "Solana (SVM)",
+ "pages": [
+ "features/networks/solana",
+ "features/networks/solana-transaction-construction",
+ "features/networks/solana-rent-refunds"
+ ]
+ },
+ "features/networks/bitcoin",
+ "features/networks/spark",
+ "features/networks/hyperliquid",
+ "features/networks/cosmos",
+ "features/networks/tron",
+ "features/networks/sui",
+ "features/networks/sei",
+ "features/networks/stacks",
+ "features/networks/aptos",
+ "features/networks/tempo",
+ "features/networks/movement",
+ "features/networks/iota",
+ "features/networks/doge",
+ "features/networks/others"
]
- },
- "sdks/flutter/sub-organization-customization",
- "sdks/flutter/using-embedded-wallets",
- "sdks/flutter/signing",
- "sdks/flutter/advanced-api-requests"
+ }
]
},
{
- "group": "Swift",
+ "group": "Policies",
"pages": [
- "sdks/swift/overview",
- "sdks/swift/getting-started",
+ "features/policies/overview",
+ "features/policies/quickstart",
+ "features/policies/language",
+ "features/policies/smart-contract-interfaces",
{
- "group": "Authentication",
+ "group": "Examples",
"pages": [
- "sdks/swift/authentication/overview",
- "sdks/swift/authentication/email-sms",
- "sdks/swift/authentication/passkey",
- "sdks/swift/authentication/social-logins"
+ "features/policies/examples/access-control",
+ "features/policies/examples/co-signing-transactions",
+ "features/policies/examples/signing-control",
+ "features/policies/examples/ethereum",
+ "features/policies/examples/solana",
+ "features/policies/examples/tron",
+ "features/policies/examples/bitcoin",
+ "features/policies/examples/tempo"
]
},
- "sdks/swift/signing",
- "sdks/swift/sub-organization-customization",
- "sdks/swift/advanced-api-requests",
- "sdks/swift/using-embedded-wallets",
- "sdks/swift/advanced-backend-authentication"
+ {
+ "group": "Delegated access",
+ "pages": [
+ "features/policies/delegated-access/overview",
+ "features/policies/delegated-access/frontend",
+ "features/policies/delegated-access/backend",
+ "features/policies/delegated-access/agentic-wallets"
+ ]
+ }
]
},
{
- "group": "Kotlin",
+ "group": "Transaction management",
"pages": [
- "sdks/kotlin/overview",
- "sdks/kotlin/getting-started",
+ "features/transaction-management",
{
- "group": "Authentication",
+ "group": "Broadcasting",
"pages": [
- "sdks/kotlin/authentication/overview",
- "sdks/kotlin/authentication/email-sms",
- "sdks/kotlin/authentication/passkey",
- "sdks/kotlin/authentication/social-logins",
- "sdks/kotlin/authentication/rp-id-setup"
+ "features/transaction-management/broadcasting",
+ "features/transaction-management/sending-sponsored-transactions",
+ "features/transaction-management/sending-sponsored-solana-transactions"
]
},
- "sdks/kotlin/sub-organization-customization",
- "sdks/kotlin/using-embedded-wallets",
- "sdks/kotlin/signing",
- "sdks/kotlin/advanced-api-requests"
+ "features/transaction-management/balances",
+ "features/transaction-management/fiat-on-ramp"
]
},
{
- "group": "TypeScript | Frontend",
+ "group": "Turnkey Verifiable Cloud",
"pages": [
- "sdks/typescript-frontend/index",
- "sdks/typescript-frontend/getting-started",
- "sdks/typescript-frontend/auth",
- "sdks/typescript-frontend/advanced-backend-authentication",
- "sdks/typescript-frontend/advanced-api-requests",
- "sdks/typescript-frontend/legacy",
- {
- "group": "SDK reference",
- "pages": [
- "generated-docs/core/turnkey-client-add-oauth-provider",
- "generated-docs/core/turnkey-client-add-passkey",
- "generated-docs/core/turnkey-client-build-wallet-login-request",
- "generated-docs/core/turnkey-client-clear-all-sessions",
- "generated-docs/core/turnkey-client-clear-session",
- "generated-docs/core/turnkey-client-clear-unused-key-pairs",
- "generated-docs/core/turnkey-client-complete-oauth",
- "generated-docs/core/turnkey-client-complete-otp",
- "generated-docs/core/turnkey-client-connect-wallet-account",
- "generated-docs/core/turnkey-client-constructor",
- "generated-docs/core/turnkey-client-create-api-key-pair",
- "generated-docs/core/turnkey-client-create-http-client",
- "generated-docs/core/turnkey-client-create-passkey",
- "generated-docs/core/turnkey-client-create-wallet",
- "generated-docs/core/turnkey-client-create-wallet-accounts",
- "generated-docs/core/turnkey-client-delete-sub-organization",
- "generated-docs/core/turnkey-client-disconnect-wallet-account",
- "generated-docs/core/turnkey-client-eth-send-erc20-transfer",
- "generated-docs/core/turnkey-client-eth-send-transaction",
- "generated-docs/core/turnkey-client-export-private-key",
- "generated-docs/core/turnkey-client-export-wallet",
- "generated-docs/core/turnkey-client-export-wallet-account",
- "generated-docs/core/turnkey-client-fetch-boot-proof-for-app-proof",
- "generated-docs/core/turnkey-client-fetch-or-create-p256-api-key-user",
- "generated-docs/core/turnkey-client-fetch-or-create-policies",
- "generated-docs/core/turnkey-client-fetch-private-keys",
- "generated-docs/core/turnkey-client-fetch-user",
- "generated-docs/core/turnkey-client-fetch-wallet-accounts",
- "generated-docs/core/turnkey-client-fetch-wallet-providers",
- "generated-docs/core/turnkey-client-fetch-wallets",
- "generated-docs/core/turnkey-client-get-active-session-key",
- "generated-docs/core/turnkey-client-get-all-sessions",
- "generated-docs/core/turnkey-client-get-proxy-auth-config",
- "generated-docs/core/turnkey-client-get-session",
- "generated-docs/core/turnkey-client-import-private-key",
- "generated-docs/core/turnkey-client-import-wallet",
- "generated-docs/core/turnkey-client-init",
- "generated-docs/core/turnkey-client-init-otp",
- "generated-docs/core/turnkey-client-login-or-signup-with-wallet",
- "generated-docs/core/turnkey-client-login-with-oauth",
- "generated-docs/core/turnkey-client-login-with-otp",
- "generated-docs/core/turnkey-client-login-with-passkey",
- "generated-docs/core/turnkey-client-login-with-wallet",
- "generated-docs/core/turnkey-client-logout",
- "generated-docs/core/turnkey-client-poll-transaction-status",
- "generated-docs/core/turnkey-client-refresh-session",
- "generated-docs/core/turnkey-client-remove-oauth-providers",
- "generated-docs/core/turnkey-client-remove-passkeys",
- "generated-docs/core/turnkey-client-remove-user-email",
- "generated-docs/core/turnkey-client-remove-user-phone-number",
- "generated-docs/core/turnkey-client-set-active-session",
- "generated-docs/core/turnkey-client-sign-and-send-transaction",
- "generated-docs/core/turnkey-client-sign-message",
- "generated-docs/core/turnkey-client-sign-transaction",
- "generated-docs/core/turnkey-client-sign-up-with-oauth",
- "generated-docs/core/turnkey-client-sign-up-with-otp",
- "generated-docs/core/turnkey-client-sign-up-with-passkey",
- "generated-docs/core/turnkey-client-sign-up-with-wallet",
- "generated-docs/core/turnkey-client-sol-send-transaction",
- "generated-docs/core/turnkey-client-store-session",
- "generated-docs/core/turnkey-client-switch-wallet-account-chain",
- "generated-docs/core/turnkey-client-update-user-email",
- "generated-docs/core/turnkey-client-update-user-name",
- "generated-docs/core/turnkey-client-update-user-phone-number",
- "generated-docs/core/turnkey-client-verify-app-proofs",
- "generated-docs/core/turnkey-client-verify-otp"
- ]
- }
+ "features/verifiable-cloud/overview",
+ "features/verifiable-cloud/onboarding",
+ "features/verifiable-cloud/quickstart"
+ ]
+ }
+ ]
+ },
+ {
+ "group": "Reference",
+ "pages": [
+ "reference/resource-limits",
+ "reference/webhooks",
+ "reference/migration-guide",
+ "reference/faq"
+ ]
+ }
+ ]
+ },
+ {
+ "tab": "API & SDK reference",
+ "pages": [
+ {
+ "group": "REST API",
+ "pages": [
+ "api-reference/overview/intro",
+ "api-reference/overview/stamps",
+ "api-reference/overview/errors",
+ {
+ "group": "Activities",
+ "pages": [
+ "api-reference/activities/overview",
+ "api-reference/activities/approve-activity",
+ "api-reference/activities/broadcast-evm-transaction",
+ "api-reference/activities/broadcast-svm-transaction",
+ "api-reference/activities/create-a-fiat-on-ramp-credential",
+ "api-reference/activities/create-a-tvc-app",
+ "api-reference/activities/create-a-tvc-deployment",
+ "api-reference/activities/create-an-oauth-20-credential",
+ "api-reference/activities/create-api-keys",
+ "api-reference/activities/create-authenticators",
+ "api-reference/activities/create-invitations",
+ "api-reference/activities/create-oauth-providers",
+ "api-reference/activities/create-policies",
+ "api-reference/activities/create-policy",
+ "api-reference/activities/create-private-key-tag",
+ "api-reference/activities/create-private-keys",
+ "api-reference/activities/create-read-only-session",
+ "api-reference/activities/create-read-write-session",
+ "api-reference/activities/create-smart-contract-interface",
+ "api-reference/activities/create-sub-organization",
+ "api-reference/activities/create-tvc-manifest-approvals",
+ "api-reference/activities/create-user-tag",
+ "api-reference/activities/create-users",
+ "api-reference/activities/create-wallet",
+ "api-reference/activities/create-wallet-accounts",
+ "api-reference/activities/create-webhook-endpoint",
+ "api-reference/activities/delete-a-fiat-on-ramp-credential",
+ "api-reference/activities/delete-a-tvc-app-and-all-of-its-deployments",
+ "api-reference/activities/delete-a-tvc-deployment",
+ "api-reference/activities/delete-an-oauth-20-credential",
+ "api-reference/activities/delete-api-keys",
+ "api-reference/activities/delete-authenticators",
+ "api-reference/activities/delete-invitation",
+ "api-reference/activities/delete-oauth-providers",
+ "api-reference/activities/delete-policies",
+ "api-reference/activities/delete-policy",
+ "api-reference/activities/delete-private-key-tags",
+ "api-reference/activities/delete-private-keys",
+ "api-reference/activities/delete-smart-contract-interface",
+ "api-reference/activities/delete-sub-organization",
+ "api-reference/activities/delete-user-tags",
+ "api-reference/activities/delete-users",
+ "api-reference/activities/delete-wallet-accounts",
+ "api-reference/activities/delete-wallets",
+ "api-reference/activities/delete-webhook-endpoint",
+ "api-reference/activities/export-private-key",
+ "api-reference/activities/export-wallet",
+ "api-reference/activities/export-wallet-account",
+ "api-reference/activities/import-private-key",
+ "api-reference/activities/import-wallet",
+ "api-reference/activities/init-email-recovery",
+ "api-reference/activities/init-fiat-on-ramp",
+ "api-reference/activities/init-generic-otp",
+ "api-reference/activities/init-import-private-key",
+ "api-reference/activities/init-import-wallet",
+ "api-reference/activities/init-otp-auth",
+ "api-reference/activities/login-with-a-stamp",
+ "api-reference/activities/login-with-oauth",
+ "api-reference/activities/login-with-otp",
+ "api-reference/activities/oauth",
+ "api-reference/activities/oauth-20-authentication",
+ "api-reference/activities/otp-auth",
+ "api-reference/activities/perform-email-auth",
+ "api-reference/activities/recover-a-user",
+ "api-reference/activities/reject-activity",
+ "api-reference/activities/remove-ip-allowlist",
+ "api-reference/activities/remove-organization-feature",
+ "api-reference/activities/restore-a-tvc-deployment",
+ "api-reference/activities/set-ip-allowlist",
+ "api-reference/activities/set-organization-feature",
+ "api-reference/activities/sign-raw-payload",
+ "api-reference/activities/sign-raw-payloads",
+ "api-reference/activities/sign-transaction",
+ "api-reference/activities/update-a-fiat-on-ramp-credential",
+ "api-reference/activities/update-an-oauth-20-credential",
+ "api-reference/activities/update-organization-name",
+ "api-reference/activities/update-policy",
+ "api-reference/activities/update-private-key-tag",
+ "api-reference/activities/update-root-quorum",
+ "api-reference/activities/update-user",
+ "api-reference/activities/update-user-tag",
+ "api-reference/activities/update-users-email",
+ "api-reference/activities/update-users-name",
+ "api-reference/activities/update-users-phone-number",
+ "api-reference/activities/update-wallet",
+ "api-reference/activities/update-webhook-endpoint",
+ "api-reference/activities/verify-generic-otp"
+ ]
+ },
+ {
+ "group": "Queries",
+ "pages": [
+ "api-reference/queries/overview",
+ "api-reference/queries/get-a-specific-boot-proof",
+ "api-reference/queries/get-activity",
+ "api-reference/queries/get-api-key",
+ "api-reference/queries/get-api-keys",
+ "api-reference/queries/get-authenticator",
+ "api-reference/queries/get-authenticators",
+ "api-reference/queries/get-balances",
+ "api-reference/queries/get-configs",
+ "api-reference/queries/get-gas-usage",
+ "api-reference/queries/get-ip-allowlist",
+ "api-reference/queries/get-nonces",
+ "api-reference/queries/get-oauth-20-credential",
+ "api-reference/queries/get-oauth-providers",
+ "api-reference/queries/get-on-ramp-transaction-status",
+ "api-reference/queries/get-policy",
+ "api-reference/queries/get-policy-evaluations",
+ "api-reference/queries/get-private-key",
+ "api-reference/queries/get-send-transaction-status",
+ "api-reference/queries/get-smart-contract-interface",
+ "api-reference/queries/get-sub-organizations",
+ "api-reference/queries/get-the-latest-boot-proof-for-an-app",
+ "api-reference/queries/get-tvc-app",
+ "api-reference/queries/get-tvc-app-status",
+ "api-reference/queries/get-tvc-deployment",
+ "api-reference/queries/get-user",
+ "api-reference/queries/get-verified-sub-organizations",
+ "api-reference/queries/get-wallet",
+ "api-reference/queries/get-wallet-account",
+ "api-reference/queries/list-activities",
+ "api-reference/queries/list-app-proofs-for-an-activity",
+ "api-reference/queries/list-fiat-on-ramp-credentials",
+ "api-reference/queries/list-oauth-20-credentials",
+ "api-reference/queries/list-policies",
+ "api-reference/queries/list-private-key-tags",
+ "api-reference/queries/list-private-keys",
+ "api-reference/queries/list-smart-contract-interfaces",
+ "api-reference/queries/list-supported-assets",
+ "api-reference/queries/list-tvc-apps",
+ "api-reference/queries/list-tvc-deployments",
+ "api-reference/queries/list-user-tags",
+ "api-reference/queries/list-users",
+ "api-reference/queries/list-wallets",
+ "api-reference/queries/list-wallets-accounts",
+ "api-reference/queries/list-webhook-endpoints",
+ "api-reference/queries/validate-container-image-for-tvc",
+ "api-reference/queries/who-am-i"
+ ]
+ },
+ {
+ "group": "Auth Proxy",
+ "pages": [
+ "api-reference/auth-proxy/account",
+ "api-reference/auth-proxy/oauth-login",
+ "api-reference/auth-proxy/oauth2-authenticate",
+ "api-reference/auth-proxy/otp-init",
+ "api-reference/auth-proxy/otp-login",
+ "api-reference/auth-proxy/otp-verify",
+ "api-reference/auth-proxy/signup",
+ "api-reference/auth-proxy/wallet-kit-config"
+ ]
+ }
+ ]
+ },
+ {
+ "group": "SDK reference",
+ "pages": [
+ "sdks/introduction",
+ {
+ "group": "React wallet kit",
+ "pages": [
+ "generated-docs/react-wallet-kit/client-context-type-add-oauth-provider",
+ "generated-docs/react-wallet-kit/client-context-type-add-passkey",
+ "generated-docs/react-wallet-kit/client-context-type-build-wallet-login-request",
+ "generated-docs/react-wallet-kit/client-context-type-clear-all-sessions",
+ "generated-docs/react-wallet-kit/client-context-type-clear-session",
+ "generated-docs/react-wallet-kit/client-context-type-clear-unused-key-pairs",
+ "generated-docs/react-wallet-kit/client-context-type-complete-oauth",
+ "generated-docs/react-wallet-kit/client-context-type-complete-otp",
+ "generated-docs/react-wallet-kit/client-context-type-connect-wallet-account",
+ "generated-docs/react-wallet-kit/client-context-type-create-api-key-pair",
+ "generated-docs/react-wallet-kit/client-context-type-create-http-client",
+ "generated-docs/react-wallet-kit/client-context-type-create-passkey",
+ "generated-docs/react-wallet-kit/client-context-type-create-wallet",
+ "generated-docs/react-wallet-kit/client-context-type-create-wallet-accounts",
+ "generated-docs/react-wallet-kit/client-context-type-delete-sub-organization",
+ "generated-docs/react-wallet-kit/client-context-type-disconnect-wallet-account",
+ "generated-docs/react-wallet-kit/client-context-type-eth-send-erc20-transfer",
+ "generated-docs/react-wallet-kit/client-context-type-eth-send-transaction",
+ "generated-docs/react-wallet-kit/client-context-type-export-private-key",
+ "generated-docs/react-wallet-kit/client-context-type-export-wallet",
+ "generated-docs/react-wallet-kit/client-context-type-export-wallet-account",
+ "generated-docs/react-wallet-kit/client-context-type-fetch-boot-proof-for-app-proof",
+ "generated-docs/react-wallet-kit/client-context-type-fetch-or-create-p256-api-key-user",
+ "generated-docs/react-wallet-kit/client-context-type-fetch-or-create-policies",
+ "generated-docs/react-wallet-kit/client-context-type-fetch-private-keys",
+ "generated-docs/react-wallet-kit/client-context-type-fetch-user",
+ "generated-docs/react-wallet-kit/client-context-type-fetch-wallet-accounts",
+ "generated-docs/react-wallet-kit/client-context-type-fetch-wallet-providers",
+ "generated-docs/react-wallet-kit/client-context-type-fetch-wallets",
+ "generated-docs/react-wallet-kit/client-context-type-get-active-session-key",
+ "generated-docs/react-wallet-kit/client-context-type-get-all-sessions",
+ "generated-docs/react-wallet-kit/client-context-type-get-proxy-auth-config",
+ "generated-docs/react-wallet-kit/client-context-type-get-session",
+ "generated-docs/react-wallet-kit/client-context-type-handle-add-email",
+ "generated-docs/react-wallet-kit/client-context-type-handle-add-oauth-provider",
+ "generated-docs/react-wallet-kit/client-context-type-handle-add-passkey",
+ "generated-docs/react-wallet-kit/client-context-type-handle-add-phone-number",
+ "generated-docs/react-wallet-kit/client-context-type-handle-apple-oauth",
+ "generated-docs/react-wallet-kit/client-context-type-handle-connect-external-wallet",
+ "generated-docs/react-wallet-kit/client-context-type-handle-discord-oauth",
+ "generated-docs/react-wallet-kit/client-context-type-handle-export-private-key",
+ "generated-docs/react-wallet-kit/client-context-type-handle-export-wallet",
+ "generated-docs/react-wallet-kit/client-context-type-handle-export-wallet-account",
+ "generated-docs/react-wallet-kit/client-context-type-handle-facebook-oauth",
+ "generated-docs/react-wallet-kit/client-context-type-handle-google-oauth",
+ "generated-docs/react-wallet-kit/client-context-type-handle-import-private-key",
+ "generated-docs/react-wallet-kit/client-context-type-handle-import-wallet",
+ "generated-docs/react-wallet-kit/client-context-type-handle-login",
+ "generated-docs/react-wallet-kit/client-context-type-handle-on-ramp",
+ "generated-docs/react-wallet-kit/client-context-type-handle-remove-oauth-provider",
+ "generated-docs/react-wallet-kit/client-context-type-handle-remove-passkey",
+ "generated-docs/react-wallet-kit/client-context-type-handle-remove-user-email",
+ "generated-docs/react-wallet-kit/client-context-type-handle-remove-user-phone-number",
+ "generated-docs/react-wallet-kit/client-context-type-handle-send-erc20-transfer",
+ "generated-docs/react-wallet-kit/client-context-type-handle-send-transaction",
+ "generated-docs/react-wallet-kit/client-context-type-handle-sign-message",
+ "generated-docs/react-wallet-kit/client-context-type-handle-update-user-email",
+ "generated-docs/react-wallet-kit/client-context-type-handle-update-user-name",
+ "generated-docs/react-wallet-kit/client-context-type-handle-update-user-phone-number",
+ "generated-docs/react-wallet-kit/client-context-type-handle-verify-app-proofs",
+ "generated-docs/react-wallet-kit/client-context-type-handle-xoauth",
+ "generated-docs/react-wallet-kit/client-context-type-import-private-key",
+ "generated-docs/react-wallet-kit/client-context-type-import-wallet",
+ "generated-docs/react-wallet-kit/client-context-type-init-otp",
+ "generated-docs/react-wallet-kit/client-context-type-login-or-signup-with-wallet",
+ "generated-docs/react-wallet-kit/client-context-type-login-with-oauth",
+ "generated-docs/react-wallet-kit/client-context-type-login-with-otp",
+ "generated-docs/react-wallet-kit/client-context-type-login-with-passkey",
+ "generated-docs/react-wallet-kit/client-context-type-login-with-wallet",
+ "generated-docs/react-wallet-kit/client-context-type-logout",
+ "generated-docs/react-wallet-kit/client-context-type-refresh-session",
+ "generated-docs/react-wallet-kit/client-context-type-refresh-user",
+ "generated-docs/react-wallet-kit/client-context-type-refresh-wallets",
+ "generated-docs/react-wallet-kit/client-context-type-remove-oauth-providers",
+ "generated-docs/react-wallet-kit/client-context-type-remove-passkeys",
+ "generated-docs/react-wallet-kit/client-context-type-remove-user-email",
+ "generated-docs/react-wallet-kit/client-context-type-remove-user-phone-number",
+ "generated-docs/react-wallet-kit/client-context-type-set-active-session",
+ "generated-docs/react-wallet-kit/client-context-type-sign-and-send-transaction",
+ "generated-docs/react-wallet-kit/client-context-type-sign-message",
+ "generated-docs/react-wallet-kit/client-context-type-sign-transaction",
+ "generated-docs/react-wallet-kit/client-context-type-sign-up-with-oauth",
+ "generated-docs/react-wallet-kit/client-context-type-sign-up-with-otp",
+ "generated-docs/react-wallet-kit/client-context-type-sign-up-with-passkey",
+ "generated-docs/react-wallet-kit/client-context-type-sign-up-with-wallet",
+ "generated-docs/react-wallet-kit/client-context-type-sol-send-transaction",
+ "generated-docs/react-wallet-kit/client-context-type-store-session",
+ "generated-docs/react-wallet-kit/client-context-type-switch-wallet-account-chain",
+ "generated-docs/react-wallet-kit/client-context-type-update-user-email",
+ "generated-docs/react-wallet-kit/client-context-type-update-user-name",
+ "generated-docs/react-wallet-kit/client-context-type-update-user-phone-number",
+ "generated-docs/react-wallet-kit/client-context-type-verify-app-proofs",
+ "generated-docs/react-wallet-kit/client-context-type-verify-otp",
+ "generated-docs/react-wallet-kit/turnkey-provider-config"
+ ]
+ },
+ {
+ "group": "React Native wallet kit",
+ "pages": [
+ "generated-docs/react-native-wallet-kit/client-context-type-add-oauth-provider",
+ "generated-docs/react-native-wallet-kit/client-context-type-add-passkey",
+ "generated-docs/react-native-wallet-kit/client-context-type-clear-all-sessions",
+ "generated-docs/react-native-wallet-kit/client-context-type-clear-session",
+ "generated-docs/react-native-wallet-kit/client-context-type-clear-unused-key-pairs",
+ "generated-docs/react-native-wallet-kit/client-context-type-complete-oauth",
+ "generated-docs/react-native-wallet-kit/client-context-type-complete-otp",
+ "generated-docs/react-native-wallet-kit/client-context-type-create-api-key-pair",
+ "generated-docs/react-native-wallet-kit/client-context-type-create-http-client",
+ "generated-docs/react-native-wallet-kit/client-context-type-create-passkey",
+ "generated-docs/react-native-wallet-kit/client-context-type-create-wallet",
+ "generated-docs/react-native-wallet-kit/client-context-type-create-wallet-accounts",
+ "generated-docs/react-native-wallet-kit/client-context-type-delete-sub-organization",
+ "generated-docs/react-native-wallet-kit/client-context-type-eth-send-erc20-transfer",
+ "generated-docs/react-native-wallet-kit/client-context-type-eth-send-transaction",
+ "generated-docs/react-native-wallet-kit/client-context-type-fetch-boot-proof-for-app-proof",
+ "generated-docs/react-native-wallet-kit/client-context-type-fetch-or-create-p256-api-key-user",
+ "generated-docs/react-native-wallet-kit/client-context-type-fetch-or-create-policies",
+ "generated-docs/react-native-wallet-kit/client-context-type-fetch-private-keys",
+ "generated-docs/react-native-wallet-kit/client-context-type-fetch-user",
+ "generated-docs/react-native-wallet-kit/client-context-type-fetch-wallet-accounts",
+ "generated-docs/react-native-wallet-kit/client-context-type-fetch-wallets",
+ "generated-docs/react-native-wallet-kit/client-context-type-get-active-session-key",
+ "generated-docs/react-native-wallet-kit/client-context-type-get-all-sessions",
+ "generated-docs/react-native-wallet-kit/client-context-type-get-proxy-auth-config",
+ "generated-docs/react-native-wallet-kit/client-context-type-get-session",
+ "generated-docs/react-native-wallet-kit/client-context-type-handle-apple-oauth",
+ "generated-docs/react-native-wallet-kit/client-context-type-handle-discord-oauth",
+ "generated-docs/react-native-wallet-kit/client-context-type-handle-facebook-oauth",
+ "generated-docs/react-native-wallet-kit/client-context-type-handle-google-oauth",
+ "generated-docs/react-native-wallet-kit/client-context-type-handle-xoauth",
+ "generated-docs/react-native-wallet-kit/client-context-type-init-otp",
+ "generated-docs/react-native-wallet-kit/client-context-type-login-with-oauth",
+ "generated-docs/react-native-wallet-kit/client-context-type-login-with-otp",
+ "generated-docs/react-native-wallet-kit/client-context-type-login-with-passkey",
+ "generated-docs/react-native-wallet-kit/client-context-type-logout",
+ "generated-docs/react-native-wallet-kit/client-context-type-refresh-session",
+ "generated-docs/react-native-wallet-kit/client-context-type-refresh-user",
+ "generated-docs/react-native-wallet-kit/client-context-type-refresh-wallets",
+ "generated-docs/react-native-wallet-kit/client-context-type-remove-oauth-providers",
+ "generated-docs/react-native-wallet-kit/client-context-type-remove-passkeys",
+ "generated-docs/react-native-wallet-kit/client-context-type-remove-user-email",
+ "generated-docs/react-native-wallet-kit/client-context-type-remove-user-phone-number",
+ "generated-docs/react-native-wallet-kit/client-context-type-set-active-session",
+ "generated-docs/react-native-wallet-kit/client-context-type-sign-and-send-transaction",
+ "generated-docs/react-native-wallet-kit/client-context-type-sign-message",
+ "generated-docs/react-native-wallet-kit/client-context-type-sign-transaction",
+ "generated-docs/react-native-wallet-kit/client-context-type-sign-up-with-oauth",
+ "generated-docs/react-native-wallet-kit/client-context-type-sign-up-with-otp",
+ "generated-docs/react-native-wallet-kit/client-context-type-sign-up-with-passkey",
+ "generated-docs/react-native-wallet-kit/client-context-type-sol-send-transaction",
+ "generated-docs/react-native-wallet-kit/client-context-type-store-session",
+ "generated-docs/react-native-wallet-kit/client-context-type-update-user-email",
+ "generated-docs/react-native-wallet-kit/client-context-type-update-user-name",
+ "generated-docs/react-native-wallet-kit/client-context-type-update-user-phone-number",
+ "generated-docs/react-native-wallet-kit/client-context-type-verify-app-proofs",
+ "generated-docs/react-native-wallet-kit/client-context-type-verify-otp",
+ "generated-docs/react-native-wallet-kit/turnkey-provider-config"
+ ]
+ },
+ {
+ "group": "TypeScript core",
+ "pages": [
+ "generated-docs/core/turnkey-client-add-oauth-provider",
+ "generated-docs/core/turnkey-client-add-passkey",
+ "generated-docs/core/turnkey-client-build-wallet-login-request",
+ "generated-docs/core/turnkey-client-clear-all-sessions",
+ "generated-docs/core/turnkey-client-clear-session",
+ "generated-docs/core/turnkey-client-clear-unused-key-pairs",
+ "generated-docs/core/turnkey-client-complete-oauth",
+ "generated-docs/core/turnkey-client-complete-otp",
+ "generated-docs/core/turnkey-client-connect-wallet-account",
+ "generated-docs/core/turnkey-client-constructor",
+ "generated-docs/core/turnkey-client-create-api-key-pair",
+ "generated-docs/core/turnkey-client-create-http-client",
+ "generated-docs/core/turnkey-client-create-passkey",
+ "generated-docs/core/turnkey-client-create-wallet",
+ "generated-docs/core/turnkey-client-create-wallet-accounts",
+ "generated-docs/core/turnkey-client-delete-sub-organization",
+ "generated-docs/core/turnkey-client-disconnect-wallet-account",
+ "generated-docs/core/turnkey-client-eth-send-erc20-transfer",
+ "generated-docs/core/turnkey-client-eth-send-transaction",
+ "generated-docs/core/turnkey-client-export-private-key",
+ "generated-docs/core/turnkey-client-export-wallet",
+ "generated-docs/core/turnkey-client-export-wallet-account",
+ "generated-docs/core/turnkey-client-fetch-boot-proof-for-app-proof",
+ "generated-docs/core/turnkey-client-fetch-or-create-p256-api-key-user",
+ "generated-docs/core/turnkey-client-fetch-or-create-policies",
+ "generated-docs/core/turnkey-client-fetch-private-keys",
+ "generated-docs/core/turnkey-client-fetch-user",
+ "generated-docs/core/turnkey-client-fetch-wallet-accounts",
+ "generated-docs/core/turnkey-client-fetch-wallet-providers",
+ "generated-docs/core/turnkey-client-fetch-wallets",
+ "generated-docs/core/turnkey-client-get-active-session-key",
+ "generated-docs/core/turnkey-client-get-all-sessions",
+ "generated-docs/core/turnkey-client-get-proxy-auth-config",
+ "generated-docs/core/turnkey-client-get-session",
+ "generated-docs/core/turnkey-client-import-private-key",
+ "generated-docs/core/turnkey-client-import-wallet",
+ "generated-docs/core/turnkey-client-init",
+ "generated-docs/core/turnkey-client-init-otp",
+ "generated-docs/core/turnkey-client-login-or-signup-with-wallet",
+ "generated-docs/core/turnkey-client-login-with-oauth",
+ "generated-docs/core/turnkey-client-login-with-otp",
+ "generated-docs/core/turnkey-client-login-with-passkey",
+ "generated-docs/core/turnkey-client-login-with-wallet",
+ "generated-docs/core/turnkey-client-logout",
+ "generated-docs/core/turnkey-client-poll-transaction-status",
+ "generated-docs/core/turnkey-client-refresh-session",
+ "generated-docs/core/turnkey-client-remove-oauth-providers",
+ "generated-docs/core/turnkey-client-remove-passkeys",
+ "generated-docs/core/turnkey-client-remove-user-email",
+ "generated-docs/core/turnkey-client-remove-user-phone-number",
+ "generated-docs/core/turnkey-client-set-active-session",
+ "generated-docs/core/turnkey-client-sign-and-send-transaction",
+ "generated-docs/core/turnkey-client-sign-message",
+ "generated-docs/core/turnkey-client-sign-transaction",
+ "generated-docs/core/turnkey-client-sign-up-with-oauth",
+ "generated-docs/core/turnkey-client-sign-up-with-otp",
+ "generated-docs/core/turnkey-client-sign-up-with-passkey",
+ "generated-docs/core/turnkey-client-sign-up-with-wallet",
+ "generated-docs/core/turnkey-client-sol-send-transaction",
+ "generated-docs/core/turnkey-client-store-session",
+ "generated-docs/core/turnkey-client-switch-wallet-account-chain",
+ "generated-docs/core/turnkey-client-update-user-email",
+ "generated-docs/core/turnkey-client-update-user-name",
+ "generated-docs/core/turnkey-client-update-user-phone-number",
+ "generated-docs/core/turnkey-client-verify-app-proofs",
+ "generated-docs/core/turnkey-client-verify-otp"
]
},
- "sdks/javascript-server",
- "sdks/golang",
- "sdks/rust",
- "sdks/ruby",
- "sdks/cli",
- "sdks/python",
{
"group": "Web3 libraries",
"pages": [
- "category/web3-libraries",
+ "sdks/web3/overview",
"sdks/web3/ethers",
"sdks/web3/viem",
+ "sdks/web3/wagmi",
"sdks/web3/cosmjs",
"sdks/web3/eip-1193",
"sdks/web3/solana",
- "sdks/web3/gas-station"
+ "sdks/web3/gas-station",
+ "sdks/foundry"
]
},
{
"group": "Advanced",
"pages": [
- "category/advanced",
+ "sdks/advanced/overview",
"sdks/advanced/turnkey-client",
"sdks/advanced/api-key-stamper",
"sdks/advanced/wallet-stamper",
"sdks/advanced/webauthn-stamper",
"sdks/advanced/iframe-stamper",
+ "sdks/advanced/client-side-signing",
"sdks/advanced/indexed-db-stamper"
]
- },
- "sdks/migration-path"
- ]
- }
- ]
- },
- {
- "tab": "API reference",
- "pages": [
- "api-reference/overview",
- {
- "group": "Activities",
- "pages": [
- "api-reference/activities/overview",
- "api-reference/activities/approve-activity",
- "api-reference/activities/broadcast-evm-transaction",
- "api-reference/activities/broadcast-svm-transaction",
- "api-reference/activities/create-a-fiat-on-ramp-credential",
- "api-reference/activities/create-a-tvc-app",
- "api-reference/activities/create-a-tvc-deployment",
- "api-reference/activities/create-an-oauth-20-credential",
- "api-reference/activities/create-api-keys",
- "api-reference/activities/create-authenticators",
- "api-reference/activities/create-invitations",
- "api-reference/activities/create-oauth-providers",
- "api-reference/activities/create-policies",
- "api-reference/activities/create-policy",
- "api-reference/activities/create-private-key-tag",
- "api-reference/activities/create-private-keys",
- "api-reference/activities/create-read-only-session",
- "api-reference/activities/create-read-write-session",
- "api-reference/activities/create-smart-contract-interface",
- "api-reference/activities/create-sub-organization",
- "api-reference/activities/create-tvc-manifest-approvals",
- "api-reference/activities/create-user-tag",
- "api-reference/activities/create-users",
- "api-reference/activities/create-wallet",
- "api-reference/activities/create-wallet-accounts",
- "api-reference/activities/create-webhook-endpoint",
- "api-reference/activities/delete-a-fiat-on-ramp-credential",
- "api-reference/activities/delete-a-tvc-app-and-all-of-its-deployments",
- "api-reference/activities/delete-a-tvc-deployment",
- "api-reference/activities/delete-an-oauth-20-credential",
- "api-reference/activities/delete-api-keys",
- "api-reference/activities/delete-authenticators",
- "api-reference/activities/delete-invitation",
- "api-reference/activities/delete-oauth-providers",
- "api-reference/activities/delete-policies",
- "api-reference/activities/delete-policy",
- "api-reference/activities/delete-private-key-tags",
- "api-reference/activities/delete-private-keys",
- "api-reference/activities/delete-smart-contract-interface",
- "api-reference/activities/delete-sub-organization",
- "api-reference/activities/delete-user-tags",
- "api-reference/activities/delete-users",
- "api-reference/activities/delete-wallet-accounts",
- "api-reference/activities/delete-wallets",
- "api-reference/activities/delete-webhook-endpoint",
- "api-reference/activities/export-private-key",
- "api-reference/activities/export-wallet",
- "api-reference/activities/export-wallet-account",
- "api-reference/activities/import-private-key",
- "api-reference/activities/import-wallet",
- "api-reference/activities/init-email-recovery",
- "api-reference/activities/init-fiat-on-ramp",
- "api-reference/activities/init-generic-otp",
- "api-reference/activities/init-import-private-key",
- "api-reference/activities/init-import-wallet",
- "api-reference/activities/init-otp-auth",
- "api-reference/activities/login-with-a-stamp",
- "api-reference/activities/login-with-oauth",
- "api-reference/activities/login-with-otp",
- "api-reference/activities/oauth",
- "api-reference/activities/oauth-20-authentication",
- "api-reference/activities/otp-auth",
- "api-reference/activities/perform-email-auth",
- "api-reference/activities/recover-a-user",
- "api-reference/activities/reject-activity",
- "api-reference/activities/remove-ip-allowlist",
- "api-reference/activities/remove-organization-feature",
- "api-reference/activities/restore-a-tvc-deployment",
- "api-reference/activities/set-ip-allowlist",
- "api-reference/activities/set-organization-feature",
- "api-reference/activities/sign-raw-payload",
- "api-reference/activities/sign-raw-payloads",
- "api-reference/activities/sign-transaction",
- "api-reference/activities/update-a-fiat-on-ramp-credential",
- "api-reference/activities/update-an-oauth-20-credential",
- "api-reference/activities/update-organization-name",
- "api-reference/activities/update-policy",
- "api-reference/activities/update-private-key-tag",
- "api-reference/activities/update-root-quorum",
- "api-reference/activities/update-user",
- "api-reference/activities/update-user-tag",
- "api-reference/activities/update-users-email",
- "api-reference/activities/update-users-name",
- "api-reference/activities/update-users-phone-number",
- "api-reference/activities/update-wallet",
- "api-reference/activities/update-webhook-endpoint",
- "api-reference/activities/verify-generic-otp"
- ]
- },
- {
- "group": "Queries",
- "pages": [
- "api-reference/queries/overview",
- "api-reference/queries/get-a-specific-boot-proof",
- "api-reference/queries/get-activity",
- "api-reference/queries/get-api-key",
- "api-reference/queries/get-api-keys",
- "api-reference/queries/get-authenticator",
- "api-reference/queries/get-authenticators",
- "api-reference/queries/get-balances",
- "api-reference/queries/get-configs",
- "api-reference/queries/get-gas-usage",
- "api-reference/queries/get-ip-allowlist",
- "api-reference/queries/get-nonces",
- "api-reference/queries/get-oauth-20-credential",
- "api-reference/queries/get-oauth-providers",
- "api-reference/queries/get-on-ramp-transaction-status",
- "api-reference/queries/get-policy",
- "api-reference/queries/get-policy-evaluations",
- "api-reference/queries/get-private-key",
- "api-reference/queries/get-send-transaction-status",
- "api-reference/queries/get-smart-contract-interface",
- "api-reference/queries/get-sub-organizations",
- "api-reference/queries/get-the-latest-boot-proof-for-an-app",
- "api-reference/queries/get-tvc-app",
- "api-reference/queries/get-tvc-app-status",
- "api-reference/queries/get-tvc-deployment",
- "api-reference/queries/get-user",
- "api-reference/queries/get-verified-sub-organizations",
- "api-reference/queries/get-wallet",
- "api-reference/queries/get-wallet-account",
- "api-reference/queries/list-activities",
- "api-reference/queries/list-app-proofs-for-an-activity",
- "api-reference/queries/list-fiat-on-ramp-credentials",
- "api-reference/queries/list-oauth-20-credentials",
- "api-reference/queries/list-policies",
- "api-reference/queries/list-private-key-tags",
- "api-reference/queries/list-private-keys",
- "api-reference/queries/list-smart-contract-interfaces",
- "api-reference/queries/list-supported-assets",
- "api-reference/queries/list-tvc-apps",
- "api-reference/queries/list-tvc-deployments",
- "api-reference/queries/list-user-tags",
- "api-reference/queries/list-users",
- "api-reference/queries/list-wallets",
- "api-reference/queries/list-wallets-accounts",
- "api-reference/queries/list-webhook-endpoints",
- "api-reference/queries/validate-container-image-for-tvc",
- "api-reference/queries/who-am-i"
+ }
]
},
- {
- "group": "Auth Proxy",
- "pages": [
- "api-reference/auth-proxy/account",
- "api-reference/auth-proxy/oauth-login",
- "api-reference/auth-proxy/oauth2-authenticate",
- "api-reference/auth-proxy/otp-init",
- "api-reference/auth-proxy/otp-login",
- "api-reference/auth-proxy/otp-verify",
- "api-reference/auth-proxy/signup",
- "api-reference/auth-proxy/wallet-kit-config"
- ]
- }
- ]
- },
- {
- "tab": "Security",
- "pages": [
- {
- "group": "Security",
- "pages": [
- "category/security",
- "security/our-approach",
- "security/non-custodial-key-mgmt",
- "security/secure-enclaves",
- "security/quorum-deployments",
- "security/verifiable-data",
- "security/turnkey-verified",
- "security/disaster-recovery",
- "security/enclave-secure-channels",
- "security/whitepaper",
- "security/shared-responsibility-model",
- "security/reporting-a-vulnerability"
- ]
- }
- ]
- },
- {
- "tab": "Changelogs",
- "pages": [
{
"group": "Changelogs",
"pages": [
@@ -988,35 +926,84 @@
"changelogs/core/readme",
"changelogs/react-wallet-kit/readme"
]
+ },
+ {
+ "group": "API changelog",
+ "pages": [
+ "changelogs/api-changelog/readme"
+ ]
+ },
+ {
+ "group": "TVC changelog",
+ "pages": [
+ "changelogs/tvc-changelog/readme"
+ ]
}
]
}
]
- }
- ]
- },
- "logo": {
- "light": "/logo/light.svg",
- "dark": "/logo/dark.svg",
- "href": "https://www.turnkey.com/"
- },
- "styling": {
- "codeblocks": "system"
- },
- "navbar": {
- "links": [
- {
- "label": "Demo",
- "href": "https://wallets.turnkey.com/"
},
{
- "label": "Login",
- "href": "https://app.turnkey.com/dashboard/auth/login?step=1"
- }
- ],
- "primary": {
- "type": "button",
- "label": "Get started",
+ "tab": "Security",
+ "groups": [
+ {
+ "group": "Overview",
+ "pages": [
+ "security/overview",
+ "security/shared-responsibility-model"
+ ]
+ },
+ {
+ "group": "Architecture",
+ "pages": [
+ "security/our-approach",
+ "security/non-custodial-key-mgmt",
+ "security/secure-enclaves",
+ "security/quorum-deployments",
+ "security/enclave-secure-channels",
+ "security/verifiable-data",
+ "security/remote-attestation"
+ ]
+ },
+ {
+ "group": "Resources",
+ "pages": [
+ "security/turnkey-verified",
+ "security/disaster-recovery",
+ "security/whitepaper",
+ "security/reporting-a-vulnerability"
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "logo": {
+ "light": "/logo/light.svg",
+ "dark": "/logo/dark.svg",
+ "href": "https://www.turnkey.com/"
+ },
+ "styling": {
+ "codeblocks": "system"
+ },
+ "navbar": {
+ "links": [
+ {
+ "label": "Support",
+ "href": "https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ"
+ },
+ {
+ "label": "Blog",
+ "href": "https://www.turnkey.com/blog"
+ },
+ {
+ "label": "Contact us",
+ "href": "https://www.turnkey.com/contact-us"
+ }
+ ],
+ "primary": {
+ "type": "button",
+ "label": "Get started",
"href": "https://app.turnkey.com/dashboard/auth/initial"
}
},
@@ -1031,162 +1018,162 @@
"redirects": [
{
"source": "/users/sessions",
- "destination": "/features/sessions",
+ "destination": "/features/authentication/sessions",
"permanent": true
},
{
"source": "/users/:slug*",
- "destination": "/concepts/users/:slug*",
+ "destination": "/features/users/:slug*",
"permanent": true
},
{
"source": "/api-introduction",
- "destination": "/developer-reference/api-overview/intro",
+ "destination": "/api-reference/overview/intro",
"permanent": true
},
{
"source": "/api-design/:slug*",
- "destination": "/api-overview/:slug*",
+ "destination": "/api-reference/overview/:slug*",
"permanent": true
},
{
"source": "/managing-policies/:slug*",
- "destination": "/concepts/policies/:slug*",
+ "destination": "/features/policies/:slug*",
"permanent": true
},
{
"source": "/managing-users/:slug*",
- "destination": "/concepts/users/:slug*",
+ "destination": "/features/users/:slug*",
"permanent": true
},
{
"source": "/getting-started/email-auth",
- "destination": "/features/email-auth",
+ "destination": "/features/authentication/email",
"permanent": true
},
{
"source": "/concepts/email-auth",
- "destination": "/features/email-auth",
+ "destination": "/features/authentication/email",
"permanent": true
},
{
"source": "/concepts/email-recovery",
- "destination": "/features/email-recovery",
+ "destination": "/features/authentication/email",
"permanent": true
},
{
"source": "/integration-guides/export-wallets",
- "destination": "/features/export-wallets",
+ "destination": "/features/wallets/export-wallets",
"permanent": true
},
{
"source": "/integration-guides/import-wallets",
- "destination": "/features/import-wallets",
+ "destination": "/features/wallets/import-wallets",
"permanent": true
},
{
"source": "/integration-guides/aa-wallets",
- "destination": "/reference/aa-wallets",
+ "destination": "/features/wallets/aa-wallets",
"permanent": true
},
{
"source": "/integration-guides/sub-organization-auth",
- "destination": "/embedded-wallets/sub-organization-auth",
+ "destination": "/features/authentication/email",
"permanent": true
},
{
"source": "/integration-guides/sub-organization-recovery",
- "destination": "/embedded-wallets/sub-organization-recovery",
+ "destination": "/features/authentication/email",
"permanent": true
},
{
"source": "/integration-guides/webhooks",
- "destination": "/features/webhooks",
+ "destination": "/reference/webhooks",
"permanent": true
},
{
"source": "/reference/react-components",
- "destination": "/reference/embedded-wallet-kit",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/getting-started",
"permanent": true
},
{
"source": "/getting-started/resource-limits",
- "destination": "/concepts/resource-limits",
+ "destination": "/reference/resource-limits",
"permanent": true
},
{
"source": "/ecosystem-integrations/ethereum",
- "destination": "/ecosystems/ethereum",
+ "destination": "/features/networks/ethereum",
"permanent": true
},
{
"source": "/ecosystem-integrations/solana",
- "destination": "/ecosystems/solana",
+ "destination": "/features/networks/solana",
"permanent": true
},
{
"source": "/ecosystem-integrations/bitcoin",
- "destination": "/ecosystems/bitcoin",
+ "destination": "/features/networks/bitcoin",
"permanent": true
},
{
"source": "/ecosystem-integrations/index",
- "destination": "/ecosystems/overview",
+ "destination": "/features/networks/overview",
"permanent": true
},
{
"source": "/passkeys/discoverable-vs-non-discoverable",
- "destination": "/authentication/passkeys/discoverable-vs-non-discoverable",
+ "destination": "/features/authentication/passkeys/discoverable-vs-non-discoverable",
"permanent": true
},
{
"source": "/passkeys/integration",
- "destination": "/authentication/passkeys/integration",
+ "destination": "/features/authentication/passkeys/integration",
"permanent": true
},
{
"source": "/passkeys/introduction",
- "destination": "/authentication/passkeys/introduction",
+ "destination": "/features/authentication/passkeys/introduction",
"permanent": true
},
{
"source": "/passkeys/native",
- "destination": "/authentication/passkeys/native",
+ "destination": "/features/authentication/passkeys/native",
"permanent": true
},
{
"source": "/passkeys/options",
- "destination": "/authentication/passkeys/options",
+ "destination": "/features/authentication/passkeys/options",
"permanent": true
},
{
"source": "/features/oauth",
- "destination": "/authentication/social-logins",
+ "destination": "/features/authentication/social-logins",
"permanent": true
},
{
"source": "/concepts/introduction",
- "destination": "/concepts/overview",
+ "destination": "/get-started/about-turnkey",
"permanent": true
},
{
"source": "/features/email-auth",
- "destination": "/authentication/email",
+ "destination": "/features/authentication/email",
"permanent": true
},
{
"source": "/features/email-recovery",
- "destination": "/authentication/email",
+ "destination": "/features/authentication/email",
"permanent": true
},
{
"source": "/api-overview/:slug*",
- "destination": "/developer-reference/api-overview/:slug*",
+ "destination": "/api-reference/overview/:slug*",
"permanent": true
},
{
"source": "/ecosystems/:slug*",
- "destination": "/networks/:slug*",
+ "destination": "/features/networks/:slug*",
"permanent": true
},
{
@@ -1201,22 +1188,1302 @@
},
{
"source": "/getting-started/signing-automation-quickstart",
- "destination": "/getting-started/company-wallets-quickstart",
+ "destination": "/solutions/company-wallets/quickstart",
"permanent": true
},
{
"source": "/signing-automation/overview",
- "destination": "/company-wallets/overview",
+ "destination": "/solutions/company-wallets/overview",
"permanent": true
},
{
"source": "/signing-automation/code-examples/smart-contract-management",
- "destination": "/company-wallets/code-examples/smart-contract-management",
+ "destination": "/solutions/company-wallets/smart-contract-management",
"permanent": true
},
{
"source": "/signing-automation/code-examples/payment-orchestration",
- "destination": "/company-wallets/code-examples/payment-orchestration",
+ "destination": "/solutions/company-wallets/payment-orchestration",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/overview",
+ "destination": "/solutions/embedded-wallets/overview",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/embedded-consumer-wallet",
+ "destination": "/solutions/embedded-wallets/embedded-consumer-wallet",
+ "permanent": true
+ },
+ {
+ "source": "/products/embedded-business-wallets/overview",
+ "destination": "/solutions/embedded-wallets/embedded-business-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/embedded-waas",
+ "destination": "/solutions/embedded-wallets/embedded-waas",
+ "permanent": true
+ },
+ {
+ "source": "/getting-started/embedded-wallet-quickstart",
+ "destination": "/solutions/embedded-wallets/quickstart",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/integration-guide/overview",
+ "destination": "/solutions/embedded-wallets/integration-guide/overview",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/index",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/index",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/getting-started",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/getting-started",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/auth",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/auth",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/using-embedded-wallets",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/using-external-wallets/overview",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/using-external-wallets/authentication",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/using-external-wallets/authentication",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/using-external-wallets/connecting",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/using-external-wallets/connecting",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/signing",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/signing",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/ui-customization",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/ui-customization",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/sub-organization-customization",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/sub-organization-customization",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/advanced-api-requests",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/advanced-api-requests",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/advanced-backend-authentication",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/advanced-backend-authentication",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/migrating-sdk-react",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/migrating-sdk-react",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/troubleshooting",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/troubleshooting",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/legacy",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/legacy",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react-native/overview",
+ "destination": "/solutions/embedded-wallets/integration-guide/react-native/overview",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react-native/getting-started",
+ "destination": "/solutions/embedded-wallets/integration-guide/react-native/getting-started",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react-native/authentication/overview",
+ "destination": "/solutions/embedded-wallets/integration-guide/react-native/authentication/overview",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react-native/authentication/email-sms",
+ "destination": "/solutions/embedded-wallets/integration-guide/react-native/authentication/email-sms",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react-native/authentication/passkey",
+ "destination": "/solutions/embedded-wallets/integration-guide/react-native/authentication/passkey",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react-native/authentication/social-logins",
+ "destination": "/solutions/embedded-wallets/integration-guide/react-native/authentication/social-logins",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react-native/sub-organization-customization",
+ "destination": "/solutions/embedded-wallets/integration-guide/react-native/sub-organization-customization",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react-native/using-embedded-wallets",
+ "destination": "/solutions/embedded-wallets/integration-guide/react-native/using-embedded-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react-native/signing",
+ "destination": "/solutions/embedded-wallets/integration-guide/react-native/signing",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react-native/advanced-api-requests",
+ "destination": "/solutions/embedded-wallets/integration-guide/react-native/advanced-api-requests",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/typescript-frontend/index",
+ "destination": "/solutions/embedded-wallets/integration-guide/typescript/index",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/typescript-frontend/getting-started",
+ "destination": "/solutions/embedded-wallets/integration-guide/typescript/getting-started",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/typescript-frontend/auth",
+ "destination": "/solutions/embedded-wallets/integration-guide/typescript/auth",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/typescript-frontend/advanced-backend-authentication",
+ "destination": "/solutions/embedded-wallets/integration-guide/typescript/advanced-backend-authentication",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/typescript-frontend/advanced-api-requests",
+ "destination": "/solutions/embedded-wallets/integration-guide/typescript/advanced-api-requests",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/typescript-frontend/legacy",
+ "destination": "/solutions/embedded-wallets/integration-guide/typescript/legacy",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/flutter/index",
+ "destination": "/solutions/embedded-wallets/integration-guide/flutter/index",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/flutter/getting-started",
+ "destination": "/solutions/embedded-wallets/integration-guide/flutter/getting-started",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/flutter/authentication/overview",
+ "destination": "/solutions/embedded-wallets/integration-guide/flutter/authentication/overview",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/flutter/authentication/email-sms",
+ "destination": "/solutions/embedded-wallets/integration-guide/flutter/authentication/email-sms",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/flutter/authentication/passkey",
+ "destination": "/solutions/embedded-wallets/integration-guide/flutter/authentication/passkey",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/flutter/authentication/social-logins",
+ "destination": "/solutions/embedded-wallets/integration-guide/flutter/authentication/social-logins",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/flutter/sub-organization-customization",
+ "destination": "/solutions/embedded-wallets/integration-guide/flutter/sub-organization-customization",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/flutter/using-embedded-wallets",
+ "destination": "/solutions/embedded-wallets/integration-guide/flutter/using-embedded-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/flutter/signing",
+ "destination": "/solutions/embedded-wallets/integration-guide/flutter/signing",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/flutter/advanced-api-requests",
+ "destination": "/solutions/embedded-wallets/integration-guide/flutter/advanced-api-requests",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/swift/overview",
+ "destination": "/solutions/embedded-wallets/integration-guide/swift/overview",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/swift/getting-started",
+ "destination": "/solutions/embedded-wallets/integration-guide/swift/getting-started",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/swift/authentication/overview",
+ "destination": "/solutions/embedded-wallets/integration-guide/swift/authentication/overview",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/swift/authentication/email-sms",
+ "destination": "/solutions/embedded-wallets/integration-guide/swift/authentication/email-sms",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/swift/authentication/passkey",
+ "destination": "/solutions/embedded-wallets/integration-guide/swift/authentication/passkey",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/swift/authentication/social-logins",
+ "destination": "/solutions/embedded-wallets/integration-guide/swift/authentication/social-logins",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/swift/signing",
+ "destination": "/solutions/embedded-wallets/integration-guide/swift/signing",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/swift/sub-organization-customization",
+ "destination": "/solutions/embedded-wallets/integration-guide/swift/sub-organization-customization",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/swift/advanced-api-requests",
+ "destination": "/solutions/embedded-wallets/integration-guide/swift/advanced-api-requests",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/swift/using-embedded-wallets",
+ "destination": "/solutions/embedded-wallets/integration-guide/swift/using-embedded-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/swift/advanced-backend-authentication",
+ "destination": "/solutions/embedded-wallets/integration-guide/swift/advanced-backend-authentication",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/kotlin/overview",
+ "destination": "/solutions/embedded-wallets/integration-guide/kotlin/overview",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/kotlin/getting-started",
+ "destination": "/solutions/embedded-wallets/integration-guide/kotlin/getting-started",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/kotlin/authentication/overview",
+ "destination": "/solutions/embedded-wallets/integration-guide/kotlin/authentication/overview",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/kotlin/authentication/email-sms",
+ "destination": "/solutions/embedded-wallets/integration-guide/kotlin/authentication/email-sms",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/kotlin/authentication/passkey",
+ "destination": "/solutions/embedded-wallets/integration-guide/kotlin/authentication/passkey",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/kotlin/authentication/social-logins",
+ "destination": "/solutions/embedded-wallets/integration-guide/kotlin/authentication/social-logins",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/kotlin/authentication/rp-id-setup",
+ "destination": "/solutions/embedded-wallets/integration-guide/kotlin/authentication/rp-id-setup",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/kotlin/sub-organization-customization",
+ "destination": "/solutions/embedded-wallets/integration-guide/kotlin/sub-organization-customization",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/kotlin/using-embedded-wallets",
+ "destination": "/solutions/embedded-wallets/integration-guide/kotlin/using-embedded-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/kotlin/signing",
+ "destination": "/solutions/embedded-wallets/integration-guide/kotlin/signing",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/kotlin/advanced-api-requests",
+ "destination": "/solutions/embedded-wallets/integration-guide/kotlin/advanced-api-requests",
+ "permanent": true
+ },
+ {
+ "source": "/company-wallets/overview",
+ "destination": "/solutions/company-wallets/overview",
+ "permanent": true
+ },
+ {
+ "source": "/company-wallets/code-examples/payment-orchestration",
+ "destination": "/solutions/company-wallets/payment-orchestration",
+ "permanent": true
+ },
+ {
+ "source": "/company-wallets/code-examples/smart-contract-management",
+ "destination": "/solutions/company-wallets/smart-contract-management",
+ "permanent": true
+ },
+ {
+ "source": "/company-wallets/use-cases/agentic-wallets",
+ "destination": "/solutions/company-wallets/agentic-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/getting-started/company-wallets-quickstart",
+ "destination": "/solutions/company-wallets/quickstart",
+ "permanent": true
+ },
+ {
+ "source": "/company-wallets/integration-guide/overview",
+ "destination": "/solutions/company-wallets/integration-guide/overview",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/javascript-server",
+ "destination": "/solutions/company-wallets/integration-guide/javascript-server",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/golang",
+ "destination": "/solutions/company-wallets/integration-guide/golang",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/ruby",
+ "destination": "/solutions/company-wallets/integration-guide/ruby",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/rust",
+ "destination": "/solutions/company-wallets/integration-guide/rust",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/python",
+ "destination": "/solutions/company-wallets/integration-guide/python",
+ "permanent": true
+ },
+ {
+ "source": "/products/key-management/overview",
+ "destination": "/solutions/key-management/overview",
+ "permanent": true
+ },
+ {
+ "source": "/products/key-management/examples/encryption-key-storage",
+ "destination": "/solutions/key-management/encryption-key-storage",
+ "permanent": true
+ },
+ {
+ "source": "/products/key-management/examples/enterprise-disaster-recovery",
+ "destination": "/solutions/key-management/enterprise-disaster-recovery",
+ "permanent": true
+ },
+ {
+ "source": "/cookbook/landing",
+ "destination": "/solutions/cookbooks/landing",
+ "permanent": true
+ },
+ {
+ "source": "/cookbook/morpho",
+ "destination": "/solutions/cookbooks/morpho",
+ "permanent": true
+ },
+ {
+ "source": "/cookbook/aave",
+ "destination": "/solutions/cookbooks/aave",
+ "permanent": true
+ },
+ {
+ "source": "/cookbook/breeze",
+ "destination": "/solutions/cookbooks/breeze",
+ "permanent": true
+ },
+ {
+ "source": "/cookbook/yieldxyz",
+ "destination": "/solutions/cookbooks/yieldxyz",
+ "permanent": true
+ },
+ {
+ "source": "/cookbook/jupiter",
+ "destination": "/solutions/cookbooks/jupiter",
+ "permanent": true
+ },
+ {
+ "source": "/cookbook/lifi",
+ "destination": "/solutions/cookbooks/lifi",
+ "permanent": true
+ },
+ {
+ "source": "/cookbook/0x",
+ "destination": "/solutions/cookbooks/0x",
+ "permanent": true
+ },
+ {
+ "source": "/cookbook/relay",
+ "destination": "/solutions/cookbooks/relay",
+ "permanent": true
+ },
+ {
+ "source": "/cookbook/polymarket-builders",
+ "destination": "/solutions/cookbooks/polymarket-builders",
+ "permanent": true
+ },
+ {
+ "source": "/cookbook/base-builder-codes",
+ "destination": "/solutions/cookbooks/base-builder-codes",
+ "permanent": true
+ },
+ {
+ "source": "/cookbook/brale",
+ "destination": "/solutions/cookbooks/brale",
+ "permanent": true
+ },
+ {
+ "source": "/reference/tron-gasless-transactions",
+ "destination": "/solutions/cookbooks/tron-gasless-transactions",
+ "permanent": true
+ },
+ {
+ "source": "/home",
+ "destination": "/welcome",
+ "permanent": true
+ },
+ {
+ "source": "/getting-started/quickstart",
+ "destination": "/get-started/quickstart",
+ "permanent": true
+ },
+ {
+ "source": "/developer-reference/using-llms",
+ "destination": "/get-started/using-llms",
+ "permanent": true
+ },
+ {
+ "source": "/ai/skills",
+ "destination": "/get-started/ai-skills",
+ "permanent": true
+ },
+ {
+ "source": "/getting-started/examples",
+ "destination": "/get-started/examples",
+ "permanent": true
+ },
+ {
+ "source": "/production-checklist/production-checklist",
+ "destination": "/get-started/production-checklist",
+ "permanent": true
+ },
+ {
+ "source": "/production-checklist/backup-recovery",
+ "destination": "/get-started/backup-recovery",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/organizations",
+ "destination": "/features/organizations",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/sub-organizations",
+ "destination": "/features/sub-organizations",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/users/introduction",
+ "destination": "/features/users/introduction",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/users/credentials",
+ "destination": "/features/users/credentials",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/users/root-quorum",
+ "destination": "/features/users/root-quorum",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/users/best-practices",
+ "destination": "/features/users/best-practices",
+ "permanent": true
+ },
+ {
+ "source": "/authentication/overview",
+ "destination": "/features/authentication/overview",
+ "permanent": true
+ },
+ {
+ "source": "/authentication/email",
+ "destination": "/features/authentication/email",
+ "permanent": true
+ },
+ {
+ "source": "/authentication/social-logins",
+ "destination": "/features/authentication/social-logins",
+ "permanent": true
+ },
+ {
+ "source": "/authentication/sms",
+ "destination": "/features/authentication/sms",
+ "permanent": true
+ },
+ {
+ "source": "/authentication/passkeys/introduction",
+ "destination": "/features/authentication/passkeys/introduction",
+ "permanent": true
+ },
+ {
+ "source": "/authentication/passkeys/integration",
+ "destination": "/features/authentication/passkeys/integration",
+ "permanent": true
+ },
+ {
+ "source": "/authentication/passkeys/options",
+ "destination": "/features/authentication/passkeys/options",
+ "permanent": true
+ },
+ {
+ "source": "/authentication/passkeys/native",
+ "destination": "/features/authentication/passkeys/native",
+ "permanent": true
+ },
+ {
+ "source": "/authentication/passkeys/discoverable-vs-non-discoverable",
+ "destination": "/features/authentication/passkeys/discoverable-vs-non-discoverable",
+ "permanent": true
+ },
+ {
+ "source": "/authentication/backend-setup",
+ "destination": "/features/authentication/backend-setup",
+ "permanent": true
+ },
+ {
+ "source": "/authentication/bring-your-own-auth",
+ "destination": "/features/authentication/bring-your-own-auth",
+ "permanent": true
+ },
+ {
+ "source": "/reference/auth-proxy",
+ "destination": "/features/authentication/auth-proxy",
+ "permanent": true
+ },
+ {
+ "source": "/authentication/sessions",
+ "destination": "/features/authentication/sessions",
+ "permanent": true
+ },
+ {
+ "source": "/authentication/proxying-signed-requests",
+ "destination": "/features/authentication/proxying-signed-requests",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/wallets",
+ "destination": "/features/wallets",
+ "permanent": true
+ },
+ {
+ "source": "/products/company-wallets/features/import-wallets",
+ "destination": "/features/wallets/import-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/products/company-wallets/features/export-wallets",
+ "destination": "/features/wallets/export-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/wallets/pregenerated-wallets",
+ "destination": "/features/wallets/pregenerated-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/wallets/claim-links",
+ "destination": "/features/wallets/claim-links",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/send-crypto-via-url",
+ "destination": "/features/wallets/send-crypto-via-url",
+ "permanent": true
+ },
+ {
+ "source": "/reference/aa-wallets",
+ "destination": "/features/wallets/aa-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/networks/overview",
+ "destination": "/features/networks/overview",
+ "permanent": true
+ },
+ {
+ "source": "/networks/ethereum",
+ "destination": "/features/networks/ethereum",
+ "permanent": true
+ },
+ {
+ "source": "/networks/solana",
+ "destination": "/features/networks/solana",
+ "permanent": true
+ },
+ {
+ "source": "/networks/solana-transaction-construction",
+ "destination": "/features/networks/solana-transaction-construction",
+ "permanent": true
+ },
+ {
+ "source": "/networks/solana-rent-refunds",
+ "destination": "/features/networks/solana-rent-refunds",
+ "permanent": true
+ },
+ {
+ "source": "/networks/bitcoin",
+ "destination": "/features/networks/bitcoin",
+ "permanent": true
+ },
+ {
+ "source": "/networks/spark",
+ "destination": "/features/networks/spark",
+ "permanent": true
+ },
+ {
+ "source": "/networks/hyperliquid",
+ "destination": "/features/networks/hyperliquid",
+ "permanent": true
+ },
+ {
+ "source": "/networks/cosmos",
+ "destination": "/features/networks/cosmos",
+ "permanent": true
+ },
+ {
+ "source": "/networks/tron",
+ "destination": "/features/networks/tron",
+ "permanent": true
+ },
+ {
+ "source": "/networks/sui",
+ "destination": "/features/networks/sui",
+ "permanent": true
+ },
+ {
+ "source": "/networks/sei",
+ "destination": "/features/networks/sei",
+ "permanent": true
+ },
+ {
+ "source": "/networks/stacks",
+ "destination": "/features/networks/stacks",
+ "permanent": true
+ },
+ {
+ "source": "/networks/aptos",
+ "destination": "/features/networks/aptos",
+ "permanent": true
+ },
+ {
+ "source": "/networks/tempo",
+ "destination": "/features/networks/tempo",
+ "permanent": true
+ },
+ {
+ "source": "/networks/movement",
+ "destination": "/features/networks/movement",
+ "permanent": true
+ },
+ {
+ "source": "/networks/iota",
+ "destination": "/features/networks/iota",
+ "permanent": true
+ },
+ {
+ "source": "/networks/doge",
+ "destination": "/features/networks/doge",
+ "permanent": true
+ },
+ {
+ "source": "/networks/others",
+ "destination": "/features/networks/others",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/policies/overview",
+ "destination": "/features/policies/overview",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/policies/quickstart",
+ "destination": "/features/policies/quickstart",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/policies/language",
+ "destination": "/features/policies/language",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/policies/smart-contract-interfaces",
+ "destination": "/features/policies/smart-contract-interfaces",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/policies/examples/access-control",
+ "destination": "/features/policies/examples/access-control",
+ "permanent": true
+ },
+ {
+ "source": "/company-wallets/co-signing-transactions",
+ "destination": "/features/policies/examples/co-signing-transactions",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/policies/examples/signing-control",
+ "destination": "/features/policies/examples/signing-control",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/policies/examples/ethereum",
+ "destination": "/features/policies/examples/ethereum",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/policies/examples/solana",
+ "destination": "/features/policies/examples/solana",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/policies/examples/tron",
+ "destination": "/features/policies/examples/tron",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/policies/examples/bitcoin",
+ "destination": "/features/policies/examples/bitcoin",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/policies/examples/tempo",
+ "destination": "/features/policies/examples/tempo",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/policies/delegated-access-overview",
+ "destination": "/features/policies/delegated-access/overview",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/policies/delegated-access-frontend",
+ "destination": "/features/policies/delegated-access/frontend",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/policies/delegated-access-backend",
+ "destination": "/features/policies/delegated-access/backend",
+ "permanent": true
+ },
+ {
+ "source": "/products/embedded-wallets/features/agentic-wallets",
+ "destination": "/features/policies/delegated-access/agentic-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/transaction-management",
+ "destination": "/features/transaction-management",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/broadcasting",
+ "destination": "/features/transaction-management/broadcasting",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/sending-sponsored-transactions",
+ "destination": "/features/transaction-management/sending-sponsored-transactions",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/sending-sponsored-solana-transactions",
+ "destination": "/features/transaction-management/sending-sponsored-solana-transactions",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/balances",
+ "destination": "/features/transaction-management/balances",
+ "permanent": true
+ },
+ {
+ "source": "/wallets/fiat-on-ramp",
+ "destination": "/features/transaction-management/fiat-on-ramp",
+ "permanent": true
+ },
+ {
+ "source": "/products/verifiable-cloud/overview",
+ "destination": "/features/verifiable-cloud/overview",
+ "permanent": true
+ },
+ {
+ "source": "/products/verifiable-cloud/onboarding",
+ "destination": "/features/verifiable-cloud/onboarding",
+ "permanent": true
+ },
+ {
+ "source": "/getting-started/verifiable-cloud-quickstart",
+ "destination": "/features/verifiable-cloud/quickstart",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/resource-limits",
+ "destination": "/reference/resource-limits",
+ "permanent": true
+ },
+ {
+ "source": "/developer-reference/webhooks",
+ "destination": "/reference/webhooks",
+ "permanent": true
+ },
+ {
+ "source": "/getting-started/migration-guide",
+ "destination": "/reference/migration-guide",
+ "permanent": true
+ },
+ {
+ "source": "/faq",
+ "destination": "/reference/faq",
+ "permanent": true
+ },
+ {
+ "source": "/developer-reference/api-overview/intro",
+ "destination": "/api-reference/overview/intro",
+ "permanent": true
+ },
+ {
+ "source": "/developer-reference/api-overview/stamps",
+ "destination": "/api-reference/overview/stamps",
+ "permanent": true
+ },
+ {
+ "source": "/developer-reference/api-overview/errors",
+ "destination": "/api-reference/overview/errors",
+ "permanent": true
+ },
+ {
+ "source": "/category/web3-libraries",
+ "destination": "/sdks/web3/overview",
+ "permanent": true
+ },
+ {
+ "source": "/wallets/wagmi",
+ "destination": "/sdks/web3/wagmi",
+ "permanent": true
+ },
+ {
+ "source": "/category/advanced",
+ "destination": "/sdks/advanced/overview",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/client-side-signing",
+ "destination": "/sdks/advanced/client-side-signing",
+ "permanent": true
+ },
+ {
+ "source": "/category/security",
+ "destination": "/security/overview",
+ "permanent": true
+ },
+ {
+ "source": "/products/company-wallets/features/security/remote-attestation",
+ "destination": "/security/remote-attestation",
+ "permanent": true
+ },
+ {
+ "source": "/products/company-wallets/features/dashboard",
+ "destination": "/solutions/company-wallets/overview",
+ "permanent": true
+ },
+ {
+ "source": "/products/company-wallets/features/multi-chain-support",
+ "destination": "/features/networks/overview",
+ "permanent": true
+ },
+ {
+ "source": "/products/company-wallets/features/off-chain-contracts",
+ "destination": "/solutions/company-wallets/overview",
+ "permanent": true
+ },
+ {
+ "source": "/products/company-wallets/features/scoped-api-key",
+ "destination": "/solutions/company-wallets/overview",
+ "permanent": true
+ },
+ {
+ "source": "/products/company-wallets/features/security/compliance",
+ "destination": "/security/our-approach",
+ "permanent": true
+ },
+ {
+ "source": "/products/company-wallets/features/security/quorum-os",
+ "destination": "/security/secure-enclaves",
+ "permanent": true
+ },
+ {
+ "source": "/products/company-wallets/features/security/secure-hardware",
+ "destination": "/security/secure-enclaves",
+ "permanent": true
+ },
+ {
+ "source": "/products/company-wallets/policy-engine",
+ "destination": "/features/policies/quickstart",
+ "permanent": true
+ },
+ {
+ "source": "/products/embedded-wallets/features/export-wallets",
+ "destination": "/features/wallets/export-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/products/embedded-wallets/features/fiat-on-ramp",
+ "destination": "/features/transaction-management/fiat-on-ramp",
+ "permanent": true
+ },
+ {
+ "source": "/products/embedded-wallets/features/gas-sponsorship",
+ "destination": "/features/transaction-management/broadcasting",
+ "permanent": true
+ },
+ {
+ "source": "/products/embedded-wallets/features/import-wallets",
+ "destination": "/features/wallets/import-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/products/embedded-wallets/features/multi-chain-support",
+ "destination": "/features/networks/overview",
+ "permanent": true
+ },
+ {
+ "source": "/products/embedded-wallets/features/policy-engine",
+ "destination": "/features/policies/quickstart",
+ "permanent": true
+ },
+ {
+ "source": "/api-overview",
+ "destination": "/api-reference/overview/intro",
+ "permanent": true
+ },
+ {
+ "source": "/api-reference/activities/submit-a-raw-transaction-for-broadcasting",
+ "destination": "/api-reference/activities/overview",
+ "permanent": true
+ },
+ {
+ "source": "/api-reference/activities/submit-a-transaction-intent-for-broadcasting",
+ "destination": "/api-reference/activities/overview",
+ "permanent": true
+ },
+ {
+ "source": "/api-reference/overview",
+ "destination": "/api-reference/overview/intro",
+ "permanent": true
+ },
+ {
+ "source": "/api-reference/queries/get-gas-usage-and-limits",
+ "destination": "/api-reference/queries/get-gas-usage",
+ "permanent": true
+ },
+ {
+ "source": "/api-reference/queries/get-nonces-for-an-address",
+ "destination": "/api-reference/queries/get-nonces",
+ "permanent": true
+ },
+ {
+ "source": "/api-reference/queries/get-suborgs",
+ "destination": "/api-reference/queries/get-sub-organizations",
+ "permanent": true
+ },
+ {
+ "source": "/api-reference/queries/get-verified-suborgs",
+ "destination": "/api-reference/queries/get-verified-sub-organizations",
+ "permanent": true
+ },
+ {
+ "source": "/company-wallets/code-examples/balance-sweeper",
+ "destination": "/solutions/company-wallets/overview",
+ "permanent": true
+ },
+ {
+ "source": "/company-wallets/code-examples/sending-sponsored-transactions",
+ "destination": "/features/transaction-management/broadcasting",
+ "permanent": true
+ },
+ {
+ "source": "/company-wallets/code-examples/signing-transactions",
+ "destination": "/solutions/company-wallets/overview",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/add-credential",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/index",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/authenticate-user-email",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/auth",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/authenticate-user-passkey",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/sub-organization-customization",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/create-passkey-session",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/auth",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/create-sub-org-passkey",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/sub-organization-customization",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/create-user-email",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/sub-organization-customization",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/email-recovery",
+ "destination": "/features/authentication/email",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/export",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/fiat-on-ramp",
+ "destination": "/features/transaction-management/fiat-on-ramp",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/import",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/signing-transactions",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/signing",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/social-linking",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/auth",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/code-examples/wallet-auth",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview",
+ "permanent": true
+ },
+ {
+ "source": "/category/code-examples",
+ "destination": "/solutions/embedded-wallets/overview",
+ "permanent": true
+ },
+ {
+ "source": "/category/code-examples-1",
+ "destination": "/solutions/company-wallets/overview",
+ "permanent": true
+ },
+ {
+ "source": "/concepts/overview",
+ "destination": "/get-started/about-turnkey",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/demos",
+ "destination": "/solutions/embedded-wallets/quickstart",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/features/overview",
+ "destination": "/solutions/embedded-wallets/overview",
+ "permanent": true
+ },
+ {
+ "source": "/products/key-management/examples/overview",
+ "destination": "/solutions/key-management/overview",
+ "permanent": true
+ },
+ {
+ "source": "/products/verifiable-cloud/lifecycle",
+ "destination": "/features/verifiable-cloud/overview",
+ "permanent": true
+ },
+ {
+ "source": "/authentication/credentials",
+ "destination": "/features/users/credentials",
+ "permanent": true
+ },
+ {
+ "source": "/authentication/otp-migration-guide",
+ "destination": "/features/authentication/overview",
+ "permanent": true
+ },
+ {
+ "source": "/cookbook/gelato",
+ "destination": "/sdks/web3/gas-station",
+ "permanent": true
+ },
+ {
+ "source": "/developer-reference/api-overview/queries",
+ "destination": "/api-reference/queries/overview",
+ "permanent": true
+ },
+ {
+ "source": "/developer-reference/api-overview/submissions",
+ "destination": "/api-reference/activities/overview",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/sub-organization-auth",
+ "destination": "/features/authentication/email",
+ "permanent": true
+ },
+ {
+ "source": "/embedded-wallets/sub-organization-recovery",
+ "destination": "/features/authentication/email",
+ "permanent": true
+ },
+ {
+ "source": "/getting-started",
+ "destination": "/get-started/about-turnkey",
+ "permanent": true
+ },
+ {
+ "source": "/getting-started/launch-checklist",
+ "destination": "/get-started/production-checklist",
+ "permanent": true
+ },
+ {
+ "source": "/production-checklist/company-wallet",
+ "destination": "/solutions/company-wallets/integration-guide/overview",
+ "permanent": true
+ },
+ {
+ "source": "/production-checklist/embedded-wallet",
+ "destination": "/solutions/embedded-wallets/integration-guide/overview",
+ "permanent": true
+ },
+ {
+ "source": "/reference/embedded-wallet-kit",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/getting-started",
+ "permanent": true
+ },
+ {
+ "source": "/reference/solana-gasless-transactions",
+ "destination": "/features/transaction-management",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/cli",
+ "destination": "/sdks/introduction",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/flutter/landing",
+ "destination": "/solutions/embedded-wallets/integration-guide/flutter/getting-started",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/kotlin",
+ "destination": "/solutions/embedded-wallets/integration-guide/kotlin/overview",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/kotlin/landing",
+ "destination": "/solutions/embedded-wallets/integration-guide/kotlin/getting-started",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react-native",
+ "destination": "/solutions/embedded-wallets/integration-guide/react-native/getting-started",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/react/landing",
+ "destination": "/solutions/embedded-wallets/integration-guide/react/getting-started",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/swift",
+ "destination": "/solutions/embedded-wallets/integration-guide/swift/overview",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/swift/landing",
+ "destination": "/solutions/embedded-wallets/integration-guide/swift/getting-started",
+ "permanent": true
+ },
+ {
+ "source": "/sdks/typescript-frontend/landing",
+ "destination": "/solutions/embedded-wallets/integration-guide/typescript/getting-started",
+ "permanent": true
+ },
+ {
+ "source": "/wallets/export-wallets",
+ "destination": "/features/wallets/export-wallets",
+ "permanent": true
+ },
+ {
+ "source": "/wallets/import-wallets",
+ "destination": "/features/wallets/import-wallets",
"permanent": true
}
]
diff --git a/embedded-wallets/code-examples/add-credential.mdx b/embedded-wallets/code-examples/add-credential.mdx
deleted file mode 100644
index 1949c69c..00000000
--- a/embedded-wallets/code-examples/add-credential.mdx
+++ /dev/null
@@ -1,551 +0,0 @@
----
-title: "Add an additional passkey"
-description: "This guide demonstrates how to add a new credential (specifically, a passkey) to an existing wallet using the Turnkey SDK."
----
-> ⚠️ **This example is outdated !**
-> Head over to [SDK Reference](https://docs.turnkey.com/generated-docs/formatted/react-wallet-kit/client-context-type-add-passkey) for the updated packages.
-
-### Initialize the Passkey client
-
-Begin by initializing the Turnkey SDK by passing in a config object containing:
-
-* `rpId`: The [Relying Party](https://developer.mozilla.org/en-US/docs/Glossary/Relying_party) Identifier, which is the effective domain of your application.
-* `apiBaseUrl`: The base URL of the Turnkey API: `https://api.turnkey.com`
-* `defaultOrganizationId`: Your parent organization ID, which you can find in the [Turnkey dashboard](https://app.turnkey.com/dashboard).
-
-
-
- The `rpId` is used in WebAuthn to uniquely identify the server that the passkey is associated with. The `rpId` is typically the effective domain of the web application, which is the domain portion of the URL without any subdomains. For example, if your application is hosted at `app.example.com`, the `rpId` would typically be `example.com`. This ensures that credentials are scoped to the correct domain and cannot be used by other domains, enhancing security.
-
-
-
-
-
-First, wrap your application with the `TurnkeyProvider` in your `app/layout.tsx` file:
-
-```ts app/layout.tsx
-import { TurnkeyProvider } from "@turnkey/sdk-react";
-
-export default function RootLayout({
- children,
-}: {
- children: React.ReactNode;
-}) {
- return (
-
-
-
- {children}
-
-
-
- );
-}
-```
-
-Then, create a new file `app/add-passkey.tsx` where we'll implement the passkey functionality:
-
-```tsx app/add-passkey.tsx
-"use client";
-
-import { useState } from "react";
-import { useTurnkey } from "@turnkey/sdk-react";
-
-export default function AddPasskey() {
- const { passkeyClient } = useTurnkey();
-
- // We'll add more functionality here in the following steps
-
- return
{/* We'll add UI elements here */}
;
-}
-```
-
-
-
-Create a new file `src/add-passkey.ts`:
-
-```ts src/add-passkey.ts
-import { Turnkey } from "@turnkey/sdk-browser";
-
-// Initialize the Turnkey SDK with your organization credentials
-const turnkey = new Turnkey({
- rpId: process.env.TURNKEY_RP_ID, // Your relying party ID
- apiBaseUrl: process.env.TURNKEY_API_BASE_URL, // Turnkey API base URL
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID, // Your parent organization ID
-});
-
-// Initialize the Passkey Client
-const passkeyClient = turnkey.passkeyClient();
-
-// We'll add more functionality here in the following steps
-```
-
-
-
-### Authenticate the user
-
-Now that that the Passkey Client is initialized, we'll call the `login` function which will prompt the user to authenticate with their passkey. Additionally, this function will set the current user in local storage upon successful authentication, which will be used later when creating an additional authenticator.
-
-
- The user object which gets stored in local storage is defined as follows:
-
- ```
- export interface User {
- userId: string;
- username: string;
- organization: SubOrganization;
- readOnlySession?: ReadOnlySession;
- }
- ```
-
-
-
-
-```tsx app/add-passkey.tsx
-// ... previous code
-
-export default function AddPasskey() {
- // We'll need the base Turnkey client to get the current user
- const { passkeyClient, turnkey } = useTurnkey();
-
- // ... previous code
-
- const getUser = async () => {
- // Get the current user from local storage,
- // we'll need the `userId` to create the authenticator in the next step
- const user = await turnkey?.getCurrentUser();
- if (user) {
- console.log("User retrieved successfully");
- }
- // return the user to be used in the next step
- return user;
- };
-
- return (
-
-
-
- );
-}
-```
-
-
-```ts src/add-passkey.ts
-// ... previous code
-
-const login = async () => {
- const response = await passkeyClient.login();
- if (response.organizationId) {
- console.log("User authenticated successfully");
- } else {
- console.log("User authentication failed");
- }
-};
-```
-
-
-
-### Get the current user
-
-Before creating a new passkey, we'll get the current user. This function will retrieve the user from local storage, which was set after calling the `login` function. We'll need the `userId` to create the authenticator in the final step.
-
-
-
-```ts app/add-passkey.tsx
-// ... previous code
-
-export default function AddPasskey() {
- // We'll need the base Turnkey client to get the current user
- const { passkeyClient, turnkey } = useTurnkey();
-
- // ... previous code
-
- const getUser = async () => {
- // Get the current user from local storage,
- // we'll need the `userId` to create the authenticator in the next step
- const user = await turnkey?.getCurrentUser();
- if (user) {
- console.log("User retrieved successfully");
- }
- // return the user to be used in the next step
- return user;
- };
-
- return (
-
-
-
- );
-}
-```
-
-
-```ts src/add-passkey.ts
-// ... previous code
-
-const getCurrentUser = async () => {
- // Get the current user from local storage,
- // we'll need the `userId` to create the authenticator in the next step
- const user = await turnkey?.getCurrentUser();
- if (user) {
- console.log("User retrieved successfully");
- }
- // return the user to be used in the next step
- return user;
-};
-```
-
-
-
-### Create user passkey
-
-Now that you have authenticated the user, you can call the `createUserPasskey` function to create a new user passkey credential. Calling this method will prompt the user to create a passkey, which will be securely stored by their browser. This credential will be associated with the user's account and used for future authentication. Once the credential is created, we'll use it in the next step to create a new authenticator for the user.
-
-
- The credential includes an encoded challenge and attestation. The encoded challenge ensures the request is fresh and legitimate, while the attestation verifies the authenticity of the device creating the credential. For more information on how passkeys work, including details on the challenge and attestation objects, you can refer to the [Passkeys Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API#passkeys).
-
-
-
-
-
-```tsx app/add-passkey.tsx
-// ... previous code
-
-export default function AddPasskey() {
- const { passkeyClient } = useTurnkey();
-
- // ... previous code
-
- // We'll pass the user object returned from `getUser` to this function
- const createNewPasskey = async (user: User) => {
- const credential = await passkeyClient?.createUserPasskey({
- publicKey: {
- // This is the name of the passkey that will be displayed to the user
- rp: {
- name: "Wallet Passkey",
- },
- user: {
- // We can use the username as the name and display name
- name: user.username,
- displayName: user.username,
- },
- },
- });
-
- // we'll use this credential in the next step to create a new authenticator
- return credential;
- };
-
- return (/* ... */);
-}
-```
-
-
-```ts src/add-passkey.ts
-// ... previous code
-
-// We'll pass the user object returned from `getUser` to this function
-const createNewPasskey = async (user: User) => {
- const credential = await passkeyClient?.createUserPasskey({
- publicKey: {
- // This is the name of the passkey that will be displayed to the user
- rp: {
- name: "Wallet Passkey",
- },
- user: {
- // We can use the username as the name and display name
- name: user.username,
- displayName: user.username,
- },
- },
- });
- // we'll use this credential in the next step to create a new authenticator
- return credential;
-};
-```
-
-
-
-### Add the credential to the wallet
-
-Now that you have created a new user passkey credential, we'll use this credential to create a new passkey authenticator for the user. We'll need the userId to create the authenticator, so we'll get the current user first. This value comes from local storage which was set in the previous step when the user successfully authenticated via the `login` function.
-
-
-
-
- ```tsx app/add-passkey.tsx
- // ... previous code
-
- export default function AddPasskey() {
- const { passkeyClient, turnkey } = useTurnkey();
-
- // ... previous code
-
- const addPasskey = async () => {
- const user = await getUser();
- const credential = await createNewPasskey(user);
-
- const authenticatorsResponse = await passkeyClient.createAuthenticators({
- authenticators: [
- {
- authenticatorName: "New Passkey Authenticator",
- challenge: credential.encodedChallenge,
- attestation: credential.attestation,
- },
- ],
- userId: user.userId,
- });
-
- // Check if the authenticator was created successfully
- if (authenticatorsResponse?.activity.id) {
- console.log("Authenticator created successfully");
- }
- };
-
- return (
-
- {/* Add a button to add the passkey to the wallet */}
-
-
-
- );
-}
- ```
-
-
-
-
-```ts src/add-passkey.ts
-// ... previous code
-
-const addPasskey = async () => {
- const user = await getUser();
- const credential = await createNewPasskey(user);
-
- // Check if the credential was created successfully
- if (!credential) {
- console.log("Credential not created");
- return;
- }
-
- const authenticatorsResponse = await passkeyClient.createAuthenticators({
- authenticators: [
- {
- authenticatorName: "New Passkey Authenticator",
- challenge: credential.encodedChallenge,
- attestation: credential.attestation,
- },
- ],
- userId: user.userId,
- });
-
- // Check if the authenticator was created successfully
- if (authenticatorsResponse?.activity.id) {
- console.log("Authenticator created successfully");
- }
-};
-```
-
-
-
-### Optional: read/write sessions
-
-In some cases, you may want to create a read/write session for the user to reduce the number of passkey prompts. This session can be used instead of the passkey to sign requests to Turnkey's API to improve the user experience.
-
-In the this tutorial we used the passkey to authenticate the request to create a new authenticator. The result is that the user will be prompted 3 times:
-
-1. To login
-2. To create the new passkey
-3. To authenticate the request to create a new authenticator
-
-By creating a read/write session, we can reduce the number of passkey prompts to 2:
-
-1. To login and create a session
-2. To authenticate the request to create a new authenticator
-
-To create a read/write session, we simply replace `passkeyClient.login()` with `passkeyClient.loginWithReadwriteSession()`:
-
-```ts src/add-passkey.ts
-// ... previous code
-
-const login = async () => {
- const response = await passkeyClient.loginWithReadwriteSession();
- // ... previous code
-};
-```
-
-Assuming the login is successful, a read/write session object will be stored in local storage. We'll use the stored session in conjunction with the iframe client to authenticate the create authenticator request.
-
-
-
-
-We'll use the active client returned from the `useTurnkey` hook which will be initialized with the read/write session. The rest of the code remains the same.
-
-```tsx app/add-passkey.tsx
-// ... previous code
-
-export default function AddPasskey() {
- const { getActiveClient, turnkey } = useTurnkey();
-
- // ... previous code
-
- const addPasskey = async () => {
- const user = await getUser();
- const credential = await createNewPasskey(user);
-
- // Get the active client which returns the iframe client initialized with the read/write session
- const activeClient = await getActiveClient();
-
- // Since we're using the read/write session this won't prompt the user
- const authenticatorsResponse = await activeClient.createAuthenticators({
- // ...
- });
-
- // ... rest of the code remains the same
- };
-
- return (/* ... */);
-}
-```
-
-
-
-##### 1. Initialize the iframe client
-
-We'll create a new function to initialize the iframe client and inject the read/write session.
-
-```ts src/add-passkey.ts
-// ... previous code
-
-const getIframeClient = async () => {
- const iframeContainerId = "turnkey-auth-container-id";
-
- const authIframeClient = await turnkey.iframeClient(
- document.getElementById(iframeContainerId),
- );
-
- const readWriteSession = await turnkey?.getReadWriteSession();
-
- if (readWriteSession) {
- const injected = await authIframeClient?.injectCredentialBundle(
- readWriteSession.authBundle,
- );
- }
-
- return authIframeClient;
-};
-```
-
-
- When using the TypeScript SDK, you'll need to ensure that the HTML element exists somewhere in the rendered DOM.
-
- ```
-
- ```
-
-
-##### 2. Update the `addPasskey` function
-
-We'll update the `addPasskey` function to use the iframe client to authenticate the request to create a new authenticator.
-
-```ts src/add-passkey.ts
-// ... previous code
-
-const addPasskey = async () => {
- // ... previous code
-
- const iframeClient = await getIframeClient();
-
- const authenticatorsResponse = await iframeClient.createAuthenticators({
- // ...
- });
- // ... rest of the code remains the same
-};
-```
-
-
-
-## Conclusion
-
-In this guide, we've walked through the process of adding a new credential to an existing wallet using the Turnkey SDK. By following these steps, you can improve the usability of your application by allowing users to create multiple authentication methods. This flexibility enables users to add a hardware security device like a Yubikey, or a native passkey via providers like iCloud keychain or 1Password, enhancing their overall experience with your application.
-
-For a complete example, check out our [demo embedded wallet](https://github.com/tkhq/demo-embedded-wallet/blob/main/src/components/add-passkey.tsx).
diff --git a/embedded-wallets/code-examples/authenticate-user-email.mdx b/embedded-wallets/code-examples/authenticate-user-email.mdx
deleted file mode 100644
index 952f9a52..00000000
--- a/embedded-wallets/code-examples/authenticate-user-email.mdx
+++ /dev/null
@@ -1,106 +0,0 @@
----
-title: "Authenticate a user with email"
-mode: wide
----
-> ⚠️ **This example is outdated !**
-> Head over to [SDK Reference](https://docs.turnkey.com/sdks/react/auth) for the updated packages.
-
-
-
-
-```JavaScript
-import { Turnkey } from "@turnkey/sdk-browser";
-
-const turnkey = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
-});
-```
-
-
-
-
-Note that the iframe client must be initialized with the dom element where the iframe will be injected. If you are using the [react-sdk](/sdks/react) you can import the `iframeClient` from the `useTurnkey()` hook without this step and the iframe dom element will be managed for you. Note that the `iframeClient` must be initialized before calling `emailAuth` because you need the `iframePublicKey` as a parameter to the `emailAuth` call.
-
-```JavaScript
-import { Turnkey, TurnkeySDKBrowserConfig } from "@turnkey/sdk-browser";
-
-const turnkeyConfig: TurnkeySDKBrowserConfig = {...};
-const turnkey = new Turnkey(turnkeyConfig);
-
-const iframeContainerId = "turnkey-auth-iframe-container-id";
-
-// ensure the HTML element exists somewhere in the rendered DOM
-
-
-const iframeClient = await turnkey.iframeClient(document.getElementById(iframeContainerId))
-```
-
-
-
-
-```JavaScript
-await turnkey.serverSign(
- "emailAuth",
- [{
- email: ,
- targetPublicKey: iframeClient.iframePublicKey,
- organizationId:
- }]
-)
-```
-
-If you need to lookup the user `subOrganizationId` by email, you can call the `getSubOrgIds` method with the `filterType` parameter set to `"EMAIL"`
-
-```JavaScript
-const subOrgIds = await turnkey.serverSign(
- "getSubOrgIds",
- [{
- filterType: "EMAIL",
- filterValue:
- }]
-)
-
-const userSubOrganizationId = subOrgIds.organizationIds[0];
-```
-
-
-
-
-```JavaScript
-const authenticationResponse =
- await iframeClient.injectCredentialBundle(credentialBundle);
-if (authenticationResponse) {
- // user is authenticated and can perform actions from the `iframeClient`
- await iframeClient.login();
- navigate("/authenticated-route");
-} else {
- // credential bundle does not match emailed credential
- navigate("/not-authenticated-route");
-}
-```
-
-
-
-
-
-```JavaScript
-const currentUserSession = await turnkey.currentUserSession();
-const walletsResponse = await currentUserSession.getWallets();
-const walletName = walletsResponse.wallets[0].walletName;
-```
-
-
-
-
-
-```JavaScript
-import { DEFAULT_ETHEREUM_ACCOUNTS } from "@turnkey/sdk-browser";
-const newWalletResponse = await iframeClient.createWallet({
- walletName: "New Wallet for User",
- accounts: DEFAULT_ETHEREUM_ACCOUNTS,
-});
-```
-
-
-
diff --git a/embedded-wallets/code-examples/authenticate-user-passkey.mdx b/embedded-wallets/code-examples/authenticate-user-passkey.mdx
deleted file mode 100644
index f0d086b2..00000000
--- a/embedded-wallets/code-examples/authenticate-user-passkey.mdx
+++ /dev/null
@@ -1,53 +0,0 @@
----
-title: "Authenticate a user with a passkey credential"
-mode: wide
----
-> ⚠️ **This example is outdated !**
-> Head over to [SDK Reference](https://docs.turnkey.com/sdks/react/sub-organization-customization) for the updated packages.
-
-
-
-```tsx
-import { Turnkey } from "@turnkey/sdk-browser";
-
-const turnkey = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
-});
-const passkeyClient = turnkey.passkeyClient();
-```
-
-
-
-```tsx
-const response = await passkeyClient.login();
-if (response.organizationId) {
- navigate("/authenticated-route");
-} else {
- navigate("/not-authenticated-route");
-}
-```
-
-
-
-
-```tsx
-const currentUserSession = await turnkey.currentUserSession();
-const walletsResponse = await currentUserSession.getWallets();
-const walletName = walletsResponse.wallets[0].walletName;
-```
-
-
-
-
-This will always prompt a user to confirm the action with their passkey credential
-
-```tsx
-import { DEFAULT_ETHEREUM_ACCOUNTS } from "@turnkey/sdk-browser";
-const newWalletResponse = await passkeyClient.createWallet({
- walletName: "New Wallet for User",
- accounts: DEFAULT_ETHEREUM_ACCOUNTS,
-});
-```
-
-
diff --git a/embedded-wallets/code-examples/create-passkey-session.mdx b/embedded-wallets/code-examples/create-passkey-session.mdx
deleted file mode 100644
index d7459ae0..00000000
--- a/embedded-wallets/code-examples/create-passkey-session.mdx
+++ /dev/null
@@ -1,118 +0,0 @@
----
-title: "Create a user passkey session"
-description: 'A passkey session is an expiring session enabled by an initial passkey authentication. You could think of this as a "lightning mode" of sorts: creating a passkey session allows users to authenticate subsequent requests touch-free. Under the hood, this is powered by our [indexedDbStamper](/sdks/advanced/indexed-db-stamper). These sessions are enabled by creating a short-lived embedded API key in the browser, stored in localStorage, and cryptographically scoped to a public key generated by IndexedDB.'
----
-> ⚠️ **This example is outdated !**
-> Head over to [SDK Reference](https://docs.turnkey.com/generated-docs/formatted/react-wallet-kit/client-context-type-login-with-passkey) for the updated packages.
-
-By calling `loginWithPasskey()`, the SDK stores the session and active client in localStorage. The signing key material remains securely stored in the browser’s IndexedDB and is never extractable. Turnkey uses this public key to scope and encrypt the session to the appropriate user.
-
-## Steps using `@turnkey/sdk-react`
-
-This process is made seamless by leveraging our [React package](/sdks/react). Read on for a non-React implementation below.
-
-
-
-
-```js
-import { TurnkeyProvider } from "@turnkey/sdk-react";
-
-const turnkeyConfig = {
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
- rpId: process.env.RPID,
-};
-
-...
-
-
-
- {/* Your app components */}
-
-
-```
-
-
-
-
-
-```js
-import { useTurnkey } from "@turnkey/sdk-react";
-
-const { passkeyClient, indexedDbClient } = useTurnkey();
-
-await indexedDbClient.init();
-const publicKey = await indexedDbClient.getPublicKey();
-
-await passkeyClient.loginWithPasskey({
- publicKey,
- sessionType: "SESSION_TYPE_READ_WRITE", // or "SESSION_TYPE_READ_ONLY"
- expirationSeconds: 900,
-});
-```
-
-
-
-
-
-```js
-const { getActiveClient } = useTurnkey();
-const client = await getActiveClient();
-
-const whoami = await client.getWhoami({
- organizationId: ,
-});
-```
-
-`getActiveClient()` returns the currently active client (e.g. IndexedDb-backed), refreshing automatically if needed.
-
-
-
-
-## Alternative steps (non-React)
-
-
-
-
-```js
-import { Turnkey } from "@turnkey/sdk-browser";
-
-const turnkey = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
-});
-
-const passkeyClient = turnkey.passkeyClient();
-const indexedDbClient = turnkey.indexedDbClient();
-
-await indexedDbClient.init();
-```
-
-
-
-
-
-```js
-const publicKey = await indexedDbClient.getPublicKey();
-
-await passkeyClient.loginWithPasskey({
- publicKey,
- sessionType: "SESSION_TYPE_READ_WRITE", // or "SESSION_TYPE_READ_ONLY"
- expirationSeconds: 900,
-});
-```
-
-
-
-
-
-```js
-const whoami = await turnkey.getWhoami({
- organizationId: ,
-});
-```
-
-Once `loginWithPasskey` completes, the session is stored in localStorage and all requests are signed using the IndexedDb-backed keypair.
-
-
-
diff --git a/embedded-wallets/code-examples/create-sub-org-passkey.mdx b/embedded-wallets/code-examples/create-sub-org-passkey.mdx
deleted file mode 100644
index 319d8b6e..00000000
--- a/embedded-wallets/code-examples/create-sub-org-passkey.mdx
+++ /dev/null
@@ -1,535 +0,0 @@
----
-title: "Create a sub-org with a passkey user"
-description: "In this guide, we'll walk through the process of creating a new end user with a passkey."
----
-> ⚠️ **This example is outdated !**
-> Head over to [SDK Reference](https://docs.turnkey.com/sdks/react/sub-organization-customization) for the updated packages.
-
-## Overview
-
-Generally, these new users will take the form of a [Turnkey Sub-Organization](/concepts/sub-organizations). This process involves using the following Turnkey SDK packages:
-
-1. [`@turnkey/sdk-server`](https://www.npmjs.com/package/@turnkey/sdk-server): Used on the server-side to leverage the parent organization's public/private API key pair to create the new user's sub-organization.
-2. [`@turnkey/sdk-browser`](https://www.npmjs.com/package/@turnkey/sdk-browser): Used on the client-side to complete the email recovery process by adding an end-user passkey.
-3. [`@turnkey/sdk-react`](https://www.npmjs.com/package/@turnkey/sdk-react): Used for Next.js applications to initialize the Turnkey SDK.
-
-The process of creating a new sub-organization is split between client-side and server-side operations to prevent exposing the parent organization's private API key.
-
-
- For a refresher on the relationship between your application's end users and Turnkey Sub-Organizations, see [this page](/embedded-wallets/overview#how-it-works) for more.
-
-
-## Implementation
-
-### Initialize the Turnkey SDK on the browser
-
-
-
-Wrap the root layout of your application with the `TurnkeyProvider` providing the required configuration options. This allows you to use the Turnkey client throughout your app via the `useTurnkey()` hook.
-```tsx app/layout.tsx
-import { TurnkeyProvider } from "@turnkey/sdk-react";
-
-export default function RootLayout({
- children,
-}: {
- children: React.ReactNode;
-}) {
- return (
-
-
-
- {children}
-
-
-
- );
-}
-```
-
- The `NEXT_PUBLIC_ORGANIZATION_ID` should be set to the parent organization ID which can be found in the [Turnkey Dashboard](https://app.turnkey.com/dashboard).
-
- The `NEXT_PUBLIC_TURNKEY_RP_ID` should be set to your application's desired relying party ID; this is typically your domain, or localhost if developing locally. See [this page](/authentication/passkeys/options#rp) for more details.
-
-
-
-```tsx src/turnkey.ts
-import { Turnkey } from "@turnkey/sdk-browser";
-
-// Initialize the Turnkey SDK with your organization ID and API base URL
-const turnkeyBrowser = new Turnkey({
- rpId: process.env.TURNKEY_RP_ID,
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
-});
-```
-
- The `TURNKEY_ORGANIZATION_ID` should be set to the parent organization ID which can be found in the [Turnkey Dashboard](https://app.turnkey.com/dashboard).
-
- The `TURNKEY_RP_ID` should be set to your application's desired relying party ID; this is typically your domain, or localhost if developing locally. See [this page](/authentication/passkeys/options#rp) for more details.
-
-
-
-
-
-
-### Initialize the Passkey client
-
-Next, we'll initialize the `passkeyClient`, which will enable your application to interact with passkeys.
-
-
-
-We add the `"use client"` directive to the Recovery component to as react hooks can only be used client-side.
-
-```tsx app/create-suborg.tsx
-"use client";
-
-import { useTurnkey } from "@turnkey/sdk-react";
-
-export default function CreateSubOrganization() {
- const { passkeyClient } = useTurnkey();
-
- return
{/* ... rest of the code */}
;
-}
-```
-
-
-
-```tsx src/create-suborg.ts
-import { Turnkey } from "@turnkey/sdk-browser";
-
-// Initialize the Turnkey SDK with your organization credentials
-const turnkey = new Turnkey({
- rpId: process.env.TURNKEY_RP_ID, // Your relying party ID
- apiBaseUrl: process.env.TURNKEY_API_BASE_URL, // Turnkey API base URL
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID, // Your parent organization ID
-});
-
-// Initialize the Passkey Client
-const passkeyClient = turnkey.passkeyClient();
-
-// We'll add more functionality here in the following steps
-```
-
-
-
-### Create user passkey
-
-In order to create a new passkey for a user, you can call the `createUserPasskey` SDK function. Calling this method will prompt the user to create a passkey, which will be securely stored by their browser. This credential will be associated with the user's account (sub-organization) and used for future authentication. Once the credential is created, we'll use it in the next step to create a new sub-organization that corresponds to the user.
-
-
- The result of `createUserPasskey` includes an encoded challenge and attestation. The encoded challenge ensures the request is fresh and legitimate, while the attestation verifies the authenticity of the device creating the credential. For more information on how passkeys work, including details on the challenge and attestation objects, you can refer to the [Passkeys Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API#passkeys).
-
-
-
-
-
-```tsx app/create-suborg.tsx
-// ... previous code
-
-export default function CreateSubOrganization() {
- const { passkeyClient } = useTurnkey();
-
- const createNewPasskey = async () => {
- const credential = await passkeyClient?.createUserPasskey({
- publicKey: {
- // This is the name of the passkey that will be displayed to the user
- rp: {
- name: "Wallet Passkey",
- },
- user: {
- // We can use the username as the name and display name
- name: "Default User Name",
- displayName: "Default User Name",
- },
- },
- });
-
- // we'll use this credential in the next step to create a new sub-organization
- return credential;
- };
-
- // ... rest of the code
-
- return (/* ... */);
-}
-```
-
-
-
-```tsx src/create-suborg.ts
-// ... previous code
-
-const createNewPasskey = async () => {
- const credential = await passkeyClient?.createUserPasskey({
- publicKey: {
- // This is the name of the passkey that will be displayed to the user
- rp: {
- name: "Wallet Passkey",
- },
- user: {
- // We can use the username as the name and display name
- name: "Default User Name",
- displayName: "Default User Name",
- },
- },
- });
-
- // we'll use this credential in the next step to create a new sub-organization
- return credential;
-};
-```
-
-
-
-### Initialize the Turnkey SDK on the server
-
-Initialize the Turnkey SDK on the **server-side** using the `@turnkey/sdk-server` package. This allows you to use the parent organization's public/private API key pair to create sub-organizations.
-
-
-
-
-For Next.js, add the `"use server"` directive at the top of the file where you're initializing the Turnkey server client. This will ensure that the function is executed on the server-side and will have access to the server-side environment variables e.g. your parent organization's public/private API key pair. For more information on Next.js server actions, see the Next.js documentation on [Server Actions and Mutations](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations).
-
-```tsx app/actions.ts
-"use server";
-
-import { Turnkey } from "@turnkey/sdk-server";
-
-// Initialize the Turnkey Server Client on the server-side
-const turnkeyServer = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPrivateKey: process.env.TURNKEY_API_PRIVATE_KEY,
- apiPublicKey: process.env.TURNKEY_API_PUBLIC_KEY,
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
-}).apiClient();
-```
-
-
- ```tsx src/turnkey.ts
- import { Turnkey } from "@turnkey/sdk-server";
-
- // Initialize the Turnkey Server Client on the server-side
- const turnkeyServer = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPrivateKey: process.env.TURNKEY_API_PRIVATE_KEY,
- apiPublicKey: process.env.TURNKEY_API_PUBLIC_KEY,
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
- }).apiClient();
- ```
-
-
-
-### Create a function for sub-org creation
-
-Next we'll create a new function called `createSubOrganization` that will be used to create a new sub-organization from the server-side. This method will be called from the client-side with the end-user's details.
-
-
-
-
-We export the `createSubOrganization` server action to be called from the client-side.
-
-```tsx app/actions.tsx
-import { DEFAULT_ETHEREUM_ACCOUNTS } from "@turnkey/sdk-browser";
-
-// ... previous code
-
-type TAttestation = {
- credentialId: string;
- clientDataJson: string;
- attestationObject: string;
- transports: (
- | "AUTHENTICATOR_TRANSPORT_BLE"
- | "AUTHENTICATOR_TRANSPORT_INTERNAL"
- | "AUTHENTICATOR_TRANSPORT_NFC"
- | "AUTHENTICATOR_TRANSPORT_USB"
- | "AUTHENTICATOR_TRANSPORT_HYBRID"
- )[];
-};
-
-export const createSubOrganization = async (
- email: string,
- credential: string,
- attestation: string,
-) => {
- const createSubOrgResponse = await turnkeyServer.createSubOrganization({
- subOrganizationName: "My New Suborg",
- rootUsers: [
- {
- userName: "Default User Name",
- userEmail: email,
- apiKeys: [],
- authenticators: [
- {
- authenticatorName: "Default Passkey",
- challenge: challenge,
- attestation: attestation,
- },
- ],
- oauthProviders: [],
- },
- ],
- rootQuorumThreshold: 1,
- wallet: {
- walletName: "Default Wallet",
- accounts: DEFAULT_ETHEREUM_ACCOUNTS,
- },
- });
-
- return createSubOrgResponse;
-};
-```
-
-
-```tsx src/turnkey-server.ts
-/// ... previous code
-
-type TAttestation = {
- credentialId: string;
- clientDataJson: string;
- attestationObject: string;
- transports: (
- | "AUTHENTICATOR_TRANSPORT_BLE"
- | "AUTHENTICATOR_TRANSPORT_INTERNAL"
- | "AUTHENTICATOR_TRANSPORT_NFC"
- | "AUTHENTICATOR_TRANSPORT_USB"
- | "AUTHENTICATOR_TRANSPORT_HYBRID"
- )[];
-};
-
-export const createSubOrganization = async (
- email: string,
- credential: string,
- attestation: string,
-) => {
- const createSubOrgResponse = await turnkeyServer.createSubOrganization({
- subOrganizationName: "My New Suborg",
- rootUsers: [
- {
- userName: "Default User Name",
- userEmail: email,
- apiKeys: [],
- authenticators: [
- {
- authenticatorName: "Default Passkey",
- challenge: challenge,
- attestation: attestation,
- },
- ],
- oauthProviders: [],
- },
- ],
- rootQuorumThreshold: 1,
- wallet: {
- walletName: "Default Wallet",
- accounts: DEFAULT_ETHEREUM_ACCOUNTS,
- },
- });
-
- return createSubOrgResponse;
-};
-```
-
-
-
-### Complete create sub-organization
-
-At this stage, we create the sub-organization using the **server-side** function we created in the previous step.
-
-
-
-
-
-
- ```tsx app/create-suborg.tsx
- import { createSubOrganization } from "./actions";
- ```
-
-
-
-
- ```tsx app/create-suborg.tsx
- // ...
-
- import { useForm } from "react-hook-form";
-
- type TSubOrgFormData = {
- email: string;
- };
-
- export default function CreateSubOrganization() {
- // ...
-
- // Use form handler for suborg creation
- const { register: subOrgFormRegister, handleSubmit: subOrgFormSubmit } =
- useForm();
-
- // Maintain state
- const [createSubOrganizationResponse, setCreateSubOrganizationResponse] =
- useState(null);
-
- const createSubOrg = async (data: TSubOrgFormData) => {
- const { encodedChallenge: challenge, attestation } =
- await createNewPasskey();
-
- const createSubOrganizationResponse = await createSubOrganization(
- data.email,
- challenge,
- attestation,
- );
-
- setCreateSubOrganizationResponse(createSubOrganizationResponse);
- };
-
- return (
-
- {createSubOrganizationResponse ? (
-
You've created a sub-organization!
- ) : (
-
- )}
-
- );
- }
- ```
-
- ```tsx
- "use client";
-
- import { useState } from "react";
- import { useTurnkey } from "@turnkey/sdk-react";
- import { useForm } from "react-hook-form";
-
- // Import the createSubOrganization server action
- import { createSubOrganization } from "./actions";
-
- type TSubOrgFormData = {
- email: string;
- };
-
- type TAttestation = {
- credentialId: string;
- clientDataJson: string;
- attestationObject: string;
- transports: (
- | "AUTHENTICATOR_TRANSPORT_BLE"
- | "AUTHENTICATOR_TRANSPORT_INTERNAL"
- | "AUTHENTICATOR_TRANSPORT_NFC"
- | "AUTHENTICATOR_TRANSPORT_USB"
- | "AUTHENTICATOR_TRANSPORT_HYBRID"
- )[];
- };
-
- export default function CreateSubOrganization() {
- const { passkeyClient } = useTurnkey();
-
- // Use form handler for suborg creation
- const { register: subOrgFormRegister, handleSubmit: subOrgFormSubmit } =
- useForm();
-
- // Maintain state
- const [createSubOrganizationResponse, setCreateSubOrganizationResponse] =
- useState(null);
-
- const createNewPasskey = async () => {
- const credential = await passkeyClient?.createUserPasskey({
- publicKey: {
- // This is the name of the passkey that will be displayed to the user
- rp: {
- name: "Wallet Passkey",
- },
- user: {
- // We can use the username as the name and display name
- name: "Default User Name",
- displayName: "Default User Name",
- },
- },
- });
-
- // we'll use this credential in the next step to create a new sub-organization
- return credential;
- };
-
- const createSubOrg = async (data: TSubOrgFormData) => {
- const { encodedChallenge: challenge, attestation } =
- await createNewPasskey();
-
- const createSubOrganizationResponse = await createSubOrganization(
- data.email,
- challenge,
- attestation,
- );
-
- setCreateSubOrganizationResponse(createSubOrganizationResponse);
- };
-
- return (
-
- {createSubOrganizationResponse ? (
-
You've created a sub-organization!
- ) : (
-
- )}
-
- );
- }
- ```
-
-
-
-
-
-
-
-
-
-```tsx app/create-suborg.tsx
-import { createSubOrganization } from "./turnkey-server";
-```
-
-
-
-
-```tsx src/turnkey.ts
-import { createSubOrganization } from "./turnkey-server";
-
-// ... rest of the code
-
-const createSubOrganizationResponse = await createSubOrganization(
- email,
- attestation,
- challenge,
-);
-```
-
-
-
-
-
-## Examples
-
-A few mini examples where sub-orgs are created with passkeys, see the following:
-
-
-
-
-
-
diff --git a/embedded-wallets/code-examples/create-user-email.mdx b/embedded-wallets/code-examples/create-user-email.mdx
deleted file mode 100644
index 867c46a3..00000000
--- a/embedded-wallets/code-examples/create-user-email.mdx
+++ /dev/null
@@ -1,53 +0,0 @@
----
-title: "Create a user with email only"
-description: "This example demonstrates how to create a sub organization using just an end-user's email: passkeys not required! Note that this flow does not require emails to be verified."
-mode: wide
----
-> ⚠️ **This example is outdated !**
-> Head over to [SDK Reference](https://docs.turnkey.com/sdks/react/sub-organization-customization) for the updated packages.
-
-
-
-
-```JavaScript
-import { Turnkey } from "@turnkey/sdk-browser";
-
-const turnkey = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
-});
-```
-
-
-
-
-```JavaScript
-import { DEFAULT_ETHEREUM_ACCOUNTS } from "@turnkey/sdk-browser;"
-
-const subOrganizationConfig = {
- subOrganizationName: ,
- rootUsers: [{
- userName: ,
- userEmail: ,
- apiKeys: [],
- authenticators: [],
- oauthProviders: []
- }],
- rootQuorumThreshold: 1,
- wallet: {
- walletName: ,
- accounts: DEFAULT_ETHEREUM_ACCOUNTS
- }
-};
-```
-
-
-
-
-```JavaScript
-await turnkey.serverSign("createSubOrganization", [subOrganizationConfig]);
-```
-
-This is all that is needed to create a user without any authentication credential other than their email address, in the [login](/embedded-wallets/code-examples/authenticate-user-email) flow you can see how to then authenticate the user after their `subOrganization` is created.
-
-
diff --git a/embedded-wallets/code-examples/email-recovery.mdx b/embedded-wallets/code-examples/email-recovery.mdx
deleted file mode 100644
index 2c9ce666..00000000
--- a/embedded-wallets/code-examples/email-recovery.mdx
+++ /dev/null
@@ -1,669 +0,0 @@
----
-title: "Recover a user with email"
-description: "In this guide, we'll walk through the process of recovering a user using their email."
----
-
-{/* This is an internal note from Traian: email recovery is in maintenance mode, this page should be removed as some point, for now I'm just gonna hide it from the public */}
-
-
- Email Recovery is a legacy flow, now superseded by [Email Auth](/embedded-wallets/code-examples/authenticate-user-email), which can used to implement recovery flows and more.
-
-
-## Overview
-
-This process involves using the following Turnkey SDK packages:
-
-1. [`@turnkey/sdk-server`](https://www.npmjs.com/package/@turnkey/sdk-server): Used on the server-side to leverage the parent organization's public/private API key pair for initializing the email recovery.
-2. [`@turnkey/sdk-browser`](https://www.npmjs.com/package/@turnkey/sdk-browser): Used on the client-side to complete the email recovery process by adding an end-user passkey.
-3. [`@turnkey/sdk-react`](https://www.npmjs.com/package/@turnkey/sdk-react): Used for Next.js applications to initialize the Turnkey SDK.
-
-The email recovery process is split between client-side and server-side operations to prevent exposing the parent organization's private API key.
-
-For an in-depth understanding of the email recovery process at Turnkey, refer to our docs on [email recovery](/authentication/email#recovery-flow).
-
-## Implementation
-
-### Initialize the Turnkey SDKs
-
-Begin by initializing the Turnkey SDK with your organization ID and the Turnkey API's base URL on the **client-side**.
-
-
-
-
-Wrap the root layout of your application with the `TurnkeyProvider` providing the required configuration options. This allows you to use the Turnkey client throughout your app via the `useTurnkey()` hook.
-
-```tsx app/layout.tsx
-import { TurnkeyProvider } from "@turnkey/sdk-react";
-
-export default function RootLayout({
- children,
-}: {
- children: React.ReactNode;
-}) {
- return (
-
-
-
- {children}
-
-
-
- );
-}
-```
-
- The `NEXT_PUBLIC_ORGANIZATION_ID` should be set to the parent organization ID which can be found in the [Turnkey Dashboard](https://app.turnkey.com/dashboard).
-
- The `NEXT_PUBLIC_TURNKEY_RP_ID` should be set to your application's desired relying party ID; this is typically your domain, or localhost if developing locally. See [this page](/authentication/passkeys/options#rp) for more details.
-
-
-
-```tsx src/turnkey.ts
-import { Turnkey } from "@turnkey/sdk-browser";
-
-// Initialize the Turnkey SDK with your organization ID and API base URL
-const turnkeyBrowser = new Turnkey({
- rpId: process.env.TURNKEY_RP_ID,
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
-});
-```
-
- The `TURNKEY_ORGANIZATION_ID` should be set to the parent organization ID which can be found in the [Turnkey Dashboard](https://app.turnkey.com/dashboard).
-
- The `TURNKEY_RP_ID` should be set to your application's desired relying party ID; this is typically your domain, or localhost if developing locally. See [this page](/authentication/passkeys/options#rp) for more details.
-
-
-
-
-
-#### Server-side initialization
-
-Initialize the Turnkey SDK on the **server-side** using the `@turnkey/sdk-server` package. This allows you to use the parent organization's public/private API key pair to initialize the email recovery process securely.
-
-
-
-For Next.js, add the `"use server"` directive at the top of the file where you're initializing the Turnkey server client. This will ensure that the function is executed on the server-side and will have access to the server-side environment variables e.g. your parent organization's public/private API key pair. For more information on Next.js server actions, see the Next.js documentation on [Server Actions and Mutations](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations).
-
-```tsx app/actions.ts
-"use server";
-
-import { Turnkey } from "@turnkey/sdk-server";
-
-// Initialize the Turnkey Server Client on the server-side
-const turnkeyServer = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPrivateKey: process.env.TURNKEY_API_PRIVATE_KEY,
- apiPublicKey: process.env.TURNKEY_API_PUBLIC_KEY,
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
-}).apiClient();
-```
-
-
-
-```tsx src/turnkey.ts
-import { Turnkey } from "@turnkey/sdk-server";
-
-// Initialize the Turnkey Server Client on the server-side
-const turnkeyServer = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPrivateKey: process.env.TURNKEY_API_PRIVATE_KEY,
- apiPublicKey: process.env.TURNKEY_API_PUBLIC_KEY,
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
-}).apiClient();
-```
-
-
-
-#### Initialize the iframe client
-
-Next, we'll initialize the `iframeClient` which will create a secure iframe within your application. The `iframeClient` must be initialized before beginning the user recovery process, as we'll need the iframe's public key as a parameter for the `initEmailRecovery` method.
-
-
-
-
-We add the `"use client"` directive to the Recovery component to as react hooks can only be used client-side.
-
-```tsx app/recovery.tsx
-"use client";
-
-import { useTurnkey } from "@turnkey/sdk-react";
-
-export default function Recovery() {
- const { authIframeClient } = useTurnkey();
-
- return
{/* ... rest of the code */}
;
-}
-```
-
-
-
-```ts src/turnkey.ts
-const iframeContainerId = "turnkey-recovery-iframe-container-id";
-
-const authIframeClient = await turnkey.iframeClient(
- document.getElementById(iframeContainerId),
-);
-```
-
-When using the TypeScript SDK, you'll need to ensure that the HTML element exists somewhere in the rendered DOM.
-
-
-
-```html index.html
-
-```
-
-
-
-### Create a recovery function
-
-Next we'll create a new function called `initEmailRecovery` that will be used to initialize the email recovery process on the server-side. This method will be called from the client-side with the user's email and the target public key from the iframe client. Calling the `initEmailRecovery` method will trigger an email sent to the user containing a credential bundle which will be used to authenticate the authIframeClient in the next step.
-
-
-
-
-We export the `initEmailRecovery` server action to be called from the client-side.
-
-```tsx app/actions.ts
-// ... previous code
-
-export const initEmailRecovery = async ({
- email,
- targetPublicKey,
-}: {
- email: string;
- targetPublicKey: string;
-}) => {
- const recoveryResponse = await turnkeyServer.initUserEmailRecovery({
- email,
- targetPublicKey,
- });
- return recoveryResponse;
-};
-```
-
-
-
-```tsx src/turnkey-server.ts
-export const initEmailRecovery = async ({
- email,
- targetPublicKey,
-}: {
- email: string;
- targetPublicKey: string;
-}) => {
- const recoveryResponse = await turnkeyServer.initUserEmailRecovery({
- email,
- targetPublicKey,
- });
- return recoveryResponse;
-};
-```
-
-
-
-### Initialize email recovery
-
-At this stage, we initialize the email recovery process using the **server-side** function we created in the previous step. The user will need to paste the credential bundle they receive in their email into your app, which is then used to authenticate the `authIframeClient` via the `injectCredentialBundle` method.
-
-
-
-
-
-
-```tsx app/recovery.tsx
-import { initEmailRecovery } from "./actions";
-```
-
-
-
-
-```tsx app/recovery.tsx
-// ...
-
-export default function Recovery() {
- // ...
-
- // Create a state variable for the user's email
- const [email, setEmail] = useState("");
-
- return (
-
- setEmail(e.target.value)}
- type="text"
- />
-
- );
-}
-```
-
-
-
-
-```tsx app/recovery.tsx
-//...
-
-export default function Recovery() {
- // ...
-
- // We'll use this later to conditionally render the input for the credential bundle
- const [initRecoveryResponse, setInitRecoveryResponse] = useState(null);
-
- const initRecovery = async (email: string) => {
- // Call the initEmailRecovery server action
- const response = await initEmailRecovery({
- email,
- targetPublicKey: authIframeClient?.iframePublicKey,
- });
- if (response) {
- setInitRecoveryResponse(response);
- }
- };
-
- return (
-
- {/* If we have initiated the recovery process we'll render an input
- for the user to paste their credential bundle they received in their email */}
- {initRecoveryResponse ? (
- setCredentialBundle(e.target.value)}
- type="text"
- />
- ) : (
- setEmail(e.target.value)}
- type="text"
- />
- )}
-
-
- );
-}
-```
-
-
-```ts
-"use client";
-
-import { useState } from "react";
-import { useTurnkey } from "@turnkey/sdk-react";
-
-// Import the initEmailRecovery server action
-import { initEmailRecovery } from "./actions";
-
-export default function Recovery() {
- const { authIframeClient } = useTurnkey();
-
- // Create a state variable for the user's email
- const [email, setEmail] = useState("");
- const [initRecoveryResponse, setInitRecoveryResponse] = useState(null);
- const [credentialBundle, setCredentialBundle] = useState("");
-
- const initRecovery = async (email: string) => {
- // Call the initEmailRecovery server action
- const response = await initEmailRecovery({
- email,
- targetPublicKey: authIframeClient?.iframePublicKey,
- });
- if (response) {
- setInitRecoveryResponse(response);
- }
- };
-
- return (
-
- {/* If we have initiated the recovery process we'll render an input
- for the user to paste their credential bundle they received in their email */}
- {initRecoveryResponse ? (
- setCredentialBundle(e.target.value)}
- type="text"
- />
- ) : (
- setEmail(e.target.value)}
- type="text"
- />
- )}
-
-
- );
-}
- ```
-
-
-
-
-
-
-```tsx src/turnkey.ts
-import { initEmailRecovery } from "./turnkey-server";
-
-// ... rest of the code
-
-const initRecoveryResponse = await initEmailRecovery({
- email,
- targetPublicKey: authIframeClient?.iframePublicKey,
-});
-
-// Inject the recovery bundle into the iframe client
-// The recovery bundle is the credential bundle that the user will receive in their email
-// The application will need to provide a way for the user to input this recovery bundle
-// by pasting it into the UI
-await authIframeClient.injectCredentialBundle(credentialBundle);
-```
-
-
-
-### Create user passkey
-
-Next, we'll create a new passkey for the user and associate it with the email that was used in the recovery process. Assuming that the user has successfully received and entered their credential bundle, we generate a passkey to be used authenticate Turnkey requests.
-
-
-
-
-
-
-We'll add a new function called `completeRecovery` that will create a new passkey for the user which will be used in the final recovery step.
-
-```ts app/recovery.tsx
-//...export default function Recovery() { //... // We'll use //...
-
-export default function Recovery() {
- //...
-
- // We'll use the useTurnkey hook to get the turnkey instance
- const { authIframeClient, turnkey } = useTurnkey();
-
- const completeRecovery = async () => {
- const passkeyClient = await turnkey.passkeyClient();
-
- const passkeyResponse = await passkeyClient?.createUserPasskey({
- publicKey: {
- user: {
- name: email,
- displayName: email,
- },
- },
- });
- };
-
- return
- {/* ... */}
-
- {/* If we have the credential bundle, we'll render a button to complete the recovery process */}
- {credentialBundle ? (
-
- ) : (
-
- )}
-
- );
-}
-```
-
-
-
-
-
-```ts src/turnkey.ts
-const completeRecovery = async () => {
- const passkeyClient = await turnkey.passkeyClient();
-
- const passkeyResponse = await passkeyClient?.createUserPasskey({
- publicKey: {
- user: {
- name: email,
- displayName: email,
- },
- },
- });
-};
-```
-
-
-
-### Complete email recovery
-
-Finally, we complete the email recovery process by passing the `encodedChallenge` and `attestation` from the passkey we previously created to the `recoverUser` method. This method will complete the email recovery process and if successful, will return a response containing the authenticator ID of the new passkey authenticator.
-
-
-
-
-
-```ts app/recovery.tsx
-
-//...
-
-export default function Recovery() {
- // We'll use the useTurnkey hook to get the turnkey instance
- const { authIframeClient, turnkey } = useTurnkey();
-
- const [initRecoveryResponse, setInitRecoveryResponse] = useState(null);
-
- const completeRecovery = async () => {
- const passkeyClient = await turnkey.passkeyClient();
-
- const passkeyResponse = await passkeyClient?.createUserPasskey({
- publicKey: {
- user: {
- name: email,
- displayName: email,
- },
- },
- });
-
- // If we have the encodedChallenge and attestation, we can complete the recovery process
- if (passkeyResponse?.encodedChallenge && passkeyResponse?.attestation) {
- const response = await authIframeClient!.recoverUser({
- organizationId: initRecoveryResponse?.activity.organizationId,
- userId: initRecoveryResponse.userId,
- authenticator: {
- // This should be set by the user to name their authenticator
- authenticatorName: "User Passkey",
- challenge: passkeyResponse.encodedChallenge,
- attestation: passkeyResponse.attestation,
- },
- });
- if (response) {
- console.log("User recovered successfully");
- }
- }
- };
-
- return (
-
- {/* ... */}
-
- {/* If we have the credential bundle, we'll render a button to complete the recovery process */}
- {credentialBundle ? (
-
- ) : (
-
- )}
-
- );
-}
-```
-
-
-```ts app/recovery.tsx
-"use client";
-
-import { useState } from "react";
-import { useTurnkey } from "@turnkey/sdk-react";
-
-// Import the initEmailRecovery server action
-import { initEmailRecovery } from "./actions";
-
-export default function Recovery() {
- const { authIframeClient, turnkey } = useTurnkey();
-
- // Create a state variable for the user's email
- const [email, setEmail] = useState("");
- const [initRecoveryResponse, setInitRecoveryResponse] = useState(null);
- const [credentialBundle, setCredentialBundle] = useState("");
-
- const initRecovery = async (email: string) => {
- // Call the initEmailRecovery server action
- const response = await initEmailRecovery({
- email,
- targetPublicKey: authIframeClient?.iframePublicKey,
- });
- if (response) {
- setInitRecoveryResponse(response);
- }
- };
-
- const completeRecovery = async () => {
- const passkeyClient = await turnkey.passkeyClient();
-
- const passkeyResponse = await passkeyClient?.createUserPasskey({
- publicKey: {
- user: {
- name: email,
- displayName: email,
- },
- },
- });
-
- // If we have the encodedChallenge and attestation, we can complete the recovery process
- if (passkeyResponse?.encodedChallenge && passkeyResponse?.attestation) {
- const response = await authIframeClient!.recoverUser({
- organizationId: initRecoveryResponse?.activity.organizationId,
- userId: initRecoveryResponse.userId,
- authenticator: {
- // This should be set by the user to name their authenticator
- authenticatorName: "User Passkey",
- challenge: passkeyResponse.encodedChallenge,
- attestation: passkeyResponse.attestation,
- },
- });
- if (response) {
- console.log("User recovered successfully");
- }
- }
- };
-
- return (
-
- );
-}
- ```
-
-
-
-
-
-```ts src/turnkey.ts
-const completeRecovery = async () => {
- const passkeyClient = await turnkey.passkeyClient();
-
- const passkeyResponse = await passkeyClient?.createUserPasskey({
- publicKey: {
- user: {
- name: email,
- displayName: email,
- },
- },
- });
-
- // If we have the encodedChallenge and attestation, we can complete the recovery process
- if (passkeyResponse?.encodedChallenge && passkeyResponse?.attestation) {
- const response = await authIframeClient!.recoverUser({
- organizationId: initRecoveryResponse?.activity.organizationId,
- userId: initRecoveryResponse.userId,
- authenticator: {
- // This should be set by the user to name their authenticator
- authenticatorName: "User Passkey",
- challenge: passkeyResponse.encodedChallenge,
- attestation: passkeyResponse.attestation,
- },
- });
- if (response) {
- console.log("User recovered successfully");
- }
- }
-};
-```
-
-
-
-## Conclusion
-
-In this guide, we've walked through the process of recovering a user using their email using the Turnkey SDKs. By following these steps, you can implement email recovery in your application, providing users with a reliable way to regain access to their accounts or to onboard new users using only their email address.
-To remind, this is a legacy flow, if you intend to implement a fresh recovery mechanism please use [Email Auth](/embedded-wallets/code-examples/authenticate-user-email), which supports all activities, including adding new authenticators.
diff --git a/embedded-wallets/code-examples/embedded-consumer-wallet.mdx b/embedded-wallets/code-examples/embedded-consumer-wallet.mdx
deleted file mode 100644
index 0b04d528..00000000
--- a/embedded-wallets/code-examples/embedded-consumer-wallet.mdx
+++ /dev/null
@@ -1,241 +0,0 @@
----
-title: "Embedded Consumer Wallet"
-description:
- "Turnkey provides wallet infrastructure with flexible authentication, programmable transaction
- flows, and granular access controls, while keys remain in hardware-backed enclaves. Start with the
- Embedded Wallet Kit and drop down to low-level primitives when you need to customize. "
----
-
-**Why Turnkey for Embedded Consumer Wallets**\
-Turnkey delivers a secure, flexible solution for embedding end-user wallets directly into your
-application. Users sign in with familiar methods (passkeys, email, OAuth), without seed phrases,
-browser extensions, or external wallets. Turnkey lets you compose your app's core experiences
-(onboarding, wallet flows, and transactions) with full control, without restricting critical product
-decisions to pre-built flows. Keys stay inside hardware-backed Trusted Execution Environments
-[(TEEs)](/security/secure-enclaves), ensuring private keys are never exposed to your developers or
-to Turnkey.
-
-You can use the [Embedded Wallet Kit](/reference/embedded-wallet-kit) for fast integration, or
-[Turnkey SDKs](/sdks/introduction) and the [API](/api-reference/overview) for more customization.
-Leading apps like
-[Moonshot](https://www.turnkey.com/customers/how-moonshot-powers-millions-of-self-custodial-wallets-using-turnkey),
-[Infinex](https://www.turnkey.com/customers/making-onchain-ux-seamless-with-infinex-and-turnkey),
-and [Axiom](https://www.turnkey.com/customers/axiom-global-defi-trading-platform) use Turnkey for
-embedded consumer wallets in production.
-
-## Key implementation decisions
-
-Turnkey enables developers to tailor non-custodial, embedded user wallets across dimensions such as
-custody model, authentication, and more. See the key implementation decisions below to curate the
-exact user experience you need. For a full map of embedded wallet capabilities, see the
-[Features overview](/embedded-wallets/features/overview).
-
-| Decision | Explanation | Learn more |
-| :------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| **Custody model** | Determine the appropriate custody model for your app. Options include user-controlled, app-controlled, or delegated/hybrid. Configure via policies and sub-organization settings. | [Delegated Access](/concepts/policies/delegated-access-frontend), [Sub-Organization Customization](/sdks/react/sub-organization-customization) |
-| **Authentication methods** | Choose user auth methods: Passkeys, OAuth/email, or SMS. You can use the [Auth Proxy](/reference/auth-proxy) for backend-signed OTP/OAuth/signup without your own backend, or wire auth to your app. | [Authentication Overview](/authentication/overview), [Auth Proxy](/reference/auth-proxy) |
-| **Session management** | Allow a user to take multiple, contiguous actions in a defined period of time. Actions include: Read-write or read-only. | [Sessions](/authentication/sessions) |
-| **Wallet architecture** | Choose between key-based (HD) or smart contract wallets for your users. Turnkey supports both. | [Wallets Concept](/concepts/wallets), [Transaction Management](/concepts/transaction-management) |
-| **Gas sponsorship** | Integrate a gasless UX via sponsored transactions to cover who pays gas and how transactions are broadcast. | [Transaction Management](/concepts/transaction-management), [Sending sponsored transactions](/embedded-wallets/code-examples/sending-sponsored-transactions) |
-| **Key portability** | Determine whether users can import or export keys. | [Import/Export](https://docs.turnkey.com/sdks/react/using-embedded-wallets#importing-and-exporting-wallets) |
-
-### Custody model
-
-Choose how much control users and your app have over signing:
-
-| Model | Description | Why choose this? |
-| :--------------------- | :----------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| **User-controlled** | Only the user can authorize actions (self-custody). | **Full Sovereignty**: Best for non-custodial apps where users require exclusive signing authority via their own authenticators (e.g., passkeys). |
-| **App-controlled** | Your backend can authorize actions (automation, trading, subscriptions). | **Seamless Automation:** Ideal for custodial products like trading bots or subscriptions that require acting on a user's behalf without manual approval. |
-| **Delegated / hybrid** | Scoped permissions shared between user and backend. | **Frictionless UX:** Enables background actions (e.g., gas sponsorship or scheduled ops) while keeping the user in final control of asset transfers. |
-
-Configure via [policies](/concepts/policies/quickstart)
-and[ sub-organization settings](/sdks/react/sub-organization-customization). See
-[Delegated Access](/concepts/policies/delegated-access-frontend) for non-custodial, hybrid, and
-app-controlled options.
-
-### Authentication
-
-Balance security and friction for your audience:
-
-- **Passkeys:** Phishing-resistant, biometric. See
- [passkey authentication](/authentication/overview).
-- **OAuth / email:** Familiar, low-friction. See
- [Authentication Overview](/authentication/overview).
-- **SMS:** Market-dependent; consider risk and compliance.
-
-Turnkey authentication plugs into your onboarding flow. You can use the
-[Auth Proxy](/reference/auth-proxy) when you want backend-signed OTP/OAuth/signup with origin
-enforcement and central config without hosting your own backend; your frontend calls Auth Proxy
-endpoints directly. Alternatively, wire auth to your app. Get started with the
-[Embedded Wallets Quickstart](/sdks/react/index).
-
-### Session management
-
-Choose how users stay authorized and where session credentials live:
-
-- **Read-write vs read-only:** Read-write sessions (OTP, OAuth, passkey sessions) let users perform
- multiple signed actions in a time window. Read-only sessions suit low-touch apps where you mainly
- need to read data (e.g., via parent-org access or a read-only session token).
-- **Storage:** IndexedDB (web) for persistent, client-held sessions without exposing keys to your
- JavaScript; SecureStorage (mobile); or LocalStorage (keys in app-accessible storage).
-- **Session duration:** Default: 15 minutes (configurable via `expirationSeconds`).
-
-See [Sessions](/authentication/sessions) for mechanisms, refresh, and FAQ, and the
-[Embedded Wallets Quickstart](/sdks/react/index) for configuration.
-
-### Wallet architecture
-
-Choose where keys are generated and how wallets interact with the blockchain.
-
-| Approach | Pros | Considerations |
-| :------------------------- | :----------------------------------------------------------- | :----------------------------------------------- |
-| **Key-based (HD wallets)** | Chain-agnostic, no on-chain deployment, broad compatibility. | Standard derivation and signing. |
-| **Smart contract wallets** | Gas sponsorship, batching, advanced permissions. | Requires on-chain deployment and infrastructure. |
-
-Turnkey supports both. See [Wallets Concept](/concepts/wallets) and
-[Transaction Management](/concepts/transaction-management) for derivation and gas sponsorship.
-
-### Gas sponsorship
-
-Provide gasless UX by sponsoring gas for your users. Turnkey supports sponsored transactions and
-relay integration so users can sign and send without holding native tokens.
-
-See [Transaction Management](/concepts/transaction-management) for gas sponsorship, transaction
-construction, broadcast, nonce management and monitoring capabilities.
-
-### Key portability
-
-Enable key portability and define whether users can import or export private keys. Enabling export
-can support user sovereignty and long-term trust. See
-[Import/Export wallets](https://docs.turnkey.com/sdks/react/using-embedded-wallets#importing-and-exporting-wallets).
-
-## Core security principles
-
-Embedded consumer wallet with Turnkey is built on these key principles:
-
-- **Keys never leave the enclave:** Private keys live in
- [Trusted Execution Environments (TEEs)](/security/secure-enclaves). All derivation and signing
- happen inside verifiable infrastructure; only signatures are returned.
- [Remote attestation](https://whitepaper.turnkey.com/architecture) lets you verify enclave
- integrity. Raw keys are never exposed to your app or to Turnkey.
-- **Authenticator-bound requests:** Every sensitive operation is signed by a user-held authenticator
- (passkey, email, etc.). The enclave verifies the signature and then performs the operation. No
- request, no signing; a compromise outside the enclave cannot move funds. See
- [Authentication Overview](/authentication/overview) for supported methods and
- [Enclave to end-user secure channel](/security/enclave-secure-channels) for how requests are
- verified.
-- **Scoped, programmable control:** Choose non-custodial, hybrid, or app-controlled custody.
- [Policies](/concepts/policies/quickstart) and sub-organization isolation limit who can sign what.
-- **Trusted vs. untrusted separation:** Verification and execution run only inside secure enclaves.
- Trusted and untrusted infrastructure are strictly separated so that a breach of your app or
- backend does not expose keys or signing capability.
-
-## Architecture at a glance
-
-User authentication flows into a signed request to Turnkey. Inside the enclave, the
-[policy engine](/concepts/policies/overview) evaluates the request; key derivation and signing
-follow, and only the signature is returned. Your app can then broadcast the transaction through
-another provider or with
-[Turnkey Transaction Management](https://docs.turnkey.com/concepts/transaction-management#construction-and-broadcast).
-For data flow and infrastructure details, see
-[Embedded Wallets overview](/embedded-wallets/overview) and
-[Secure enclaves](/security/secure-enclaves).
-
-
- 
-
-
-## Example: Neobank-style embedded consumer wallet
-
-Typical requirements and how Turnkey addresses them:
-
-| Requirement | Turnkey capability |
-| :-------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| Seamless onboarding | Automated provisioning via [Quickstart](/sdks/react/getting-started) and [SDKs](/sdks/introduction) |
-| User custody without key exposure | Keys remain in [secure enclaves](/security/secure-enclaves); only signatures are returned |
-| Gasless UX | [Sponsored transactions](/concepts/transaction-management) and [sending sponsored transactions](/embedded-wallets/code-examples/sending-sponsored-transactions) |
-| Email-based auth and recovery | [Sub-organization recovery](/embedded-wallets/sub-organization-recovery) |
-| Send without wallet setup | [Claim links](/wallets/claim-links#claim-links): send via URL; recipient claims with email |
-| Backend automation | [Delegated access](/concepts/policies/delegated-access-backend) and scoped signing policies |
-| Multichain support | Chain-agnostic derivation and signing; [Networks](/networks/overview) and [Wallets Concept](/concepts/wallets) |
-| Fast integration | [Code Examples Hub](/category/code-examples) and [SDKs](/sdks/introduction) |
-
-## Setting up your embedded consumer wallet
-
-Follow these steps to launch an embedded consumer wallet experience inside your app.
-
-
-
- Create an organization in the [Turnkey Dashboard](https://app.turnkey.com) and choose how end users authenticate (Email OTP, Passkeys, OAuth).
-
- **Docs**
-
- - [Account setup (create org)](https://docs.turnkey.com/getting-started/quickstart)
- - [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.
-
- **Docs**
-
- - [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:
-
- - The user is authenticated
- - The Turnkey client is initialized
-
- **Docs**
-
- - [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:**
-
- 1. Create a sub-organization
- 2. Create a wallet
- 3. Create required accounts (e.g., Ethereum, Solana)
-
- **Docs**
-
- - [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.
-
- **Signing Docs**
-
- - [Sign message](/sdks/react/signing)
- - [Sign transaction](https://docs.turnkey.com/sdks/react/signing#signing-transactions)
- - [Sign & send transaction](/embedded-wallets/code-examples/sending-sponsored-transactions)
-
- **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).
-
-
- 
-
diff --git a/embedded-wallets/code-examples/export.mdx b/embedded-wallets/code-examples/export.mdx
deleted file mode 100644
index ccef5a35..00000000
--- a/embedded-wallets/code-examples/export.mdx
+++ /dev/null
@@ -1,744 +0,0 @@
----
-title: "Export wallet or private key"
-description: "This is a guide to exporting your wallet or private key from Turnkey. For more information about the security of this flow, check out [Enclave secure channels](/security/enclave-secure-channels)."
----
-> ⚠️ **This example is outdated !**
-> Head over to [SDK Reference](/sdks/react/using-embedded-wallets#importing-and-exporting-wallets) for the updated packages.
-
-## Implementation guides
-
-Follow along with the Turnkey CLI, Embedded iframe, NodeJS, and Local Storage guides.
-
-### CLI
-
-Install the latest version of Turnkey CLI to access the new import functionality. You can find detailed instructions for installation [here](https://github.com/tkhq/tkcli).
-
-#### Steps
-
-
-
-
-```bash
-turnkey wallets export --name "New Wallet" -k --organization --export-bundle-output --host api.turnkey.com
-```
-
-- The `--export-bundle-output` flag (required) is the desired output file path for the “encrypted bundle” that will be returned by Turnkey. This bundle contains the encrypted key material.
-
-
-
-
-
-```bash
-turnkey decrypt --export-bundle-input --organization --signer-quorum-key 04bce6666ca6c12e0e00a503a52c301319687dca588165b551d369496bd1189235bd8302ae5e001fde51d1e22baa1d44249f2de9705c63797316fc8b7e3969a665 --encryption-key-name
-
->> ""
-```
-
-- The `--export-bundle-input` flag (required) is the filepath for the “encrypted bundle” (from the previous step) that will be decrypted.
-- The `--plaintext-output` flag (optional) is a filepath for the decrypted plaintext to be written to.
-- The `--signer-quorum-key` flag (optional) is the public key of Turnkey's signer enclave. This is a static value.
-- The `--encryption-key-name` flag (optional) is a local encryption key. This is required for import and export using the CLI. A new one can be generated using `turnkey generate encryption-key`. See `turnkey generate --help` for more details.
-
-Congrats! You've exported your wallet 🎉
-
-
-
-
-#### Private key support
-
-
-
-
-```bash
-turnkey private-keys export --name "New Private Key" --encryption-key-name --organization --export-bundle-output --host api.turnkey.com
-```
-
-- The `--export-bundle-output` flag (required) is the desired output file path for the “encrypted bundle” that will be returned by Turnkey. This bundle contains the encrypted key material.
-
-
-
-
-
-```bash
-turnkey decrypt --export-bundle-input --organization --signer-quorum-key 04bce6666ca6c12e0e00a503a52c301319687dca588165b551d369496bd1189235bd8302ae5e001fde51d1e22baa1d44249f2de9705c63797316fc8b7e3969a665 --encryption-key-name
-
->> ""
-```
-
-- The `--export-bundle-input` flag (required) is the file path for the “encrypted bundle” (from the previous step) that will be decrypted.
-- The `--plaintext-output` flag (optional) is a filepath for the decrypted plaintext to be written to.
-- The `--signer-quorum-key` flag (optional) is the public key of Turnkey's signer enclave. This is a static value.
-- The `--solana-address` flag (optional) is the solana address corresponding to the private key you're exporting. This will export the private key in a format compatible with most solana wallets (e.g. phantom). If unset, the resulting private key will be plain hex.
-- The `--encryption-key-name` flag (optional) is a local encryption key. This is required for import and export using the CLI. A new one can be generated using `turnkey generate encryption-key`. See `turnkey generate --help` for more details.
-
-Congrats! You've exported your private key 🎉
-
-
-
-
-#### Wallet account support
-
-
-
-
-```bash
-turnkey wallets accounts export --address "" -k --organization --export-bundle-output --host api.turnkey.com
-```
-
-- The `--export-bundle-output` flag (required) is the desired output file path for the “encrypted bundle” that will be returned by Turnkey. This bundle contains the encrypted key material.
-
-
-
-
-
-```bash
-turnkey decrypt --export-bundle-input --organization --signer-quorum-key 04bce6666ca6c12e0e00a503a52c301319687dca588165b551d369496bd1189235bd8302ae5e001fde51d1e22baa1d44249f2de9705c63797316fc8b7e3969a665 --encryption-key-name
-
->> ""
-```
-
-- The `--export-bundle-input` flag (required) is the file path for the “encrypted bundle” (from the previous step) that will be decrypted.
-- The `--plaintext-output` flag (optional) is a filepath for the decrypted plaintext to be written to.
-- The `--signer-quorum-key` flag (optional) is the public key of Turnkey's signer enclave. This is a static value.
-- The `--solana-address` flag (optional) is the solana address corresponding to the private key you're exporting. This will export the private key in a format compatible with most solana wallets (e.g. phantom). If unset, the resulting private key will be plain hex.
-- The `--encryption-key-name` flag (optional) is a local encryption key. This is required for import and export using the CLI. A new one can be generated using `turnkey generate encryption-key`. See `turnkey generate --help` for more details.
-
-Congrats! You've exported your private key 🎉
-
-
-
-
-### Embedded iframe
-
-- We have released open-source code to create target encryption keys and decrypt exported wallet mnemonics. We've deployed a static HTML page hosted on `export.turnkey.com` meant to be embedded as an iframe element (see the code [here](https://github.com/tkhq/frames)). This ensures the mnemonics are encrypted to keys that the user has access to, but that your organization does not (because they live in the iframe, on a separate domain).
-- We have also built a package to help you insert this iframe and interact with it in the context of export: [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper)
-
-In the rest of this guide we'll assume you are using these helpers.
-
-#### Steps
-
-Here's a diagram summarizing the wallet export flow step-by-step
-([direct link](/assets/files/wallet_export_steps-5bb19c72eb9596fab8db3b1dcc52e60a.png)):
-
-
-
-
-
-Let's review these steps in detail:
-
-
-
- When a user on your application clicks "export", display a new export UI. We recommend setting this export UI as a new hosted page of your application that contains language explaining the security best practices users should follow once they've successfully exported their wallet. Remember: once the wallet has been exported, Turnkey can no longer ensure its security.
-
-While the UI is in a loading state, your application uses [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper) to insert a new iframe element:
-
-```ts
-const iframeStamper = new IframeStamper({
-iframeUrl: "https://export.turnkey.com",
-// Configure how the iframe element is inserted on the page
-iframeContainer: yourContainer,
-iframeElementId: "turnkey-iframe",
-});
-
-// Inserts the iframe in the DOM. This creates the new encryption target key
-const publicKey = await iframeStamper.init();
-
-// Set state to not display iframe
-let displayIframe = "none";
-
-return (
-// The iframe element can be hidden until the wallet is exported
-
-);
-```
-
-
-
-
- Your code receives the iframe public key. Your application prompts the user to
- sign a new `EXPORT_WALLET` activity with the wallet ID and the iframe public
- key in the parameters.
-
-
-
-Your application polls for the activity response, which contains an export bundle. Remember: this export bundle is an encrypted mnemonic which can only be decrypted within the iframe.
-
-Need help setting up async polling? Checkout our guide and helper [here](https://github.com/tkhq/sdk/tree/main/packages/http#withasyncpolling-helper).
-
-
-
-
-Your application injects the export bundle into the iframe for decryption and displays the iframe upon success:
-
-```ts
-// Inject export bundle into iframe
-let success = await iframeStamper.injectWalletExportBundle(exportBundle);
-
-if (success !== true) {
- throw new Error("unexpected error while injecting export bundle");
-}
-
-// If successfully injected, update the state to display the iframe
-iframeDisplay = "block";
-```
-
-Export is complete! The iframe now displays a sentence of words separated by spaces.
-
-
-
-
-
-The exported wallet will remain stored within Turnkey’s infrastructure. In your Turnkey dashboard, the exported user Wallet will be flagged as “Exported”.
-
-
-
-
-#### Export as private keys
-
-Turnkey also supports exporting Wallet Accounts and Private Keys as private keys.
-
-##### Wallet Accounts
-
-Follow the same steps above for exporting Wallets as mnemonics, but instead use the `EXPORT_WALLET_ACCOUNT` activity and the `injectKeyExportBundle` method from the [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper). You can pass an optional `keyFormat` parameter to `injectKeyExportBundle()` that will apply either hexadecimal or Solana-specific formatting to the private key that is exported in the iframe. The default key format is `HEXADECIMAL`, which is used by MetaMask, MyEtherWallet, Phantom, Ledger, and Trezor for Ethereum keys. For Solana keys, you will need to pass the `SOLANA` key format.
-
-##### Private Keys
-
-Follow the same steps above for exporting Wallets as mnemonics, but instead use the `EXPORT_PRIVATE_KEY` activity and the `injectKeyExportBundle` method from the [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper). You can pass an optional `keyFormat` parameter to `injectKeyExportBundle()` that will apply either hexadecimal or Solana-specific formatting to the private key that is exported in the iframe. The default key format is `HEXADECIMAL`, which is used by MetaMask, MyEtherWallet, Phantom, Ledger, and Trezor for Ethereum keys. For Solana keys, you will need to pass the `SOLANA` key format.
-
-
-
-
-
-At the end of a successful private key export, the iframe displays a private key.
-
-### NodeJS
-
-A full example Node script can be found here: [https://github.com/tkhq/sdk/tree/main/examples/export-in-node](https://github.com/tkhq/sdk/tree/main/examples/export-in-node)
-
-#### Steps
-
-
-
-
-```ts
-import { Turnkey } from "@turnkey/sdk-server";
-import { generateP256KeyPair, decryptExportBundle } from "@turnkey/crypto";
-
-...
-
-const turnkeyClient = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPublicKey: process.env.API_PUBLIC_KEY!,
- apiPrivateKey: process.env.API_PRIVATE_KEY!,
- defaultOrganizationId: process.env.ORGANIZATION_ID!,
- });
-```
-
-
-
-
-
-```ts
-const keyPair = generateP256KeyPair();
-const privateKey = keyPair.privateKey;
-const publicKey = keyPair.publicKeyUncompressed;
-```
-
-
-
-
-
-```ts
-const exportResult = await turnkeyClient.apiClient().exportWallet({
- walletId: walletId,
- targetPublicKey: publicKey,
-});
-```
-
-
-
-
-
-```ts
-const decryptedBundle = await decryptExportBundle({
- exportBundle: exportResult.exportBundle,
- embeddedKey: privateKey,
- organizationId,
- returnMnemonic: true,
-});
-```
-
-Congrats! You've exported your wallet 🎉
-
-The process is largely similar for both private keys and individual wallet accounts.
-
-
-
-
-#### Private key support
-
-
-
-
-```ts
-import { Turnkey } from "@turnkey/sdk-server";
-import { generateP256KeyPair, decryptExportBundle } from "@turnkey/crypto";
-
-...
-
-const turnkeyClient = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPublicKey: process.env.API_PUBLIC_KEY!,
- apiPrivateKey: process.env.API_PRIVATE_KEY!,
- defaultOrganizationId: process.env.ORGANIZATION_ID!,
- });
-```
-
-
-
-
-
-```ts
-const keyPair = generateP256KeyPair();
-const privateKey = keyPair.privateKey;
-const publicKey = keyPair.publicKeyUncompressed;
-```
-
-
-
-
-
-```ts
-const exportResult = await turnkeyClient.apiClient().exportPrivateKey({
- privateKeyId: privateKeyId,
- targetPublicKey: publicKey,
-});
-```
-
-
-
-
-
-```ts
-const decryptedBundle = await decryptExportBundle({
- exportBundle: exportResult.exportBundle,
- embeddedKey: privateKey,
- organizationId,
- returnMnemonic: false,
- keyFormat: "HEXADECIMAL", // optionally specify a key format. Defaults to hexadecimal, but use `SOLANA` to export a private key for use in Solana wallets
-});
-```
-
-Congrats! You've exported your private key 🎉
-
-
-
-
-#### Wallet account support
-
-
-
-
-```ts
-import { Turnkey } from "@turnkey/sdk-server";
-import { generateP256KeyPair, decryptExportBundle } from "@turnkey/crypto";
-
-...
-
-const turnkeyClient = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPublicKey: process.env.API_PUBLIC_KEY!,
- apiPrivateKey: process.env.API_PRIVATE_KEY!,
- defaultOrganizationId: process.env.ORGANIZATION_ID!,
- });
-```
-
-
-
-
-
-```ts
-const keyPair = generateP256KeyPair();
-const privateKey = keyPair.privateKey;
-const publicKey = keyPair.publicKeyUncompressed;
-```
-
-
-
-
-
-```ts
-const exportResult = await turnkeyClient.apiClient().exportWalletAccount({
- address: address, // your specific wallet account address
- targetPublicKey: publicKey,
-});
-```
-
-
-
-
-
-```ts
-const decryptedBundle = await decryptExportBundle({
- exportBundle: exportResult.exportBundle,
- embeddedKey: privateKey,
- organizationId,
- returnMnemonic: false,
- keyFormat: "HEXADECIMAL", // optionally specify a key format. Defaults to hexadecimal, but use `SOLANA` to export a private key for use in Solana wallets
-});
-```
-
-Congrats! You've exported your wallet account 🎉
-
-
-
-
-### Local storage
-
-If you do not have access to an iframe (e.g. in a mobile context) or would prefer not to use an iframe, using Local Storage is an alternative method. Note that there are security considerations here due to the fact that anyone in control of your domain can access Local Storage variables.
-
-#### Steps
-
-
-
-
-```ts
-import { Turnkey } from "@turnkey/sdk-browser";
-import { generateP256KeyPair, decryptExportBundle } from "@turnkey/crypto";
-
-...
-
-const turnkey = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
-});
-const passkeyClient = turnkey.passkeyClient();
-```
-
-
-
-
-
-```ts
-const embeddedKeyPair = generateP256KeyPair();
-const embeddedPrivateKey = keyPair.privateKey;
-const embeddedPublicKey = keyPair.publicKeyUncompressed;
-```
-
-
-
-
-
-```ts
-// Storage keys
-const STORAGE_KEYS = {
- EMBEDDED_PRIVATE_KEY: "@turnkey/embedded_private_key",
- EMBEDDED_PUBLIC_KEY: "@turnkey/embedded_public_key",
-};
-
-await LocalStorage.setItem(
- STORAGE_KEYS.EMBEDDED_PRIVATE_KEY,
- embeddedPrivateKey
-);
-
-// Note that the public key can always be derived separately via the `getPublicKey` from `@turnkey/crypto`
-await LocalStorage.setItem(STORAGE_KEYS.EMBEDDED_PUBLIC_KEY, embeddedPublicKey);
-```
-
-
-
-
-4. Call export (Turnkey activity), using the embedded key as the target key for the `exportWallet` activity:
-
-```ts
-const exportResult = await passkeyClient.exportWallet({
- walletId, // desired wallet ID
- targetPublicKey: embeddedPublicKey,
-});
-```
-
-
-
-
-
-```ts
-const decryptedBundle = await decryptExportBundle({
- exportBundle: exportResult.exportBundle,
- embeddedKey: embeddedPrivateKey,
- organizationId, // your organization ID (this may be a suborg)
- returnMnemonic: true,
-});
-```
-
-
-
-
-```ts
-await LocalStorage.removeItem(
- STORAGE_KEYS.EMBEDDED_PRIVATE_KEY,
- embeddedPrivateKey
-);
-await LocalStorage.removeItem(
- STORAGE_KEYS.EMBEDDED_PUBLIC_KEY,
- embeddedPublicKey
-);
-```
-
-Congrats! You've exported your wallet 🎉
-
-The process is largely similar for both private keys and individual wallet accounts.
-
-
-
-
-#### Private key support
-
-
-
-
-```ts
-import { Turnkey } from "@turnkey/sdk-browser";
-import { generateP256KeyPair, decryptExportBundle } from "@turnkey/crypto";
-
-...
-
-const turnkey = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
-});
-const passkeyClient = turnkey.passkeyClient();
-```
-
-
-
-
-
-```ts
-const keyPair = generateP256KeyPair();
-const privateKey = keyPair.privateKey;
-const publicKey = keyPair.publicKeyUncompressed;
-```
-
-
-
-
-
-```ts
-// Storage keys
-const STORAGE_KEYS = {
- EMBEDDED_PRIVATE_KEY: "@turnkey/embedded_private_key",
- EMBEDDED_PUBLIC_KEY: "@turnkey/embedded_public_key",
-};
-
-await LocalStorage.setItem(STORAGE_KEYS.EMBEDDED_PRIVATE_KEY, privateKey);
-
-// Note that the public key can always be derived separately via the `getPublicKey` from `@turnkey/crypto`
-await LocalStorage.setItem(STORAGE_KEYS.EMBEDDED_PUBLIC_KEY, publicKey);
-```
-
-
-
-
-
-```ts
-const exportResult = await passkeyClient.exportPrivateKey({
- privateKeyId, // desired private key ID
- targetPublicKey: publicKey,
-});
-```
-
-
-
-
-
-```ts
-const decryptedBundle = await decryptExportBundle({
- exportBundle: exportResult.exportBundle,
- embeddedKey: privateKey,
- organizationId, // your organization ID (this may be a suborg)
- returnMnemonic: false, // N/A as we're working with a private key, not a wallet
- keyFormat: "HEXADECIMAL", // optionally specify a key format. Defaults to hexadecimal, but use `SOLANA` to export a private key for use in Solana wallets
-});
-```
-
-
-
-
-
-```ts
-await LocalStorage.removeItem(
- STORAGE_KEYS.EMBEDDED_PRIVATE_KEY,
- embeddedPrivateKey
-);
-await LocalStorage.removeItem(
- STORAGE_KEYS.EMBEDDED_PUBLIC_KEY,
- embeddedPublicKey
-);
-```
-
-Congrats! You've exported your private key 🎉
-
-
-
-
-#### Wallet account support
-
-
-
-
-```ts
-import { Turnkey } from "@turnkey/sdk-browser";
-import { generateP256KeyPair, decryptExportBundle } from "@turnkey/crypto";
-
-...
-
-const turnkey = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
-});
-const passkeyClient = turnkey.passkeyClient();
-```
-
-
-
-
-
-```ts
-const keyPair = generateP256KeyPair();
-const privateKey = keyPair.privateKey;
-const publicKey = keyPair.publicKeyUncompressed;
-```
-
-
-
-
-
-```ts
-// Storage keys
-const STORAGE_KEYS = {
- EMBEDDED_PRIVATE_KEY: "@turnkey/embedded_private_key",
- EMBEDDED_PUBLIC_KEY: "@turnkey/embedded_public_key",
-};
-
-await LocalStorage.setItem(STORAGE_KEYS.EMBEDDED_PRIVATE_KEY, privateKey);
-
-// Note that the public key can always be derived separately via the `getPublicKey` from `@turnkey/crypto`
-await LocalStorage.setItem(STORAGE_KEYS.EMBEDDED_PUBLIC_KEY, publicKey);
-```
-
-
-
-
-4. Call export (Turnkey activity), using the embedded key as the target key for the `exportWalletAccount` activity:
-
-```ts
-const exportResult = await passkeyClient.exportWalletAccount({
- address, // your specific wallet account address
- targetPublicKey: publicKey,
-});
-```
-
-
-
-
-
-```ts
-const decryptedBundle = await decryptExportBundle({
- exportBundle: exportResult.exportBundle,
- embeddedKey: privateKey,
- organizationId, // your organization ID (this may be a suborg)
- returnMnemonic: false, // N/A as we're working with a wallet account, not a wallet
- keyFormat: "HEXADECIMAL", // optionally specify a key format. Defaults to hexadecimal, but use `SOLANA` to export a private key for use in Solana wallets
-});
-```
-
-
-
-
-
-```ts
-await LocalStorage.removeItem(
- STORAGE_KEYS.EMBEDDED_PRIVATE_KEY,
- embeddedPrivateKey
-);
-await LocalStorage.removeItem(
- STORAGE_KEYS.EMBEDDED_PUBLIC_KEY,
- embeddedPublicKey
-);
-```
-
-Congrats! You've exported your wallet account 🎉
-
-
-
-
-## UI customization
-
-Everything is customizable in the import iframe except the sentence of mnemonic words, which is minimally styled: the text is left-aligned and the padding and margins are zero. Here's an example of how you can configure the styling of the iframe.
-
-```ts
-const iframeCss = `
- iframe {
- box-sizing: border-box;
- width: 400px;
- height: 120px;
- border-radius: 8px;
- border-width: 1px;
- border-style: solid;
- border-color: rgba(216, 219, 227, 1);
- padding: 20px;
- }
-`;
-
-return (
-
-
-
-);
-```
-
-## Solana notes
-
-Solana paths do not include an `index`. Creating a wallet account with an index specified could lead to unexpected behavior when exporting and importing into another wallet.
-
-When importing into a multichain wallet such as Phantom, see [this guide](https://help.phantom.app/hc/en-us/articles/12988493966227-What-derivation-paths-does-Phantom-wallet-support#:~:text=The%20addresses%20are%20grouped%20into,'%2F0'%2F0%2F0.) on matching private keys across Solana, Ethereum, and Polygon.
-
-When exporting, if you export with the `hexadecimal` format, you can easily convert to base58 (Phantom-compatible) with a script like the following:
-
-
-```javascript
-var web3 = require('@solana/web3.js')
-var bs58 = require('bs58')
-
-const uint8arrayToHexString = (buffer) => {
- return [...buffer].map((x) => x.toString(16).padStart(2, "0")).join("");
-};
-
-const uint8arrayFromHexString = (hexString) =>
- new Uint8Array(hexString.match(/../g).map((h) => parseInt(h, 16)));
-
-const privateKey = ""
-const address = ""
-
-const base58DecodedAddress = bs58.decode(address)
-const base58DecodedAddressHex = uint8arrayToHexString(base58decodedAddress)
-const uintarr = uint8arrayFromHexString(`${privateKey}${base58decodedAddressHex}`)
-
-const imported = web3.Keypair.fromSecretKey(uintarr);
-console.log('imported wallet', imported) // verify import
-
-const privateKeyString = bs58.encode(uintarr);
-
-// NOTE: this log is for demonstration purposes only.
-// This key material is extremely sensitive and should be handled with care.
-console.log('phantom-importable private key string', privateKeyString)
-```
diff --git a/embedded-wallets/code-examples/fiat-on-ramp.mdx b/embedded-wallets/code-examples/fiat-on-ramp.mdx
deleted file mode 100644
index 9ad07ccf..00000000
--- a/embedded-wallets/code-examples/fiat-on-ramp.mdx
+++ /dev/null
@@ -1,125 +0,0 @@
----
-title: "Fiat Onramp"
-description: "This is a guide to implementing Fiat Onramps within a Turnkey-powered application."
-mode: wide
----
-
-## Using @turnkey/react-wallet-kit
-
-Setting up Fiat Onramp with [@turnkey/react-wallet-kit](https://www.npmjs.com/package/@turnkey/react-wallet-kit) is straightforward.
-
-### handleOnRamp
-
-The `handleOnRamp()` helper abstracts the process of initializing and launching a fiat on-ramp flow as well as polling transaction status.
-
-```ts
-import { handleOnRamp } from "@turnkey/react-wallet-kit";
-
- const handleAddFunds = async () => {
- try {
- await handleOnRamp({
- onrampProvider: "FIAT_ON_RAMP_PROVIDER_MOONPAY",
- walletAccount: selectedWalletAccount!,
- sandboxMode: true,
- });
- } catch (error) {
- handleError(error);
- }
- };
-
-```
-
-## White label implementation
-
-If you prefer a more **white label** approach, you can replicate the behavior of `handleOnRamp()` directly in your own app.
-This allows full control over how you open the provider's UI, manage state, and poll transaction status.
-
-The general flow is:
-
-1. Call `initFiatOnRamp()` with your desired parameters to receive the `onRampUrl` and `onRampTransactionId`.
-2. Open the `onRampUrl` in a popup or new tab for the user to complete their purchase.
-3. Poll `getOnRampTransactionStatus()` periodically until the transaction is `COMPLETED`, `FAILED`, or `CANCELLED`.
-4. Handle cleanup and UI updates accordingly.
-
-Below is a simplified example inspired by the internal `handleOnRamp()` implementation:
-
-```ts
-import { useState, useRef, useEffect } from "react";
-import {
- FiatOnRampCryptoCurrency,
- FiatOnRampBlockchainNetwork,
-} from "@turnkey/sdk-types";
-import { useTurnkey } from "@turnkey/react-wallet-kit";
-
-async function whiteLabelOnRamp(walletAccount, organizationId) {
- const { client } = useTurnkey();
- let cryptoCurrencyCode;
- let network;
-
- switch (true) {
- case walletAccount.addressFormat === "ADDRESS_FORMAT_ETHEREUM":
- cryptoCurrencyCode = FiatOnRampCryptoCurrency.ETHEREUM;
- network = FiatOnRampBlockchainNetwork.ETHEREUM;
- break;
- case walletAccount.addressFormat?.includes("ADDRESS_FORMAT_BITCOIN"):
- cryptoCurrencyCode = FiatOnRampCryptoCurrency.BITCOIN;
- network = FiatOnRampBlockchainNetwork.BITCOIN;
- break;
- case walletAccount.addressFormat === "ADDRESS_FORMAT_SOLANA":
- cryptoCurrencyCode = FiatOnRampCryptoCurrency.SOLANA;
- network = FiatOnRampBlockchainNetwork.SOLANA;
- break;
- default:
- cryptoCurrencyCode = FiatOnRampCryptoCurrency.ETHEREUM;
- network = FiatOnRampBlockchainNetwork.ETHEREUM;
- break;
- }
-
- // Step 1: Initialize the on-ramp
- const result = await client.httpClient.initFiatOnRamp({
- onrampProvider: "FIAT_ON_RAMP_PROVIDER_MOONPAY",
- organizationId,
- walletAddress: walletAccount.address,
- network,
- cryptoCurrencyCode,
- sandboxMode: true,
- });
-
- if (!result?.onRampUrl || !result?.onRampTransactionId) {
- throw new Error("Invalid onramp initialization response");
- }
-
- // Step 2: Open the on-ramp URL
- const popup = window.open(result.onRampUrl, "_blank", "width=500,height=600");
- if (!popup) throw new Error("Failed to open on-ramp window");
-
- // Step 3: Poll the transaction status
- const pollInterval = setInterval(async () => {
- try {
- const statusResp = await client.httpClient.getOnRampTransactionStatus({
- transactionId: result.onRampTransactionId,
- refresh: true,
- });
- const status = statusResp?.transactionStatus;
-
- if (["COMPLETED", "FAILED", "CANCELLED"].includes(status ?? "")) {
- clearInterval(pollInterval);
- popup.close();
- console.log("On-ramp status:", status);
- }
- } catch (err) {
- console.warn("Polling error:", err);
- }
- }, 3000);
-}
-```
-
-This approach gives you:
-
-- Full control over the UI and provider window handling.
-- The ability to customize polling intervals, completion logic, and error handling.
-- A foundation for integrating custom analytics, logging, or notifications.
-
-## Example
-
-See our example app leveraging `handleOnRamp` [here](https://wallets.turnkey.com/) and the code [here](https://github.com/tkhq/sdk/blob/81884b2ae57f6054d45eb8009f191793c3c46aa8/examples/react-wallet-kit/src/components/demo/DemoPanel.tsx#L116)
diff --git a/embedded-wallets/code-examples/import.mdx b/embedded-wallets/code-examples/import.mdx
deleted file mode 100644
index a96bfc35..00000000
--- a/embedded-wallets/code-examples/import.mdx
+++ /dev/null
@@ -1,418 +0,0 @@
----
-title: "Import wallet or private key"
-description: "This is a guide to importing your wallet or private key into Turnkey. For more information about the security of this flow, check out [Enclave secure channels](/security/enclave-secure-channels)."
----
-> ⚠️ **This example is outdated !**
-> Head over to [SDK Reference](/sdks/react/using-embedded-wallets#importing-and-exporting-wallets) for the updated packages.
-
-## Implementation guides
-
-Follow along with the Turnkey CLI, Embedded iframe, NodeJS, and Local Storage guides.
-
-### CLI
-
-Install the latest version of Turnkey CLI to access the new import functionality. You can find detailed instructions for installation [here](https://github.com/tkhq/tkcli).
-
-#### Steps
-
-
-
- ```bash
- turnkey generate encryption-key \
- --organization $ORGANIZATION_ID \
- --user $USER_ID \
- --encryption-key-name demo-encryption-key
- ```
-
- - The `--user` flag (required) is the id of the user importing the private key; this is required because the underlying encryption keys used for import are scoped to each user.
- - The `--encryption-key-name` flag is to specify a name for the encryption key. Note that an encryption key !== Turnkey API key; an encryption key is used exclusively for secure activities like import and export.
-
-
- ```bash
- turnkey wallets init-import \
- --user $USER_ID \
- --import-bundle-output "./import_bundle.txt" \
- --key-name demo-api-key
- ```
-
- - The `--import-bundle-output` (required) flag is the desired output file path for the “import bundle” that will be received from Turnkey. The “import bundle” contains the ephemeral public key generated by the Turnkey signer enclave for the specified user. The private key plaintext is encrypted to this public key in Step 2.
- - Reminder: The `--key-name` flag specifies the name of API key with which to interact with the Turnkey API service. This should be the name of a previously created key. If you do not have one, visit the quickstart guide for help creating one.
-
-
- ```bash
- turnkey encrypt \
- --user $USER_ID \
- --import-bundle-input "./import_bundle.txt" \
- --plaintext-input /dev/fd/3 3<<<"$MNEMONIC_1" \
- --encrypted-bundle-output "./encrypted_bundle.txt" \
- --encryption-key-name demo-encryption-key
- ```
-
- - The `--import-bundle-input` flag (required) is the desired input file path for the “import bundle”.
- - The `--plaintext-input` flag is the desired input file path for the private key plaintext. You can pass a filename here or feed the plaintext string directly into the standard input as shown above.
- - The `--encrypted-bundle-output` (required) flag is the desired output file path for the “encrypted bundle” that will be sent to Turnkey in Step 3. The “encrypted bundle” contains the ephemeral public key generated by the CLI as part of the shared secret computation with the Turnkey signer enclave. It also contains the ciphertext, which is the plaintext input encrypted by the Turnkey signer’s ephemeral public key.
-
-
- ```bash
- turnkey wallets import \
- --user $USER_ID \
- --name "demo key" \
- --encrypted-bundle-input "./encrypted_bundle.txt" \
- --key-name demo-api-key
- ```
-
- - The `--encrypted-bundle-input` (required) flag is the desired input file path for the “encrypted bundle” that will be sent to Turnkey.
- - Options are listed [here](/concepts/wallets) for the `--curve` and `--address-format` flags.
-
-
-
-#### Private key support
-
-Turnkey CLI also supports importing private keys. Follow the same steps as importing a wallet via CLI but use the `turnkey private-keys` commands instead. In Step 2 (`encrypt`), pass a `--key-format` flag for key-specific formatting; the options for private keys are:
-
-- `hexadecimal`: Used for Ethereum. Examples: `0x13eff5b3f9c63eab5d53cff5149f01606b69325496e0e98b53afa938d890cd2e, 13eff5b3f9c63eab5d53cff5149f01606b69325496e0e98b53afa938d890cd2e`
-- `solana`: Used for Solana. It’s a base58-encoding of the concatenation of the private key and public key bytes. Example: `2P3qgS5A18gGmZJmYHNxYrDYPyfm6S3dJgs8tPW6ki6i2o4yx7K8r5N8CF7JpEtQiW8mx1kSktpgyDG1xuWNzfsM`
-
-```bash
-turnkey encrypt \
---import-bundle-input "./import_bundle.txt" \
---plaintext-input /dev/fd/3 3<<<"$RAW_KEY_1" \
---key-format “hexadecimal” \
---encrypted-bundle-output "./encrypted_bundle.txt"
-```
-
-### Embedded iframe
-
-- We have released open-source code to create target encryption keys and encrypt wallet mnemonics for import. We've deployed a static HTML page hosted on `import.turnkey.com` meant to be embedded as an iframe element (see the code [here](https://github.com/tkhq/frames)). This ensures the mnemonics and keys are encrypted to keys that the user has access to, but that your organization does not (because they live in the iframe, on a separate domain).
-- We have also built a package to help you insert this iframe and interact with it in the context of import: [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper)
-
-In the rest of this guide we'll assume you are using these helpers. We also have a [code example](https://github.com/tkhq/sdk/blob/main/examples/wallet-import-export/src/components/ImportWallet.tsx) you can follow along with.
-
-#### Steps
-
-Here's a diagram summarizing the wallet import flow step-by-step ([direct link](/assets/files/wallet_import_steps-6c4753c1e726e1632ce475bc838388c2.png)):
-
-
- 
-
-
-Let's review these steps in detail:
-
-
-
- When a user on your application clicks "import", display a new import UI. We recommend setting this import UI as a new hosted page of your application that contains the iframe element that the user will enter their mnemonic into and an import button.
-
- While the UI is in a loading state, your application uses [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper) to insert a new iframe element:
-
- ```js
- const iframeStamper = new IframeStamper({
- iframeUrl: "https://import.turnkey.com",
- // Configure how the iframe element is inserted on the page
- iframeContainer: yourContainer,
- iframeElementId: "turnkey-iframe",
- });
-
- // Inserts the iframe in the DOM.
- await iframeStamper.init();
-
- // Set state to not display iframe
- let displayIframe = "none";
-
- return (
- // The iframe element does not need to be displayed yet
-
- );
- ```
-
-
- Your application prompts the user to sign a new `INIT_IMPORT_WALLET` activity with the ID of the user importing the wallet.
-
-
- Your application polls for the activity response, which contains an import bundle.
-
- Need help setting up async polling? Checkout our guide and helper [here](https://github.com/tkhq/sdk/tree/main/packages/http#withasyncpolling-helper).
-
-
- Your application injects the import bundle into the iframe and displays the iframe upon success:
-
- ```js
- // Inject import bundle into iframe
- let success = await iframeStamper.injectImportBundle(importBundle);
-
- if (success !== true) {
- throw new Error("unexpected error while injecting import bundle");
- }
-
- // If successfully injected, update the state to display the iframe
- iframeDisplay = "block";
- ```
-
-
- When a user clicks on the import button on your web page, your application can extract the encrypted mnemonic bundle from the iframe:
-
- ```js
- // Extract the encrypted bundle from the iframe
- let encryptedBundle =
- await iframeStamper.extractWalletEncryptedBundle(importBundle);
- ```
-
- Your applications passes the encrypted bundle as a parameter in a new `IMPORT_WALLET` activity and prompts the user to sign it.
-
- Import is complete!
-
- In your Turnkey dashboard, the imported user Wallet will be flagged as “Imported”.
-
-
-
-### NodeJS
-
-A full example Node script can be found here: https://github.com/tkhq/sdk/tree/main/examples/import-in-node
-
-#### Steps
-
-
-
- ```ts
- import { Turnkey } from "@turnkey/sdk-server";
- import {
- encryptPrivateKeyToBundle,
- encryptWalletToBundle,
- } from "@turnkey/crypto";
-
- ...
-
- const turnkeyClient = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPublicKey: process.env.API_PUBLIC_KEY!,
- apiPrivateKey: process.env.API_PRIVATE_KEY!,
- defaultOrganizationId: process.env.ORGANIZATION_ID!,
- });
- ```
-
-
- ```ts
- const initResult = await turnkeyClient.apiClient().initImportWallet({
- userId,
- });
- ```
-
-
- ```ts
- const walletBundle = await encryptWalletToBundle({
- mnemonic,
- importBundle: initResult.importBundle,
- userId,
- organizationId,
- });
- ```
-
-
- ```ts
- const walletImportResult = await turnkeyClient.apiClient().importWallet({
- userId: userId,
- walletName: "Your imported wallet!",
- encryptedBundle: walletBundle,
- accounts: [], // these are the wallet accounts you'd like to derive; after all, you've just imported a HD wallet! See https://learnmeabitcoin.com/technical/hd-wallets for more
- });
- ```
-
- Congrats! You've imported your wallet 🎉
-
-
-
-#### Private key support
-
-The process for importing a private key instead of wallet is largely similar, but has a key difference in that you must specify the format of your imported private key:
-
-
-
- ```js
- import { Turnkey } from "@turnkey/sdk-server";
- import {
- encryptPrivateKeyToBundle,
- encryptWalletToBundle,
- } from "@turnkey/crypto";
-
- ...
-
- const turnkeyClient = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- apiPublicKey: process.env.API_PUBLIC_KEY!,
- apiPrivateKey: process.env.API_PRIVATE_KEY!,
- defaultOrganizationId: process.env.ORGANIZATION_ID!,
- });
- ```
-
-
- ```js
- const initResult = await turnkeyClient.apiClient().initImportPrivateKey({
- userId,
- });
- ```
-
-
- ```js
- const privateKeyBundle = await encryptPrivateKeyToBundle({
- privateKey,
- keyFormat,
- importBundle: initResult.importBundle,
- userId,
- organizationId,
- });
- ```
-
-
- ```js
- const privateKeyImportResult = await turnkeyClient
- .apiClient()
- .importPrivateKey({
- userId: userId,
- privateKeyName: "Your imported private key!",
- encryptedBundle: privateKeyBundle,
- curve: keyFormat == "SOLANA" ? "CURVE_ED25519" : "CURVE_SECP256K1",
- addressFormats:
- keyFormat == "SOLANA"
- ? ["ADDRESS_FORMAT_SOLANA"]
- : ["ADDRESS_FORMAT_ETHEREUM"],
- });
- ```
-
- Congrats! You've imported your private key 🎉
-
-
-
-### Local storage
-
-If you do not have access to an iframe (e.g. in a mobile context) or would prefer not to use an iframe, you can opt to use other environment-agnostic methods to perform import using Turnkey libraries. So while this section is called Local Storage (for consistency with the [Export](/embedded-wallets/code-examples/export) guide), nothing is stored in Local Storage; instead, the relevant `encrypt{Wallet, PrivateKey}ToBundle` method uses an [ephemeral key](https://github.com/tkhq/sdk/blob/6b3ea14d1184c5394449ecaad2b0f445e373823f/packages/crypto/src/crypto.ts#L62-L70).
-
-#### Steps
-
-
-
- ```ts
- import { Turnkey } from "@turnkey/sdk-browser";
- import { generateP256KeyPair, encryptWalletToBundle } from "@turnkey/crypto";
-
- ...
-
- const turnkey = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
- });
- const passkeyClient = turnkey.passkeyClient();
- ```
-
-
- ```ts
- const initResult = await passkeyClient.initImportWallet({
- userId, // your user ID
- });
- ```
-
-
- ```ts
- const walletBundle = await encryptWalletToBundle({
- mnemonic,
- importBundle: initResult.importBundle,
- userId, // your user ID
- organizationId, // your organization ID
- });
- ```
-
-
- ```ts
- const walletImportResult = await passkeyClient.importWallet({
- userId, // your user ID
- walletName: "Your imported wallet!", // your desired name for the resulting imported wallet
- encryptedBundle: walletBundle,
- accounts: [], // these are the wallet accounts you'd like to derive; after all, you've just imported a HD wallet! See https://learnmeabitcoin.com/technical/hd-wallets for more
- });
- ```
-
- Congrats! You've imported your wallet 🎉
-
- The process for importing a private key instead of wallet is largely similar, but has a key difference in that you must specify the format of your imported private key:
-
-
-
-#### Private key support
-
-
-
- ```ts
- import { Turnkey } from "@turnkey/sdk-browser";
- import { generateP256KeyPair, encryptPrivateKeyToBundle } from "@turnkey/crypto";
-
- ...
-
- const turnkey = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
- });
- const passkeyClient = turnkey.passkeyClient();
- ```
-
-
- ```
- const initResult = await passkeyClient.initImportPrivateKey({
- userId, // your user ID
- });
- ```
-
-
- ```ts
- const privateKeyBundle = await encryptPrivateKeyToBundle({
- privateKey, // your private key string
- keyFormat, // your desired key format. See the Private Key notes section for more
- importBundle: initResult.importBundle,
- userId, // your user ID
- organizationId, // your organization ID
- });
- ```
-
-
- ```ts
- const privateKeyImportResult = await passkeyClient.importPrivateKey({
- userId,
- privateKeyName: "Your imported private key!", // your desired name for the resulting imported private key
- encryptedBundle: privateKeyBundle,
- curve: keyFormat == "SOLANA" ? "CURVE_ED25519" : "CURVE_SECP256K1",
- addressFormats:
- keyFormat == "SOLANA"
- ? ["ADDRESS_FORMAT_SOLANA"]
- : ["ADDRESS_FORMAT_ETHEREUM"],
- });
- ```
-
- Congrats! You've imported your private key 🎉
-
-
-
-## Private key notes
-
-Turnkey also supports importing Private Keys. Follow the same steps above for importing Wallets as mnemonics, but instead use the `INIT_IMPORT_PRIVATE_KEY` and `IMPORT_PRIVATE_KEY` activities and the `extractKeyEncryptedBundle` method from the [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper). You can pass an optional `keyFormat` to `extractKeyEncryptedBundle(keyFormat)` that will apply either `Hexadecimal` or `Solana` formatting to the private key that is entered in the iframe. The default key format is `hexadecimal`, which is used by MetaMask, MyEtherWallet, Phantom, Ledger, and Trezor for Ethereum keys. For Solana keys, you will need to pass the `solana` key format.
-
-## UI customization
-
-Everything is customizable in the import iframe except the sentence of mnemonic words, which is minimally styled: the text is left-aligned and the padding and margins are zero. Here's an example of how you can configure the styling of the iframe.
-
-```css
-const iframeCss = `
- iframe {
- box-sizing: border-box;
- width: 400px;
- height: 120px;
- border-radius: 8px;
- border-width: 1px;
- border-style: solid;
- border-color: rgba(216, 219, 227, 1);
- padding: 20px;
- }
-`;
-
-return (
-
-
-
-);
-```
diff --git a/embedded-wallets/code-examples/signing-transactions.mdx b/embedded-wallets/code-examples/signing-transactions.mdx
deleted file mode 100644
index 3e11615b..00000000
--- a/embedded-wallets/code-examples/signing-transactions.mdx
+++ /dev/null
@@ -1,112 +0,0 @@
----
-title: "Signing transactions"
-description: "This is a guide to signing transactions in the browser context. While these snippets leverage Ethers, it can be swapped out for other signers in the Viem or Solana contexts. See [here](https://github.com/tkhq/sdk/tree/main/examples/with-eth-passkeys-galore) for an example with both Ethers and Viem in the passkey + browser context, and [here](https://github.com/tkhq/sdk/tree/main/examples/with-solana-passkeys) for a similar example with Solana."
----
-> ⚠️ **This example is outdated !**
-> Head over to [SDK Reference](/sdks/react/signing) for the updated packages.
-
-## Steps using `@turnkey/sdk-react`
-
-This process is made the most seamless by leveraging our [React package](/sdks/react). Read on for a non-React implementation.
-
-
-
-
-```js
-import { TurnkeyProvider } from "@turnkey/sdk-react";
-const turnkeyConfig = {
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID, // prefix with NEXT_PUBLIC for NextJS
- rpId: process.env.RPID, // your application's domain
- iframeUrl: "https://auth.turnkey.com"
-}
-
-...
-
-
-
- // Rest of app ...
-
-
-```
-
-
-
-
-```js
-import { ethers } from "ethers";
-import { TurnkeySigner } from "@turnkey/ethers";
-
-import { useTurnkey } from "@turnkey/sdk-react";
-const { turnkey, passkeyClient } = useTurnkey();
-
-const provider = new ethers.JsonRpcProvider();
-const currentUser = await turnkey.getCurrentUser();
-const turnkeySigner = new TurnkeySigner({
- client: passkeyClient,
- organizationId: currentUser.organization.organizationId,
- signWith: ""
-})
-const connectedSigner = turnkeySigner.connect(provider);
-```
-
-
-
-
-```js
-const transactionRequest = {
- to: "",
- value: ethers.parseEther(""),
- type: 2,
-};
-const sendTransaction = await connectedSigner.sendTransaction(transactionRequest);
-```
-
-
-
-## Alternative steps (non-React)
-
-
-
-
-```js
-import { Turnkey } from "@turnkey/sdk-browser";
-
-const turnkey = new Turnkey({
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
-});
-const passkeyClient = turnkey.passkeyClient();
-```
-
-
-
-
-```
-import { ethers } from "ethers";
-import { TurnkeySigner } from "@turnkey/ethers";
-
-const provider = new ethers.JsonRpcProvider();
-const currentUser = await turnkey.getCurrentUser(); // assumes user details have been stored in LocalStorage via `login()`
-const turnkeySigner = new TurnkeySigner({
- client: passkeyClient,
- organizationId: currentUser.organization.organizationId,
- signWith: ""
-})
-const connectedSigner = turnkeySigner.connect(provider);
-```
-
-
-
-
-```js
-const transactionRequest = {
- to: "",
- value: ethers.parseEther(""),
- type: 2,
-};
-const sendTransaction =
- await connectedSigner.sendTransaction(transactionRequest);
-```
-
-
diff --git a/embedded-wallets/code-examples/social-linking.mdx b/embedded-wallets/code-examples/social-linking.mdx
deleted file mode 100644
index dc657577..00000000
--- a/embedded-wallets/code-examples/social-linking.mdx
+++ /dev/null
@@ -1,262 +0,0 @@
----
-title: "Social linking"
-description: "This is a guide to implementing social linking within a Turnkey-powered application. For more information on what social linking is, see [here](/authentication/social-logins#social-linking)."
----
-> ⚠️ **This example is outdated !**
-> Head over to [SDK Reference](https://docs.turnkey.com/sdks/react/auth#configuring-oauth) for the updated packages.
-
-## Using @turnkey/sdk-react
-
-Setting up social linking with [@turnkey/sdk-react](https://www.npmjs.com/package/@turnkey/sdk-react) using the `` component is straightforward.
-
-Simply add the `socialLinking` property to your `authConfig` object and set it to `true`. This will enable social linking for your application.
-
-```jsx
-import { Auth } from "@turnkey/sdk-react";
-
-function AuthPage() {
- const handleAuthSuccess = async () => {
- console.log("Auth successful!");
- };
-
- const handleAuthError = (errorMessage: string) => {
- console.log("Error!");
- };
-
- const authConfig = {
- emailEnabled: true,
- passkeyEnabled: true,
- phoneEnabled: false,
- googleEnabled: true,
- appleEnabled: false,
- facebookEnabled: false,
- socialLinking: true, // Enable social linking
- };
-
- const configOrder = ["socials", "email", "phone", "passkey"];
-
- return (
-
- );
-}
-
-export default AuthPage;
-```
-
-You can view the implementation of the `handleOAuthLogin` function within the `Auth` component in the [@turnkey/sdk-react GitHub repository](https://github.com/tkhq/sdk/blob/main/packages/sdk-react/src/components/auth/Auth.tsx#L281).
-
-## Manual implementation
-
-If you prefer to implement social linking manually, you can follow this guide to create a backend `handleOAuthLogin` function / endpoint that can optionally allow for social linking. Code references are in TypeScript, but you can easily adapt this to your backend language of choice.
-
-### Parameters
-
-This function will accept the following parameters
-
-- `oidcToken`: The OIDC token received from the social login provider.
-- `providerName`: The name of the social login provider (e.g., "google", "apple", etc.).
-- `publicKey`: A public key generated by the client.
-- `socialLinking`: A boolean indicating whether social linking is enabled. Defaults to `false`.
-
-### Parse the OIDC token
-
-Extract the `email` and `issuer`(`iss`) from the user's OIDC token.
-
-```ts
-import { jwtDecode } from "jwt-decode";
-
-const { email, iss } =
- jwtDecode<{ email?: string; iss?: string }>(oidcToken) || {};
-```
-
-### Look up sub-orgs by OIDC token
-
-Check if this OIDC token is already linked to a sub-org user within your organization. If it is, you can simply continue to the OAuth login step.
-
-```ts
-const { organizationIds: orgIdsOidc } = await turnkey.getSubOrgIds({
- filterType: "OIDC_TOKEN",
- filterValue: oidcToken,
-});
-
-if (orgIdsOidc.length > 0) {
- organizationId = orgIdsOidc[0];
- // Proceed to oauthLogin
-}
-```
-
-### If no OIDC match and Google issuer, try finding the email
-
-If the token is from Google and has a valid email, try getting the sub-org by **verified** email. If a sub-org is found, you can create the OAuth provider for the user. Note, this should only be done for social linking flows.
-
-```ts
-if (socialLinking && email && iss === "https://accounts.google.com") {
- const { organizationIds: orgIdsEmail } = await turnkey.getVerifiedSubOrgIds({
- filterType: "EMAIL",
- filterValue: email,
- });
-
- if (orgIdsEmail.length > 0) {
- organizationId = orgIdsEmail[0];
-
- // Fetch the user ID in the sub-org
- const { users } = await turnkey.getUsers({ organizationId });
- const userId = users[0].userId; // If the sub-org has multiple users, you may want to handle this differently.
-
- // Link the Google OIDC provider
- await turnkey.createOauthProviders({
- organizationId,
- userId,
- oauthProviders: [
- {
- providerName,
- oidcToken,
- },
- ],
- });
- }
-}
-```
-
-### If still no match, create a new sub-organization
-
-If no match is found, create a new sub-org and include the email in the payload for a social linking flow. The email passed in will be marked as verified provided the OIDC token comes from Google and the email within the token matches the email passed in.
-
-```ts
-const createSuborgParams: Record = {
- ...(socialLinking && email && { email }),
- oauthProviders: [{ providerName, oidcToken }],
-};
-
-const result = await handleCreateSubOrg(createSuborgParams);
-organizationId = result.subOrganizationId;
-```
-
-### Complete the OAuth login
-
-Finally, perform the OAuth login using the `oidcToken`, `publicKey`, and the determined `organizationId`.
-
-```ts
-const oauthResponse = await turnkey.oauthLogin({
- organizationId,
- oidcToken,
- publicKey,
- expirationSeconds: 900, // Set the expiration time as needed
-});
-```
-
-### Final implementation
-
-Here's the complete implementation of the `handleOAuthLogin` function as well as a helper function to create a sub-organization (can also be implemented inline).
-
-```ts
-import { Turnkey } from "@turnkey/sdk-server";
-import { jwtDecode } from "jwt-decode";
-
-export const turnkeyConfig = {
- apiBaseUrl: process.env.TURNKEY_API_URL ?? "",
- defaultOrganizationId: process.env.ORGANIZATION_ID ?? "",
- apiPublicKey: process.env.TURNKEY_API_PUBLIC_KEY ?? "",
- apiPrivateKey: process.env.TURNKEY_API_PRIVATE_KEY ?? "",
-};
-
-const turnkey = new Turnkey(turnkeyConfig).apiClient();
-
-async function handleCreateSubOrg(params: Record) {
- const { email, oauthProviders } = params;
-
- const result = await turnkey.createSubOrganization({
- organizationId: turnkeyConfig.defaultOrganizationId,
- subOrganizationName: "A social linking suborganization",
- rootUsers: [
- {
- userName: "A suborganization user",
- userEmail: email,
- oauthProviders,
- },
- ],
- rootQuorumThreshold: 1,
- wallet: {
- walletName: "Default Wallet",
- accounts: DEFAULT_ETHEREUM_ACCOUNTS,
- },
- });
-
- return result;
-}
-
-async function handleOAuthLogin(
- oidcToken: string,
- providerName: string,
- publicKey: string,
- socialLinking = false
-) {
- let organizationId: string = turnkeyConfig.defaultOrganizationId;
-
- const { email, iss } =
- jwtDecode<{ email?: string; iss?: string }>(oidcToken) || {};
-
- const oauthProviders = [{ providerName, oidcToken }];
- const createSuborgParams: Record = {
- ...(socialLinking && email && { email }),
- oauthProviders,
- };
-
- const { organizationIds: orgIdsOidc } = await turnkey.getSubOrgIds({
- filterType: "OIDC_TOKEN",
- filterValue: oidcToken,
- });
-
- if (orgIdsOidc.length > 0) {
- organizationId = orgIdsOidc[0];
- } else if (socialLinking && email && iss === "https://accounts.google.com") {
- // For Google, first check if there is an organization with the email
- const { organizationIds: orgIdsEmail } = await turnkey.getVerifiedSubOrgIds(
- {
- filterType: "EMAIL",
- filterValue: email,
- }
- );
-
- if (orgIdsEmail.length > 0) {
- organizationId = orgIdsEmail[0];
-
- const { users } = await turnkey.getUsers({
- organizationId,
- });
-
- const userId = users[0].userId;
-
- await turnkey.createOauthProviders({
- organizationId,
- userId,
- oauthProviders: [
- {
- providerName,
- oidcToken,
- },
- ],
- });
- } else {
- const result = await handleCreateSubOrg(createSubOrgParams);
- organizationId = result.subOrganizationId;
- }
- } else {
- const result = await handleCreateSubOrg(createSubOrgParams);
- organizationId = result.subOrganizationId;
- }
- const oauthResponse = await turnkey.oauthLogin({
- organizationId,
- oidcToken,
- publicKey,
- expirationSeconds: 900,
- });
-
- return oauthResponse;
-}
-```
diff --git a/embedded-wallets/code-examples/wallet-auth.mdx b/embedded-wallets/code-examples/wallet-auth.mdx
deleted file mode 100644
index f1f289c2..00000000
--- a/embedded-wallets/code-examples/wallet-auth.mdx
+++ /dev/null
@@ -1,952 +0,0 @@
----
-title: 'Wallet authentication'
-description: "In this guide, we'll explore how to leverage the `WalletClient` in the Turnkey SDK to authenticate requests to Turnkey's API using either Solana or Ethereum wallets."
----
-> ⚠️ **This example is outdated !**
-> Head over to [SDK Reference](/sdks/react/using-external-wallets/overview) for the updated packages.
-
-## Initialize
-
-Begin by initializing the Turnkey SDK by passing in a config object containing:
-
-- `apiBaseUrl`: The base URL of the Turnkey API: `https://api.turnkey.com`.
-- `defaultOrganizationId`: Your parent organization ID, which you can find in the [Turnkey dashboard](https://app.turnkey.com/dashboard).
-- `wallet`: The wallet interface used to sign requests. In this example, we'll use the `EthereumWallet` interface.
-
-```ts config.ts
-import { EthereumWallet } from '@turnkey/wallet-stamper';
-
-export const turnkeyConfig = {
- // Turnkey API base URL
- apiBaseUrl: 'https://api.turnkey.com',
- // Your parent organization ID
- defaultOrganizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!,
- // The wallet interface used to sign requests
- wallet: new EthereumWallet(),
-};
-```
-
-First, wrap your application with the `TurnkeyProvider` in your `app/layout.tsx` file.
-As this file is required by Next.js to be a server component, we need to define a `TurnkeyClientProvider` client component.
-
-```tsx app/TurnkeyClientProvider.tsx
-'use client';
-
-import { TurnkeyProvider } from '@turnkey/sdk-react';
-
-import { turnkeyConfig } from './config';
-
-export function TurnkeyClientProvider({
- children,
-}: {
- children: React.ReactNode;
-}) {
- return {children};
-}
-```
-
-```tsx app/layout.tsx
-import './globals.css';
-import '@turnkey/sdk-react/styles';
-
-import { TurnkeyClientProvider } from './TurnkeyClientProvider';
-
-export default function RootLayout({
- children,
-}: {
- children: React.ReactNode;
-}) {
- return (
-
-
- {children}
-
-
- );
-}
-```
-
-Then, create a new page component `app/page.tsx` where we'll implement the wallet authentication functionality:
-
-
-
-```tsx app/page.tsx
-"use client";
-
-import { useState } from "react";
-import { useTurnkey } from "@turnkey/sdk-react";
-
-export default function WalletAuth() {
- const { walletClient } = useTurnkey();
-
-// We'll add more functionality here in the following steps
-
-return
{/* We'll add UI elements here */}
;
-}
-
-````
-
-
-
-Create a new file `src/wallet-auth.ts` where we'll implement the wallet authentication functionality:
-
-```ts src/wallet-auth.ts
-import { Turnkey } from "@turnkey/sdk-browser";
-import { EthereumWallet } from "@turnkey/wallet-stamper";
-import { turnkeyConfig } from "./config";
-
-// Initialize the Turnkey SDK with the config object defined above
-const turnkey = new Turnkey(turnkeyConfig);
-
-// Initialize the Wallet Client with the EthereumWallet interface
-const walletClient = turnkey.walletClient(new EthereumWallet());
-
-// We'll add more functionality here in the following steps
-````
-
-
-
-
-## Sign up
-
-In this section, we'll guide you through the process of implementing a sign-up flow using an Ethereum wallet for authentication. The sign-up process involves creating a new sub-organization within your existing organization. This requires authentication of the parent organization using its public/private key pair. Additionally, we'll cover how to verify if a user already has an associated sub-organization before proceeding.
-
-### Server-side
-
-Initialize the Turnkey SDK on the **server-side** using the `@turnkey/sdk-server` package. This setup enables you to authenticate requests to Turnkey's API using the parent organization's public/private API key pair. This is required to create new sub-organizations on behalf of a user.
-
-
-
-For Next.js, add the `"use server"` directive at the top of the file where you're initializing the Turnkey server client. This will ensure that the function is executed on the server-side and will have access to the server-side environment variables e.g. your parent organization's public/private API key pair. For more information on Next.js server actions, see the Next.js documentation on [Server Actions and Mutations](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations).
-
-```tsx app/actions.ts
-'use server';
-
-import { Turnkey } from '@turnkey/sdk-server';
-import { turnkeyConfig } from './config';
-
-const { apiBaseUrl, defaultOrganizationId } = turnkeyConfig;
-
-// Initialize the Turnkey Server Client on the server-side
-const turnkeyServer = new Turnkey({
- apiPrivateKey: process.env.TURNKEY_API_PRIVATE_KEY!,
- apiPublicKey: process.env.TURNKEY_API_PUBLIC_KEY!,
- apiBaseUrl,
- defaultOrganizationId,
-}).apiClient();
-```
-
-
-
-
-```ts src/wallet-auth-server.ts
-import { Turnkey } from "@turnkey/sdk-server";
-import { turnkeyConfig } from "./config";
-
-const { apiBaseUrl, defaultOrganizationId } = turnkeyConfig;
-
-// Initialize the Turnkey Server Client on the server-side
-const turnkeyServer = new Turnkey({
-apiPrivateKey: process.env.TURNKEY_API_PRIVATE_KEY,
-apiPublicKey: process.env.TURNKEY_API_PUBLIC_KEY,
-apiBaseUrl,
-defaultOrganizationId,
-}).apiClient();
-
-````
-
-
-
-### Check for existing user
-
-Before signing up a new user, we can try and retrieve the user's sub-organization ID using the public key associated with the Ethereum or Solana account they want to authenticate with. If a sub-organization is found, we can proceed with authentication; otherwise, we assume the user is signing up.
-
-We'll use the `getPublicKey` method on the `WalletClient` instance which will retrieve the public key from the user's wallet.
-
-
- The main distinction between signing with an Ethereum Wallet and a Solana Wallet lies in how the public key is obtained. For Solana, the public key can be directly derived from the wallet. In contrast, with Ethereum, the secp256k1 public key isn't directly accessible. Instead, you need to first obtain a signature from the user and then recover the public key from that signature. This requires an additional step of signing a message with the user's Ethereum wallet before we can retrieve the public key.
-
-We'll define this function in the server-side code we initialized earlier.
-
-
-```ts app/actions.ts
-"use server";
-
-// ...
-
-export const getSubOrg = async (publicKey: string) => {
- try {
- const { organizationIds } = await turnkeyServer.getSubOrgIds({
- organizationId: turnkeyConfig.defaultOrganizationId,
- filterType: "PUBLIC_KEY",
- filterValue: publicKey,
- });
-
- return organizationIds[0] ?? null;
- } catch (err: any) {
- return null;
- }
-};
-````
-
-
-```ts src/wallet-auth-server.ts
-'use server';
-
-// ...
-
-export const getSubOrg = async (publicKey: string) => {
- try {
- const { organizationIds } = await turnkeyServer.getSubOrgIds({
- organizationId: turnkeyConfig.defaultOrganizationId,
- filterType: 'PUBLIC_KEY',
- filterValue: publicKey,
- });
-
- return organizationIds[0] ?? null;
- } catch (err: any) {
- return null;
- }
-};
-```
-
-
-
-
-Next, we'll add the client-side functionality to the `app/page.tsx` file we created earlier importing the `getSubOrg` function we defined in our server action. We'll use the `getSubOrg` function in the login method to check if a user already has a sub-organization.
-
-
-
-```tsx app/page.tsx
-'use client';
-
-import { useState } from 'react';
-import { useTurnkey } from '@turnkey/sdk-react';
-// Import the getSubOrg function we defined earlier
-import { getSubOrg } from './actions';
-
-export default function WalletAuth() {
- const { walletClient } = useTurnkey();
-
-const login = async () => {
-// Get the public key of the wallet, for Ethereum wallets this will trigger a prompt for the user to sign a message
-const publicKey = await walletClient?.getPublicKey();
-
- if (!publicKey) {
- throw new Error('No public key found');
- }
-
- const subOrgId = await getSubOrg(publicKey);
- if (!subOrgId) {
- // User does not have a sub-organization, proceed with sign-up
- }
- // User has a sub-organization, proceed with login
-
-};
-
-return (
-
-
-
-);
-}
-
-````
-
-
-```ts src/wallet-auth.ts
-import { getSubOrg } from './wallet-auth-server';
-// ...
-const walletClient = turnkey.walletClient(new EthereumWallet());
-
-export const login = async () => {
- // Get the public key of the wallet, for Ethereum wallets this will trigger a prompt for the user to sign a message
- const publicKey = await walletClient?.getPublicKey();
-
- if (!publicKey) {
- throw new Error('No public key found');
- }
-
- const subOrgId = await getSubOrg(publicKey);
- if (!subOrgId) {
- // User does not have a sub-organization, proceed with sign-up
- }
- // User has a sub-organization, proceed with login
-};
-````
-
-
-
-### Create sub-organization
-
-Next, we'll define a method to create a sub-organization for new user sign-ups.
-
-For more information, refer to the [Sub-Organizations](/concepts/sub-organizations) guide.
-
-
-
-We'll define another server action `createSubOrg` to create a sub-organization for new user sign-ups.
-
-```ts app/actions.ts
-'use server';
-
-// ...
-
-// Import the default Ethereum accounts helper
-import { DEFAULT_ETHEREUM_ACCOUNTS } from '@turnkey/sdk-browser';
-
-export const createSubOrg = async (
- publicKey: string,
- curveType: 'API_KEY_CURVE_ED25519' | 'API_KEY_CURVE_SECP256K1'
-) => {
- const apiKeys = [
- {
- apiKeyName: `Wallet Auth - ${publicKey}`,
- // The public key of the wallet that will be added as an API key and used to stamp future requests
- publicKey,
- // We set the curve type to 'API_KEY_CURVE_ED25519' for solana wallets
- // If using an Ethereum wallet, set the curve type to 'API_KEY_CURVE_SECP256K1'
- curveType,
- },
- ];
-
- const subOrg = await turnkeyServer.createSubOrganization({
- // The parent organization ID
- organizationId: turnkeyConfig.defaultOrganizationId,
- subOrganizationName: 'New Sub Org',
- rootUsers: [
- {
- // Replace with user provided values if desired
- userName: 'New User',
- userEmail: 'wallet@domain.com',
- apiKeys,
- authenticators: [],
- oauthProviders: [],
- },
- ],
- rootQuorumThreshold: 1,
- wallet: {
- walletName: 'Default Wallet',
- // This is used to create a new Ethereum wallet for the sub-organization
- accounts: DEFAULT_ETHEREUM_ACCOUNTS,
- },
- });
-
- return subOrg;
-};
-```
-
-Then, we'll import and use this `createSubOrg` function within the login method. The curve type is set to `API_KEY_CURVE_SECP256K1` since we're using an Ethereum wallet in this example.
-
-```tsx app/page.tsx
-'use client';
-import { getSubOrg, createSubOrg } from './actions';
-// ...
-
-export default function WalletAuth() {
- const { walletClient } = useTurnkey();
-
- const login = async () => {
- // Get the public key of the wallet, for Ethereum wallets this will trigger a prompt for the user to sign a message
- const publicKey = await walletClient?.getPublicKey();
-
- if (!publicKey) {
- throw new Error('No public key found');
- }
-
- const subOrgId = await getSubOrg(publicKey);
- if (!subOrgId) {
- const subOrgResponse = await createSubOrg(
- publicKey,
- 'API_KEY_CURVE_SECP256K1'
- );
- const subOrg = subOrgResponse?.subOrganizationId ?? null;
-
- if (!subOrg) throw new Error('Failed to create sub-organization');
- }
- // In the next step we'll sign in the user
- };
-
- return (
-
-
-
- );
-}
-```
-
-
-
-We'll define another server-side function `createSubOrg`, to create a sub-organization for new user sign-ups.
-
-```ts src/wallet-auth-server.ts
-// ...
-
-// Import the default Ethereum accounts helper
-import { DEFAULT_ETHEREUM_ACCOUNTS } from '@turnkey/sdk-browser';
-
-export const createSubOrg = async (
- publicKey: string,
- curveType: 'API_KEY_CURVE_ED25519' | 'API_KEY_CURVE_SECP256K1'
-) => {
- const apiKeys = [
- {
- apiKeyName: `Wallet Auth - ${publicKey}`,
- // The public key of the wallet that will be added as an API key and used to stamp future requests
- publicKey,
- // We set the curve type to 'API_KEY_CURVE_ED25519' for solana wallets
- // If using an Ethereum wallet, set the curve type to 'API_KEY_CURVE_SECP256K1'
- curveType,
- },
- ];
-
- const subOrg = await turnkeyServer.createSubOrganization({
- // The parent organization ID
- organizationId: turnkeyConfig.defaultOrganizationId,
- subOrganizationName: 'New Sub Org',
- rootUsers: [
- {
- // Replace with user provided values if desired
- userName: 'New User',
- userEmail: 'wallet@domain.com',
- apiKeys,
- authenticators: [],
- oauthProviders: [],
- },
- ],
- rootQuorumThreshold: 1,
- wallet: {
- walletName: 'Default Wallet',
- // This is used to create a new Ethereum wallet for the sub-organization
- accounts: DEFAULT_ETHEREUM_ACCOUNTS,
- },
- });
-
- return subOrg;
-};
-```
-
-Then, we'll import and use this `createSubOrg` function within the login method. The curve type is set to `API_KEY_CURVE_SECP256K1` since we're using an Ethereum wallet in this example.
-
-```ts src/wallet-auth.ts
-import { getSubOrg, createSubOrg } from './wallet-auth-server';
-// ...
-const walletClient = turnkey.walletClient(new EthereumWallet());
-
-export const login = async () => {
- // Get the public key of the wallet, for Ethereum wallets this will trigger a prompt for the user to sign a message
- const publicKey = await walletClient?.getPublicKey();
-
- if (!publicKey) {
- throw new Error('No public key found');
- }
-
- const subOrgId = await getSubOrg(publicKey);
- if (!subOrgId) {
- const subOrgResponse = await createSubOrg(
- publicKey,
- 'API_KEY_CURVE_SECP256K1'
- );
- const subOrg = subOrgResponse?.subOrganizationId ?? null;
-
- if (!subOrg) throw new Error('Failed to create sub-organization');
- }
- // In the next step we'll sign in the user
-};
-```
-
-
-
-
-## Sign in
-
-At this point, we have a working sign-up flow. Next, we'll implement the signing in functionality by creating a read-write session, retrieving the user's wallets and adding a new one.
-
-Create a read-write session for the user by calling the `loginWithWallet` method on the `WalletClient` instance which will use a newly generated `indexedDb` API key. This will save a read-write session token to the `localStorage` to authenticate future read-write requests.
-
-
-
-
-```tsx app/page.tsx
-'use client';
-
-import { useState } from 'react';
-import { useTurnkey } from '@turnkey/sdk-react';
-import { getSubOrg, createSubOrg } from './actions';
-import { SessionType } from '@turnkey/sdk-types';
-import { DEFAULT_ETHEREUM_ACCOUNTS } from '@turnkey/sdk-browser';
-
-export default function WalletAuth() {
- const [wallets, setWallets] = useState([]);
- const [session, setSession] = useState(null);
- const { walletClient, indexedDbClient, turnkey } = useTurnkey();
-
- const login = async () => {
- try {
- // Get the public key of the wallet, for Ethereum wallets this will trigger a prompt for the user to sign a message
- const publicKey = await walletClient?.getPublicKey();
- if (!publicKey) throw new Error('No public key found');
-
- if (!walletClient) {
- throw new Error('Wallet client not initialized');
- }
-
- const subOrgId = await getSubOrg(publicKey);
-
- if (!subOrgId) {
- const subOrgResponse = await createSubOrg(
- publicKey,
- 'API_KEY_CURVE_SECP256K1'
- );
- const subOrg = subOrgResponse?.subOrganizationId ?? null;
-
- if (!subOrg) throw new Error('Failed to create sub-organization');
- console.log('Sub-Organization created:', subOrg);
- }
-
- if (!indexedDbClient) throw new Error('IndexedDb client not available');
-
- // Reset the indexedDb key pair and session before each login
- // Note that session reset is important when switching between multiple wallets within the same browser
- await turnkey?.logout();
- await client?.clear();
- await indexedDbClient.resetKeyPair();
- const pubKey = await indexedDbClient.getPublicKey();
-
- await walletClient!.loginWithWallet({
- sessionType: SessionType.READ_WRITE, // use SessionType.READ_ONLY for read-only sessions
- publicKey: pubKey!,
- });
-
- console.log('Login successful');
-
- const session = await turnkey?.getSession();
- setSession(session);
-
- const subOrganizationId = session!.organizationId;
-
- // get existing suborg wallets
- const wallets = await indexedDbClient.getWallets({
- organizationId: subOrgId!,
- });
- setWallets(wallets.wallets);
-
- // create a new wallet with an Ethereum wallet account
- const newWalletResponse = await indexedDbClient.createWallet({
- walletName: 'New Wallet 1',
- accounts: DEFAULT_ETHEREUM_ACCOUNTS,
- });
- console.log('Created new wallet:', newWalletResponse);
-
- const updatedWallets = await indexedDbClient.getWallets({
- organizationId: subOrganizationId,
- });
-
- setWallets(updatedWallets.wallets);
- } catch (err) {
- console.error('Login error:', err);
- }
- };
-
- return (
-
-
- Turnkey Wallet Auth
-
-
- {/* If logged in: Show wallets */}
- {session && wallets.length > 0 && (
-
-
🧾 Wallets
- {wallets.map((wallet) => (
-
-
- {wallet.walletName}
-
-
- Wallet ID: {wallet.walletId}
-
-
- ))}
-
- )}
-
- {/* If not logged in: Show Sign In */}
- {walletClient && !session && (
-
- )}
-
-
- );
-}
-```
-
-
-
-
-```ts src/wallet-auth.ts
-import { Turnkey } from '@turnkey/sdk-browser';
-import { EthereumWallet } from '@turnkey/wallet-stamper';
-import { turnkeyConfig } from './config';
-import { getSubOrg, createSubOrg } from './wallet-auth-server';
-import { SessionType } from '@turnkey/sdk-types';
-import { DEFAULT_ETHEREUM_ACCOUNTS } from '@turnkey/sdk-browser';
-
-// Initialize the Turnkey SDK with the config object defined above
-const turnkey = new Turnkey(turnkeyConfig);
-
-// Initialize the Wallet Client with the EthereumWallet interface
-const walletClient = turnkey.walletClient(new EthereumWallet());
-
-export const login = async () => {
- try {
- // Get the public key of the wallet, for Ethereum wallets this will trigger a prompt for the user to sign a message
- const publicKey = await walletClient?.getPublicKey();
-
- if (!publicKey) {
- throw new Error('No public key found');
- }
-
- if (!walletClient) {
- throw new Error('Wallet client not initialized');
- }
-
- const subOrgId = await getSubOrg(publicKey);
- if (!subOrgId) {
- const subOrgResponse = await createSubOrg(
- publicKey,
- 'API_KEY_CURVE_SECP256K1'
- );
- const subOrg = subOrgResponse?.subOrganizationId ?? null;
-
- if (!subOrg) throw new Error('Failed to create sub-organization');
- console.log('Sub-Organization created:', subOrg);
- }
-
- // Initialize the indexedDbClient
- const client = await turnkey.indexedDbClient();
-
- if (!client) {
- throw new Error('indexedDbClient not initialized');
- }
-
- // Reset the indexedDb key pair and session before each login
- // Note that session reset is important when switching between multiple wallets within the same browser
- await turnkey?.logout();
- await client?.clear();
- await client!.resetKeyPair();
- const pubKey = await client!.getPublicKey();
-
- await walletClient!.loginWithWallet({
- sessionType: SessionType.READ_WRITE, // use SessionType.READ_ONLY for read-only sessions
- publicKey: pubKey!,
- });
-
- console.log('Login successful');
-
- const session = await turnkey?.getSession();
-
- const subOrganizationId = session!.organizationId;
-
- // get existing suborg wallets
- const wallets = await client.getWallets({
- organizationId: subOrgId!,
- });
-
- // create a new wallet with an Ethereum wallet account
- const newWalletResponse = await client.createWallet({
- walletName: 'New Wallet 1',
- accounts: DEFAULT_ETHEREUM_ACCOUNTS,
- });
- console.log('Created new wallet:', newWalletResponse);
-
- const updatedWallets = await client.getWallets({
- organizationId: subOrganizationId,
- });
- } catch (err) {
- console.error('Login error:', err);
- }
-};
-```
-
-
-
-
-## Sign in with a Solana wallet
-
-As with Solana wallets there's not standard API like `personal_sign` for Ethereum, we'll need to build a couple of things:
-
-- Use the Turnkey `SolanaWalletInterface` to build our own `SolanaWallet()` function that would get the public key and sign a message. Create this new `SolanaWalletFactory.ts` component:
-
-```tsx app/SolanaWalletFactory.ts
-// This wrapper implements SolanaWalletInterface for WalletStamper
-import { WalletType, SolanaWalletInterface } from "@turnkey/wallet-stamper";
-
-export function SolanaWallet(wallet: {
- publicKey: { toBytes(): Uint8Array } | null;
- signMessage?: (msg: Uint8Array) => Promise;
-}): SolanaWalletInterface {
- return {
- type: WalletType.Solana,
-
- async getPublicKey() {
- if (!wallet.publicKey) throw new Error("No public key");
- return Buffer.from(wallet.publicKey.toBytes()).toString("hex");
- },
-
- async signMessage(message: string) {
- if (!wallet.signMessage) {
- throw new Error("Wallet does not support signMessage");
- }
- const encoded = new TextEncoder().encode(message);
- const signature = await wallet.signMessage(encoded);
- return Buffer.from(signature).toString("hex");
- },
- };
-}
-```
-- Use the Solana wallet-addapter to detect and connect the installed wallets. Create this SolanaWalletProvider.tsx component:
-
-```tsx app/SolanaWalletProvider.tsx
-"use client";
-
-import { FC, ReactNode } from "react";
-import { ConnectionProvider, WalletProvider } from "@solana/wallet-adapter-react";
-import { WalletModalProvider } from "@solana/wallet-adapter-react-ui";
-import { WalletAdapterNetwork } from "@solana/wallet-adapter-base";
-
-export const SolanaWalletContextProvider: FC<{ children: ReactNode }> = ({ children }) => {
- const network = WalletAdapterNetwork.Mainnet;
-
- const endpoint = "https://api.mainnet-beta.solana.com";
-
- return (
-
- // you can add adapters for walllets not auto-detected here
- {children}
-
-
- );
-};
-```
-
-Update the layout.tsx file:
-
-```tsx app/layout.tsx
-import "./globals.css";
-import "@solana/wallet-adapter-react-ui/styles.css";
-import { SolanaWalletContextProvider } from "./SolanaWalletProvider";
-
-export default function RootLayout({ children }: { children: React.ReactNode }) {
- return (
-
-
-
- {children}
-
-
-
- );
-}
-```
-
-Update the config.ts file to include Solana:
-
-```ts config.ts
-import { EthereumWallet } from "@turnkey/wallet-stamper";
-import { SolanaWallet } from "./SolanaWalletFactory";
-
-export const turnkeyConfig = {
- apiBaseUrl: "https://api.turnkey.com",
- defaultOrganizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!,
-};
-
-export const turnkeyEthereumConfig = {
- ...turnkeyConfig,
- wallet: new EthereumWallet(),
-};
-
-// Factory function for Solana
-export function createSolanaConfig(wallet: Parameters[0]) {
- return {
- ...turnkeyConfig,
- wallet: SolanaWallet(wallet),
- };
-}
-```
-Now let's put everything together:
-
-```tsx app/page.tsx expandable
-'use client';
-
-import { useWallet } from '@solana/wallet-adapter-react';
-import { WalletMultiButton } from '@solana/wallet-adapter-react-ui';
-import { Turnkey } from '@turnkey/sdk-browser';
-import { getSubOrg, createSubOrg } from './actions';
-import { useCallback, useEffect, useState } from 'react';
-import { DEFAULT_ETHEREUM_ACCOUNTS } from '@turnkey/sdk-browser';
-import { SessionType } from '@turnkey/sdk-types';
-import { SolanaWallet } from "./SolanaWalletFactory";
-import { createSolanaConfig } from "./config";
-
-export default function WalletAuth() {
- const wallet = useWallet();
- const [mounted, setMounted] = useState(false);
- const [session, setSession] = useState(null);
- const [wallets, setWallets] = useState([]);
-
- useEffect(() => {
- setMounted(true);
- }, []);
-
- const login = useCallback(async () => {
- try {
- if (!wallet.connected || !wallet.publicKey) {
- throw new Error('Wallet not connected');
- }
-
- const turnkeyConfig = createSolanaConfig(wallet);
- const turnkey = new Turnkey(turnkeyConfig);
- const walletClient = turnkey.walletClient(SolanaWallet(wallet));
-
- // Get the injected wallet public key
- const publicKey = await walletClient?.getPublicKey();
-
- const subOrgId = await getSubOrg(publicKey);
- if (!subOrgId) {
- const subOrgResponse = await createSubOrg(
- publicKey,
- 'API_KEY_CURVE_ED25519'
- );
- const subOrg = subOrgResponse?.subOrganizationId ?? null;
-
- if (!subOrg) throw new Error('Failed to create sub-organization');
- console.log('Sub-Organization created:', subOrg);
- }
-
- // Initialize the indexedDbClient
- const client = await turnkey.indexedDbClient();
-
- if (!client) {
- throw new Error('indexedDbClient not initialized');
- }
-
- // Reset the indexedDb key pair and session before each login
- // Note that session reset is important when switching between multiple wallets within the same browser
- await turnkey?.logout();
- await client?.clear();
- await client!.resetKeyPair();
-
- // Get the indexedDbClient public key
- const pubKey = await client!.getPublicKey();
-
- await walletClient!.loginWithWallet({
- sessionType: SessionType.READ_WRITE, // use SessionType.READ_ONLY for read-only sessions
- publicKey: pubKey!,
- });
-
- console.log('Login successful');
-
- const session = await turnkey?.getSession();
- setSession(session);
-
- const subOrganizationId = session!.organizationId;
-
- // Get existing suborg wallets
- const wallets = await client.getWallets({
- organizationId: subOrgId!,
- });
- setWallets(wallets.wallets);
-
- // Create a new wallet with an Ethereum wallet account
- const newWalletResponse = await client.createWallet({
- walletName: 'New Wallet 1',
- accounts: DEFAULT_ETHEREUM_ACCOUNTS,
- });
-
- const updatedWallets = await client.getWallets({
- organizationId: subOrganizationId,
- });
- setWallets(updatedWallets.wallets);
- } catch (err) {
- console.error('Login error:', err);
- }
- }, [wallet]);
-
- if (!mounted) return null;
-
- return (
-
- );
-}
-```
-
-## Examples
-
-You can find examples of how to implement the above functionality using the indexedDbClient and more in the following repositories:
-
-
-
-
-
diff --git a/embedded-wallets/embedded-waas.mdx b/embedded-wallets/embedded-waas.mdx
deleted file mode 100644
index 1edc2255..00000000
--- a/embedded-wallets/embedded-waas.mdx
+++ /dev/null
@@ -1,262 +0,0 @@
----
-title: "Embedded WaaS"
-description:
- "Build a white-labeled Wallet-as-a-Service product on Turnkey. This guide covers the step-by-step
- implementation for embedding dedicated, non-custodial wallets with authenticators and signing
- rules into your platform."
----
-
-## Why Turnkey for Embedded WaaS?
-
-Turnkey provides the infrastructure to embed wallets directly into your developer product without
-building or managing key management yourself. Use it to provision isolated user wallets, enforce
-signing policies, and create your own APIs, SDKs, and UI components on top of Turnkey.
-
-## 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:** For every fund-moving transaction, you can require
- approval from both the end user and your platform, enforced directly at the signing layer.
-- **User-authenticated action:** No transaction executes without the end user’s authentication
- (e.g., passkey).
-- **Non-custodial by design:** End users remain in control of their keys, while platform controls
- allow you to manage transaction-level approvals.
-- **User-controlled key export:** End users can [export their wallet](/wallets/export-wallets)
- independently if they choose to leave, or if your platform goes offline.
-- **Quorum control:** 2-of-2 root quorum ensures billing, compliance, and risk controls are enforced
- at the cryptographic layer, while guaranteeing explicit user consent on every transaction.
-
-## Architecture
-
-The diagram below shows the recommended sub-org structure for a WaaS deployment using 2-of-2 root
-quorum signing.
-
-
-
-
-
-### 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 your 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.
-- Your platform approves via API key and the transaction executes.
-- If the platform withholds approval, the transaction does not execute.
-
-
-
-
-
-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). The standard
-approach is one sub-org per end user.
-
-- **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.
-
-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 your 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 (Step 3a). 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: "Platform", 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 will 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
- platform approval" states.
-- **Backend service:** Handle platform 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:** Platform 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%.
-- **Fully branded interface:** DIMO built a native auth and signing experience on an open-source
- [transactions SDK](https://github.com/DIMO-Network/transactions), powered by Turnkey’s Embedded
- WaaS passkey-based signing.
-- **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.
-- **2-3 week integration:** DIMO deployed into their global login stack in under three weeks.
-
-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/embedded-wallets/features/overview.mdx b/embedded-wallets/features/overview.mdx
deleted file mode 100644
index af174bf6..00000000
--- a/embedded-wallets/features/overview.mdx
+++ /dev/null
@@ -1,61 +0,0 @@
----
-title: "Features"
-sidebarTitle: "Overview"
----
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {" "}
-
-
-
-
- {" "}
-
-
-
-
- {" "}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/embedded-wallets/overview.mdx b/embedded-wallets/overview.mdx
deleted file mode 100644
index 5782ffee..00000000
--- a/embedded-wallets/overview.mdx
+++ /dev/null
@@ -1,215 +0,0 @@
----
-title: "Overview"
-sidebarTitle: "Overview"
----
-
-import { Logo } from "/snippets/logo.mdx";
-import { SquareCard } from "/snippets/square-card.mdx";
-
-With Embedded Wallets, you can create custom wallet experiences that are seamlessly integrated into your product, without compromising on security. Whether you need custodial or non-custodial wallets, our infrastructure provides the foundation for building innovative, user-friendly crypto products.
-
-### Why embedded wallets?
-
-Embedded Wallets give you the freedom to design and control the entire user experience, while offloading the complexity and risk of private key management to Turnkey.
-
-With Embedded Wallets, you can:
-
-- Leverage pre-built UI components to speed up your integration
-- Easily create a variety of wallets for your users
-- Authenticate users via email, phone number, biometrics, social logins, etc
-- Determine delegated access and co-owernership controls
-- Access out-of-the-box support for multiple chains and assets
-- Sign multiple transactions without additional approvals
-- Access simple integrations for gas sponsorship and smart contract wallets
-
-### Custodial vs non-custodial
-
-Turnkey's Embedded Wallets are built on top of Sub-Organizations.
-Each wallet is represented by a sub-organization, which can be configured with different security settings and access controls.
-
-- For custodial wallets, your application holds the master key and can initiate transactions on behalf of users.
-- For non-custodial wallets, users hold their own private keys and must approve each transaction,
- using one of their configured [authentication](/authentication/overview) methods.
-
-Below, we'll dive into how we set each of these up but first, let's make sure you're familiar with
-the Embedded Wallets concepts and architecture.
-
-### Embedded wallets quickstart
-
-Head over to the [Getting Started](/sdks/react/getting-started) guide to set up your React app with `@turnkey/react-wallet-kit`.
-
-Looking for more support? Check out our Demos, SDKs and Code Examples below\!
-
-## Demos
-{/* TODO: Please add wallets.turnkey.com in here after we replace it with the new ewk2 demo (the one with the spinning Turnkey logo!).
-If you're from the future, we probably already replaced wallets.turnkey.com with the new ewk2 demo. If this comment is still here, FIX IT!*/}
-
-### Demo embedded wallet ([code](https://github.com/tkhq/demo-embedded-wallet))
-
-A comprehensive demo showcasing how to build an embedded wallet using Turnkey. This demo uses the [`@turnkey/sdk-browser`](https://www.npmjs.com/package/@turnkey/sdk-browser), [`@turnkey/sdk-react`](https://www.npmjs.com/package/@turnkey/sdk-react) and [`@turnkey/sdk-server`](https://www.npmjs.com/package/@turnkey/sdk-server) packages and includes features such as:
-
-- User authentication with passkeys, email auth, and OAuth
-- Creating new wallets and wallet accounts
-- Sending and receiving funds
-- Importing/Exporting a wallet
-- Adding a credential to the wallet
-
-
-
-
-
-
-
-
-
-
-
-See [https://github.com/tkhq/demo-embedded-wallet](https://github.com/tkhq/demo-embedded-wallet) for the code.
-
-### Demo consumer wallet ([code](https://github.com/tkhq/demo-consumer-wallet))
-
-A minimal consumer wallet app powered by Turnkey. Behind the scenes, it uses [`@turnkey/ethers`](https://www.npmjs.com/package/@turnkey/ethers) for signing and WalletConnect (v1) for accessing dapps.
-
-
-
-
-
-See [https://github.com/tkhq/demo-consumer-wallet](https://github.com/tkhq/demo-consumer-wallet) for the code.
-
-### Demo embedded wallet ([code](https://github.com/tkhq/demo-embedded-wallet), [live link](https://wallet.tx.xyz))
-
-A wallet application showing how users can register and authenticate using passkeys. This demo uses the Turnkey API to create a new [Turnkey Sub-Organization](/concepts/sub-organizations) for each user, create a testnet Ethereum address and send a transaction on Sepolia (ETH testnet).
-
-
-
-
-
-See [https://wallet.tx.xyz](https://wallet.tx.xyz) (and [https://github.com/tkhq/demo-embedded-wallet](https://github.com/tkhq/demo-embedded-wallet) for the code).
-
-### Demo Ethers passkeys ([code](https://github.com/tkhq/demo-ethers-passkeys))
-
-A simple application demonstrating how to create sub-organizations, create private keys, and sign with the [`@turnkey/ethers`](https://github.com/tkhq/sdk/tree/main/packages/ethers) signer, using passkeys.
-
-
-
-
-
-See [https://github.com/tkhq/demo-ethers-passkeys](https://github.com/tkhq/demo-ethers-passkeys) for the code.
-
-### Demo Viem passkeys ([code](https://github.com/tkhq/demo-viem-passkeys))
-
-A similar, simple application demonstrating how to create sub-organizations, create private keys, and sign with the [`@turnkey/viem`](https://github.com/tkhq/sdk/tree/main/packages/viem) signer, using passkeys.
-
-
-
-
-
-See [https://github.com/tkhq/demo-viem-passkeys](https://github.com/tkhq/demo-viem-passkeys) for the code.
-
-### Demo Viem passkeys with Gelato relay ([code](https://github.com/gelatodigital/gelato-turnkey-passkeys-relay))
-
-This example demonstrates how to leverage Turnkey’s secure key management and Gelato's battle-tested relay infrastructure to enable seamless, sponsored interactions with meta-transactions using the [`@turnkey/viem`](https://github.com/tkhq/sdk/tree/main/packages/viem) signer and [`@gelatonetwork/relay-sdk-viem`](https://github.com/gelatodigital/relay-sdk-viem).
-
-
-
-
-
-
-
-#### How Infinex leverages Turnkey and Gelato
-
-Infinex, a platform designed to unify the decentralized ecosystem and applications under a single UX layer, eliminates the complexities of navigating fragmented crypto protocols. By integrating **Turnkey** and **Gelato**, Infinex delivers a seamless, secure, and cost-efficient experience for decentralized finance users.
-
-- **Secure Key Management with Turnkey**: Infinex ensures private keys are securely managed within Turnkey’s infrastructure, removing the need for traditional wallet pop-ups. This approach streamlines authentication through passkeys, offering a frictionless and secure user experience.
-
-- **Gasless Transactions with Gelato**: Leveraging Gelato’s Relay (ERC-2771), Infinex enables fully **sponsored transactions**, allowing users to interact with decentralized applications without ever paying gas fees. This enhances accessibility and usability, ensuring that users can participate without holding or managing native blockchain tokens for fees.
-
-The synergy between Turnkey and Gelato allows Infinex to offer an intuitive, cost-free user experience while maintaining the highest standards of security and scalability.
-
-### React Native demo app ([code](https://github.com/tkhq/react-native-demo-wallet))
-
-A React Native app that demonstrates how to use the Turnkey's JavaScript packages in a mobile environment to authenticate users, create wallets, export wallets, sign messages, and more
-
-
-
-
-See [https://github.com/tkhq/react-native-demo-wallet](https://github.com/tkhq/react-native-demo-wallet)
-for the code.
-
-### Flutter demo app ([code](https://github.com/tkhq/dart-sdk/tree/main/examples/flutter-demo-app))
-
-A Flutter app that demonstrates how to use the Turnkey's Flutter packages to authenticate users, create wallets, export wallets, sign messages, and more
-
-
-
-
-See [https://github.com/tkhq/dart-sdk/tree/main/examples/flutter-demo-app](https://github.com/tkhq/dart-sdk/tree/main/examples/flutter-demo-app)
-for the code
-
-### SDKs
-
-
-
-### Next steps
-
-Learn more about our powerful features [here](/embedded-wallets/features/overview).
diff --git a/embedded-wallets/sub-organization-auth.mdx b/embedded-wallets/sub-organization-auth.mdx
deleted file mode 100644
index a378b642..00000000
--- a/embedded-wallets/sub-organization-auth.mdx
+++ /dev/null
@@ -1,244 +0,0 @@
----
-title: "Email authentication"
-description: "Email auth is a powerful feature to couple with [sub-organizations](/concepts/sub-organizations) for your users. This approach empowers your users to authenticate their Turnkey in a simple way (via email!), while minimizing your involvement: we engineered this feature to ensure your organization is unable to take over sub-organizations even if it wanted to."
----
-
-{/* This is an internal note from Traian: this is a leftover, not referenced anywhere, we can probably delete it */}
-
-
-Our [Demo Embedded Wallet](https://wallet.tx.xyz) application serves an example of how email auth functionality might be integrated. We encourage you to try it (and check out the [code](https://github.com/tkhq/demo-embedded-wallet)) before diving into your own implementation.
-
-## Prerequisites
-
-Make sure you have set up your primary Turnkey organization with at least one API user that can programmatically initiate email auth on behalf of suborgs. Check out our [Quickstart guide](/getting-started/quickstart) if you need help getting started. To allow an API user to initiate email auth, you'll need the following policy in your main organization:
-
-```json
-{
- "effect": "EFFECT_ALLOW",
- "consensus": "approvers.any(user, user.id == '')",
- "condition": "activity.resource == 'AUTH' && activity.action == 'CREATE'"
-}
-```
-
-## Helper packages
-
-- We have released open-source code to create target encryption keys, decrypt auth credentials, and sign Turnkey activities. We've deployed this as a static HTML page hosted on `auth.turnkey.com` meant to be embedded as an iframe element (see the code [here](https://github.com/tkhq/frames)). This ensures the auth credentials are encrypted to keys that your organization doesn't have access to (because they live in the iframe, on a separate domain)
-- We have also built a package to help you insert this iframe and interact with it in the context of email auth: [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper)
-
-In the rest of this guide we'll assume you are using these helpers.
-
-## Email auth step-by-step
-
-Here's a diagram summarizing the email auth flow step-by-step ([direct link](/assets/files/email_auth_steps-d4f7ca188fd3fb9a2de5557b4cf39c7b.png)):
-
-
- 
-
-
-Let's review these steps in detail:
-
-
-
- User on `yoursite.xyz` clicks "auth", and a new auth UI is shown. We recommend this auth UI be a new hosted page of your site or application, which contains language explaining to the user what steps they will need to take next to successfully authenticate. While the UI is in a loading state your frontend uses [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper) to insert a new iframe element:
-
- ```js
- const iframeStamper = new IframeStamper({
- iframeUrl: "https://auth.turnkey.com",
- // Configure how the iframe element is inserted on the page
- iframeContainerId: "your-container",
- iframeElementId: "turnkey-iframe",
- });
-
- // Inserts the iframe in the DOM. This creates the new encryption target key
- const publicKey = await iframeStamper.init();
- ```
-
-
- Your code receives the iframe public key and shows the auth form, and the user enters their email address.
-
-
- Your app can now create and sign a new `EMAIL_AUTH` activity with the user email and the iframe public key in the parameters. Optional arguments include a custom name for the API key, and a specific duration (denoted in seconds) for it. Note: you'll need to retrieve the sub-organization ID based on the user email.
-
-
- Email is received by the user.
-
-
- User copies and pastes their auth code into your app. Remember: this code is an encrypted credential which can only be decrypted within the iframe. In order to enable persistent sessions, save the auth code in local storage:
-
- ```js
- window.localStorage.setItem("BUNDLE", bundle);
- ```
-
- See [Email Customization](#email-customization) below to use a magic link instead of a one time code.
-
-
- Your app injects the auth code into the iframe for decryption:
-
- ```js
- await iframeStamper.injectCredentialBundle(code);
- ```
-
-
- At this point, the user is authenticated\!
-
-
- Your app should use [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper) to sign a new activity, e.g. `CREATE_WALLET`:
-
- ```js
- // New client instantiated with our iframe stamper
- const client = new TurnkeyClient(
- { baseUrl: "https://api.turnkey.com" },
- iframeStamper,
- );
-
- // Sign and submits the CREATE_WALLET activity
- const response = await client.createWallet({
- type: "ACTIVITY_TYPE_CREATE_WALLET",
- timestampMs: String(Date.now()),
- organizationId: authResponse.organizationId,
- parameters: {
- walletName: "Default Wallet",
- accounts: [
- {
- curve: "CURVE_SECP256K1",
- pathFormat: "PATH_FORMAT_BIP32",
- path: "m/44'/60'/0'/0/0",
- addressFormat: "ADDRESS_FORMAT_ETHEREUM",
- },
- ],
- },
- });
- ```
-
-
- User navigates to a new tab.
-
-
- Because the code was also saved in local storage (step 6), it can be injected into the iframe across different tabs, resulting in a persistent session. See our [Demo Embedded Wallet](https://wallet.tx.xyz) for a [sample implementation](https://github.com/tkhq/demo-embedded-wallet/blob/942ccc97de7f9289892b1714b10f3a21afec71b3/src/providers/auth-provider.tsx#L150-L171), specifically dealing with sharing the iframeStamper across components.
-
- ```js
- const code = window.localStorage.getItem("BUNDLE");
- await iframeStamper.injectCredentialBundle(code);
- ```
-
-
- Again, the user is authenticated, and able to initiate activities\!
-
-
- Just like step 8, the iframeStamper can be used to sign another activity.
-
- ```js
- const client = new TurnkeyClient(
- { baseUrl: "https://api.turnkey.com" },
- iframeStamper,
- );
-
- // Sign and submits a SIGN_TRANSACTION activity
- const response = await client.signTransaction({
- type: "ACTIVITY_TYPE_SIGN_TRANSACTION_V2",
- timestampMs: String(Date.now()),
- organizationId: authResponse.organizationId,
- parameters: {
- signWith: "0x...",
- type: "TRANSACTION_TYPE_ETHEREUM",
- unsignedTransaction: "unsigned-tx",
- },
- });
- ```
-
-
-
-Congrats\! You've succcessfully implemented Email Auth\!
-
-## Integration notes
-
-### Email customization
-
-We offer customization for the following:
-
-- `appName`: the name of the application. This will be used in the email's subject, e.g. `Sign in to ${appName}`
-- `logoUrl`: a link to a PNG with a max width of 340px and max height of 124px
-- `magicLinkTemplate`: a template for the URL to be used in the magic link button, e.g. `https://dapp.xyz/%s`. The auth bundle will be interpolated into the `%s`
-
-```js
-// Sign and submits the EMAIL_AUTH activity
-const response = await client.emailAuth({
- type: "ACTIVITY_TYPE_EMAIL_AUTH",
- timestampMs: String(Date.now()),
- organizationId: ,
- parameters: {
- email: ,
- targetPublicKey: ,
- apiKeyName: ,
- expirationSeconds: ,
- emailCustomization: {
- appName: ,
- logoUrl: ,
- magicLinkTemplate:
- }
- },
-});
-```
-
-### Bespoke email templates
-
-We also support custom HTML email templates for [**Enterprise**](https://www.turnkey.com/pricing) clients. This allows you to inject arbitrary data from a JSON string containing key-value pairs. In this case, the `emailCustomization` variable may look like:
-
-```js
-...
-emailCustomization: {
- templateId: ,
- templateVariables: "{\"username\": \"alice and bob\"}"
-}
-...
-```
-
-In this specific example, the value `alice and bob` can be interpolated into the email template using the key `username`. The use of such template variables is purely optional.
-
-Here's an example of a custom HTML email containing an email auth bundle:
-
-
- 
-
-
-
- [**Bespoke HTML templates**](https://docs.turnkey.com/embedded-wallets/sub-organization-auth#bespoke-email-templates) and [**custom email sender domains**](https://docs.turnkey.com/embedded-wallets/sub-organization-auth#custom-email-sender-domain) are available to [**Enterprise clients**](https://www.turnkey.com/pricing) on the **Scale tier** or higher.
-
-
-### Custom email sender domain
-
-[Enterprise](https://www.turnkey.com/pricing) clients can also customize the email sender domain. To get set up, please reach out to your Turnkey rep to get started but here is what you'll be able to configure:
-
-```js
-message InitOtpAuthIntent {
- // Optional custom email address from which to send the OTP email
- optional string send_from_email_address = "notifs@mail.domain.com";
-
- // Optional custom sender name (e.g. "MyApp Notifications")
- optional string send_from_email_sender_name = "MyApp Notifications";
-
- // Optional reply-to email address
- optional string reply_to_email_address = "reply@mail.domain.com";
-}
-```
-
-Please keep in mind that:
-
-- Email has to be from a pre-whitelisted domain
-- If there is no `send_from_email_address` or it's invalid, the other two fields are ignored
-- If `send_from_email_sender_name` is absent, it defaults to "Notifications" (again, ONLY if `send_from_email_address` is present and valid)
-- If `reply_to_email_address` is absent, then there is no reply-to added. If it is present, it must ALSO be from a valid, whitelisted domain, but it doesn't have to be the same email address as the `send_from_email_address` one (though once again, this first one MUST be present, or the other two feature are ignored)
-
-If you are interested in implementing bespoke, fully-customized email templates and sender domain, please reach out to [hello@turnkey.com](mailto:hello@turnkey.com).
-
-### Credential validity checks
-
-By default, if a Turnkey request is signed with an expired credential, the API will return a 401 error. If you'd like to validate an injected credential, you can specifically use the `whoami` endpoint:
-
-```js
-const whoamiResponse = await client.getWhoami({
- organizationId,
-});
-```
-
-A valid response indicates the credential is still live; otherwise, an error including `unable to authenticate: api key expired` will be thrown.
\ No newline at end of file
diff --git a/embedded-wallets/sub-organization-recovery.mdx b/embedded-wallets/sub-organization-recovery.mdx
deleted file mode 100644
index 84f1cfce..00000000
--- a/embedded-wallets/sub-organization-recovery.mdx
+++ /dev/null
@@ -1,116 +0,0 @@
----
-title: "Email recovery"
-description: "Email recovery shines if you are leveraging [sub-organizations](/concepts/sub-organizations) to create embedded wallets for your users. This allows your users to recover their Turnkey account if something goes wrong with their passkeys, and keeps you out of the loop: we engineered this feature to ensure your organization is unable to take over sub-organizations even if it wanted to."
----
-
-{/* This is an internal note from Traian: email recovery is in maintenance mode, this page should be removed as some point, for now I'm just gonna hide it from the public */}
-
-
- Email Recovery is a legacy flow, now superseded by [Email Auth](/embedded-wallets/sub-organization-auth), which can used to implement recovery flows and more.
-
-
-A simple example demonstrating email recovery end-to-end can be found [here](https://github.com/tkhq/sdk/tree/main/examples/email-recovery).
-
-## Prerequisites
-
-Make sure you have set up your primary Turnkey organization with at least one API user that can programmatically initiate email recovery on behalf of suborgs. Check out our [Quickstart guide](/getting-started/quickstart) if you need help getting started. To allow an API user to initiate email recovery, you'll need the following policy in your main organization:
-
-```json
-{
- "effect": "EFFECT_ALLOW",
- "consensus": "approvers.any(user, user.id == '')",
- "condition": "activity.resource == 'RECOVERY' && activity.action == 'CREATE'"
-}
-```
-
-## Helper packages
-
-* We have released open-source code to create target encryption keys, decrypt recovery credentials, and sign Turnkey activities. We've deployed this a static HTML page hosted on `recovery.turnkey.com` meant to be embedded as an iframe element (see the code [here](https://github.com/tkhq/frames)). This ensures the recovery credentials are encrypted to keys that your organization doesn't have access to (because they live in the iframe, on a separate domain)
-* We have also built a package to help you insert this iframe and interact with it in the context of email recovery: [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper)
-
-In the rest of this guide we'll assume you are using these helpers.
-
-## Email recovery step-by-step
-
-Here's a diagram summarizing the email recovery flow step-by-step ([direct link](/assets/files/email_recovery_steps-d43c6b808682671a8294b7f420efe2a5.png)):
-
-
-
-
-
-Let's review these steps in detail:
-
-
- User on `yoursite.xyz` clicks "recovery", and a new recovery UI is shown. We recommend this recovery UI be a new hosted page of your site or application, which contains language explaining to the user what steps they will need to take next to complete recovery. While the UI is in a loading state your frontend uses [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper) to insert a new iframe element:
-
- ```js
- const iframeStamper = new IframeStamper({
- iframeUrl: "https://recovery.turnkey.com",
- // Configure how the iframe element is inserted on the page
- iframeContainerId: "your-container",
- iframeElementId: "turnkey-iframe",
- });
-
- // Inserts the iframe in the DOM. This creates the new encryption target key
- const publicKey = await iframeStamper.init();
- ```
-
-
- Your code receives the iframe public key and shows the recovery form, and the user enters their email address.
-
-
- Your app can now create and sign a new `INIT_USER_EMAIL_RECOVERY` activity with the user email and the iframe public key in the parameters. Note: you'll need to retrieve the sub-organization ID based on the user email.
-
-
-
- Email is received by the user.
-
-
- User copies and pastes their recovery code into your app. Remember: this code is an encrypted credential which can only be decrypted within the iframe.
-
-
-
- Your app injects the recovery code into the iframe for decryption:
-
- ```bash
- await iframeStamper.injectCredentialBundle(code);
- ```
-
-
- Your app prompts the user to create a new passkey (using our SDK functionality):
-
- ```js
- // Creates a new passkey
- let attestation = await getWebAuthnAttestation(...params...)
- ```
-
-
-
- Your app uses [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper) to sign a new `RECOVER_USER` activity:
-
- ```js
- // New client instantiated with our iframe stamper
- const client = new TurnkeyClient(
- { baseUrl: "https://api.turnkey.com" },
- iframeStamper,
- );
-
- // Sign and submits the RECOVER_USER activity
- const response = await client.recoverUser({
- type: "ACTIVITY_TYPE_RECOVER_USER",
- timestampMs: String(Date.now()),
- organizationId: initRecoveryResponse.organizationId,
- parameters: {
- userId: initRecoveryResponse.userId,
- authenticator: {
- authenticatorName: data.authenticatorName,
- challenge: base64UrlEncode(challenge),
- attestation: attestation,
- },
- },
- });
- ```
-
-Once the `RECOVER_USER` activity is successfully posted, the recovery is complete! If this activity succeeds, your frontend can redirect to login/sign-in or perform crypto signing with the new passkey.
-
-
diff --git a/reference/auth-proxy.mdx b/features/authentication/auth-proxy.mdx
similarity index 100%
rename from reference/auth-proxy.mdx
rename to features/authentication/auth-proxy.mdx
diff --git a/authentication/backend-setup.mdx b/features/authentication/backend-setup.mdx
similarity index 97%
rename from authentication/backend-setup.mdx
rename to features/authentication/backend-setup.mdx
index 6df9e1b6..e53e359b 100644
--- a/authentication/backend-setup.mdx
+++ b/features/authentication/backend-setup.mdx
@@ -3,6 +3,8 @@ title: "Backend authentication"
description: "Guide for integrating Turnkey authentication into your backend, covering session JWT creation, validation, and enforcing user access controls."
---
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
## Introduction
This guide shows you how to use Turnkey as the foundation for your own backend authentication system. You’ll learn how to issue, send, and validate session JWTs, and enforce access controls in your backend.
@@ -332,11 +334,6 @@ To validate the session JWT:
## Advanced topics
-
- Learn about advanced patterns like multi-signature setups requiring approvals
- from both the user and the backend.
-
+
+
+
diff --git a/authentication/bring-your-own-auth.mdx b/features/authentication/bring-your-own-auth.mdx
similarity index 90%
rename from authentication/bring-your-own-auth.mdx
rename to features/authentication/bring-your-own-auth.mdx
index e4a4045c..79c5b972 100644
--- a/authentication/bring-your-own-auth.mdx
+++ b/features/authentication/bring-your-own-auth.mdx
@@ -70,13 +70,13 @@ After provisioning, each login follows these steps:
## Requirements for your OIDC issuer
-To use the non-custodial flow, your auth system must issue OIDC-compliant tokens with standard claims (`iss`, `sub`, `aud`, `exp`), a publicly reachable `/.well-known/openid-configuration` endpoint, and a `nonce` set to `sha256(publicKey)` to bind the token to the user's device keypair. See [OIDC token verification](/authentication/social-logins#oidc-token-verification) for the full details on how Turnkey validates tokens.
+To use the non-custodial flow, your auth system must issue OIDC-compliant tokens with standard claims (`iss`, `sub`, `aud`, `exp`), a publicly reachable `/.well-known/openid-configuration` endpoint, and a `nonce` set to `sha256(publicKey)` to bind the token to the user's device keypair. See [OIDC token verification](/features/authentication/social-logins#oidc-token-verification) for the full details on how Turnkey validates tokens.
## Integration flow
### Step 1: Register the user
-When a user first authenticates, create a Turnkey sub-org for them with your OIDC provider registered. Registration requires a valid OIDC token — Turnkey verifies its signature against your JWKS and extracts the `iss`, `sub`, and `aud` claims, storing them as the user's identity fingerprint. The token itself is not retained; on each subsequent login a fresh token is verified independently and matched against that fingerprint. See [Registration vs. login tokens](/authentication/social-logins#registration-vs-login-tokens) for the full explanation.
+When a user first authenticates, create a Turnkey sub-org for them with your OIDC provider registered. Registration requires a valid OIDC token — Turnkey verifies its signature against your JWKS and extracts the `iss`, `sub`, and `aud` claims, storing them as the user's identity fingerprint. The token itself is not retained; on each subsequent login a fresh token is verified independently and matched against that fingerprint. See [Registration vs. login tokens](/features/authentication/social-logins#registration-vs-login-tokens) for the full explanation.
```ts
await client.createSubOrganization({
@@ -131,7 +131,7 @@ export async function login({ idToken, publicKey, suborgId }) {
Turnkey's enclave verifies the token signature against your JWKS and checks the nonce matches `sha256(publicKey)`. The resulting session JWT is scoped to that public key — only the device holding the private key can use it to sign.
-If you are using `@turnkey/react-wallet-kit`, see [Advanced backend authentication](/sdks/react/advanced-backend-authentication) for how to wire this up on the frontend. For a working implementation of this flow, see the [oauth example](https://github.com/tkhq/sdk/tree/main/examples/oauth) in the SDK — it uses Google as the provider, but the client/backend split and nonce binding pattern are identical for any OIDC issuer.
+If you are using `@turnkey/react-wallet-kit`, see [Advanced backend authentication](/solutions/embedded-wallets/integration-guide/react/advanced-backend-authentication) for how to wire this up on the frontend. For a working implementation of this flow, see the [oauth example](https://github.com/tkhq/sdk/tree/main/examples/oauth) in the SDK — it uses Google as the provider, but the client/backend split and nonce binding pattern are identical for any OIDC issuer.
## Adding an OIDC provider to an existing user
diff --git a/authentication/email.mdx b/features/authentication/email.mdx
similarity index 85%
rename from authentication/email.mdx
rename to features/authentication/email.mdx
index e7789371..4b80ec29 100644
--- a/authentication/email.mdx
+++ b/features/authentication/email.mdx
@@ -60,7 +60,7 @@ The legacy iframe-based flow using `INIT_USER_EMAIL_RECOVERY` and `RECOVER_USER`
## Prerequisites
-Make sure you have set up your primary Turnkey organization with at least one API user that can programmatically initiate email auth and create suborganizations. Check out our [Quickstart guide](/getting-started/quickstart) if you need help getting started. To allow an API user to initiate email auth, you'll need the following policy in your main organization:
+Make sure you have set up your primary Turnkey organization with at least one API user that can programmatically initiate email auth and create suborganizations. Check out our [Quickstart guide](/get-started/quickstart) if you need help getting started. To allow an API user to initiate email auth, you'll need the following policy in your main organization:
```json
{
@@ -113,8 +113,6 @@ After receiving the verification token, users complete OTP authentication flow w
- `expirationSeconds`: optional validity window (defaults to 15 minutes)
- `invalidateExisting`: optional boolean to invalidate previous login sessions
-If you are migrating from a legacy OTP flow to the new updated flow, check out the [OTP Migration Guide](/authentication/otp-migration-guide) for details on required changes.
-

@@ -199,88 +197,63 @@ const response = await client.emailAuth({
**Effective December 16, 2025**
-
+
Beginning December 16, 2025, all email-based OTP and recovery activities will require the `appName` parameter. Existing SDK versions will continue working, but upgrading without setting an `appName` will break email-based flows.
-
-
- **Affected:** Anyone using Auth Proxy without `appName` set
-
- **Action:** Set `appName` under [email configuration](https://app.turnkey.com/dashboard/walletKit)
-
-
- **Affected:** Users calling `init_otp_auth`, `init_otp`, `email_recovery`, or `email_auth` without `appName`
-
- **Action:**
- • For `email_recovery` or `email_auth`: include `appName` in your request
- • For `init_otp` or `init_otp_auth`: update your API call to match the new input structure when upgrading to the latest server-SDK
-
-
+ **Auth Proxy users** — Set `appName` under [email configuration](https://app.turnkey.com/dashboard/walletKit) in the dashboard.
+
+ **Server SDK users** — If you call `init_otp_auth`, `init_otp`, `email_recovery`, or `email_auth` without `appName`:
+ - For `email_recovery` or `email_auth`: include `appName` in your request
+ - For `init_otp` or `init_otp_auth`: update your API call to match the new input structure when upgrading to the latest server SDK
+
-
- Both methods use the same parameter structure. Here's an example with `emailAuth`:
-
- ```js
- await client.emailAuth({
- parameters: {
- email: "user@example.com",
- targetPublicKey: "",
- emailCustomization: {
- appName: "Your App Name" // this is now required
- }
- }
- });
- ```
-
-
-
- Both methods use the same parameter structure. Here's an example with `initOtp`:
-
- ```js
- await client.initOtp({
- parameters: {
- otpType: "OTP_TYPE_EMAIL",
- contact: "user@example.com",
- appName: "Your App Name", // this is now required
- emailCustomization: {
- // other optional customization
- }
- }
- });
- ```
-
-
-
- If you manage email flows with policies, update to the new activity types:
+**`emailAuth` and `emailRecovery`** — both methods use the same parameter structure:
- **EMAIL_AUTH**
- Old: `ACTIVITY_TYPE_EMAIL_AUTH`, `ACTIVITY_TYPE_EMAIL_AUTH_V2`
- New: `ACTIVITY_TYPE_EMAIL_AUTH_V3`
+```js
+await client.emailAuth({
+ parameters: {
+ email: "user@example.com",
+ targetPublicKey: "",
+ emailCustomization: {
+ appName: "Your App Name" // this is now required
+ }
+ }
+});
+```
- **INIT_OTP_AUTH**
- Old: `ACTIVITY_TYPE_INIT_OTP_AUTH`, `ACTIVITY_TYPE_INIT_OTP_AUTH_V2`
- New: `ACTIVITY_TYPE_INIT_OTP_AUTH_V3`
+**`initOtp` and `initOtpAuth`** — both methods use the same parameter structure:
- **INIT_OTP** (contact verification & signup)
- Old: `ACTIVITY_TYPE_INIT_OTP`, `ACTIVITY_TYPE_INIT_OTP_V2`
- New: `ACTIVITY_TYPE_INIT_OTP_V3`
+```js
+await client.initOtp({
+ parameters: {
+ otpType: "OTP_TYPE_EMAIL",
+ contact: "user@example.com",
+ appName: "Your App Name", // this is now required
+ emailCustomization: {
+ // other optional customization
+ }
+ }
+});
+```
- **VERIFY_OTP**
- Old: `ACTIVITY_TYPE_VERIFY_OTP`
- New: `ACTIVITY_TYPE_VERIFY_OTP_V2`
+
- **OTP_LOGIN**
- Old: `ACTIVITY_TYPE_OTP_LOGIN`
- New: `ACTIVITY_TYPE_OTP_LOGIN_V2`
+
- **INIT_USER_EMAIL_RECOVERY**
- Old: `ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY`
- New: `ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY_V2`
-
+If you manage email flows with policies, update to the new activity types:
-
+| **Flow** | **Old activity type** | **New activity type** |
+| :--- | :--- | :--- |
+| Email auth | `ACTIVITY_TYPE_EMAIL_AUTH`, `ACTIVITY_TYPE_EMAIL_AUTH_V2` | `ACTIVITY_TYPE_EMAIL_AUTH_V3` |
+| Init OTP auth | `ACTIVITY_TYPE_INIT_OTP_AUTH`, `ACTIVITY_TYPE_INIT_OTP_AUTH_V2` | `ACTIVITY_TYPE_INIT_OTP_AUTH_V3` |
+| Init OTP (signup) | `ACTIVITY_TYPE_INIT_OTP`, `ACTIVITY_TYPE_INIT_OTP_V2` | `ACTIVITY_TYPE_INIT_OTP_V3` |
+| Verify OTP | `ACTIVITY_TYPE_VERIFY_OTP` | `ACTIVITY_TYPE_VERIFY_OTP_V2` |
+| OTP login | `ACTIVITY_TYPE_OTP_LOGIN` | `ACTIVITY_TYPE_OTP_LOGIN_V2` |
+| Email recovery | `ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY` | `ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY_V2` |
+
+
### Email templates
@@ -341,13 +314,13 @@ If you are interested in implementing bespoke, fully-customized email templates
### Authorization
-Authorization is managed through our [policy engine](/concepts/policies/overview):
+Authorization is managed through our [policy engine](/features/policies/overview):
### Authentication
Both OTP-based and credential bundle authentication activities:
-- Can be performed by [root quorum](/concepts/users/root-quorum#root-quorum) or users with proper policy authorization
+- Can be performed by [root quorum](/features/users/root-quorum#root-quorum) or users with proper policy authorization
- Require the respective feature to be enabled in the organization and sub-organization
- Can target any user in the organization or sub-organizations
diff --git a/authentication/overview.mdx b/features/authentication/overview.mdx
similarity index 59%
rename from authentication/overview.mdx
rename to features/authentication/overview.mdx
index b262ef42..55d56e0a 100644
--- a/authentication/overview.mdx
+++ b/features/authentication/overview.mdx
@@ -3,6 +3,8 @@ title: Overview
description: Learn about supported authentication methods for Turnkey, how to add them, and usage details.
---
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
Turnkey's wallet system supports granular controls on who can access wallets and what actions different users can perform.
To enforce these controls, Turnkey's API must verify the identity of the party requesting a wallet action, ensuring that only authorized actions are executed by the system. This process is known as **authentication**.
@@ -15,7 +17,7 @@ With **API authentication**, Turnkey authenticates a request from your server di
In addition to the API secret, you can also configure **authorization policies** that control specific wallets, private keys, and other resources. Any requests to use or update these resources require approval according to the corresponding policy. This allows you to enforce granular controls on all Turnkey resources.
-For backend implementation details, see our [Backend Setup](/authentication/backend-setup) guide.
+For backend implementation details, see our [Backend Setup](/features/authentication/backend-setup) guide.
**API Reference**: [Create API Keys](/api-reference/api-keys/create-api-keys), [Get API Keys](/api-reference/api-keys/get-api-key)
@@ -25,10 +27,10 @@ Turnkey is a powerful toolkit for progressive authentication of users. With fine
Using any of Turnkey's client-side SDKs, your app can authenticate users across web2 and web3 accounts, including:
-- **WebAuthN/Passkeys**: Biometric or passkey-based login based on the WebAuthn standard. [Learn more](/authentication/passkeys/introduction)
-- **Email or SMS**: Passwordless login via a one-time passcode sent to a user's email address or phone number. [Learn more](/authentication/email) | [SMS Authentication](/authentication/sms)
-- **OAuth and social logins**: Social login with Google, Apple, Twitter, Discord, GitHub, LinkedIn, and more. [Learn more](/authentication/social-logins)
-- **Wallets**: External wallet login via Sign-In With Ethereum and Sign-In With Solana. [Learn more](/embedded-wallets/code-examples/wallet-auth)
+- **WebAuthN/Passkeys**: Biometric or passkey-based login based on the WebAuthn standard. [Learn more](/features/authentication/passkeys/introduction)
+- **Email or SMS**: Passwordless login via a one-time passcode sent to a user's email address or phone number. [Learn more](/features/authentication/email) | [SMS Authentication](/features/authentication/sms)
+- **OAuth and social logins**: Social login with Google, Apple, Twitter, Discord, GitHub, LinkedIn, and more. [Learn more](/features/authentication/social-logins)
+- **Wallets**: External wallet login via Sign-In With Ethereum and Sign-In With Solana. [Learn more](/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview)
Your app can configure each of these authentication methods to be an upfront login method, or as an account that users link later.
@@ -36,34 +38,14 @@ All of Turnkey's authentication methods create a common user object, where you c
Once a user successfully authenticates with Turnkey, Turnkey creates a session for that user that your app can use to represent an authenticated session or to make authenticated requests to your backend.
-For information about managing authenticated sessions, see our [Sessions](/authentication/sessions) documentation.
+For information about managing authenticated sessions, see our [Sessions](/features/authentication/sessions) documentation.
## Related resources
-
-
- Biometric and hardware-based passwordless authentication using WebAuthn
- standard.
-
-
- Passwordless login via one-time codes sent to users' email addresses.
-
-
- User verification through one-time passwords sent via text message.
-
-
- OAuth authentication with popular social providers like Google, Apple, and
- Twitter.
-
-
- Manage authenticated user sessions and access tokens in your application.
-
-
+
+
+
+
+
+
+
diff --git a/authentication/passkeys/discoverable-vs-non-discoverable.mdx b/features/authentication/passkeys/discoverable-vs-non-discoverable.mdx
similarity index 100%
rename from authentication/passkeys/discoverable-vs-non-discoverable.mdx
rename to features/authentication/passkeys/discoverable-vs-non-discoverable.mdx
diff --git a/authentication/passkeys/integration.mdx b/features/authentication/passkeys/integration.mdx
similarity index 96%
rename from authentication/passkeys/integration.mdx
rename to features/authentication/passkeys/integration.mdx
index 8071486c..39978ad2 100644
--- a/authentication/passkeys/integration.mdx
+++ b/features/authentication/passkeys/integration.mdx
@@ -63,7 +63,7 @@ const completedActivity = await activityPoller({
* [`@turnkey/viem`](https://www.npmjs.com/package/@turnkey/viem) is a package wrapping all of the above so that you work directly with Viem without worrying about passkeys. See [this demo](https://github.com/tkhq/demo-viem-passkeys).
-Regardless of whether you use our helpers and abstractions, take a look at [our registration and authentication options guide](/authentication/passkeys/options). This will help you choose the right options for your passkey flow.
+Regardless of whether you use our helpers and abstractions, take a look at [our registration and authentication options guide](/features/authentication/passkeys/options). This will help you choose the right options for your passkey flow.
If you have questions, feedback, or find yourself in need of an abstraction or integration that doesn't exist yet, please get in touch with us! You can
@@ -75,4 +75,4 @@ We're here to make this as easy as possible for you and your team!
## Passkey wallets with sub-organizations
-If you're wondering how to create independent, non-custodial wallets for your end-users, head to [Sub-Organizations](/concepts/sub-organizations). In short: you'll be able to pass the registered passkeys as part of a "create sub-organization" activity, making your end-users the sole owners of any resource created within the sub-organization (including private keys). Your organization will only have read permissions.
\ No newline at end of file
+If you're wondering how to create independent, non-custodial wallets for your end-users, head to [Sub-Organizations](/features/sub-organizations). In short: you'll be able to pass the registered passkeys as part of a "create sub-organization" activity, making your end-users the sole owners of any resource created within the sub-organization (including private keys). Your organization will only have read permissions.
\ No newline at end of file
diff --git a/authentication/passkeys/introduction.mdx b/features/authentication/passkeys/introduction.mdx
similarity index 98%
rename from authentication/passkeys/introduction.mdx
rename to features/authentication/passkeys/introduction.mdx
index aafd8a4a..7697d31e 100644
--- a/authentication/passkeys/introduction.mdx
+++ b/features/authentication/passkeys/introduction.mdx
@@ -54,4 +54,4 @@ We believe **it's time to move away from passwords** so we've built Turnkey with
Authentication to Turnkey requires a passkey signature. No password needed!
-Next up, learn about how you can integrate passkeys into your app, [here](/authentication/passkeys/integration).
+Next up, learn about how you can integrate passkeys into your app, [here](/features/authentication/passkeys/integration).
diff --git a/authentication/passkeys/native.mdx b/features/authentication/passkeys/native.mdx
similarity index 100%
rename from authentication/passkeys/native.mdx
rename to features/authentication/passkeys/native.mdx
diff --git a/authentication/passkeys/options.mdx b/features/authentication/passkeys/options.mdx
similarity index 96%
rename from authentication/passkeys/options.mdx
rename to features/authentication/passkeys/options.mdx
index fc31db06..260f29dd 100644
--- a/authentication/passkeys/options.mdx
+++ b/features/authentication/passkeys/options.mdx
@@ -84,7 +84,7 @@ This option, if set, restricts the type of authenticators that can be registered
#### `requireResidentKey` and `residentKey`
-These options allow you to specify whether you want your users to create discoverable or non-discoverable credentials. See [Discoverable vs. non-discoverable](/authentication/passkeys/discoverable-vs-non-discoverable) for more information. Default values: `residentKey` is `discouraged` and `requireResidentKey` is `false`.
+These options allow you to specify whether you want your users to create discoverable or non-discoverable credentials. See [Discoverable vs. non-discoverable](/features/authentication/passkeys/discoverable-vs-non-discoverable) for more information. Default values: `residentKey` is `discouraged` and `requireResidentKey` is `false`.
Important note: the default for `requireResidentKey` (`discouraged`) results in different outcomes based on OS: Android devices create non-discoverable credentials whereas iOS devices create discoverable credentials. If you want to create discoverable credentials whenever possible, set `requireResidentKey` to `false` and `residentKey` to `preferred`, which work across Android and iOS devices.
@@ -116,7 +116,7 @@ Must match the `rp.id` option during passkey registration. Passkeys are domain b
### `allowCredentials`
-List of objects restricting which credentials can be used during authentication. This is crucial to specify if you're using [non-discoverable credentials](/authentication/passkeys/discoverable-vs-non-discoverable#non-discoverable-credentials) or if you want to tailor browser prompts to the right type of transport.
+List of objects restricting which credentials can be used during authentication. This is crucial to specify if you're using [non-discoverable credentials](/features/authentication/passkeys/discoverable-vs-non-discoverable#non-discoverable-credentials) or if you want to tailor browser prompts to the right type of transport.
Each object in this list has an ID (the credential ID) and a list of transports (e.g. "hybrid", "internal", "usb", etc). The `transports` list is **optional** but results in better, more targeted prompts. For example, here are screenshot of targeted prompts captured on Chrome, on a MacBook laptop:
diff --git a/authentication/proxying-signed-requests.mdx b/features/authentication/proxying-signed-requests.mdx
similarity index 100%
rename from authentication/proxying-signed-requests.mdx
rename to features/authentication/proxying-signed-requests.mdx
diff --git a/authentication/sessions.mdx b/features/authentication/sessions.mdx
similarity index 100%
rename from authentication/sessions.mdx
rename to features/authentication/sessions.mdx
diff --git a/authentication/sms.mdx b/features/authentication/sms.mdx
similarity index 91%
rename from authentication/sms.mdx
rename to features/authentication/sms.mdx
index 09fdfe55..618667e5 100644
--- a/authentication/sms.mdx
+++ b/features/authentication/sms.mdx
@@ -20,7 +20,7 @@ Select your country below to view pricing.
## Prerequisites
-Make sure you have set up your primary Turnkey organization with at least one API user that can programmatically initiate OTP and create sub-organizations. Check out our [Quickstart guide](/getting-started/quickstart) if you need help getting started. To allow an API user to initiate email auth, you'll need the following policy in your main organization:
+Make sure you have set up your primary Turnkey organization with at least one API user that can programmatically initiate OTP and create sub-organizations. Check out our [Quickstart guide](/get-started/quickstart) if you need help getting started. To allow an API user to initiate email auth, you'll need the following policy in your main organization:
```json
{
@@ -38,7 +38,6 @@ SMS authentication uses three activities:
2. `VERIFY_OTP_V2` — securely verifies the code and returns a signed verificationToken JWT
3. `OTP_LOGIN_V2` — validates the verificationToken and returns a session (signed with the verification token key)
-If you are migrating from a legacy OTP flow to the new updated flow, check out the [OTP Migration Guide](/authentication/otp-migration-guide) for details on required changes.
## Implementation
@@ -79,7 +78,6 @@ After receiving the verification token, users complete OTP authentication flow w
- `expirationSeconds`: optional validity window (defaults to 15 minutes)
- `invalidateExisting`: optional boolean to invalidate previous login sessions
-If you are migrating from a legacy OTP flow to the new updated flow, check out the [OTP Migration Guide](/authentication/otp-migration-guide) for details on required changes.
## Authorization
diff --git a/authentication/social-logins.mdx b/features/authentication/social-logins.mdx
similarity index 97%
rename from authentication/social-logins.mdx
rename to features/authentication/social-logins.mdx
index 2b300c66..6467f208 100644
--- a/authentication/social-logins.mdx
+++ b/features/authentication/social-logins.mdx
@@ -3,7 +3,7 @@ title: "Social logins"
description: "Social logins provide a familiar and convenient way for users to access applications using their existing accounts from popular platforms like Google, Apple, Facebook, X/Twitter, etc. Under the hood, this functionality is powered by OAuth - a robust auth protocol which enables secure user verification through OpenID Connect ([OIDC](https://openid.net/specs/openid-connect-core-1_0.html)) tokens. This feature is available exclusively for sub-organization users."
---
-Similar to [email auth](/authentication/email), social login authentication is ideal for users who prefer not to manage API keys or [passkeys](/authentication/passkeys/introduction) directly. This makes it particularly well-suited for onboarding users who are comfortable with traditional web2-style accounts but may be unfamiliar with cryptographic keys and credentials. An example implementing social login authentication for an organization can be found in our SDK repo [here](https://github.com/tkhq/sdk/tree/main/examples/oauth).
+Similar to [email auth](/features/authentication/email), social login authentication is ideal for users who prefer not to manage API keys or [passkeys](/features/authentication/passkeys/introduction) directly. This makes it particularly well-suited for onboarding users who are comfortable with traditional web2-style accounts but may be unfamiliar with cryptographic keys and credentials. An example implementing social login authentication for an organization can be found in our SDK repo [here](https://github.com/tkhq/sdk/tree/main/examples/oauth).
## Types of social login providers
@@ -277,7 +277,7 @@ The cases are as follows:
2. The end-user authenticates with a Google email address (e.g., @gmail.com) via email OTP or email auth. If they later authenticate with Google, the Google OIDC provider will automatically be added as a valid login method, provided the email matches.
3. The end-user has existing non-Google authentication methods (e.g. phone number, passkeys, etc.) and later adds Google OIDC as a login method (via [CREATE_OAUTH_PROVIDERS](/api-reference/activities/create-oauth-providers#api-key)). The email address in the Google account will be automatically marked as "verified" and linked to the existing user.
-For more information on how to implement social linking, see the [social linking code example](/embedded-wallets/code-examples/social-linking).
+For more information on how to implement social linking, see the [social linking code example](/solutions/embedded-wallets/integration-guide/react/auth).
## Setup for OAuth 2.0-only providers
diff --git a/networks/aptos.mdx b/features/networks/aptos.mdx
similarity index 100%
rename from networks/aptos.mdx
rename to features/networks/aptos.mdx
diff --git a/networks/bitcoin.mdx b/features/networks/bitcoin.mdx
similarity index 98%
rename from networks/bitcoin.mdx
rename to features/networks/bitcoin.mdx
index a61d53e5..4a926d91 100644
--- a/networks/bitcoin.mdx
+++ b/features/networks/bitcoin.mdx
@@ -5,7 +5,7 @@ sidebarTitle: "Bitcoin"
## BIP32 and BIP44: the basis for Turnkey wallets
-[BIP32](https://en.bitcoin.it/wiki/BIP_0032) and [BIP44](https://en.bitcoin.it/wiki/BIP_0044) are standards developed in the Bitcoin ecosystem. Turnkey closely follows this to power [Wallets](/concepts/wallets) since they're adopted within Bitcoin and outside, spanning many other ecosystems.
+[BIP32](https://en.bitcoin.it/wiki/BIP_0032) and [BIP44](https://en.bitcoin.it/wiki/BIP_0044) are standards developed in the Bitcoin ecosystem. Turnkey closely follows this to power [Wallets](/features/wallets) since they're adopted within Bitcoin and outside, spanning many other ecosystems.
## BIP39: mnemonics
@@ -56,7 +56,7 @@ For more information on PSBTs look here: https://learnmeabitcoin.com/technical/t
### How to use Turnkey’s policy-enabled Bitcoin transaction signing flow
The transaction signing flow works as follows:
-* Client creates Bitcoin policies for enabling or restriction transaction signing using the `bitcoin.tx` namespace. For reference look at the Policy Launguage documentation [language section](/concepts/policies/language#bitcoin) or the [Bitcoin policy examples](/concepts/policies/examples/bitcoin) documentation
+* Client creates Bitcoin policies for enabling or restriction transaction signing using the `bitcoin.tx` namespace. For reference look at the Policy Launguage documentation [language section](/features/policies/language#bitcoin) or the [Bitcoin policy examples](/features/policies/examples/bitcoin) documentation
* Client constructs a PSBT (using a library like bitcoinjs-lib[https://github.com/bitcoinjs/bitcoinjs-lib]) representing the transaction they need signed, hex serializes it and passes in the string of the hex representation of the PSBT into Turnkey’s Sign Transaction endpoint with type: `TRANSACTION_TYPE_BITCOIN`
* The `SIGN TRANSACTION` endpoint constructs the sighashes ONLY for inputs which are to be signed by the signing resource which was specified in the `SIGN TRANSACTION` request, and based on policy evaluation, signs these sighashes and reinserts them into the correct corresponding inputs in the PSBT. For more details on how reinsertion works across each address derivation type, look below.
* Client receives hex representation of PSBT with reinserted signatures, continues signing process for other inputs if needed, finalizes inputs, and broadcasts.
diff --git a/networks/cosmos.mdx b/features/networks/cosmos.mdx
similarity index 100%
rename from networks/cosmos.mdx
rename to features/networks/cosmos.mdx
diff --git a/networks/doge.mdx b/features/networks/doge.mdx
similarity index 100%
rename from networks/doge.mdx
rename to features/networks/doge.mdx
diff --git a/networks/ethereum.mdx b/features/networks/ethereum.mdx
similarity index 97%
rename from networks/ethereum.mdx
rename to features/networks/ethereum.mdx
index b668e401..cba803ef 100644
--- a/networks/ethereum.mdx
+++ b/features/networks/ethereum.mdx
@@ -14,9 +14,9 @@ To construct and sign an EVM transaction with Turnkey, we offer:
- [@turnkey/viem](https://github.com/tkhq/sdk/tree/main/packages/viem): contains a `createAccount` method to create a Turnkey-powered [custom account](https://viem.sh/docs/accounts/local) which [Viem](https://viem.sh/) can use seamlessly.
- [@turnkey/ethers](https://github.com/tkhq/sdk/tree/main/packages/ethers): contains a `TurnkeySigner` which implements Ethers' `AbstractSigner` interface. See [Ethers docs](https://docs.ethers.org/v6/api/providers/abstract-signer/#AbstractSigner).
-## Transaction Management and Gas Sponsorship
+## Transaction management and gas sponsorship
-Turnkey's [Transaction Management](/concepts/transaction-management) handles the full lifecycle of EVM transactions — construction, broadcast, nonce management, and status monitoring — down to a few API calls.
+Turnkey's [Transaction Management](/features/transaction-management) handles the full lifecycle of EVM transactions — construction, broadcast, nonce management, and status monitoring — down to a few API calls.
### What Turnkey auto-fills
@@ -49,11 +49,11 @@ Set `sponsor: false` to have gas paid by the sender's wallet. Turnkey still mana
After broadcast, Turnkey monitors your transaction until it is included in a block or fails, with structured error decoding for smart contract reverts. Query status via the [Get Send Transaction Status](/api-reference/queries/get-send-transaction-status) endpoint.
-For a full walkthrough, see [Sending Sponsored EVM Transactions](/embedded-wallets/code-examples/sending-sponsored-transactions).
+For a full walkthrough, see [Sending Sponsored EVM Transactions](/features/transaction-management/sending-sponsored-transactions).
## Transaction parsing, policies, and signing
-Turnkey has built an EVM parser which runs in a secure enclave, to parse unsigned EVM transactions and extract useful metadata: transaction source, destination, amount, chain ID, and more. See the `EthereumTransaction` struct in our [policy language](/concepts/policies/language) page for a full list.
+Turnkey has built an EVM parser which runs in a secure enclave, to parse unsigned EVM transactions and extract useful metadata: transaction source, destination, amount, chain ID, and more. See the `EthereumTransaction` struct in our [policy language](/features/policies/language) page for a full list.
As a bonus, Turnkey also takes care of combining the signature with the original payload if you use the `SIGN_TRANSACTION` activity types: the input is the unsigned payload (RLP encoded), and the output is the signed RLP encoded transaction, ready to be broadcast\!
@@ -61,7 +61,7 @@ Additionally, Turnkey supports signing operations over EIP-712 Typed Data payloa
### Ethereum ABIs
-You can use Ethereum ABIs in conjunction with our policy engine to secure users' transactions. See [the guide](/concepts/policies/smart-contract-interfaces) for more details.
+You can use Ethereum ABIs in conjunction with our policy engine to secure users' transactions. See [the guide](/features/policies/smart-contract-interfaces) for more details.
### What transaction types does Turnkey support?
@@ -233,7 +233,7 @@ You can also find examples of EIP-712-aware Policies associated with these integ
Turnkey is built to be flexible: a lot of our customers use Turnkey as a smart contract signer, alongside other types of signers.
-This is so common that AA wallet providers have integrated Turnkey as a default solution in their documentation. Refer to our [AA Wallet](/reference/aa-wallets) documentation for further information.
+This is so common that AA wallet providers have integrated Turnkey as a default solution in their documentation. Refer to our [AA Wallet](/features/wallets/aa-wallets) documentation for further information.
## EIP-1193 provider
diff --git a/networks/hyperliquid.mdx b/features/networks/hyperliquid.mdx
similarity index 72%
rename from networks/hyperliquid.mdx
rename to features/networks/hyperliquid.mdx
index b0b540e0..d19650f1 100644
--- a/networks/hyperliquid.mdx
+++ b/features/networks/hyperliquid.mdx
@@ -16,6 +16,6 @@ To construct and sign a Hyperliquid (EVM) transaction with Turnkey, we offer:
## Transaction parsing, policies, and signing
-Please refer to our [Ethereum network page](/networks/ethereum) for details on transaction parsing, policies, and signing, as Hyperliquid shares the same EVM architecture. However, HyperCore notably uses EIP-712 messages to perform various actions. More information on defining EIP-712 policies, see [here](../networks/ethereum#eip-712). Additionally, top-level policy details can be found [here](../concepts/policies/language).
+Please refer to our [Ethereum network page](/features/networks/ethereum) for details on transaction parsing, policies, and signing, as Hyperliquid shares the same EVM architecture. However, HyperCore notably uses EIP-712 messages to perform various actions. More information on defining EIP-712 policies, see [here](../networks/ethereum#eip-712). Additionally, top-level policy details can be found [here](../concepts/policies/language).
For an example of how to construct a policy targeting such Hyperliquid-specific EIP-712 messages, see [here](../concepts/policies/examples/ethereum#allow-signing-of-eip-712-payloads-for-hyperliquid-approveagent-operations).
\ No newline at end of file
diff --git a/networks/iota.mdx b/features/networks/iota.mdx
similarity index 100%
rename from networks/iota.mdx
rename to features/networks/iota.mdx
diff --git a/networks/movement.mdx b/features/networks/movement.mdx
similarity index 99%
rename from networks/movement.mdx
rename to features/networks/movement.mdx
index 868ace0b..08fb6ba5 100644
--- a/networks/movement.mdx
+++ b/features/networks/movement.mdx
@@ -202,7 +202,7 @@ Movement leverages the Move VM for smart contracts. When developing Move smart c
* Deploying Move modules
* Publishing packages
* Executing Move functions
-* Managing on-chain resources
+* Managing onchain resources
If you're building on Movement and need assistance with your Turnkey integration, feel free to contact us at [hello@turnkey.com](mailto:hello@turnkey.com), on [X](https://x.com/turnkeyhq/), or [on Slack](https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ).
```
diff --git a/networks/others.mdx b/features/networks/others.mdx
similarity index 100%
rename from networks/others.mdx
rename to features/networks/others.mdx
diff --git a/networks/overview.mdx b/features/networks/overview.mdx
similarity index 61%
rename from networks/overview.mdx
rename to features/networks/overview.mdx
index 78eef1b1..a958c6ac 100644
--- a/networks/overview.mdx
+++ b/features/networks/overview.mdx
@@ -4,7 +4,7 @@ description: "Turnkey operates at the **cryptographic curve** level rather than
mode: "wide"
---
-import NetworkLinks from "/snippets/shared/networks-links.mdx";
+import { NetworkLinks } from "/snippets/shared/networks-links.mdx";
## Multichain support at Turnkey
@@ -26,7 +26,7 @@ Cryptographic curves are our fundamental primitive, allowing Turnkey private key
Turnkey abstracts address generation, automatically deriving addresses for supported cryptocurrencies.
-For a full list of address formats you can derive on Turnkey, refer to [Address formats and Curves](/concepts/wallets).
+For a full list of address formats you can derive on Turnkey, refer to [Address formats and Curves](/features/wallets).
**Tier 3: SDK for transaction construction and signing**
@@ -38,10 +38,10 @@ At our highest level of support, Turnkey offers the ability to parse transaction
| Tier | Depth of support | EVM | SVM | BTC | ATOM | TRON | SUI | APT | TON | XRP | SEI |
| ------ | :------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- |
-| Tier 1 | Curve-level | | | | | | | | | | |
-| Tier 2 | Address derivation | | | | | | | | | | |
-| Tier 3 | SDK construction and signing | | | | | | | | | | |
-| Tier 4 | Transaction parsing and policies | | | | | | | | | | |
+| Tier 1 | Curve-level | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Tier 2 | Address derivation | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Tier 3 | SDK construction and signing | ✓ | ✓ | | | | | | | | |
+| Tier 4 | Transaction parsing and policies | ✓ | ✓ | ✓ | | ✓ | | | | | |
We are continuously evaluating and adding support for emerging assets and protocols. If there are specific cryptocurrencies you'd like to see us offer deeper support for, please let us know by contacting us at [hello@turnkey.com](mailto:hello@turnkey.com), on [X](https://x.com/turnkeyhq/), or [on Slack](https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ).
diff --git a/networks/sei.mdx b/features/networks/sei.mdx
similarity index 100%
rename from networks/sei.mdx
rename to features/networks/sei.mdx
diff --git a/networks/solana-rent-refunds.mdx b/features/networks/solana-rent-refunds.mdx
similarity index 93%
rename from networks/solana-rent-refunds.mdx
rename to features/networks/solana-rent-refunds.mdx
index 526a5003..6c6afefc 100644
--- a/networks/solana-rent-refunds.mdx
+++ b/features/networks/solana-rent-refunds.mdx
@@ -1,7 +1,7 @@
---
title: "Solana rent sponsorship"
description: "Understand how Solana rent sponsorship works, when rent is pre-funded, and how to reduce rent-refund leakage in sponsored flows."
-sidebarTitle: "Rent Sponsorship"
+sidebarTitle: "Rent sponsorship"
---
## Overview
@@ -14,9 +14,9 @@ When rent is enabled:
- If an instruction creates a new account and the user signer is the payer, Turnkey pre-funds that signer for the rent-exempt amount. The amount is based on the size of the new account data and is intended to make the account rent exempt.
-- Sponsored rent is added to your monthly gas bill and counts toward the same spend limits used for sponsored transaction fees. See [Spend limits](/concepts/transaction-management#spend-limits).
+- Sponsored rent is added to your monthly gas bill and counts toward the same spend limits used for sponsored transaction fees. See [Spend limits](/features/transaction-management#spend-limits).
-For the broader transaction-construction model behind sponsored Solana flows, including payer behavior and account-creation caveats, see [Solana transaction construction for sponsored flows](/networks/solana-transaction-construction).
+For the broader transaction-construction model behind sponsored Solana flows, including payer behavior and account-creation caveats, see [Solana transaction construction for sponsored flows](/features/networks/solana-transaction-construction).
## Enable rent sponsorship
@@ -151,7 +151,7 @@ These example deny policies can help reduce common Solana rent-leakage patterns
## Next steps
-- See [Solana (SVM) support on Turnkey](/networks/solana)
-- See [Solana transaction construction for sponsored flows](/networks/solana-transaction-construction)
-- See [Sending Sponsored Solana Transactions](/embedded-wallets/code-examples/sending-sponsored-solana-transactions)
-- See [Solana policy examples](/concepts/policies/examples/solana)
+- See [Solana (SVM) support on Turnkey](/features/networks/solana)
+- See [Solana transaction construction for sponsored flows](/features/networks/solana-transaction-construction)
+- See [Sending Sponsored Solana Transactions](/features/transaction-management/sending-sponsored-solana-transactions)
+- See [Solana policy examples](/features/policies/examples/solana)
diff --git a/networks/solana-transaction-construction.mdx b/features/networks/solana-transaction-construction.mdx
similarity index 89%
rename from networks/solana-transaction-construction.mdx
rename to features/networks/solana-transaction-construction.mdx
index ead8abe6..03d3e50d 100644
--- a/networks/solana-transaction-construction.mdx
+++ b/features/networks/solana-transaction-construction.mdx
@@ -1,7 +1,7 @@
---
title: "Solana transaction construction for sponsored flows"
description: "Understand what Turnkey manages for sponsored Solana transactions, what your application still controls, and the current transaction-construction caveats."
-sidebarTitle: "Transaction Construction"
+sidebarTitle: "Transaction construction"
---
## Overview
@@ -43,10 +43,10 @@ Recommended guardrails:
- reuse persistent token accounts where possible instead of creating and closing temporary ones repeatedly
- inspect third-party-built transactions before submission, especially when they may wrap and unwrap SOL or close accounts automatically
-If you use a routing service such as Jupiter, review the final instruction payload carefully. Temporary account creation and `CloseAccount` behavior are common sources of rent leakage and sponsorship surprises. See [Solana Rent Sponsorship](/networks/solana-rent-refunds) for refund-path risk and mitigation guidance.
+If you use a routing service such as Jupiter, review the final instruction payload carefully. Temporary account creation and `CloseAccount` behavior are common sources of rent leakage and sponsorship surprises. See [Solana Rent Sponsorship](/features/networks/solana-rent-refunds) for refund-path risk and mitigation guidance.
## Next steps
-- See [Solana (SVM) support on Turnkey](/networks/solana)
-- See [Solana Rent Sponsorship](/networks/solana-rent-refunds)
-- See [Sending Sponsored Solana Transactions](/embedded-wallets/code-examples/sending-sponsored-solana-transactions)
+- See [Solana (SVM) support on Turnkey](/features/networks/solana)
+- See [Solana Rent Sponsorship](/features/networks/solana-rent-refunds)
+- See [Sending Sponsored Solana Transactions](/features/transaction-management/sending-sponsored-solana-transactions)
diff --git a/networks/solana.mdx b/features/networks/solana.mdx
similarity index 84%
rename from networks/solana.mdx
rename to features/networks/solana.mdx
index f92caec6..d4efd0e2 100644
--- a/networks/solana.mdx
+++ b/features/networks/solana.mdx
@@ -11,9 +11,9 @@ Turnkey supports Solana address derivation with `ADDRESS_TYPE_SOLANA`. Solana ad
To construct and sign a Solana transaction we offer a `@turnkey/solana` NPM package. It offers a `TurnkeySigner` which integrates our remote signer with the official Solana [`web3js`](https://solana-labs.github.io/solana-web3.js/) library.
-## Transaction Management and Gas Sponsorship
+## Transaction management and gas sponsorship
-Turnkey's [Transaction Management](/concepts/transaction-management) handles the full lifecycle of Solana transactions — construction, broadcast, and status monitoring — down to a few API calls.
+Turnkey's [Transaction Management](/features/transaction-management) handles the full lifecycle of Solana transactions — construction, broadcast, and status monitoring — down to a few API calls.
### What Turnkey auto-fills
@@ -35,7 +35,7 @@ Set `sponsor: true` to enable fee sponsorship — your users never need to hold
To enable gas sponsorship, ensure it is activated in your Turnkey dashboard before setting `sponsor: true`.
-For sponsored Solana flows, especially when you accept prebuilt transactions, see [Solana transaction construction for sponsored flows](/networks/solana-transaction-construction) for the current payload constraints and account-creation caveats.
+For sponsored Solana flows, especially when you accept prebuilt transactions, see [Solana transaction construction for sponsored flows](/features/networks/solana-transaction-construction) for the current payload constraints and account-creation caveats.
### Solana rent sponsorship
@@ -45,7 +45,7 @@ If an instruction creates a new account and the user signer is the payer, Turnke
If those accounts are later closed, the refunded rent follows Solana account rules and can go back to the signer rather than the sponsor.
-See [Solana Rent Sponsorship](/networks/solana-rent-refunds) for setup steps, the dashboard flow, and mitigation guidance.
+See [Solana Rent Sponsorship](/features/networks/solana-rent-refunds) for setup steps, the dashboard flow, and mitigation guidance.
### Non-sponsored transactions
@@ -55,23 +55,23 @@ Set `sponsor: false` to have the transaction fee paid by the sender's wallet. Tu
After broadcast, Turnkey monitors your transaction until it is confirmed or fails. Query status via the [Get Send Transaction Status](/api-reference/queries/get-send-transaction-status) endpoint.
-For a full walkthrough, see [Sending Sponsored Solana Transactions](/embedded-wallets/code-examples/sending-sponsored-solana-transactions).
+For a full walkthrough, see [Sending Sponsored Solana Transactions](/features/transaction-management/sending-sponsored-solana-transactions).
## Transaction parsing, policies, and signing
-Turnkey has built a Solana parser which runs in a secure enclave, to parse unsigned transactions and extract metadata. Solana transactions are a list of instructions. We offer details about program keys, accounts, signers, and more. See the `SolanaTransaction` struct in our [policy language](/concepts/policies/language) page for a full list.
+Turnkey has built a Solana parser which runs in a secure enclave, to parse unsigned transactions and extract metadata. Solana transactions are a list of instructions. We offer details about program keys, accounts, signers, and more. See the `SolanaTransaction` struct in our [policy language](/features/policies/language) page for a full list.
As a bonus, Turnkey also takes care of combining the signature with the original payload if you use the `SIGN_TRANSACTION` activity types: the input is the unsigned payload, and the output is the signed Solana transaction, ready to be broadcast onchain.
### Solana IDLs
-You can use Solana IDLs in conjunction with our policy engine to secure users' transactions. See [the guide](/concepts/policies/smart-contract-interfaces) for more details.
+You can use Solana IDLs in conjunction with our policy engine to secure users' transactions. See [the guide](/features/policies/smart-contract-interfaces) for more details.
## Import and export formats
Turnkey offers wallet or private key imports and export functionality. To be compatible with the Solana ecosystem, we support imports in mnemonics form (for wallet seeds, this is most common) or in base58 format (for single private key import or export).
-See the [import](/embedded-wallets/code-examples/import) and [export](/embedded-wallets/code-examples/export) guides for more details.
+See the [import](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets) and [export](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets) guides for more details.
## Wallet signer
diff --git a/networks/spark.mdx b/features/networks/spark.mdx
similarity index 94%
rename from networks/spark.mdx
rename to features/networks/spark.mdx
index 4c5fad1e..d4c5f7ee 100644
--- a/networks/spark.mdx
+++ b/features/networks/spark.mdx
@@ -3,7 +3,7 @@ title: "Spark support on Turnkey"
sidebarTitle: "Spark"
---
-[Spark](https://www.spark.money/) is a Bitcoin Layer 2 network that uses an identity key system for on-chain addressing. Turnkey supports Spark address derivation and signing via plain [BIP-340 Schnorr](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) signatures.
+[Spark](https://www.spark.money/) is a Bitcoin Layer 2 network that uses an identity key system for onchain addressing. Turnkey supports Spark address derivation and signing via plain [BIP-340 Schnorr](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) signatures.
The supported address formats are:
diff --git a/networks/stacks.mdx b/features/networks/stacks.mdx
similarity index 100%
rename from networks/stacks.mdx
rename to features/networks/stacks.mdx
diff --git a/networks/sui.mdx b/features/networks/sui.mdx
similarity index 100%
rename from networks/sui.mdx
rename to features/networks/sui.mdx
diff --git a/networks/tempo.mdx b/features/networks/tempo.mdx
similarity index 94%
rename from networks/tempo.mdx
rename to features/networks/tempo.mdx
index 6615076c..ee4115cc 100644
--- a/networks/tempo.mdx
+++ b/features/networks/tempo.mdx
@@ -15,7 +15,7 @@ Turnkey supports both transaction types on Tempo:
- [Ethereum legacy transactions](https://docs.tempo.xyz/quickstart/evm-compatibility#transaction-differences) with full parsing & policy support
- Tempo transactions with full parsing & policy support via the `tempo.tx` namespace
-Tempo transactions natively support batched calls — multiple calls can be sent atomically in a single transaction. See the [policy language reference](/concepts/policies/language#tempo) and [Tempo policy examples](/concepts/policies/examples/tempo) for details on governing Tempo transactions.
+Tempo transactions natively support batched calls — multiple calls can be sent atomically in a single transaction. See the [policy language reference](/features/policies/language#tempo) and [Tempo policy examples](/features/policies/examples/tempo) for details on governing Tempo transactions.
## Examples
@@ -35,7 +35,7 @@ Turnkey supports:
- **Full policy engine support**: Govern Tempo transactions with granular policies using the `tempo.tx` namespace — control call destinations, function selectors, gas limits, fee tokens, and more
- **Batch call support**: Write policies over Tempo's native batch calls using `tempo.tx.calls` with list quantifiers (`all`, `any`, `count`)
-- **Raw calldata inspection**: Inspect ABI-encoded arguments in call input data using [slicing](/concepts/policies/examples/tempo#raw-calldata-inspection) (e.g. `tempo.tx.calls[0].input[34..74]`)
+- **Raw calldata inspection**: Inspect ABI-encoded arguments in call input data using [slicing](/features/policies/examples/tempo#raw-calldata-inspection) (e.g. `tempo.tx.calls[0].input[34..74]`)
- **Out of the box Legacy EVM TX support**: Turnkey fully supports the legacy transaction type on Tempo
- **Native gas sponsorship**: Our example repository provides a reference implementation for building transactions with Tempo's native gas sponsorship
diff --git a/networks/tron.mdx b/features/networks/tron.mdx
similarity index 97%
rename from networks/tron.mdx
rename to features/networks/tron.mdx
index da15b570..78b709ad 100644
--- a/networks/tron.mdx
+++ b/features/networks/tron.mdx
@@ -93,7 +93,7 @@ The policy engine currently supports the following Tron contract types:
- UnfreezeBalanceV2Contract - Unfreeze frozen TRX
- AccountPermissionUpdateContract - Update permissions on an account, can be used for [multisig](https://developers.tron.network/docs/multi-signature)
-A full field breakdown can be found in our [policy language definition](/concepts/policies/language) and examples can be found in [Tron policy examples](/concepts/policies/examples/tron)
+A full field breakdown can be found in our [policy language definition](/features/policies/language) and examples can be found in [Tron policy examples](/features/policies/examples/tron)
To reference a Tron contract in the policy language you must specify the index of the contract in the contracts array: `tron.tx.contract[0]`. While Tron only currently supports 1 contract in this array, this could change in the future.
diff --git a/concepts/organizations.mdx b/features/organizations.mdx
similarity index 92%
rename from concepts/organizations.mdx
rename to features/organizations.mdx
index 303204de..2c9c34e6 100644
--- a/concepts/organizations.mdx
+++ b/features/organizations.mdx
@@ -1,11 +1,12 @@
---
title: "Organizations"
description: "An organization is a logical grouping of resources (e.g. users, policies, wallets). These resources can only be accessed by authorized and permissioned users within the organization. Resources are not shared between organizations."
+sidebarTitle: "Overview"
---
## Root quorum
-All organizations are controlled by a [Root Quorum](/concepts/users/root-quorum) which contains the root users and the required threshold of approvals to take any action. Only the root quorum can update the root quorum or feature set.
+All organizations are controlled by a [Root Quorum](/features/users/root-quorum) which contains the root users and the required threshold of approvals to take any action. Only the root quorum can update the root quorum or feature set.
## Features
@@ -38,10 +39,10 @@ All activity requests are subject to enforcement by Turnkey's policy engine. The
## Resource limits
-Organizations have [resource limits](/concepts/resource-limits) for performance and security considerations. If you're bumping into these limits, check out sub-organizations below.
+Organizations have [resource limits](/reference/resource-limits) for performance and security considerations. If you're bumping into these limits, check out sub-organizations below.
## Sub-organizations
A sub-organization is an isolated organization that has a pointer to a parent organization. The parent organization has **read** access to all sub-organizations, but no **write** access. This means users within the parent organization have no ability to use wallets or alter any resources in the sub-organization.
-For more information on sub-organizations and common use cases for this functionality, follow along in the next section .
\ No newline at end of file
+For more information on sub-organizations and common use cases for this functionality, follow along in the next section.
\ No newline at end of file
diff --git a/products/embedded-wallets/features/agentic-wallets.mdx b/features/policies/delegated-access/agentic-wallets.mdx
similarity index 86%
rename from products/embedded-wallets/features/agentic-wallets.mdx
rename to features/policies/delegated-access/agentic-wallets.mdx
index 11777323..31616157 100644
--- a/products/embedded-wallets/features/agentic-wallets.mdx
+++ b/features/policies/delegated-access/agentic-wallets.mdx
@@ -1,8 +1,11 @@
---
-title: "Agentic wallets"
-description: "Enable AI agents and automated systems to operate crypto wallets with granular policy controls"
+title: "End-User Delegated Agent Signing"
+sidebarTitle: "Agent signing"
+description: "Let embedded wallet users delegate scoped signing authority to AI agents, controlled by granular policies"
---
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
## What is an agentic wallet?
An agentic wallet is a crypto wallet that an AI agent or automated backend can operate programmatically—signing transactions, interacting with smart contracts, and executing onchain strategies without requiring human approval for every action.
@@ -20,15 +23,15 @@ This enables a new class of onchain applications:
## Why build on Turnkey
- **Private keys never leave the secure enclave** - Unlike solutions that expose raw keys, Turnkey generates and stores keys in hardware-backed secure enclaves. Your agent authenticates via an API key and receives signatures—it never touches the private key itself.
-- **Sub-100ms signing latency** - Signing speeds 100x faster than MPC-based alternatives, enabling agents to react to market movements and onchain events in real time. [Transaction Management](/concepts/transaction-management) automates construction, gas sponsorship, and broadcasting.
-- **Granular policy engine** - Every signing request is evaluated by Turnkey's [Policy Engine](/concepts/policies/overview) inside the secure enclave before a signature is produced. Scope exactly what the agent can sign by recipient address, contract address, function selector, chain ID, and transaction value limits.
+- **Sub-100ms signing latency** - Signing speeds 100x faster than MPC-based alternatives, enabling agents to react to market movements and onchain events in real time. [Transaction Management](/features/transaction-management) automates construction, gas sponsorship, and broadcasting.
+- **Granular policy engine** - Every signing request is evaluated by Turnkey's [Policy Engine](/features/policies/overview) inside the secure enclave before a signature is produced. Scope exactly what the agent can sign by recipient address, contract address, function selector, chain ID, and transaction value limits.
- **Multi-chain support** - One integration covers EVM chains, Solana, Bitcoin, Tron, and any blockchain using supported cryptographic curves.
- **Consensus for high-stakes actions** - For sensitive operations, require both the agent and a human (or another agent) to approve a transaction before it executes. Provides defense-in-depth even if the agent behaves unexpectedly.
- **Framework agnostic** - Low-level cryptographic primitives without imposing opinions on your agent architecture. Integrates naturally with LangChain, CrewAI, Vercel AI SDK, and agentic protocols like x402 and OpenClawd.
## Architecture
-The diagram below shows how an AI agent gets scoped access through [Delegated Access](/concepts/policies/delegated-access-overview):
+The diagram below shows how an AI agent gets scoped access through [Delegated Access](/features/policies/delegated-access/overview):

@@ -148,7 +151,7 @@ An AI agent that analyzes market data and executes trades on a DEX. The agent ha
### DeFi yield optimizer
-An agent that moves user funds between yield protocols. Policies restrict the agent to a whitelist of approved protocol contracts and deposit/withdraw functions only. Use Turnkey's [smart contract interface upload feature](/concepts/policies/smart-contract-interfaces) to write policies against decoded ABI parameters.
+An agent that moves user funds between yield protocols. Policies restrict the agent to a whitelist of approved protocol contracts and deposit/withdraw functions only. Use Turnkey's [smart contract interface upload feature](/features/policies/smart-contract-interfaces) to write policies against decoded ABI parameters.
### Automated payment processor
@@ -195,17 +198,9 @@ For sensitive operations, require multiple approvers:
## Next steps
-
-
- Client-side and server-side setup guides
-
-
- Ready-to-use templates for EVM, Solana, Bitcoin, and Tron
-
-
- Automate construction, gas sponsorship, and broadcasting
-
-
- Decode ABI parameters for granular function-level policies
-
-
+
+
+
+
+
+
diff --git a/concepts/policies/delegated-access-backend.mdx b/features/policies/delegated-access/backend.mdx
similarity index 97%
rename from concepts/policies/delegated-access-backend.mdx
rename to features/policies/delegated-access/backend.mdx
index 8ca25486..719c9be4 100644
--- a/concepts/policies/delegated-access-backend.mdx
+++ b/features/policies/delegated-access/backend.mdx
@@ -74,7 +74,7 @@ A simple example demonstrating the server-side delegated access setup can be fou
}
```
-### Step 2: limit the permissions of the Delegated Account user via policies
+### Step 2: limit the permissions of the delegated account user via policies
- Create a custom policy granting the Delegated Account specific permissions. You might grant that user permissions to:
- Sign any transaction
@@ -100,7 +100,7 @@ Here’s one example, granting the Delegated Account only the permission to sign
}
```
-### Step 3: remove the Delegated Account from the root quorum using the Delegated Account's credentials:
+### Step 3: remove the delegated account from the root quorum using the delegated account's credentials:
```json
// Update the root quorum of the sub organization to ONLY include the end user, removing the delegated access user
diff --git a/concepts/policies/delegated-access-frontend.mdx b/features/policies/delegated-access/frontend.mdx
similarity index 100%
rename from concepts/policies/delegated-access-frontend.mdx
rename to features/policies/delegated-access/frontend.mdx
diff --git a/concepts/policies/delegated-access-overview.mdx b/features/policies/delegated-access/overview.mdx
similarity index 98%
rename from concepts/policies/delegated-access-overview.mdx
rename to features/policies/delegated-access/overview.mdx
index 0c82b75e..8d57ccf0 100644
--- a/concepts/policies/delegated-access-overview.mdx
+++ b/features/policies/delegated-access/overview.mdx
@@ -29,7 +29,7 @@ This avoids temporarily granting the Delegated User root access — see [Caution
**Limitations:**
- You can’t assume the delegated user or its policies already exist. Before referencing it, you’ll need to call `fetchOrCreateP256ApiKeyUser` and `fetchOrCreatePolicies` to ensure the user and permissions are properly set up.
-For a detailed step-by-step guide see [Client-side Delegated Access setup](/concepts/policies/delegated-access-frontend).
+For a detailed step-by-step guide see [Client-side Delegated Access setup](/features/policies/delegated-access/frontend).
### 2. Backend
@@ -56,9 +56,9 @@ If you adopt this approach, implement strict validation to confirm that:
For most end-user applications, it’s recommended to perform delegated access setup client-side, where all actions are explicitly initiated and approved by the user.
-For a detailed step-by-step guide see [Server-side Delegated Access setup](/concepts/policies/delegated-access-backend).
+For a detailed step-by-step guide see [Server-side Delegated Access setup](/features/policies/delegated-access/backend).
-## Frequently Asked Questions
+## Frequently asked questions
### Policy design and creation
diff --git a/concepts/policies/examples/access-control.mdx b/features/policies/examples/access-control.mdx
similarity index 95%
rename from concepts/policies/examples/access-control.mdx
rename to features/policies/examples/access-control.mdx
index a1585e28..db3c4d6f 100644
--- a/concepts/policies/examples/access-control.mdx
+++ b/features/policies/examples/access-control.mdx
@@ -59,7 +59,7 @@ sidebarTitle: "Access control"
}
```
-#### Allow a specific user to perform auth type activities (full list [here](/concepts/policies/language#activity-breakdown))
+#### Allow a specific user to perform auth type activities (full list [here](/features/policies/language#activity-breakdown))
Note: The `activity.resource` portion determines which activities can be performed. The `activity.action` determines what types of actions can be taken upon those resources.
@@ -83,7 +83,7 @@ Note: The `activity.resource` portion determines which activities can be perform
}
```
-#### Allow a specific user to perform a specific activity type (full list [here](/concepts/policies/language#activity-breakdown))
+#### Allow a specific user to perform a specific activity type (full list [here](/features/policies/language#activity-breakdown))
Note: Activities may be upgraded over time, and thus new versions may be introduced.
These policies will NOT be valid if an activity type is upgraded and requests are made on the new activity type.
@@ -99,7 +99,7 @@ and a request is made with the newer `V3` version, this policy with not allow th
}
```
-#### Allow a specific credential type to perform a specific action (full list of credential types [here](/authentication/credentials#credential-types))
+#### Allow a specific credential type to perform a specific action (full list of credential types [here](/features/users/credentials#credential-types))
This policy can be used to say, only passkeys are allowed to sign transactions and not authentication through SMS (or any other authentication method).
diff --git a/concepts/policies/examples/bitcoin.mdx b/features/policies/examples/bitcoin.mdx
similarity index 91%
rename from concepts/policies/examples/bitcoin.mdx
rename to features/policies/examples/bitcoin.mdx
index c7d7ff45..8e3a342d 100644
--- a/concepts/policies/examples/bitcoin.mdx
+++ b/features/policies/examples/bitcoin.mdx
@@ -4,7 +4,7 @@ description: "This page provides examples of policies governing Bitcoin signing.
sidebarTitle: "Bitcoin"
---
-Note: see the [language section](/concepts/policies/language#bitcoin) for more details. For context on Bitcoin transaction reinsertion, see the [Bitcoin network support](/networks/bitcoin) page
+Note: see the [language section](/features/policies/language#bitcoin) for more details. For context on Bitcoin transaction reinsertion, see the [Bitcoin network support](/features/networks/bitcoin) page
#### Allow signing Bitcoin transactions ONLY if all outputs are being sent to a certain address
diff --git a/company-wallets/co-signing-transactions.mdx b/features/policies/examples/co-signing-transactions.mdx
similarity index 100%
rename from company-wallets/co-signing-transactions.mdx
rename to features/policies/examples/co-signing-transactions.mdx
diff --git a/concepts/policies/examples/ethereum.mdx b/features/policies/examples/ethereum.mdx
similarity index 98%
rename from concepts/policies/examples/ethereum.mdx
rename to features/policies/examples/ethereum.mdx
index b6b4699d..191fa723 100644
--- a/concepts/policies/examples/ethereum.mdx
+++ b/features/policies/examples/ethereum.mdx
@@ -4,7 +4,7 @@ description: "This page provides examples of policies governing Ethereum (EVM) s
sidebarTitle: "Ethereum (EVM)"
---
-Note: see the [language section](/concepts/policies/language#ethereum) for more details.
+Note: see the [language section](/features/policies/language#ethereum) for more details.
#### Allow ABI-specific contract call parameters
diff --git a/concepts/policies/examples/signing-control.mdx b/features/policies/examples/signing-control.mdx
similarity index 100%
rename from concepts/policies/examples/signing-control.mdx
rename to features/policies/examples/signing-control.mdx
diff --git a/concepts/policies/examples/solana.mdx b/features/policies/examples/solana.mdx
similarity index 98%
rename from concepts/policies/examples/solana.mdx
rename to features/policies/examples/solana.mdx
index 9a919422..a6086eec 100644
--- a/concepts/policies/examples/solana.mdx
+++ b/features/policies/examples/solana.mdx
@@ -4,11 +4,11 @@ description: "This page provides examples of policies governing Solana signing."
sidebarTitle: "Solana"
---
-Note: see the [language section](/concepts/policies/language#solana) for various approaches on writing Solana policies.
+Note: see the [language section](/features/policies/language#solana) for various approaches on writing Solana policies.
For sponsored Solana transactions, start with
- [Solana Rent Sponsorship](/networks/solana-rent-refunds) before applying the
+ [Solana Rent Sponsorship](/features/networks/solana-rent-refunds) before applying the
examples below. That guide covers account-creation risk, rent refunds, and
mitigation strategy for sponsored flows.
diff --git a/concepts/policies/examples/tempo.mdx b/features/policies/examples/tempo.mdx
similarity index 96%
rename from concepts/policies/examples/tempo.mdx
rename to features/policies/examples/tempo.mdx
index 0818ab1c..bb1bfd23 100644
--- a/concepts/policies/examples/tempo.mdx
+++ b/features/policies/examples/tempo.mdx
@@ -4,7 +4,7 @@ description: "This page provides examples of policies governing Tempo signing."
sidebarTitle: "Tempo"
---
-Note: see the [language section](/concepts/policies/language#tempo) for more details.
+Note: see the [language section](/features/policies/language#tempo) for more details.
## Overview
@@ -150,7 +150,7 @@ Tempo transactions contain one or more calls in `tempo.tx.calls`. You can target
## Raw calldata inspection
-Since Tempo does not support [Smart Contract Interfaces](/concepts/policies/smart-contract-interfaces) (ABI parsing), you can use slicing on `tempo.tx.calls[i].input` to inspect encoded arguments directly. The `input` field is case-insensitive, so hex comparisons work regardless of casing.
+Since Tempo does not support [Smart Contract Interfaces](/features/policies/smart-contract-interfaces) (ABI parsing), you can use slicing on `tempo.tx.calls[i].input` to inspect encoded arguments directly. The `input` field is case-insensitive, so hex comparisons work regardless of casing.
In standard ABI encoding, each argument occupies a 32-byte (64 hex character) word. The function selector occupies the first 4 bytes (8 hex characters, plus the `0x` prefix), so the first argument word starts at position 10. For an `address` argument, the address value itself starts at position 34, because it is right-aligned within the 32-byte word and preceded by 12 bytes (24 hex characters) of left-padding. Each subsequent argument word starts 64 hex characters later.
@@ -247,4 +247,4 @@ These policies work the same as other blockchain types — you can combine `temp
## Legacy Ethereum transactions on Tempo
-During Tempo's testnet period, [legacy Ethereum transactions](https://docs.tempo.xyz/quickstart/evm-compatibility#transaction-differences) are also supported on Tempo and can be governed using standard Ethereum policy syntax. See the [Ethereum policy examples](/concepts/policies/examples/ethereum) for more details on how to write policies for these transaction types.
+During Tempo's testnet period, [legacy Ethereum transactions](https://docs.tempo.xyz/quickstart/evm-compatibility#transaction-differences) are also supported on Tempo and can be governed using standard Ethereum policy syntax. See the [Ethereum policy examples](/features/policies/examples/ethereum) for more details on how to write policies for these transaction types.
diff --git a/concepts/policies/examples/tron.mdx b/features/policies/examples/tron.mdx
similarity index 94%
rename from concepts/policies/examples/tron.mdx
rename to features/policies/examples/tron.mdx
index 112eab70..8dc9e9d0 100644
--- a/concepts/policies/examples/tron.mdx
+++ b/features/policies/examples/tron.mdx
@@ -4,7 +4,7 @@ description: "This page provides examples of policies governing signing."
sidebarTitle: "Tron"
---
-Note: see the [language section](/concepts/policies/language#tron) for more details.
+Note: see the [language section](/features/policies/language#tron) for more details.
#### Allow Tether TRC-20 transfers on the Nile Testnet
diff --git a/concepts/policies/language.mdx b/features/policies/language.mdx
similarity index 98%
rename from concepts/policies/language.mdx
rename to features/policies/language.mdx
index 2aa142a4..a0050690 100644
--- a/concepts/policies/language.mdx
+++ b/features/policies/language.mdx
@@ -78,7 +78,7 @@ The language is strongly typed which makes policies easy to author and maintain.
| | alias | string | The alias of the user |
| **Credential** | id | string | The identifier of the API key or authenticator that was used to approve the request |
| | user_id | string | The identifier of the user who owns this request and approved the request |
-| | type | string | The credential type, a full list can be found [here](/authentication/credentials#credential-types) |
+| | type | string | The credential type, a full list can be found [here](/features/users/credentials#credential-types) |
| | credential_id | string | The credential ID of a passkey. Note: this is only populated for passkeys (also known as Authenticators within Turnkey resources), not API keys |
| | public_key | string | The public key of the credential that approved the request |
| **Activity** | type | string | The type of the activity (e.g. ACTIVITY_TYPE_SIGN_TRANSACTION_V2) |
@@ -219,7 +219,7 @@ The language is strongly typed which makes policies easy to author and maintain.
| | sequence | int | The sequence field on this input which is set whether the transaction can be replaced or when it can be mined |
| **BitcoinTxOutput** | value | int | The value of this output in Satoshis |
| | script_pubkey | string | The locking code for this transaction output |
-| | address | string | The on chain address representation for this transaction output |
+| | address | string | The onchain address representation for this transaction output |
| | address_type | string | The address derivation type of the address for this transaction output |
| **BitcoinTxLocktime** | amount | int | The amount represented in this transaction's locktime |
| | type | string | The type of locktime represented (either 'Seconds' or 'Blocks') |
@@ -374,13 +374,13 @@ To allow a user to delete only themselves:
### Root quorum activities
-There are a select few activities that are not governed by policies, but rather by an organization's [root quorum](/concepts/users/root-quorum). These activities are: `ACTIVITY_TYPE_UPDATE_ROOT_QUORUM`, `ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE`, `ACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE`, `ACTIVITY_TYPE_UPDATE_ORGANIZATION_NAME`. For example, if a policy is added that allows a specific non-root user to perform `ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE` activities, these requests will still fail as they are subject specifically to root quorum.
+There are a select few activities that are not governed by policies, but rather by an organization's [root quorum](/features/users/root-quorum). These activities are: `ACTIVITY_TYPE_UPDATE_ROOT_QUORUM`, `ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE`, `ACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE`, `ACTIVITY_TYPE_UPDATE_ORGANIZATION_NAME`. For example, if a policy is added that allows a specific non-root user to perform `ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE` activities, these requests will still fail as they are subject specifically to root quorum.
### Ethereum
Our Ethereum policy language (accessible via `eth.tx`) allows for the granular governance of signing Ethereum (EVM-compatible) transactions. Our policy engine exposes a [fairly standard set of properties](https://ethereum.org/en/developers/docs/transactions/#typed-transaction-envelope) belonging to a transaction.
-See the [Ethereum policy examples](/concepts/policies/examples/ethereum) for sample scenarios.
+See the [Ethereum policy examples](/features/policies/examples/ethereum) for sample scenarios.
{" "}
@@ -403,19 +403,19 @@ Similarly, the policy engine exposes `solana.tx.spl_transfers`, which contains o
Here are some approaches you might take to govern transfers:
-- _All_ transfers need to match the policy condition. Useful for allowlists ([example](/concepts/policies/examples/solana#allow-solana-transactions-that-include-a-transfer-to-only-one-specific-recipient))
-- _Just one_ transfer needs to match the policy condition. Useful for blocklists ([example](/concepts/policies/examples/solana#deny-all-solana-transactions-transferring-to-an-undesired-address))
-- Only match if there is a _single_ transfer in the transaction, _and_ that transfer meets the criteria ([example](/concepts/policies/examples/solana#allow-solana-transactions-that-have-exactly-one-transfer,-to-one-specific-recipient)). This is the most secure approach, and thus most restrictive.
+- _All_ transfers need to match the policy condition. Useful for allowlists ([example](/features/policies/examples/solana#allow-solana-transactions-that-include-a-transfer-to-only-one-specific-recipient))
+- _Just one_ transfer needs to match the policy condition. Useful for blocklists ([example](/features/policies/examples/solana#deny-all-solana-transactions-transferring-to-an-undesired-address))
+- Only match if there is a _single_ transfer in the transaction, _and_ that transfer meets the criteria ([example](/features/policies/examples/solana#allow-solana-transactions-that-have-exactly-one-transfer,-to-one-specific-recipient)). This is the most secure approach, and thus most restrictive.
#### Account address lookups
-Solana transactions can reference onchain address lookup tables for account addresses. Turnkey surfaces any account address pulled from a lookup table as the literal string `ADDRESS_TABLE_LOOKUP` in Solana address fields (`account_keys`, instruction accounts, `transfers`, and `spl_transfers`). The `solana.tx.address_table_lookups` array indicates when lookups are present, but the specific addresses are not resolved. If you rely on allowlists or denylists of addresses, add a guard for this placeholder (for example, require `solana.tx.address_table_lookups.count == 0` before comparing addresses, or explicitly deny when `ADDRESS_TABLE_LOOKUP` appears with something like `solana.tx.transfers.any(t, t.to == 'ADDRESS_TABLE_LOOKUP')`) so that dynamic lookups cannot bypass or unexpectedly fail your policy. See the [address table lookup examples](/concepts/policies/examples/solana#deny-all-address-table-lookups) for examples on how to enforce this.
+Solana transactions can reference onchain address lookup tables for account addresses. Turnkey surfaces any account address pulled from a lookup table as the literal string `ADDRESS_TABLE_LOOKUP` in Solana address fields (`account_keys`, instruction accounts, `transfers`, and `spl_transfers`). The `solana.tx.address_table_lookups` array indicates when lookups are present, but the specific addresses are not resolved. If you rely on allowlists or denylists of addresses, add a guard for this placeholder (for example, require `solana.tx.address_table_lookups.count == 0` before comparing addresses, or explicitly deny when `ADDRESS_TABLE_LOOKUP` appears with something like `solana.tx.transfers.any(t, t.to == 'ADDRESS_TABLE_LOOKUP')`) so that dynamic lookups cannot bypass or unexpectedly fail your policy. See the [address table lookup examples](/features/policies/examples/solana#deny-all-address-table-lookups) for examples on how to enforce this.
#### Program address lookups
-Turnkey rejects Solana transactions where program addresses are resolved via address lookup tables. Program IDs must be statically defined in the transaction to enable static analysis of instructions without requiring on-chain data lookups. If your transaction references a program via an address table lookup, the signing request will fail. Account addresses (non-program) can still be dynamically resolved via lookup tables as described above.
+Turnkey rejects Solana transactions where program addresses are resolved via address lookup tables. Program IDs must be statically defined in the transaction to enable static analysis of instructions without requiring onchain data lookups. If your transaction references a program via an address table lookup, the signing request will fail. Account addresses (non-program) can still be dynamically resolved via lookup tables as described above.
-See the [Solana policy examples](/concepts/policies/examples/solana) for sample scenarios.
+See the [Solana policy examples](/features/policies/examples/solana) for sample scenarios.
### Tron
@@ -429,7 +429,7 @@ Our Tron policy language (accessible via `tron.tx`) allows for policy control ov
- UnfreezeBalanceV2Contract
- AccountPermissionUpdateContract
-See the [Tron policy examples](/concepts/policies/examples/tron) for sample scenarios.
+See the [Tron policy examples](/features/policies/examples/tron) for sample scenarios.
### Bitcoin
@@ -437,9 +437,9 @@ Our Bitcoin policy language (accessible via `bitcoin.tx`) allows for policy cont
NOTE: While our `SIGN TRANSACTION` endpoint takes in a Partially Signed Bitcoin Transaction (PSBT) as required for signing context -- our policy language supports only the standard fields inside a Bitcoin transaction: https://learnmeabitcoin.com/technical/transaction/#structure
-For further reference on how Turnkey handles Bitcoin transactions in our policy-enabled transaction signing flow, check out this section in our [Bitcoin Network Support](/networks/bitcoin#policy-enabled-bitcoin-transaction-signing) page.
+For further reference on how Turnkey handles Bitcoin transactions in our policy-enabled transaction signing flow, check out this section in our [Bitcoin Network Support](/features/networks/bitcoin#policy-enabled-bitcoin-transaction-signing) page.
-See the [Bitcoin policy examples](/concepts/policies/examples/bitcoin) for sample Bitcoin policies.
+See the [Bitcoin policy examples](/features/policies/examples/bitcoin) for sample Bitcoin policies.
### Tempo
@@ -449,4 +449,4 @@ The `tempo.tx` namespace exposes the following transaction-level fields: `chain_
You can also govern Tempo transactions at the activity level using `activity.params.type == 'TRANSACTION_TYPE_TEMPO'`, combined with other fields such as specific wallets, private keys, or consensus rules.
-See the [Tempo policy examples](/concepts/policies/examples/tempo) for sample scenarios.
+See the [Tempo policy examples](/features/policies/examples/tempo) for sample scenarios.
diff --git a/concepts/policies/overview.mdx b/features/policies/overview.mdx
similarity index 79%
rename from concepts/policies/overview.mdx
rename to features/policies/overview.mdx
index 0fd2c7d5..a7e92e26 100644
--- a/concepts/policies/overview.mdx
+++ b/features/policies/overview.mdx
@@ -1,11 +1,11 @@
---
-title: "Policy overview"
+title: "Policies"
description: "Our policy engine is the foundation for flexible controls and permissions within your organization. This page provides an overview of how to author policies."
-sidebarTitle: "Policies"
+sidebarTitle: "Overview"
---
import PolicyEngine from "/snippets/shared/policy-engine.mdx";
-To learn more about our Policies, check out our Policy Language [here](/concepts/policies/language).
+To learn more about our Policies, check out our Policy Language [here](/features/policies/language).
diff --git a/concepts/policies/quickstart.mdx b/features/policies/quickstart.mdx
similarity index 88%
rename from concepts/policies/quickstart.mdx
rename to features/policies/quickstart.mdx
index 9d39b53c..7e036d49 100644
--- a/concepts/policies/quickstart.mdx
+++ b/features/policies/quickstart.mdx
@@ -4,7 +4,7 @@ description: "This guide will help you add an additional user to your Turnkey or
sidebarTitle: "Quickstart"
---
-This assumes that you previously completed the [Sign a transaction](/getting-started/quickstart) guide, and thus have already set up:
+This assumes that you previously completed the [Sign a transaction](/get-started/quickstart) guide, and thus have already set up:
* Your Turnkey organization
* An API key for the Root User
@@ -54,7 +54,7 @@ Choose a name and note to describe your new policy. Next, enter the following po
Generate sample transactions using our [transaction tool](https://build.tx.xyz). **You'll want to create two transactions**: one transaction to the address you selected in your whitelist policy above, and one to any other address.
-Next, try signing these two different transactions by replacing `` in the code snippet below. As a reminder, this guide assumes you've completed the [Quickstart](/getting-started/quickstart) guide, and have set `$ORGANIZATION_ID` as an environment variable.
+Next, try signing these two different transactions by replacing `` in the code snippet below. As a reminder, this guide assumes you've completed the [Quickstart](/get-started/quickstart) guide, and have set `$ORGANIZATION_ID` as an environment variable.
```json
turnkey request --path /public/v1/submit/sign_transaction --body '{
@@ -73,6 +73,6 @@ You'll see that the activity to allowlisted address comes back as `COMPLETED`, w
## Extra credit
-* Try out some of our [policy examples](/concepts/policies/examples)
-* Check out the [policy overview](/concepts/policies/overview)
-* Learn how to author policies with our [policy language](/concepts/policies/overview)
+* Try out some of our [policy examples](/features/policies/examples/ethereum)
+* Check out the [policy overview](/features/policies/overview)
+* Learn how to author policies with our [policy language](/features/policies/overview)
diff --git a/concepts/policies/smart-contract-interfaces.mdx b/features/policies/smart-contract-interfaces.mdx
similarity index 100%
rename from concepts/policies/smart-contract-interfaces.mdx
rename to features/policies/smart-contract-interfaces.mdx
diff --git a/concepts/sub-organizations.mdx b/features/sub-organizations.mdx
similarity index 100%
rename from concepts/sub-organizations.mdx
rename to features/sub-organizations.mdx
diff --git a/features/transaction-management.mdx b/features/transaction-management.mdx
new file mode 100644
index 00000000..5e70458f
--- /dev/null
+++ b/features/transaction-management.mdx
@@ -0,0 +1,16 @@
+---
+description: "Learn about Turnkey's gas sponsorship, transaction construction, broadcast, nonce management and monitoring capabilities."
+sidebarTitle: "Overview"
+---
+
+import SendTxConcepts from "/snippets/shared/send-tx-concepts.mdx";
+
+
+
+## Next steps
+
+For implementation guides, see:
+
+- [Sending Sponsored EVM Transactions (React)](/features/transaction-management/sending-sponsored-transactions) - Using `@turnkey/react-wallet-kit`
+- [Sending Sponsored Solana Transactions (React)](/features/transaction-management/sending-sponsored-solana-transactions) - Using `@turnkey/react-wallet-kit`
+- [Sending Sponsored Transactions](/features/transaction-management/broadcasting) - Using `@turnkey/core` directly
\ No newline at end of file
diff --git a/concepts/balances.mdx b/features/transaction-management/balances.mdx
similarity index 100%
rename from concepts/balances.mdx
rename to features/transaction-management/balances.mdx
diff --git a/company-wallets/code-examples/sending-sponsored-transactions.mdx b/features/transaction-management/broadcasting.mdx
similarity index 89%
rename from company-wallets/code-examples/sending-sponsored-transactions.mdx
rename to features/transaction-management/broadcasting.mdx
index 466bc658..9645cee4 100644
--- a/company-wallets/code-examples/sending-sponsored-transactions.mdx
+++ b/features/transaction-management/broadcasting.mdx
@@ -13,7 +13,7 @@ import SendTxGasUsage from "/snippets/shared/send-tx-gas-usage.mdx";
-This page walks you through the `@turnkey/core` flow with full code examples. For using the React handler, see [Sending Sponsored Transactions (React)](/embedded-wallets/code-examples/sending-sponsored-transactions).
+This page walks you through the `@turnkey/core` flow with full code examples. For using the React handler, see [Sending Sponsored Transactions (React)](/features/transaction-management/sending-sponsored-transactions).
---
diff --git a/wallets/fiat-on-ramp.mdx b/features/transaction-management/fiat-on-ramp.mdx
similarity index 92%
rename from wallets/fiat-on-ramp.mdx
rename to features/transaction-management/fiat-on-ramp.mdx
index 58df4126..715ced98 100644
--- a/wallets/fiat-on-ramp.mdx
+++ b/features/transaction-management/fiat-on-ramp.mdx
@@ -1,5 +1,5 @@
---
-title: "Fiat Onramp"
+title: "Fiat onramp"
description: "Turnkey’s Fiat Onramp lets your end users convert traditional currency (USD, EUR, etc.) into crypto assets (ETH, USDC, BTC, etc.) directly within your application."
mode: wide
---
diff --git a/embedded-wallets/code-examples/sending-sponsored-solana-transactions.mdx b/features/transaction-management/sending-sponsored-solana-transactions.mdx
similarity index 91%
rename from embedded-wallets/code-examples/sending-sponsored-solana-transactions.mdx
rename to features/transaction-management/sending-sponsored-solana-transactions.mdx
index 74da7b84..b64d4a1b 100644
--- a/embedded-wallets/code-examples/sending-sponsored-solana-transactions.mdx
+++ b/features/transaction-management/sending-sponsored-solana-transactions.mdx
@@ -14,9 +14,9 @@ import SendSolanaTxSdkOverview from "/snippets/shared/send-solana-tx-sdk-overvie
Rent` has been enabled in the dashboard first. Review whether the unsigned
transaction creates accounts, closes accounts, or routes rent refunds back to
the signer. See
- [Solana Rent Sponsorship](/networks/solana-rent-refunds) for rent setup and
+ [Solana Rent Sponsorship](/features/networks/solana-rent-refunds) for rent setup and
refund-path guidance, and [Solana transaction construction for sponsored
- flows](/networks/solana-transaction-construction) for payer-model and
+ flows](/features/networks/solana-transaction-construction) for payer-model and
account-creation caveats.
@@ -83,4 +83,4 @@ if (resp?.usageUsd! > resp?.windowLimitUsd!) {
}
```
-For additional references leveraging these endpoints, check out our [Swapping Example](/cookbook/jupiter) and [Sweeping Example](/cookbook/sweeping).
+For additional references leveraging these endpoints, check out our [Swapping Example](/solutions/cookbooks/jupiter).
diff --git a/embedded-wallets/code-examples/sending-sponsored-transactions.mdx b/features/transaction-management/sending-sponsored-transactions.mdx
similarity index 94%
rename from embedded-wallets/code-examples/sending-sponsored-transactions.mdx
rename to features/transaction-management/sending-sponsored-transactions.mdx
index bd032b4d..f1901f95 100644
--- a/embedded-wallets/code-examples/sending-sponsored-transactions.mdx
+++ b/features/transaction-management/sending-sponsored-transactions.mdx
@@ -10,7 +10,7 @@ import SendTxGasUsage from "/snippets/shared/send-tx-gas-usage.mdx";
-This page walks you through the React flow with full code examples. For using `@turnkey/core` directly, see [Sending Sponsored Transactions](/company-wallets/code-examples/sending-sponsored-transactions).
+This page walks you through the React flow with full code examples. For using `@turnkey/core` directly, see [Sending Sponsored Transactions](/features/transaction-management/broadcasting).
diff --git a/concepts/users/best-practices.mdx b/features/users/best-practices.mdx
similarity index 100%
rename from concepts/users/best-practices.mdx
rename to features/users/best-practices.mdx
diff --git a/features/users/credentials.mdx b/features/users/credentials.mdx
new file mode 100644
index 00000000..20225c2b
--- /dev/null
+++ b/features/users/credentials.mdx
@@ -0,0 +1,30 @@
+---
+title: "Credentials"
+description: "Credentials are how users authenticate to Turnkey. Turnkey only stores public keys; private keys never leave your device."
+sidebarTitle: "Credentials"
+---
+
+## Types
+
+**Authenticators** — WebAuthn devices registered on Turnkey: passkeys, biometrics, and hardware keys. Used to sign requests directly, using the [WebAuthn standard](https://www.w3.org/TR/webauthn-2/) (no passwords).
+
+**API keys** — P-256 key pairs used to sign API requests. Come in two forms:
+- *Long-lived* — created via the dashboard, CLI, or [API](/api-reference/activities/create-api-keys). You generate the key pair; Turnkey stores the public key.
+- *Expiring* — issued automatically when a user authenticates via email, SMS, OAuth, or wallet auth. Short-lived by default (15 minutes), with a configurable expiration window.
+
+## Credential types
+
+Each issuance path produces a credential of a specific type, which Turnkey returns in API responses. You can retrieve the type and public key for any API key via [GetAPIKey](/api-reference/queries/get-api-key).
+
+| Credential type | Issued by |
+|---|---|
+| `CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR` | [Passkeys](/features/authentication/passkeys/introduction) |
+| `CREDENTIAL_TYPE_API_KEY_P256` | [Manually created API keys](/api-reference/activities/create-api-keys) |
+| `CREDENTIAL_TYPE_OTP_AUTH_KEY_P256` | [Email OTP](/features/authentication/email) or [SMS](/features/authentication/sms) auth |
+| `CREDENTIAL_TYPE_EMAIL_AUTH_KEY_P256` | [Email auth — credential bundle method](/features/authentication/email) (legacy) |
+| `CREDENTIAL_TYPE_RECOVER_USER_KEY_P256` | [Email recovery](/features/authentication/email) (legacy) |
+| `CREDENTIAL_TYPE_OAUTH_KEY_P256` | [Social logins](/features/authentication/social-logins) |
+| `CREDENTIAL_TYPE_API_KEY_SECP256K1` | [Wallet auth — Ethereum/SECP256K1](/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview) |
+| `CREDENTIAL_TYPE_API_KEY_ED25519` | [Wallet auth — Solana/ED25519](/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview) |
+| `CREDENTIAL_TYPE_READ_WRITE_SESSION_KEY_P256` | [Read-write sessions](/api-reference/activities/create-read-write-session) |
+| `CREDENTIAL_TYPE_LOGIN` | [IndexedDB auth](/sdks/javascript-browser#indexeddbclient) — OTP, passkey, or OAuth |
diff --git a/concepts/users/introduction.mdx b/features/users/introduction.mdx
similarity index 72%
rename from concepts/users/introduction.mdx
rename to features/users/introduction.mdx
index bc3f0082..822d198a 100644
--- a/concepts/users/introduction.mdx
+++ b/features/users/introduction.mdx
@@ -1,11 +1,11 @@
---
-title: "Introduction to users"
+title: "Users"
description: "Turnkey users are resources within organizations or sub-organizations that can submit activities to Turnkey via a valid credential (e.g., API key, passkey)."
mode: wide
-sidebarTitle: "Introduction"
+sidebarTitle: "Overview"
---
- These requests can be made either by making direct API calls or through the Turnkey Dashboard. Users must have at least one valid credential (one of API key, passkey), with upper limits on credentials defined here in our [resource limits](/concepts/resource-limits). Users can also have associated “tags” which are logical groupings that can be referenced in policies. Users can only submit activities within their given organization — they cannot take action across organizations.
+ These requests can be made either by making direct API calls or through the Turnkey Dashboard. Users must have at least one valid credential (one of API key, passkey), with upper limits on credentials defined here in our [resource limits](/reference/resource-limits). Users can also have associated “tags” which are logical groupings that can be referenced in policies. Users can only submit activities within their given organization — they cannot take action across organizations.
A User's attributes are:
diff --git a/concepts/users/root-quorum.mdx b/features/users/root-quorum.mdx
similarity index 98%
rename from concepts/users/root-quorum.mdx
rename to features/users/root-quorum.mdx
index 8c2506bf..b482437c 100644
--- a/concepts/users/root-quorum.mdx
+++ b/features/users/root-quorum.mdx
@@ -36,7 +36,7 @@ The root quorum should only be used in cases where it is absolutely necessary. I
### Create scoped users for day-to-day actions
-Ensure that you have scoped policies for day-to-day actions that you expect to complete. For example, you may have an API user with permissions to only create sub-organizations. You can read more about creating policies in our [Policy Overview](/concepts/policies/overview).
+Ensure that you have scoped policies for day-to-day actions that you expect to complete. For example, you may have an API user with permissions to only create sub-organizations. You can read more about creating policies in our [Policy Overview](/features/policies/overview).
### Using root users with policies
diff --git a/products/verifiable-cloud/onboarding.mdx b/features/verifiable-cloud/onboarding.mdx
similarity index 96%
rename from products/verifiable-cloud/onboarding.mdx
rename to features/verifiable-cloud/onboarding.mdx
index f833d7ea..f12bbd24 100644
--- a/products/verifiable-cloud/onboarding.mdx
+++ b/features/verifiable-cloud/onboarding.mdx
@@ -1,5 +1,5 @@
---
-title: "Building Your First App"
+title: "Building your first app"
---
## TVC template
@@ -16,9 +16,9 @@ Turnkey writes all enclave applications in Rust, but TVC isn't opinionated about
If you are planning to use dynamic linking or interpreted languages, [get in touch](https://www.turnkey.com/turnkey-verifiable-cloud#waitlist) ahead of time and we can look at your toolchain's compatibility.
-## Recommended First Steps
+## Recommended first steps
-Start with our minimal template and deploy it within your TVC-enabled organization. To do this, follow our [TVC quickstart guide](/getting-started/verifiable-cloud-quickstart).
+Start with our minimal template and deploy it within your TVC-enabled organization. To do this, follow our [TVC quickstart guide](/features/verifiable-cloud/quickstart).
Verify it comes up healthy, and confirm one or more endpoints respond correctly. Once the baseline is confirmed, layer your application logic incrementally.
diff --git a/products/verifiable-cloud/overview.mdx b/features/verifiable-cloud/overview.mdx
similarity index 97%
rename from products/verifiable-cloud/overview.mdx
rename to features/verifiable-cloud/overview.mdx
index 452bddd2..84493c53 100644
--- a/products/verifiable-cloud/overview.mdx
+++ b/features/verifiable-cloud/overview.mdx
@@ -28,7 +28,7 @@ Many different types of workloads can benefit from verifiability. Below is a lis
| Chain Abstraction | Trustworthy cosigners for cross-chain resource locks (e.g. [OneBalance](https://www.onebalance.io)) |
| Transaction Construction | Users know that the unsigned transaction bytes are legitimate. |
| Transaction Parsing | Provide accurate metadata about the effects of a transaction. This is critical for trusted wallet UX. See [VisualSign Parser](https://github.com/anchorageoss/visualsign-parser/). |
-| Oracles | Leverage external data without the overhead of full decentralization, on-chain or off-chain. Replace economic incentives with verifiability. |
+| Oracles | Leverage external data without the overhead of full decentralization, onchain or offchain. Replace economic incentives with verifiability. |
| Blockchain nodes | Allow for private balance lookups, verifiable mempool inclusion, and more. |
| Web2 data bridging | Import and use data from web2 providers (centralized exchange balances, credit scores, X follower counts) in decentralized computation |
| AI training & inference | Verifiable training to prove no hidden backdoors; guarantee user prompts remain private |
@@ -42,7 +42,7 @@ These are just a subset of possible use cases. Any computation where two parties
## Architecture
-We’ve engineered TVC to fit within the existing Turnkey products and APIs. You will interact with TVC via our [dashboard](https://app.turnkey.com/), via the [TVC CLI](https://github.com/tkhq/rust-sdk/tree/main/tvc), or programmatically via [APIs](/api-reference/overview).
+We’ve engineered TVC to fit within the existing Turnkey products and APIs. You will interact with TVC via our [dashboard](https://app.turnkey.com/), via the [TVC CLI](https://github.com/tkhq/rust-sdk/tree/main/tvc), or programmatically via [APIs](/api-reference/overview/intro).
TVC provides a secure harness ([QuorumOS](https://github.com/tkhq/qos)) to verifiably run a **single program**. This program is also called "binary", "executable" or sometimes "pivot", and contains the secure workload to execute in TEEs. TVC relies on [OCI container images](https://github.com/opencontainers/image-spec) to transport this executable program from where it's built (typically, Github Action, or other CI platforms) to within TVC. This has several advantages:
* OCI containers can be hosted on many container image registries. These registries ensure integrity of the images, and clients can "pin" an image to ensure that they download the image they expect. Typically a container image URL will look like `registry.com/org/repo:some-tag@sha256:digest`.
@@ -61,7 +61,7 @@ Read more about Applications, Deployments, Manifests, and Operators in the follo
TVC is programmable infrastructure, enabling you to create and manage verifiable apps. Each TVC App is deployed on Turnkey infrastructure in the exact same way as Turnkey's own [core enclave apps](https://github.com/tkhq/core-enclaves).
* TVC Applications are deployed within Kubernetes clusters operated by Turnkey, using [QuorumOS](https://github.com/tkhq/qos) ("QOS") as a base OS.
* Key provisioning, high-availability deployments (minimum of 3 replicas), and in-depth verification workflows are supported by default.
-* Because TVC relies on Turnkey for its own operations, it's possible to use Consensus in the context of TVC activities (with [Turnkey Policies](/concepts/policies) or [Root Quorum](/concepts/users/root-quorum))
+* Because TVC relies on Turnkey for its own operations, it's possible to use Consensus in the context of TVC activities (with [Turnkey Policies](/features/policies/overview) or [Root Quorum](/features/users/root-quorum))
A TVC Application has a stable [Quorum Key](https://github.com/tkhq/qos#quorum-key) and set of approvers.
@@ -97,7 +97,7 @@ Operators are humans or systems. In TVC, an operator is represented by an alias
QuorumOS uses operators to cryptographically control deployments: operators must approve QOS manifests and take part in deployments where Quorum Keys must be injected.
-## Keys, Signatures, and Verification
+## Keys, signatures, and verification
Your TVC app has access to two keys when it boots:
diff --git a/getting-started/verifiable-cloud-quickstart.mdx b/features/verifiable-cloud/quickstart.mdx
similarity index 98%
rename from getting-started/verifiable-cloud-quickstart.mdx
rename to features/verifiable-cloud/quickstart.mdx
index 79979ea3..041f3ffb 100644
--- a/getting-started/verifiable-cloud-quickstart.mdx
+++ b/features/verifiable-cloud/quickstart.mdx
@@ -1,7 +1,7 @@
---
title: "Turnkey Verifiable Cloud quickstart"
description: "Run any code in isolated, verifiable secure enclaves powered by Turnkey’s trusted infrastructure."
-sidebarTitle: "Turnkey Verifiable Cloud"
+sidebarTitle: "Quickstart"
tag: "Beta"
---
@@ -12,7 +12,7 @@ Turnkey Verifiable Cloud is currently in Private Beta. Join the waitlist [here](
## Prerequisites
This guide assumes you've been enabled for Turnkey Verifiable Cloud, and you've completed the steps to create an account and an organization
-as described in the [account setup](/getting-started/quickstart) section.
+as described in the [account setup](/get-started/quickstart) section.
⚠️ To be enabled for TVC you will need to get in touch with our team (via Slack, typically) and tell us your new organization ID.
Our team will enable your new organization for TVC and you will be able to see a new "Verifiable Cloud" section appear in the top-level navigation.
diff --git a/concepts/wallets.mdx b/features/wallets.mdx
similarity index 97%
rename from concepts/wallets.mdx
rename to features/wallets.mdx
index fb552ead..4bb558ad 100644
--- a/concepts/wallets.mdx
+++ b/features/wallets.mdx
@@ -1,6 +1,7 @@
---
title: "Wallets"
description: "A [hierarchical deterministic (HD) wallet](https://learnmeabitcoin.com/technical/hd-wallets) is a collection of cryptographic private/public key pairs that share a common seed. A wallet is used to generate accounts."
+sidebarTitle: "Overview"
---
```json
@@ -122,11 +123,11 @@ Turnkey also supports raw private keys, but we recommend using Wallets since the
## Export keys
-Exporting on Turnkey enables you or your end users to export a copy of a Wallet or Private Key from our system at any time. While most Turnkey users opt to keep Wallets within Turnkey's secure infrastructure, the export functionality means you are never locked into Turnkey, and gives you the freedom to design your own backup processes as you see fit. Check out our [Export Wallet guide](/wallets/export-wallets) to allow your users to securely export their wallets.
+Exporting on Turnkey enables you or your end users to export a copy of a Wallet or Private Key from our system at any time. While most Turnkey users opt to keep Wallets within Turnkey's secure infrastructure, the export functionality means you are never locked into Turnkey, and gives you the freedom to design your own backup processes as you see fit. Check out our [Export Wallet guide](/features/wallets/export-wallets) to allow your users to securely export their wallets.
## Import keys
-Importing on Turnkey enables you or your end users to import a Wallet or Private Key to our system. Check out our [Import Wallet guide](/wallets/import-wallets) to allow your users to securely import their wallets.
+Importing on Turnkey enables you or your end users to import a Wallet or Private Key to our system. Check out our [Import Wallet guide](/features/wallets/import-wallets) to allow your users to securely import their wallets.
## Delete keys
diff --git a/reference/aa-wallets.mdx b/features/wallets/aa-wallets.mdx
similarity index 95%
rename from reference/aa-wallets.mdx
rename to features/wallets/aa-wallets.mdx
index f5adccb2..6d5a5e58 100644
--- a/reference/aa-wallets.mdx
+++ b/features/wallets/aa-wallets.mdx
@@ -4,7 +4,7 @@ description: "Turnkey offers flexible infrastructure to create and manage keys.
---
- For gas sponsorship without third-party AA providers, Turnkey's native Transaction Management supports sponsored transactions for EVM and Solana directly. See [Transaction Management](/concepts/transaction-management) to get started without an AA stack.
+ For gas sponsorship without third-party AA providers, Turnkey's native Transaction Management supports sponsored transactions for EVM and Solana directly. See [Transaction Management](/features/transaction-management) to get started without an AA stack.
## Alchemy's account kit
diff --git a/wallets/claim-links.mdx b/features/wallets/claim-links.mdx
similarity index 98%
rename from wallets/claim-links.mdx
rename to features/wallets/claim-links.mdx
index a7918c4d..ff84c427 100644
--- a/wallets/claim-links.mdx
+++ b/features/wallets/claim-links.mdx
@@ -18,7 +18,7 @@ When the new user clicks on the claim link, they will land directly in your app
Before you start building this feature, ensure:
-- Your organization is set up with embedded wallets in a [sub-organization model](/concepts/sub-organizations): Each of your users should map to a dedicated sub-org in Turnkey.
+- Your organization is set up with embedded wallets in a [sub-organization model](/features/sub-organizations): Each of your users should map to a dedicated sub-org in Turnkey.
- [Email authentication](https://docs.turnkey.com/embedded-wallets/sub-organization-auth) is enabled so that new users can sign up through a secure email flow.
- Your backend can store mapping records between transactions and sub-organizations
diff --git a/products/company-wallets/features/export-wallets.mdx b/features/wallets/export-wallets.mdx
similarity index 100%
rename from products/company-wallets/features/export-wallets.mdx
rename to features/wallets/export-wallets.mdx
diff --git a/products/company-wallets/features/import-wallets.mdx b/features/wallets/import-wallets.mdx
similarity index 100%
rename from products/company-wallets/features/import-wallets.mdx
rename to features/wallets/import-wallets.mdx
diff --git a/wallets/pregenerated-wallets.mdx b/features/wallets/pregenerated-wallets.mdx
similarity index 82%
rename from wallets/pregenerated-wallets.mdx
rename to features/wallets/pregenerated-wallets.mdx
index 07cd6bea..d57607b2 100644
--- a/wallets/pregenerated-wallets.mdx
+++ b/features/wallets/pregenerated-wallets.mdx
@@ -4,4 +4,4 @@ description: "Turnkey allows you to pre-generate wallets for your user before th
mode: wide
---
-To accomplish this, create a new sub-org for that user with a single root user. This root user should only have the end user’s email or phone number associated with it, and no other authenticators, which ensures that only the end user can claim the pre-generated wallet. When the end user wants to claim the wallet, they can complete [email auth](/authentication/email) flow to authenticate and sign a transaction or add a new authenticator.
+To accomplish this, create a new sub-org for that user with a single root user. This root user should only have the end user’s email or phone number associated with it, and no other authenticators, which ensures that only the end user can claim the pre-generated wallet. When the end user wants to claim the wallet, they can complete [email auth](/features/authentication/email) flow to authenticate and sign a transaction or add a new authenticator.
diff --git a/embedded-wallets/send-crypto-via-url.mdx b/features/wallets/send-crypto-via-url.mdx
similarity index 98%
rename from embedded-wallets/send-crypto-via-url.mdx
rename to features/wallets/send-crypto-via-url.mdx
index 21592333..39dfd541 100644
--- a/embedded-wallets/send-crypto-via-url.mdx
+++ b/features/wallets/send-crypto-via-url.mdx
@@ -17,7 +17,7 @@ When the new user clicks on the claim link, they will land directly in your app
Before you start building this feature, ensure:
-- Your organization is set up with embedded wallets in a [sub-organization model](/concepts/sub-organizations): Each of your users should map to a dedicated sub-org in Turnkey.
+- Your organization is set up with embedded wallets in a [sub-organization model](/features/sub-organizations): Each of your users should map to a dedicated sub-org in Turnkey.
- [Email authentication](https://docs.turnkey.com/embedded-wallets/sub-organization-auth) is enabled so that new users can sign up through a secure email flow.
- Your backend can store mapping records between transactions and sub-organizations
diff --git a/fonts/ABCFavorit-Bold.woff b/fonts/ABCFavorit-Bold.woff
new file mode 100644
index 00000000..3c0c2a95
Binary files /dev/null and b/fonts/ABCFavorit-Bold.woff differ
diff --git a/fonts/ABCFavorit-Bold.woff2 b/fonts/ABCFavorit-Bold.woff2
new file mode 100644
index 00000000..fc797cbe
Binary files /dev/null and b/fonts/ABCFavorit-Bold.woff2 differ
diff --git a/fonts/ABCFavorit-Regular.woff2 b/fonts/ABCFavorit-Regular.woff2
new file mode 100644
index 00000000..e475131f
Binary files /dev/null and b/fonts/ABCFavorit-Regular.woff2 differ
diff --git a/get-started/about-turnkey.mdx b/get-started/about-turnkey.mdx
new file mode 100644
index 00000000..7f507bcb
--- /dev/null
+++ b/get-started/about-turnkey.mdx
@@ -0,0 +1,40 @@
+---
+title: "About Turnkey"
+description: "Turnkey is wallet infrastructure for developers — secure key management, transaction signing, and programmable access controls built on hardware-backed secure enclaves."
+sidebarTitle: "About Turnkey"
+---
+
+Turnkey provides the infrastructure to create and manage wallets, sign transactions, and secure cryptographic keys at scale. Every signing operation happens inside hardware-backed secure enclaves — private keys are never exposed to Turnkey, your application, or your team.
+
+## How Turnkey works
+
+Instead of managing private keys directly, Turnkey abstracts key management into a layered system. Your application is a parent organization, and sub-organizations are available to fully isolate wallets, users, and policies per end user or tenant.
+
+Every action — signing, creating wallets, updating permissions — is evaluated by a policy engine running inside a hardware-backed secure enclave before anything executes.
+
+Keys never leave the enclave. Turnkey returns signed payloads and supports transaction broadcasting directly to the network.
+
+Turnkey operates based on a [shared responsibility model](/security/shared-responsibility-model). Turnkey is responsible for the security of the platform itself, including enclave infrastructure, policy engine correctness, key confidentiality, and service availability. You are responsible for securing your integration: configuring your root quorum, scoping user permissions, authoring policies, and managing credentials. See the [full model](/security/shared-responsibility-model) for details.
+
+
+
+
+
+## Core concepts
+
+- **Organization** — Top-level entity representing your application. Contains users, wallets, and policies.
+- **Sub-organization** — Fully isolated organization nested under the parent, typically representing an end user or business customer. Parent orgs have read-only access and cannot modify sub-org contents.
+- **User** — A resource within an org or sub-org that submits activities via a valid credential. Users can have tags, which policies reference for role-based controls.
+- **Root user / root quorum** — Root users can bypass the policy engine. A root quorum sets the approval threshold required to exercise root permissions.
+- **Authenticator** — A credential used to stamp API requests: passkeys, API keys, email OTP, or OAuth.
+- **Activity** — Any action submitted to Turnkey (sign transaction, create user, update policy). All activities are evaluated by the policy engine.
+- **Policy** — A logical rule that evaluates to ALLOW, DENY, or REQUIRES_CONSENSUS. Controls who can sign what, under what conditions.
+- **Wallet** — An HD wallet (seed phrase) that generates multiple accounts across chains. Lives inside the enclave; only addresses and signatures are returned.
+
+## Where to start
+
+- **Explore by use case** — [Embedded Wallets](/solutions/embedded-wallets/overview), [Company Wallets](/solutions/company-wallets/overview), [Key Management](/solutions/key-management/overview)
+- **Account setup** — [create your org and API key](/get-started/quickstart)
+- **SDKs** — [client libraries](/sdks/introduction) for React, React Native, Swift, Kotlin, Flutter, and more
+- **Security** — [how the enclave model works](/security/our-approach) and what Turnkey's security guarantees are
+- **AI-ready docs** — [use Turnkey docs](/get-started/using-llms) with Cursor, ChatGPT, or your own LLM tooling
diff --git a/ai/skills.mdx b/get-started/ai-skills.mdx
similarity index 80%
rename from ai/skills.mdx
rename to get-started/ai-skills.mdx
index 8d35dafc..1cd9e3fc 100644
--- a/ai/skills.mdx
+++ b/get-started/ai-skills.mdx
@@ -3,9 +3,12 @@ title: "Agent Skills"
description: "Opinionated instructions that tell AI agents how to interact with Turnkey through conversation, not code."
---
+import { FeatureCard } from '/snippets/feature-card.mdx'
+import { SolutionCard } from '/snippets/solution-card.mdx'
+
Each agent skill is a `SKILL.md` file with opinionated, step-by-step instructions for a specific Turnkey operation. Instead of an agent reasoning about API docs, parameter formatting, and chain-specific details on its own, skills give it exactly what it needs to execute correctly. Skills work with Claude Code, OpenAI, and other third-party agent frameworks.
-Skills are for interacting with Turnkey directly through an AI assistant, not for building the application layer on top of Turnkey. If you're using a coding agent to develop a Turnkey integration, connect it to the [Docs MCP server](/developer-reference/using-llms) instead.
+Skills are for interacting with Turnkey directly through an AI assistant, not for building the application layer on top of Turnkey. If you're using a coding agent to develop a Turnkey integration, connect it to the [Docs MCP server](/get-started/using-llms) instead.
Skills are open source at [**tkhq/turnkey-agent-skills**](https://github.com/tkhq/turnkey-agent-skills) on GitHub.
@@ -36,7 +39,7 @@ All skills require an API key pair and organization ID from the [Turnkey Dashboa
| Setup | Credential type | When to use |
| :--- | :--- | :--- |
| **Interactive assistant** (human approves each action) | Root API key (with extreme caution) or a scoped, non-root API key | Organization administration, testing, and exploration. Human should review every action before it executes. |
-| **Autonomous agent** (acts without human review) | Scoped, non-root API key | Production automation. **Never use root credentials for autonomous agents.** Root keys bypass all policies. Create a non-root user with scoped policies instead. See [Agentic Wallets](/company-wallets/use-cases/agentic-wallets) and the `provisioning-agent` skill. |
+| **Autonomous agent** (acts without human review) | Scoped, non-root API key | Production automation. **Never use root credentials for autonomous agents.** Root keys bypass all policies. Create a non-root user with scoped policies instead. See [Agentic Wallets](/solutions/company-wallets/agentic-wallets) and the `provisioning-agent` skill. |
## Available skills
@@ -68,3 +71,12 @@ Clone the repo and point your AI assistant at the skill files:
git clone https://github.com/tkhq/turnkey-agent-skills.git
cd turnkey-agent-skills
```
+
+## Next steps
+
+
+
+
+
+
+
diff --git a/production-checklist/backup-recovery.mdx b/get-started/backup-recovery.mdx
similarity index 61%
rename from production-checklist/backup-recovery.mdx
rename to get-started/backup-recovery.mdx
index 5db22d21..f17cd526 100644
--- a/production-checklist/backup-recovery.mdx
+++ b/get-started/backup-recovery.mdx
@@ -1,6 +1,6 @@
---
title: "Backup and recovery"
-description: "In line with responsible practices, backup and recovery of Turnkey accounts and/or wallets is an important consideration when designing any production system. The specific mechanisms (such as [wallet exports](/wallets/export-wallets)) are outlined in greater detail elsewhere - the purpose of this document is to inform and guide how to use the mechanisms available."
+description: "In line with responsible practices, backup and recovery of Turnkey accounts and/or wallets is an important consideration when designing any production system. The specific mechanisms (such as [wallet exports](/features/wallets/export-wallets)) are outlined in greater detail elsewhere - the purpose of this document is to inform and guide how to use the mechanisms available."
---
It is Turnkey's approach that the safest place for key material is within the hardened [secure enclaves](security/secure-enclaves), and within these enclaves alone. Our model guides using authenticators (or combinations thereof) of increasing sophistication, relating to the importance or consequences of a given action. For example, a full recovery of an organization may require multiple break-glass hardware authenticators, where a routine low-stakes action might only rely on an API key.
@@ -9,11 +9,11 @@ The below options all involve some combination of authentication methods and pol
## Root user recovery
-Touched on in the [production checklist](/production-checklist/production-checklist#security), the **native** method of organization recovery in Turnkey is to configure multiple root users (recommended at least 3), who each have hardware authenticators such as biometric auth (TouchID on a MacBook) or a YubiKey physical passkey. With at least 3 root users, it is possible to set up a 2 of 3 [root quorum](/concepts/users/root-quorum) which can bypass the policy engine and assert maximum authority in the case of disaster recovery - even when one root user may have lost their authenticator.
+Touched on in the [production checklist](/get-started/production-checklist#security), the **native** method of organization recovery in Turnkey is to configure multiple root users (recommended at least 3), who each have hardware authenticators such as biometric auth (TouchID on a MacBook) or a YubiKey physical passkey. With at least 3 root users, it is possible to set up a 2 of 3 [root quorum](/features/users/root-quorum) which can bypass the policy engine and assert maximum authority in the case of disaster recovery - even when one root user may have lost their authenticator.
### Sub-organizations
-In a typical non-custodial/embedded wallet configuration, the same root user recovery approach can be effectively used. One could decide on a single ultimate recovery method, such as a passkey or [email-based recovery](/authentication/email), or a combination of multiple methods mirroring the previously outlined _n_ of _m_.
+In a typical non-custodial/embedded wallet configuration, the same root user recovery approach can be effectively used. One could decide on a single ultimate recovery method, such as a passkey or [email-based recovery](/features/authentication/email), or a combination of multiple methods mirroring the previously outlined _n_ of _m_.
### Account based authenticators
@@ -23,13 +23,13 @@ An additional consideration for account-based authenticators (such as email or s
Using additional authenticators for recovery is preferred since it ensures wallets never leave the enclave. However, it is also possible for the user to backup their key material outside of Turnkey.
-Wallets, wallet accounts, and raw private keys can all be exported securely using an [embedded iframe](/embedded-wallets/code-examples/export#embedded-iframe) which ensures the key material remains encrypted while being sent from Turnkey’s enclave to the user’s device.
+Wallets, wallet accounts, and raw private keys can all be exported securely using an [embedded iframe](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets#embedded-iframe) which ensures the key material remains encrypted while being sent from Turnkey’s enclave to the user’s device.

With this process, users have two main options:
-1. Expose the seed phrase to the user in plaintext clientside so they can record it manually. See [wallet exports](/wallets/export-wallets) for more detail.
+1. Expose the seed phrase to the user in plaintext clientside so they can record it manually. See [wallet exports](/features/wallets/export-wallets) for more detail.
2. Encrypt the seed phrase to a user defined passphrase (using [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2)). Contact Turnkey support if you’re interested in this implementation.
-For non-embedded wallets, [scripted exports](/embedded-wallets/code-examples/export#nodejs) are also possible.
+For non-embedded wallets, [scripted exports](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets#nodejs) are also possible.
diff --git a/getting-started/examples.mdx b/get-started/examples.mdx
similarity index 50%
rename from getting-started/examples.mdx
rename to get-started/examples.mdx
index c9e0f331..76c5d074 100644
--- a/getting-started/examples.mdx
+++ b/get-started/examples.mdx
@@ -1,137 +1,145 @@
---
-title: "Examples"
-description: "Turnkey infrastructure is flexible by default. We intentionally prioritize low-level primitives in our product to avoid creating blockers for developers building new kinds of applications on Turnkey."
+title: "Code examples"
+description:
+ "Turnkey infrastructure is flexible by default. We intentionally prioritize low-level primitives
+ in our product to avoid creating blockers for developers building new kinds of applications on
+ Turnkey."
---
-That said, we have built out several example services and applications to help illustrate the types of functionality that Turnkey can enable.
+That said, we have built out several example services and applications to help illustrate the types
+of functionality that Turnkey can enable.
## Demos
Full end-to-end applications to see everything working together.
-| Example | Description |
-| ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| [`react-wallet-kit`](https://github.com/tkhq/sdk/tree/main/examples/react-wallet-kit) | Comprehensive demo of embedded wallet kit with auth, wallet management, signing, import/export |
-| [`demo-embedded-wallet`](https://github.com/tkhq/demo-embedded-wallet) | A minimal consumer wallet app powered by Turnkey and passkeys, with transaction sending |
-| [`demo-consumer-wallet`](https://github.com/tkhq/demo-consumer-wallet) | A minimal consumer wallet app powered by Turnkey and WalletConnect |
-| [`with-react-native-wallet-kit`](https://github.com/tkhq/sdk/tree/main/examples/with-react-native-wallet-kit) | A React Native app demonstrating how to use `@turnkey/react-native-wallet-kit` to authenticate users, create wallets, export wallets, sign messages, and more |
-| [`flutter-demo-app`](https://github.com/tkhq/dart-sdk/tree/main/examples/flutter-demo-app) | A Flutter app that demonstrates how to use the Turnkey's Flutter packages to authenticate users, create wallets, export wallets, sign messages, and more |
-| [`swift-sdk/Examples`](https://github.com/tkhq/swift-sdk/tree/main/Examples) | Native iOS wallet app with OTP, OAuth, and passkey auth, wallet creation, message signing, and transaction sending |
+| Example | Description |
+| ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [`react-wallet-kit`](https://github.com/tkhq/sdk/tree/main/examples/react-wallet-kit) | Comprehensive demo of embedded wallet kit with auth, wallet management, signing, import/export |
+| [`demo-embedded-wallet`](https://github.com/tkhq/demo-embedded-wallet) | A minimal consumer wallet app powered by Turnkey and passkeys, with transaction sending |
+| [`demo-consumer-wallet`](https://github.com/tkhq/demo-consumer-wallet) | A minimal consumer wallet app powered by Turnkey and WalletConnect |
+| [`with-react-native-wallet-kit`](https://github.com/tkhq/sdk/tree/main/examples/with-react-native-wallet-kit) | A React Native app demonstrating how to use `@turnkey/react-native-wallet-kit` to authenticate users, create wallets, export wallets, sign messages, and more |
+| [`flutter-demo-app`](https://github.com/tkhq/dart-sdk/tree/main/examples/flutter-demo-app) | A Flutter app that demonstrates how to use the Turnkey's Flutter packages to authenticate users, create wallets, export wallets, sign messages, and more |
+| [`swift-sdk/Examples`](https://github.com/tkhq/swift-sdk/tree/main/Examples) | Native iOS wallet app with OTP, OAuth, and passkey auth, wallet creation, message signing, and transaction sending |
## Authentication
-| Example | Description |
-| ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
-| [`oauth`](https://github.com/tkhq/sdk/tree/main/examples/oauth) | OAuth login (Google) integration with Turnkey via backend server actions |
-| [`otp-auth`](https://github.com/tkhq/sdk/tree/main/examples/otp-auth) | Email OTP authentication with Auth Proxy and a custom backend |
-| [`magic-link-auth`](https://github.com/tkhq/sdk/tree/main/examples/magic-link-auth) | Magic link login/signup flow using Turnkey's email OTP system |
-| [`wallet-auth`](https://github.com/tkhq/sdk/tree/main/examples/wallet-auth) | External wallet authentication (MetaMask, Phantom, etc.) with Auth Proxy and custom backend |
-| [`with-wallet-stamper`](https://github.com/tkhq/sdk/tree/main/examples/with-wallet-stamper) | Demonstrates `@turnkey/wallet-stamper` for signing Turnkey requests with an external wallet |
+| Example | Description |
+| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
+| [`oauth`](https://github.com/tkhq/sdk/tree/main/examples/oauth) | OAuth login (Google) integration with Turnkey via backend server actions |
+| [`otp-auth`](https://github.com/tkhq/sdk/tree/main/examples/otp-auth) | Email OTP authentication with Auth Proxy and a custom backend |
+| [`magic-link-auth`](https://github.com/tkhq/sdk/tree/main/examples/magic-link-auth) | Magic link login/signup flow using Turnkey's email OTP system |
+| [`wallet-auth`](https://github.com/tkhq/sdk/tree/main/examples/wallet-auth) | External wallet authentication (MetaMask, Phantom, etc.) with Auth Proxy and custom backend |
+| [`with-wallet-stamper`](https://github.com/tkhq/sdk/tree/main/examples/with-wallet-stamper) | Demonstrates `@turnkey/wallet-stamper` for signing Turnkey requests with an external wallet |
## Key & Wallet Management
-| Example | Description |
-| -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
-| [`import-export-with-rwk`](https://github.com/tkhq/sdk/tree/main/examples/import-export-with-rwk) | Wallet import and export using React Wallet Kit and Auth Proxy |
-| [`import-export-with-iframe-stamper`](https://github.com/tkhq/sdk/tree/main/examples/import-export-with-iframe-stamper) | Wallet import/export via `@turnkey/iframe-stamper` |
-| [`wallet-export-sign`](https://github.com/tkhq/sdk/tree/main/examples/wallet-export-sign) | Wallet export and signing operations via Turnkey iframe |
-| [`export-in-node`](https://github.com/tkhq/sdk/tree/main/examples/export-in-node) | Wallet export performed on the backend |
-| [`import-in-node`](https://github.com/tkhq/sdk/tree/main/examples/import-in-node) | Wallet import performed on the backend |
-| [`disaster-recovery`](https://github.com/tkhq/sdk/tree/main/examples/disaster-recovery) | Wallet disaster recovery with direct import or encryption key escrow |
-| [`encryption-key-escrow`](https://github.com/tkhq/sdk/tree/main/examples/encryption-key-escrow) | Use Turnkey to store encryption keys for external recovery bundles |
+| Example | Description |
+| ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
+| [`import-export-with-rwk`](https://github.com/tkhq/sdk/tree/main/examples/import-export-with-rwk) | Wallet import and export using React Wallet Kit and Auth Proxy |
+| [`import-export-with-iframe-stamper`](https://github.com/tkhq/sdk/tree/main/examples/import-export-with-iframe-stamper) | Wallet import/export via `@turnkey/iframe-stamper` |
+| [`wallet-export-sign`](https://github.com/tkhq/sdk/tree/main/examples/wallet-export-sign) | Wallet export and signing operations via Turnkey iframe |
+| [`export-in-node`](https://github.com/tkhq/sdk/tree/main/examples/export-in-node) | Wallet export performed on the backend |
+| [`import-in-node`](https://github.com/tkhq/sdk/tree/main/examples/import-in-node) | Wallet import performed on the backend |
+| [`disaster-recovery`](https://github.com/tkhq/sdk/tree/main/examples/disaster-recovery) | Wallet disaster recovery with direct import or encryption key escrow |
+| [`encryption-key-escrow`](https://github.com/tkhq/sdk/tree/main/examples/encryption-key-escrow) | Use Turnkey to store encryption keys for external recovery bundles |
## Signing
Signers and chain-specific transaction examples.
-| Example | Description |
-| --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| Example | Description |
+| -------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`with-ethers`](https://github.com/tkhq/sdk/tree/main/examples/with-ethers/) | Sign messages, send EIP-1559 and legacy transactions, interact with contracts (WETH), and sign EIP-712 typed data (ERC-2612 permit, ERC-3009, Hyperliquid) using `@turnkey/ethers` |
-| [`with-viem`](https://github.com/tkhq/sdk/tree/main/examples/with-viem/) | Sign messages, send transactions, sign EIP-712 typed data, and sign EIP-4844 and EIP-7702 transactions using `@turnkey/viem` |
-| [`with-eip-1193-provider`](https://github.com/tkhq/sdk/tree/main/examples/with-eip-1193-provider/) | Turnkey-compatible Ethereum provider adhering to the EIP-1193 standard |
-| [`with-nonce-manager`](https://github.com/tkhq/sdk/tree/main/examples/with-nonce-manager/) | Sign and broadcast multiple Ethereum transactions sequentially or optimistically |
-| [`with-cosmjs`](https://github.com/tkhq/sdk/tree/main/examples/with-cosmjs/) | Sign and broadcast a Cosmos transaction on Celestia testnet using `@turnkey/cosmjs` |
-| [`with-solana`](https://github.com/tkhq/sdk/tree/main/examples/with-solana/) | Sign and broadcast Solana transactions using `@turnkey/solana`, including SPL token creation \+ transfer |
-| [`with-bitcoin`](https://github.com/tkhq/sdk/tree/main/examples/with-bitcoin) | Construct, sign, and broadcast a Bitcoin transaction using bitcoinjs-lib |
-| [`with-doge`](https://github.com/tkhq/sdk/tree/main/examples/with-doge) | Dogecoin testnet transaction signing using bitcoinjs-lib |
-| [`with-aptos`](https://github.com/tkhq/sdk/tree/main/examples/with-aptos) | Aptos transaction construction and mainnet fund transfer |
-| [`with-ton`](https://github.com/tkhq/sdk/tree/main/examples/with-ton) | TON transaction construction and mainnet fund transfer |
-| [`with-tron`](https://github.com/tkhq/sdk/tree/main/examples/with-tron) | Tron wallet creation, signing, testnet funding, and policy guards |
-| [`with-stacks`](https://github.com/tkhq/sdk/tree/main/examples/with-stacks) | Stacks transaction signing with secp256k1 |
-| [`with-movement`](https://github.com/tkhq/sdk/tree/main/examples/with-movement) | Movement transaction construction and mainnet fund transfer |
-| [`with-arc`](https://github.com/tkhq/sdk/tree/main/examples/with-arc) | Arc testnet transaction construction and broadcast |
-| [`with-tempo`](https://github.com/tkhq/sdk/tree/main/examples/with-tempo) | Tempo testnet transaction construction and broadcast |
-| [`with-sui`](https://github.com/tkhq/sdk/tree/main/examples/with-sui) | Construct, sign, and broadcast a Sui transaction using Turnkey |
-| [`with-iota`](https://github.com/tkhq/sdk/tree/main/examples/with-iota) | Build, sign, and broadcast IOTA transactions using Turnkey |
+| [`with-viem`](https://github.com/tkhq/sdk/tree/main/examples/with-viem/) | Sign messages, send transactions, sign EIP-712 typed data, and sign EIP-4844 and EIP-7702 transactions using `@turnkey/viem` |
+| [`with-eip-1193-provider`](https://github.com/tkhq/sdk/tree/main/examples/with-eip-1193-provider/) | Turnkey-compatible Ethereum provider adhering to the EIP-1193 standard |
+| [`with-nonce-manager`](https://github.com/tkhq/sdk/tree/main/examples/with-nonce-manager/) | Sign and broadcast multiple Ethereum transactions sequentially or optimistically |
+| [`with-cosmjs`](https://github.com/tkhq/sdk/tree/main/examples/with-cosmjs/) | Sign and broadcast a Cosmos transaction on Celestia testnet using `@turnkey/cosmjs` |
+| [`with-solana`](https://github.com/tkhq/sdk/tree/main/examples/with-solana/) | Sign and broadcast Solana transactions using `@turnkey/solana`, including SPL token creation \+ transfer |
+| [`with-bitcoin`](https://github.com/tkhq/sdk/tree/main/examples/with-bitcoin) | Construct, sign, and broadcast a Bitcoin transaction using bitcoinjs-lib |
+| [`with-doge`](https://github.com/tkhq/sdk/tree/main/examples/with-doge) | Dogecoin testnet transaction signing using bitcoinjs-lib |
+| [`with-aptos`](https://github.com/tkhq/sdk/tree/main/examples/with-aptos) | Aptos transaction construction and mainnet fund transfer |
+| [`with-ton`](https://github.com/tkhq/sdk/tree/main/examples/with-ton) | TON transaction construction and mainnet fund transfer |
+| [`with-tron`](https://github.com/tkhq/sdk/tree/main/examples/with-tron) | Tron wallet creation, signing, testnet funding, and policy guards |
+| [`with-stacks`](https://github.com/tkhq/sdk/tree/main/examples/with-stacks) | Stacks transaction signing with secp256k1 |
+| [`with-movement`](https://github.com/tkhq/sdk/tree/main/examples/with-movement) | Movement transaction construction and mainnet fund transfer |
+| [`with-arc`](https://github.com/tkhq/sdk/tree/main/examples/with-arc) | Arc testnet transaction construction and broadcast |
+| [`with-tempo`](https://github.com/tkhq/sdk/tree/main/examples/with-tempo) | Tempo testnet transaction construction and broadcast |
+| [`with-sui`](https://github.com/tkhq/sdk/tree/main/examples/with-sui) | Construct, sign, and broadcast a Sui transaction using Turnkey |
+| [`with-iota`](https://github.com/tkhq/sdk/tree/main/examples/with-iota) | Build, sign, and broadcast IOTA transactions using Turnkey |
## Turnkey Transaction Management
-| Example | Description |
-| ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
-| [`tk-gas-station`](https://github.com/tkhq/sdk/tree/main/examples/tk-gas-station) | Gasless transactions using Gas Station SDK with EIP-7702 authorization |
-| [`with-paymaster`](https://github.com/tkhq/sdk/tree/main/examples/with-paymaster) | ERC-20 token transfer on EVM with Turnkey paymaster gas sponsorship |
-| [`with-solana-paymaster`](https://github.com/tkhq/sdk/tree/main/examples/with-solana-paymaster) | SPL token transfer on Solana with Turnkey fee sponsorship |
-| [`with-balances`](https://github.com/tkhq/sdk/tree/main/examples/with-balances) | Fetch token balances and list supported assets using Turnkey APIs |
-| [`solana-sweeper`](https://github.com/tkhq/sdk/tree/main/examples/solana-sweeper) | Solana token sweeper utility |
-| [`solana-usdc-swap`](https://github.com/tkhq/sdk/tree/main/examples/solana-usdc-swap) | SOL to USDC swap on Solana mainnet via Jupiter |
-| [`sweeper`](https://github.com/tkhq/sdk/tree/main/examples/sweeper/) | Sweep funds from one address to a different address |
-| [`rebalancer`](https://github.com/tkhq/sdk/tree/main/examples/rebalancer/) | Manage and rebalance funds across multiple wallets and key types |
+| Example | Description |
+| ----------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
+| [`tk-gas-station`](https://github.com/tkhq/sdk/tree/main/examples/tk-gas-station) | Gasless transactions using Gas Station SDK with EIP-7702 authorization |
+| [`with-paymaster`](https://github.com/tkhq/sdk/tree/main/examples/with-paymaster) | ERC-20 token transfer on EVM with Turnkey paymaster gas sponsorship |
+| [`with-solana-paymaster`](https://github.com/tkhq/sdk/tree/main/examples/with-solana-paymaster) | SPL token transfer on Solana with Turnkey fee sponsorship |
+| [`with-balances`](https://github.com/tkhq/sdk/tree/main/examples/with-balances) | Fetch token balances and list supported assets using Turnkey APIs |
+| [`solana-sweeper`](https://github.com/tkhq/sdk/tree/main/examples/solana-sweeper) | Solana token sweeper utility |
+| [`solana-usdc-swap`](https://github.com/tkhq/sdk/tree/main/examples/solana-usdc-swap) | SOL to USDC swap on Solana mainnet via Jupiter |
+| [`sweeper`](https://github.com/tkhq/sdk/tree/main/examples/sweeper/) | Sweep funds from one address to a different address |
+| [`rebalancer`](https://github.com/tkhq/sdk/tree/main/examples/rebalancer/) | Manage and rebalance funds across multiple wallets and key types |
## Account Abstraction
-| Example | Description |
-| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
+| Example | Description |
+| ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| [`with-zerodev-aa`](https://github.com/tkhq/sdk/tree/main/examples/with-zerodev-aa) | Transaction construction and broadcast with Turnkey, Viem, and ZeroDev account abstraction |
| [`with-biconomy-aa`](https://github.com/tkhq/sdk/tree/main/examples/with-biconomy-aa) | Transaction construction and broadcast with Turnkey, Viem, and Biconomy account abstraction |
## DeFi & Protocol Integrations
-| Example | Description |
-| ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
-| [`with-uniswap`](https://github.com/tkhq/sdk/tree/main/examples/with-uniswap/) | Sign and broadcast a Uniswap v3 trade using the Ethers signer |
-| [`eth-usdc-swap`](https://github.com/tkhq/sdk/tree/main/examples/eth-usdc-swap) | ETH to USDC swap on Base mainnet via Uniswap Universal Router |
-| [`with-0x`](https://github.com/tkhq/sdk/tree/main/examples/with-0x) | EVM swapping ETH for USDC using 0x Swap API |
-| [`with-lifi`](https://github.com/tkhq/sdk/tree/main/examples/with-lifi) | EVM and SVM bridging between ETH and SOL using Li.Fi |
-| [`with-aave`](https://github.com/tkhq/sdk/tree/main/examples/with-aave) | Aave v3 USDC deposit/withdraw with Turnkey policy engine controls |
-| [`with-morpho`](https://github.com/tkhq/sdk/tree/main/examples/with-morpho) | Morpho Vaults USDC deposit/withdraw on Base Mainnet |
-| [`with-yield-xyz`](https://github.com/tkhq/sdk/tree/main/examples/with-yield-xyz) | Yield.xyz vaults deposit/withdraw across 75+ networks |
-| [`with-porto`](https://github.com/tkhq/sdk/tree/main/examples/with-porto) | Porto wallet upgrade and operations using API keys |
-| [`with-x402`](https://github.com/tkhq/sdk/tree/main/examples/with-x402) | Coinbase x402 payment protocol with embedded wallets |
-| [`with-jupiter`](https://github.com/tkhq/sdk/tree/main/examples/with-jupiter) | Solana token swaps using Jupiter Ultra Swap API |
-| [`with-breeze`](https://github.com/tkhq/sdk/tree/main/examples/with-breeze) | Solana USDC staking and yield management via Breeze API |
-| [`trading-runner`](https://github.com/tkhq/sdk/tree/main/examples/trading-runner/) | Multi-user Uniswap v3 trading demo with private key tags, user tags, and policies |
-| [`with-gnosis`](https://github.com/tkhq/sdk/tree/main/examples/with-gnosis/) | Create new Ethereum addresses, configure a 3/3 Gnosis safe, and create \+ execute a transaction from it |
+| Example | Description |
+| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
+| [`with-uniswap`](https://github.com/tkhq/sdk/tree/main/examples/with-uniswap/) | Sign and broadcast a Uniswap v3 trade using the Ethers signer |
+| [`eth-usdc-swap`](https://github.com/tkhq/sdk/tree/main/examples/eth-usdc-swap) | ETH to USDC swap on Base mainnet via Uniswap Universal Router |
+| [`with-0x`](https://github.com/tkhq/sdk/tree/main/examples/with-0x) | EVM swapping ETH for USDC using 0x Swap API |
+| [`with-lifi`](https://github.com/tkhq/sdk/tree/main/examples/with-lifi) | EVM and SVM bridging between ETH and SOL using Li.Fi |
+| [`with-aave`](https://github.com/tkhq/sdk/tree/main/examples/with-aave) | Aave v3 USDC deposit/withdraw with Turnkey policy engine controls |
+| [`with-morpho`](https://github.com/tkhq/sdk/tree/main/examples/with-morpho) | Morpho Vaults USDC deposit/withdraw on Base Mainnet |
+| [`with-yield-xyz`](https://github.com/tkhq/sdk/tree/main/examples/with-yield-xyz) | Yield.xyz vaults deposit/withdraw across 75+ networks |
+| [`with-porto`](https://github.com/tkhq/sdk/tree/main/examples/with-porto) | Porto wallet upgrade and operations using API keys |
+| [`with-x402`](https://github.com/tkhq/sdk/tree/main/examples/with-x402) | Coinbase x402 payment protocol with embedded wallets |
+| [`with-jupiter`](https://github.com/tkhq/sdk/tree/main/examples/with-jupiter) | Solana token swaps using Jupiter Ultra Swap API |
+| [`with-breeze`](https://github.com/tkhq/sdk/tree/main/examples/with-breeze) | Solana USDC staking and yield management via Breeze API |
+| [`trading-runner`](https://github.com/tkhq/sdk/tree/main/examples/trading-runner/) | Multi-user Uniswap v3 trading demo with private key tags, user tags, and policies |
+| [`with-gnosis`](https://github.com/tkhq/sdk/tree/main/examples/with-gnosis/) | Create new Ethereum addresses, configure a 3/3 Gnosis safe, and create \+ execute a transaction from it |
## Policies & Access Control
-| Example | Description |
-| ----------------------------------------------------------------------------------- | -------------------------------- |
-| [`with-delegated`](https://github.com/tkhq/sdk/tree/main/examples/with-delegated/) | Delegated access setup examples |
+| Example | Description |
+| ---------------------------------------------------------------------------------- | ------------------------------- |
+| [`with-delegated`](https://github.com/tkhq/sdk/tree/main/examples/with-delegated/) | Delegated access setup examples |
## Smart Contracts & Automation
-| Example | Description |
-| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
-| [`deployer`](https://github.com/tkhq/sdk/tree/main/examples/deployer/) | Compile and deploy a smart contract |
-| [`foundry`](https://github.com/tkhq/sdk/tree/main/examples/foundry) | Smart contract setup and broadcast from a Turnkey wallet using Foundry |
+| Example | Description |
+| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- |
+| [`deployer`](https://github.com/tkhq/sdk/tree/main/examples/deployer/) | Compile and deploy a smart contract |
+| [`foundry`](https://github.com/tkhq/sdk/tree/main/examples/foundry) | Smart contract setup and broadcast from a Turnkey wallet using Foundry |
## Advanced & Utilities
-| Example | Description |
-| ------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
-| [`with-offline`](https://github.com/tkhq/sdk/tree/main/examples/with-offline/) | Stamp a Turnkey request and produce a signed URL to send it later |
-| [`kitchen-sink`](https://github.com/tkhq/sdk/tree/main/examples/kitchen-sink) | Playground scripts for common Turnkey requests via HTTP, sdk-server, and sdk-browser |
-| [`with-sdk-js`](https://github.com/tkhq/sdk/tree/main/examples/with-sdk-js) | Integration test suite for `@turnkey/core` and `@turnkey/react-wallet-kit` |
+| Example | Description |
+| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ |
+| [`with-offline`](https://github.com/tkhq/sdk/tree/main/examples/with-offline/) | Stamp a Turnkey request and produce a signed URL to send it later |
+| [`kitchen-sink`](https://github.com/tkhq/sdk/tree/main/examples/kitchen-sink) | Playground scripts for common Turnkey requests via HTTP, sdk-server, and sdk-browser |
+| [`with-sdk-js`](https://github.com/tkhq/sdk/tree/main/examples/with-sdk-js) | Integration test suite for `@turnkey/core` and `@turnkey/react-wallet-kit` |
## Demos built with Turnkey
### Embedded Wallet Kit ([live link](https://wallets.turnkey.com/))
-A full-featured embedded wallet demo built with [`@turnkey/react-wallet-kit`](https://www.npmjs.com/package/@turnkey/react-wallet-kit), showcasing the latest Turnkey SDK. Includes passkey, email, and OAuth authentication, wallet creation, and more.
+A full-featured embedded wallet demo built with
+[`@turnkey/react-wallet-kit`](https://www.npmjs.com/package/@turnkey/react-wallet-kit), showcasing
+the latest Turnkey SDK. Includes passkey, email, and OAuth authentication, wallet creation, and
+more.
### Demo Embedded Wallet ([code](https://github.com/tkhq/demo-embedded-wallet), [live link](https://wallet.tx.xyz))
-A wallet application showing how users can register and authenticate using passkeys. Includes features such as:
+A wallet application showing how users can register and authenticate using passkeys. Includes
+features such as:
- User authentication with passkeys, email auth, and OAuth
- Creating new wallets and wallet accounts
@@ -152,45 +160,71 @@ See https://github.com/tkhq/demo-embedded-wallet for the code.
### React Native Wallet Kit ([code](https://github.com/tkhq/sdk/tree/main/examples/with-react-native-wallet-kit))
-A React Native app demonstrating how to use [`@turnkey/react-native-wallet-kit`](https://www.npmjs.com/package/@turnkey/react-native-wallet-kit) to authenticate users, create wallets, export wallets, sign messages, and more.
+A React Native app demonstrating how to use
+[`@turnkey/react-native-wallet-kit`](https://www.npmjs.com/package/@turnkey/react-native-wallet-kit)
+to authenticate users, create wallets, export wallets, sign messages, and more.
### Flutter demo app ([code](https://github.com/tkhq/dart-sdk/tree/main/examples/flutter-demo-app))
-A Flutter app that demonstrates how to use the Turnkey's Flutter packages to authenticate users, create wallets, export wallets, sign messages, and more
+A Flutter app that demonstrates how to use the Turnkey's Flutter packages to authenticate users,
+create wallets, export wallets, sign messages, and more
-
+
See https://github.com/tkhq/dart-sdk/tree/main/examples/flutter-demo-app for the code
### Demo Consumer Wallet ([code](https://github.com/tkhq/demo-consumer-wallet))
-A minimal consumer wallet app powered by Turnkey. Behind the scenes, it uses [`@turnkey/ethers`](https://www.npmjs.com/package/@turnkey/ethers) for signing and WalletConnect (v1) for accessing dapps.
+A minimal consumer wallet app powered by Turnkey. Behind the scenes, it uses
+[`@turnkey/ethers`](https://www.npmjs.com/package/@turnkey/ethers) for signing and WalletConnect
+(v1) for accessing dapps.
-
+
See https://github.com/tkhq/demo-consumer-wallet for the code.
### Demo Viem Passkeys with Gelato Relay ([code](https://github.com/gelatodigital/gelato-turnkey-passkeys-relay))
-This example demonstrates how to leverage Turnkey's secure key management and Gelato's battle-tested relay infrastructure to enable seamless, sponsored interactions with meta-transactions using the [`@turnkey/viem`](https://github.com/tkhq/sdk/tree/main/packages/viem) signer and [`@gelatonetwork/relay-sdk-viem`](https://github.com/gelatodigital/relay-sdk-viem).
+This example demonstrates how to leverage Turnkey's secure key management and Gelato's battle-tested
+relay infrastructure to enable seamless, sponsored interactions with meta-transactions using the
+[`@turnkey/viem`](https://github.com/tkhq/sdk/tree/main/packages/viem) signer and
+[`@gelatonetwork/relay-sdk-viem`](https://github.com/gelatodigital/relay-sdk-viem).
-
- 
-
+
#### How Infinex leverages Turnkey and Gelato
-Infinex, a platform designed to unify the decentralized ecosystem and applications under a single UX layer, eliminates the complexities of navigating fragmented crypto protocols. By integrating **Turnkey** and **Gelato**, Infinex delivers a seamless, secure, and cost-efficient experience for decentralized finance users.
+Infinex, a platform designed to unify the decentralized ecosystem and applications under a single UX
+layer, eliminates the complexities of navigating fragmented crypto protocols. By integrating
+**Turnkey** and **Gelato**, Infinex delivers a seamless, secure, and cost-efficient experience for
+decentralized finance users.
-- **Secure Key Management with Turnkey**: Infinex ensures private keys are securely managed within Turnkey's infrastructure, removing the need for traditional wallet pop-ups. This approach streamlines authentication through passkeys, offering a frictionless and secure user experience.
-- **Gasless Transactions with Gelato**: Leveraging Gelato's Relay (ERC-2771), Infinex enables fully **sponsored transactions**, allowing users to interact with decentralized applications without ever paying gas fees. This enhances accessibility and usability, ensuring that users can participate without holding or managing native blockchain tokens for fees.
+- **Secure Key Management with Turnkey**: Infinex ensures private keys are securely managed within
+ Turnkey's infrastructure, removing the need for traditional wallet pop-ups. This approach
+ streamlines authentication through passkeys, offering a frictionless and secure user experience.
+- **Gasless Transactions with Gelato**: Leveraging Gelato's Relay (ERC-2771), Infinex enables fully
+ **sponsored transactions**, allowing users to interact with decentralized applications without
+ ever paying gas fees. This enhances accessibility and usability, ensuring that users can
+ participate without holding or managing native blockchain tokens for fees.
-The synergy between Turnkey and Gelato allows Infinex to offer an intuitive, cost-free user experience while maintaining the highest standards of security and scalability.
+The synergy between Turnkey and Gelato allows Infinex to offer an intuitive, cost-free user
+experience while maintaining the highest standards of security and scalability.
### Multichain signing (Adamik demo)
-This [demo](https://turnkey-multichain.adamik.io/) shows how the Adamik API has integrated Turnkey to securely sign transactions across 60\+ blockchains.
+This [demo](https://turnkey-multichain.adamik.io/) shows how the Adamik API has integrated Turnkey
+to securely sign transactions across 60\+ blockchains.
diff --git a/production-checklist/production-checklist.mdx b/get-started/production-checklist.mdx
similarity index 86%
rename from production-checklist/production-checklist.mdx
rename to get-started/production-checklist.mdx
index 2a4b7190..dbbf9007 100644
--- a/production-checklist/production-checklist.mdx
+++ b/get-started/production-checklist.mdx
@@ -5,19 +5,19 @@ description: "This checklist contains recommendations and steps specifically for
## Production setup
-- Many of our customers prefer to maintain separate Development and Production [organizations](/concepts/organizations). If you choose to do so, ensure your production environment is referencing the correct organization ID.
+- Many of our customers prefer to maintain separate Development and Production [organizations](/features/organizations). If you choose to do so, ensure your production environment is referencing the correct organization ID.
- Ensure you have an active subscription via the Account Settings page in the Turnkey dashboard.
- If you are on an Enterprise plan, confirm your production organization ID with your account rep.
- Double check our [resource limits](/concepts/resource-limits) and [rate
- limits](/faq#do-you-have-any-rate-limits-in-place-in-your-public-api) to
+ Double check our [resource limits](/reference/resource-limits) and [rate
+ limits](/reference/faq#do-you-have-any-rate-limits-in-place-in-your-public-api) to
ensure your implementation will not trigger these limits at production scale.
## Security
-- Lock down your [root quorum](/concepts/users/root-quorum). We recommend a quorum of at least 3 with a threshold of at least 2.
+- Lock down your [root quorum](/features/users/root-quorum). We recommend a quorum of at least 3 with a threshold of at least 2.
- Ensure any team members with critical permissions, especially root quorum members, have set up at least two authenticators for their account (e.g., touchID plus a hardware authenticator like a Yubikey).
- Avoid using root user permissions for routine operations and instead use standard users with permissions explicitly granted via policies to limit the surface area of a compromised user.
- Confirm that all API keys are stored securely and not embedded in exposed or vulnerable parts of the codebase. API keys should be stored in a secure, encrypted environment and should never be hard-coded in publicly accessible repositories or client-side code.
@@ -30,5 +30,5 @@ description: "This checklist contains recommendations and steps specifically for
## Errors and retries
- Activity submission is optimistically synchronous. In most cases activities will be completed and returned right away (synchronously), but if there is a lot of activity in a single organization, activities will be processed asynchronously. Make sure you handle PENDING activities by polling a few times until their completion. You can use [createActivityPoller](https://github.com/tkhq/sdk/blob/d9ed2aefc92d298826a40e821f959b019ea1936f/packages/http/src/async.ts#L101) to do this if you're using our Typescript SDK.
-- Implement retry strategies for API calls, adjusting for various error types and avoiding over-retrying on critical failures. Incorporate [rate limiting](/faq#do-you-have-any-rate-limits-in-place-in-your-public-api) and exponential backoff in retry mechanisms.
+- Implement retry strategies for API calls, adjusting for various error types and avoiding over-retrying on critical failures. Incorporate [rate limiting](/reference/faq#do-you-have-any-rate-limits-in-place-in-your-public-api) and exponential backoff in retry mechanisms.
- Set up monitoring to detect and alert on patterns of failures
diff --git a/getting-started/quickstart.mdx b/get-started/quickstart.mdx
similarity index 83%
rename from getting-started/quickstart.mdx
rename to get-started/quickstart.mdx
index 34249207..25e66f9a 100644
--- a/getting-started/quickstart.mdx
+++ b/get-started/quickstart.mdx
@@ -4,6 +4,8 @@ description: "Before diving into the code, let's set up your organization and co
sidebarTitle: "Account setup"
---
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
## Create an account
Navigate to the [Turnkey Dashboard](https://app.turnkey.com/dashboard/auth/initial) to create an account and setup your organization:
@@ -42,7 +44,7 @@ The API keypair is used to authenticate requests to Turnkey. We'll create one no
- Optionally, you may also generate keys using the [Turnkey CLI](/sdks/cli).
+ Optionally, you may also generate keys using the [Turnkey CLI](/sdks/introduction).
@@ -73,23 +75,7 @@ The API keypair is used to authenticate requests to Turnkey. We'll create one no
Now that you've created an organization and API keypair, you're ready to start developing with Turnkey!
-
-
- Build embedded wallets with Turnkey
-
-
- Automate signing with Turnkey
-
-
+
+
+
+
diff --git a/developer-reference/using-llms.mdx b/get-started/using-llms.mdx
similarity index 100%
rename from developer-reference/using-llms.mdx
rename to get-started/using-llms.mdx
diff --git a/getting-started.mdx b/getting-started.mdx
deleted file mode 100644
index 33755280..00000000
--- a/getting-started.mdx
+++ /dev/null
@@ -1,20 +0,0 @@
----
-title: Getting started
-description: Get started with Turnkey
-mode: wide
-sidebarTitle: Overview
----
-
-
-
- 2 items
-
-
-
- Check out some of our example apps and use cases
-
-
-
- A checklist to help you get your app to production!
-
-
diff --git a/getting-started/company-wallets-quickstart.mdx b/getting-started/company-wallets-quickstart.mdx
deleted file mode 100644
index e60cf481..00000000
--- a/getting-started/company-wallets-quickstart.mdx
+++ /dev/null
@@ -1,123 +0,0 @@
----
-title: "Company Wallets quickstart"
-description: "Turnkey's Company Wallets enable you to build secure, programmatic signing workflows directly into your applications. With features like customizable policies, multi-party approvals, and support for any blockchain, you can confidently automate complex signing operations while maintaining enterprise-grade security."
-sidebarTitle: "Company Wallets"
----
-
-## Prerequisites
-
-This guide assumes you've completed the steps to create an account, organization, and API keypair as described in the [account setup](/getting-started/quickstart) section.
-
-## Installation
-
-Install the Turnkey CLI to get started:
-
-```bash
-brew install tkhq/tap/turnkey
-```
-
-We use Homebrew for a quick installation process. For a more secure installation that requires no trust in external parties, see our [CLI repository](https://github.com/tkhq/tkcli).
-
-## Transaction signing
-
-
-
-
-Set the `ORGANIZATION_ID` environment variable to your organization ID. This will be used to identify your organization in the API requests.
-
-```bash
-export ORGANIZATION_ID=
-```
-
-An API keypair is required to authenticate requests to the Turnkey API.
-
-Create a new key named `quickstart` using the turnkey CLI:
-
-```bash
-turnkey generate api-key --organization $ORGANIZATION_ID --key-name quickstart
-```
-
-You'll see output like this:
-
-```json
-{
- "privateKeyFile": "/home/user/.config/turnkey/keys/quickstart.private",
- "publicKey": "03...72",
- "publicKeyFile": "/home/user/.config/turnkey/keys/quickstart.public"
-}
-```
-
-Follow the instructions in this [guide](/sdks/cli#add-your-public-api-key) to add your new public API key to your organization via the dashboard.
-
-
-
-
-Wallets are collections of cryptographic key pairs typically used for sending and receiving digital assets. To create one, we need to provide a name:
-
-```bash
-turnkey wallets create --name default --key-name quickstart
-```
-
-
- This command requires a key named `quickstart` to exist in your configuration. This key should have been created during the [Quickstart](/getting-started/quickstart) guide. If you haven't created it yet, please complete the initial setup steps first.
-
-If the key doesn't exist, you'll see an error like this:
-
-```json
-{
- "error": "failed to load key bytes \"quickstart\": failed to read from \"/.config/turnkey/keys/quickstart.private\": open /.config/turnkey/keys/quickstart.private: no such file or directory"
-}
-```
-
-If the key exists but has not been added to your organization, you'll see an error like this:
-
-```json
-{
- "error": "failed to associate the API key with an organization; please manually specify the organization ID"
-}
-```
-
-
-
-
-
-To create a cryptographic key pair on our new wallet, we need to pass our desired address format:
-
-```bash
-turnkey wallets accounts create --wallet default --address-format ADDRESS_FORMAT_ETHEREUM --key-name quickstart
-```
-
-This command will produce an Ethereum address (e.g. `0x08cb1216C95149DF66978b574E484869512CE2bF`) that we'll need to sign a transaction. You can see your new Wallet account with:
-
-```bash
-turnkey wallets accounts list --wallet default --key-name quickstart
-```
-
-
-
-
-Now you can sign an Ethereum transaction with this new address with our [`sign_transaction` endpoint](/api-reference/signing/sign-transaction). Make sure to replace the `unsignedTransaction` below with your own. You can use our [simple transaction generator](https://build.tx.xyz) if you need a quick transaction for testing:
-
-```bash
-turnkey request --path /public/v1/submit/sign_transaction --body '{
- "timestampMs": "'"$(date +%s)"'000",
- "type": "ACTIVITY_TYPE_SIGN_TRANSACTION_V2",
- "organizationId": "'"$ORGANIZATION_ID"'",
- "parameters": {
- "type": "TRANSACTION_TYPE_ETHEREUM",
- "signWith": "",
- "unsignedTransaction": ""
- }
-}' --key-name quickstart
-```
-
-If you'd like to broadcast your transaction, you can easily do so
-via [Etherscan](https://etherscan.io/pushTx).
-
-
-
-
-## Next steps
-
-Learn more about integrating Company Wallets and our powerful
-features [here](/company-wallets/overview).
diff --git a/getting-started/embedded-wallet-quickstart.mdx b/getting-started/embedded-wallet-quickstart.mdx
deleted file mode 100644
index acdabfb7..00000000
--- a/getting-started/embedded-wallet-quickstart.mdx
+++ /dev/null
@@ -1,11 +0,0 @@
----
-title: "Embedded wallets quickstart"
-description: "Turnkey's embedded wallets enable you to integrate secure, custom wallet experiences directly into your product. With features like advanced security, seamless authentication, and flexible UX options, you can focus on building great products while we handle the complexities of private key management."
-sidebarTitle: "Embedded wallets"
----
-
-## `@turnkey/react-wallet-kit`
-
-The `@turnkey/react-wallet-kit` is a powerful SDK that allows you to integrate Turnkey's Embedded Wallets into your React applications. It provides a set of UI components and easy-to-use functions, all exported from a hook, enabling you to quickly build secure embedded wallet experiences.
-
-Head over to the [Getting Started](/sdks/react/getting-started) guide to set up your React app with Turnkey's Embedded Wallets.
diff --git a/getting-started/launch-checklist.mdx b/getting-started/launch-checklist.mdx
deleted file mode 100644
index ea072dd5..00000000
--- a/getting-started/launch-checklist.mdx
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "Launch checklist"
-description: "Before deploying your Turnkey integration in production, take a look at our recommendations below. This checklist will guide you through a few important steps and considerations to help ensure your setup is secure, efficient and ready for prime time."
----
-
-## Production setup
-
-- Many of our customers prefer to maintain separate Development and Production [organizations](/concepts/organizations). If you choose to do so, ensure your production environment is referencing the correct organization ID.
-- Ensure you have an active subscription via the Account Settings page in the Turnkey dashboard.
-- If you are on an Enterprise plan, confirm your production organization ID with your account rep.
-
-
-Double check our [resource limits](/concepts/resource-limits) and [rate limits](/faq#do-you-have-any-rate-limits-in-place-in-your-public-api) to ensure your implementation will not trigger these limits at production scale.**
-
-
-## Security
-
-- Lock down your [root quorum](/concepts/users/root-quorum). We recommend a quorum of at least 3 with a threshold of at least 2.
-- Ensure any team members with critical permissions, especially root quorum members, have set up at least two authenticators for their account (e.g., touchID plus a hardware authenticator like a Yubikey).
-- Avoid using root user permissions for routine operations and instead use standard users with permissions explicitly granted via policies to limit the surface area of a compromised user.
-- Confirm that all API keys are stored securely and not embedded in exposed or vulnerable parts of the codebase. API keys should be stored in a secure, encrypted environment and should never be hard-coded in publicly accessible repositories or client-side code.
-
-## Logging
-
-- Key identifiers in our service include sub-organization IDs, wallet IDs and addresses. Ensure these identifiers are securely stored and associated with your users as necessary.
-- Set up logging for activities and include relevant identifiers needed for audit, compliance, or troubleshooting purposes. We recommend logging activity IDs, status, creation date, as well as credential IDs and public keys of the approvers. You should also log other resource IDs if relevant for your data model (policies, tags, wallets, accounts, etc)
-
-## Errors and retries
-
-- Activity submission is optimistically synchronous. In most cases activities will be completed and returned right away (synchronously), but if there is a lot of activity in a single organization, activities will be processed asynchronously. Make sure you handle PENDING activities by polling a few times until their completion. You can use [createActivityPoller](https://github.com/tkhq/sdk/blob/d9ed2aefc92d298826a40e821f959b019ea1936f/packages/http/src/async.ts#L101) to do this if you're using our Typescript SDK.
-- Implement retry strategies for API calls, adjusting for various error types and avoiding over-retrying on critical failures. Incorporate [rate limiting](/faq#do-you-have-any-rate-limits-in-place-in-your-public-api) and exponential backoff in retry mechanisms.
-- Set up monitoring to detect and alert on patterns of failures
diff --git a/hero-animation.js b/hero-animation.js
new file mode 100644
index 00000000..bba1ef44
--- /dev/null
+++ b/hero-animation.js
@@ -0,0 +1,33 @@
+(function () {
+ function inlineHero() {
+ document.querySelectorAll('img[data-hero-inline-src]:not([data-hero-inlined])').forEach(function (img) {
+ var src = img.getAttribute('data-hero-inline-src');
+ if (!src) return;
+
+ fetch(src)
+ .then(function (res) {
+ return res.text();
+ })
+ .then(function (markup) {
+ if (img.getAttribute('data-hero-inlined')) return;
+
+ var el = document.createElement('div');
+ el.className = img.className;
+ el.setAttribute('role', 'img');
+ el.setAttribute('aria-label', img.getAttribute('alt') || 'Turnkey hero illustration');
+ el.innerHTML = markup;
+ img.setAttribute('data-hero-inlined', 'true');
+ img.replaceWith(el);
+ })
+ .catch(function () {
+ /* Keep fallback */
+ });
+ });
+ }
+
+ if (document.readyState === 'loading') {
+ document.addEventListener('DOMContentLoaded', inlineHero);
+ } else {
+ inlineHero();
+ }
+})();
diff --git a/home.mdx b/home.mdx
deleted file mode 100644
index a0e55e34..00000000
--- a/home.mdx
+++ /dev/null
@@ -1,121 +0,0 @@
----
-title: "Overview"
-description: "Welcome to Turnkey!"
-sidebarTitle: "Overview"
----
-
-import { Logo } from "/snippets/logo.mdx";
-import { SquareCard } from "/snippets/square-card.mdx";
-
-
- 
-
-
-Turnkey provides secure, scalable and programmable crypto infrastructure for Embedded Wallets and onchain Company Wallets.
-
-Whether you're building a DeFi platform, a payments app, an AI agent, or anything requiring a private key, Turnkey's modular components empower you to build fully customizable, innovative products - offering complete flexibility without limitations.
-
-Seamlessly create in-app wallets, sign millions of transactions at millisecond speed, create superior end-user experiences and set granular controls without sacrificing security.
-
-Our documentation makes it easy for you to integrate with Turnkey, no matter what you're building.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Turnkey's products
-
-Turnkey covers two main use cases: Embedded Wallets and Company Wallets.
-
-## Embedded Wallets
-
-Turnkey's Embedded Wallets offer the most secure way to integrate wallets into your app. With Turnkey, you can create millions of embedded wallets on behalf of your users for a flawless onboarding and in-app experience.
-
-### Features
-
-| Feature | Description |
-| :-------------------- | :-------------------------------------------------------------------------------------- |
-| Embedded Wallet Kit | Speed up your integration with pre-built UI components |
-| Authentication | Authenticate users via email, phone number, biometrics, social logins, etc. |
-| Policies | Determine delegated access and co-ownership controls. |
-| Multichain support | Sign transactions across chains with out-of-the-box support for most chains and assets. |
-| Broadcasting | Broadcast signed transactions using Turnkey's infrastructure. |
-| Pre-generated wallets | Streamline onboarding by generating wallets for your users before authentication. |
-| Sessions | Sign multiple transactions without requiring additional approvals. |
-| Account abstraction | Access simple integrations for gas sponsorship and smart contract wallets. |
-| Import + export | Migrate existing wallets in and out of Turnkey without exposure. |
-| Delegated access | Onchain wallets with flexible co-ownership controls. |
-
-## Company Wallets
-
-Turnkey's Company Wallets empower teams to automate complex workflows at scale with granular policies for transaction limits, user permissions, and more.
-
-### Features
-
-| Feature | Description |
-| :------------------------ | :-------------------------------------------------------------------------------------- |
-| Multichain Support | Sign transactions across chains with out-of-the-box support for most chains and assets. |
-| Authentication | Access wallets via email, phone number, biometrics, social logins, etc. |
-| API-based authentication | Create API keys with limited permissions for specific applications or use cases. |
-| Compliance (audit trail) | Track events and changes across the stack, ensuring accountability. |
-| Import + export | Easily migrate existing private keys without exposure. |
-| Multi-signature approvals | Set a quorum of users for approving and/or denying transactions. |
-
-# Concepts
-
-Before getting started, we highly recommend familiarizing yourself with Turnkey's core concepts to ensure a smooth implementation. At the core of Turnkey is an important concept: instead of directly managing private keys, wallets are accessed through authenticators like passkeys, social logins, or API keys.
-
-### Core terms
-
-- **Organizations (parent orgs)**: The initial parent organization typically represents an entire Turnkey-powered application.
-- **Sub-organizations (sub-orgs)**: Fully segregated organizations, typically representing an end user, nested under the parent organization. Parent orgs cannot modify the contents of a sub-org.
-- **Resources**: All identifiers within parent orgs such as users, policies, and wallets are collectively referred to as resources.
-- **Users**: Resources within organizations or sub-organizations that can submit activities to Turnkey via a valid credential.
-- **Authenticators**: Each parent org, sub-org and user contain their own sets of authenticators that you can configure, including their own wallets, API keys, and private keys.
-- **Activities**: All actions Organizations can take such as signing transactions or creating users are known as activities.
-- **Policies**: Policies govern all activities and permissions within Organizations.
-- **Root users**: Users with root permissions, meaning they can bypass the policy engine to take any action within that specific organization.
-- **Root quorum**: A pre-determined consensus threshold that consists of a set of Root Users. This consensus threshold must be reached in order for any root permissions to take place.
-- **Wallets**: A collection of cryptographic private/public key pairs that share a common seed. HD seed phrases can generate multiple wallet accounts (addresses) for signing operations.
-
-
- 
-
-
-There is no set relationship between organizations, sub-organizations, activities, wallets, and resources. This makes Turnkey highly flexible and configurable to any use case.
-
-For a more in-depth overview, learn more [here](/concepts/overview).
-
-# SDKs
-
-Turnkey provides a variety of client libraries for building with Embedded Wallets, Company Wallets, and other common workflows. We also have several wrappers for popular web3 libraries for easy integration into existing dApps. We recommend reviewing our concepts, account setup and solution pages before moving forward with [our SDKs](/sdks/introduction).
-
-# AI-ready docs
-
-Turnkey documentation is fully integrated with AI tooling. Whether you're chatting with GPT, coding with Cursor, or building your own LLM assistant, our docs are structured for direct ingestion and deep context—plus, search and chat with specific pages right from your IDE or browser. Explore the [docs](/developer-reference/using-llms).
-
-# Security
-
-Turnkey is the first verifiable key management system of its kind, securing millions of wallets and private keys for a wide variety of use cases. Turnkey's security architecture ensures that raw private keys are never exposed to Turnkey, your software, or your team. We provide end-to-end private key generation and access control within secure enclaves. Our [whitepaper](https://whitepaper.turnkey.com/) covers our holistic security model in-depth, and speaks to our vision for building verifiable key management infrastructure. Learn more about our approach to security [here](/security/our-approach).
-
-# Account setup
-
-Before diving into the code, let's set up your organization and spin up an API keypair to unlock the full potential of Turnkey! Get started [here](/getting-started/quickstart).
-
-# Support
-
-To chat with our account team, please reach out [here](https://www.turnkey.com/contact-us).\
-For support, product feedback, and input, join our community Slack channel [here](https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ).
diff --git a/images/build-cube-connectors.svg b/images/build-cube-connectors.svg
new file mode 100644
index 00000000..bd66f87f
--- /dev/null
+++ b/images/build-cube-connectors.svg
@@ -0,0 +1,7 @@
+
diff --git a/images/build-cube-stack.svg b/images/build-cube-stack.svg
new file mode 100644
index 00000000..a3448b9e
--- /dev/null
+++ b/images/build-cube-stack.svg
@@ -0,0 +1,6 @@
+
diff --git a/images/grid-dark.svg b/images/grid-dark.svg
new file mode 100644
index 00000000..28fefa4f
--- /dev/null
+++ b/images/grid-dark.svg
@@ -0,0 +1,14 @@
+
diff --git a/images/grid-light.svg b/images/grid-light.svg
new file mode 100644
index 00000000..7c7a34e9
--- /dev/null
+++ b/images/grid-light.svg
@@ -0,0 +1,14 @@
+
diff --git a/images/hero-dark.svg b/images/hero-dark.svg
new file mode 100644
index 00000000..1a2ca7b1
--- /dev/null
+++ b/images/hero-dark.svg
@@ -0,0 +1,69 @@
+
diff --git a/images/hero-light.svg b/images/hero-light.svg
new file mode 100644
index 00000000..07b78cf3
--- /dev/null
+++ b/images/hero-light.svg
@@ -0,0 +1,69 @@
+
diff --git a/images/icons/arrow-square-right.svg b/images/icons/arrow-square-right.svg
new file mode 100644
index 00000000..984e2f0e
--- /dev/null
+++ b/images/icons/arrow-square-right.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/icons/bank-note-01.svg b/images/icons/bank-note-01.svg
new file mode 100644
index 00000000..57183d4a
--- /dev/null
+++ b/images/icons/bank-note-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/bank.svg b/images/icons/bank.svg
new file mode 100644
index 00000000..891577f1
--- /dev/null
+++ b/images/icons/bank.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/book-open-01.svg b/images/icons/book-open-01.svg
new file mode 100644
index 00000000..9eca906c
--- /dev/null
+++ b/images/icons/book-open-01.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/icons/check-circle.svg b/images/icons/check-circle.svg
new file mode 100644
index 00000000..c27e99be
--- /dev/null
+++ b/images/icons/check-circle.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/chevron-right.svg b/images/icons/chevron-right.svg
new file mode 100644
index 00000000..d26a600e
--- /dev/null
+++ b/images/icons/chevron-right.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/images/icons/clock.svg b/images/icons/clock.svg
new file mode 100644
index 00000000..9acddbe3
--- /dev/null
+++ b/images/icons/clock.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/code-02.svg b/images/icons/code-02.svg
new file mode 100644
index 00000000..b7d6b3d3
--- /dev/null
+++ b/images/icons/code-02.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/coins-01.svg b/images/icons/coins-01.svg
new file mode 100644
index 00000000..c54ee63f
--- /dev/null
+++ b/images/icons/coins-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/colors.svg b/images/icons/colors.svg
new file mode 100644
index 00000000..96fe3d38
--- /dev/null
+++ b/images/icons/colors.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/images/icons/cpu-chip-01.svg b/images/icons/cpu-chip-01.svg
new file mode 100644
index 00000000..24eb3ac9
--- /dev/null
+++ b/images/icons/cpu-chip-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/cryptocurrency-02.svg b/images/icons/cryptocurrency-02.svg
new file mode 100644
index 00000000..ec0c8b9f
--- /dev/null
+++ b/images/icons/cryptocurrency-02.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/icons/cube-outline.svg b/images/icons/cube-outline.svg
new file mode 100644
index 00000000..fca14797
--- /dev/null
+++ b/images/icons/cube-outline.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/icons/currency-dollar.svg b/images/icons/currency-dollar.svg
new file mode 100644
index 00000000..3ece460d
--- /dev/null
+++ b/images/icons/currency-dollar.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/dataflow-02.svg b/images/icons/dataflow-02.svg
new file mode 100644
index 00000000..29315666
--- /dev/null
+++ b/images/icons/dataflow-02.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/download-01.svg b/images/icons/download-01.svg
new file mode 100644
index 00000000..04448272
--- /dev/null
+++ b/images/icons/download-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/file-code-01.svg b/images/icons/file-code-01.svg
new file mode 100644
index 00000000..c45cad93
--- /dev/null
+++ b/images/icons/file-code-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/file-code-02.svg b/images/icons/file-code-02.svg
new file mode 100644
index 00000000..a3e5c6e5
--- /dev/null
+++ b/images/icons/file-code-02.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/file-shield-02.svg b/images/icons/file-shield-02.svg
new file mode 100644
index 00000000..2dd3222d
--- /dev/null
+++ b/images/icons/file-shield-02.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/fuel.svg b/images/icons/fuel.svg
new file mode 100644
index 00000000..ae31e3b8
--- /dev/null
+++ b/images/icons/fuel.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/icons/git-branch-01.svg b/images/icons/git-branch-01.svg
new file mode 100644
index 00000000..0ed5a303
--- /dev/null
+++ b/images/icons/git-branch-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/globe-01.svg b/images/icons/globe-01.svg
new file mode 100644
index 00000000..214286ba
--- /dev/null
+++ b/images/icons/globe-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/home-01.svg b/images/icons/home-01.svg
new file mode 100644
index 00000000..e85247d2
--- /dev/null
+++ b/images/icons/home-01.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/icons/home-02.svg b/images/icons/home-02.svg
new file mode 100644
index 00000000..8234136d
--- /dev/null
+++ b/images/icons/home-02.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/icons/intersect-circle.svg b/images/icons/intersect-circle.svg
new file mode 100644
index 00000000..5537815b
--- /dev/null
+++ b/images/icons/intersect-circle.svg
@@ -0,0 +1,6 @@
+
diff --git a/images/icons/line-chart-up-01.svg b/images/icons/line-chart-up-01.svg
new file mode 100644
index 00000000..b091dec8
--- /dev/null
+++ b/images/icons/line-chart-up-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/link-03.svg b/images/icons/link-03.svg
new file mode 100644
index 00000000..621e99cf
--- /dev/null
+++ b/images/icons/link-03.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/lock-01.svg b/images/icons/lock-01.svg
new file mode 100644
index 00000000..fb6aeef6
--- /dev/null
+++ b/images/icons/lock-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/log-in-04.svg b/images/icons/log-in-04.svg
new file mode 100644
index 00000000..f789f44e
--- /dev/null
+++ b/images/icons/log-in-04.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/phone-01.svg b/images/icons/phone-01.svg
new file mode 100644
index 00000000..cc1bc3cc
--- /dev/null
+++ b/images/icons/phone-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/puzzle-piece-01.svg b/images/icons/puzzle-piece-01.svg
new file mode 100644
index 00000000..6f9eafc2
--- /dev/null
+++ b/images/icons/puzzle-piece-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/refresh-cw-01.svg b/images/icons/refresh-cw-01.svg
new file mode 100644
index 00000000..d518c617
--- /dev/null
+++ b/images/icons/refresh-cw-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/rocket-01.svg b/images/icons/rocket-01.svg
new file mode 100644
index 00000000..54548ce2
--- /dev/null
+++ b/images/icons/rocket-01.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/icons/route.svg b/images/icons/route.svg
new file mode 100644
index 00000000..bf70cc88
--- /dev/null
+++ b/images/icons/route.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/server-04.svg b/images/icons/server-04.svg
new file mode 100644
index 00000000..b245f56e
--- /dev/null
+++ b/images/icons/server-04.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/switch-horizontal-01.svg b/images/icons/switch-horizontal-01.svg
new file mode 100644
index 00000000..673cc5d6
--- /dev/null
+++ b/images/icons/switch-horizontal-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/switch-horizontal-02.svg b/images/icons/switch-horizontal-02.svg
new file mode 100644
index 00000000..38651770
--- /dev/null
+++ b/images/icons/switch-horizontal-02.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/tablet-01.svg b/images/icons/tablet-01.svg
new file mode 100644
index 00000000..b52dca40
--- /dev/null
+++ b/images/icons/tablet-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/tool-01.svg b/images/icons/tool-01.svg
new file mode 100644
index 00000000..3976a213
--- /dev/null
+++ b/images/icons/tool-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/tool-02.svg b/images/icons/tool-02.svg
new file mode 100644
index 00000000..819082b6
--- /dev/null
+++ b/images/icons/tool-02.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/images/icons/trend-up-01.svg b/images/icons/trend-up-01.svg
new file mode 100644
index 00000000..d2707e3d
--- /dev/null
+++ b/images/icons/trend-up-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/upload-01.svg b/images/icons/upload-01.svg
new file mode 100644
index 00000000..23619832
--- /dev/null
+++ b/images/icons/upload-01.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/wallet-04.svg b/images/icons/wallet-04.svg
new file mode 100644
index 00000000..ad5146df
--- /dev/null
+++ b/images/icons/wallet-04.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/icons/wallet-embedded.svg b/images/icons/wallet-embedded.svg
new file mode 100644
index 00000000..b2247522
--- /dev/null
+++ b/images/icons/wallet-embedded.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/icons/zap.svg b/images/icons/zap.svg
new file mode 100644
index 00000000..7b963d10
--- /dev/null
+++ b/images/icons/zap.svg
@@ -0,0 +1,5 @@
+
diff --git a/images/networks/aptos.svg b/images/networks/aptos.svg
new file mode 100644
index 00000000..ac53b51c
--- /dev/null
+++ b/images/networks/aptos.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/networks/bitcoin.svg b/images/networks/bitcoin.svg
new file mode 100644
index 00000000..85aaf723
--- /dev/null
+++ b/images/networks/bitcoin.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/networks/cosmos.svg b/images/networks/cosmos.svg
new file mode 100644
index 00000000..15093555
--- /dev/null
+++ b/images/networks/cosmos.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/networks/ethereum.svg b/images/networks/ethereum.svg
new file mode 100644
index 00000000..b7c64963
--- /dev/null
+++ b/images/networks/ethereum.svg
@@ -0,0 +1,10 @@
+
diff --git a/images/networks/hyperliquid.svg b/images/networks/hyperliquid.svg
new file mode 100644
index 00000000..16bf0e31
--- /dev/null
+++ b/images/networks/hyperliquid.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/networks/iota.svg b/images/networks/iota.svg
new file mode 100644
index 00000000..76ed432b
--- /dev/null
+++ b/images/networks/iota.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/networks/movement.svg b/images/networks/movement.svg
new file mode 100644
index 00000000..f6e20c60
--- /dev/null
+++ b/images/networks/movement.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/networks/sei.svg b/images/networks/sei.svg
new file mode 100644
index 00000000..cd5737d9
--- /dev/null
+++ b/images/networks/sei.svg
@@ -0,0 +1,9 @@
+
diff --git a/images/networks/solana.svg b/images/networks/solana.svg
new file mode 100644
index 00000000..81a126e8
--- /dev/null
+++ b/images/networks/solana.svg
@@ -0,0 +1,19 @@
+
diff --git a/images/networks/spark.svg b/images/networks/spark.svg
new file mode 100644
index 00000000..9902e043
--- /dev/null
+++ b/images/networks/spark.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/networks/sui.svg b/images/networks/sui.svg
new file mode 100644
index 00000000..59151891
--- /dev/null
+++ b/images/networks/sui.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/networks/tempo.svg b/images/networks/tempo.svg
new file mode 100644
index 00000000..ac1637b9
--- /dev/null
+++ b/images/networks/tempo.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/networks/tron.svg b/images/networks/tron.svg
new file mode 100644
index 00000000..9004a02a
--- /dev/null
+++ b/images/networks/tron.svg
@@ -0,0 +1,3 @@
+
diff --git a/images/plane-a-dark.svg b/images/plane-a-dark.svg
new file mode 100644
index 00000000..695e4d06
--- /dev/null
+++ b/images/plane-a-dark.svg
@@ -0,0 +1,83 @@
+
diff --git a/images/plane-a-light.svg b/images/plane-a-light.svg
new file mode 100644
index 00000000..f3a955bb
--- /dev/null
+++ b/images/plane-a-light.svg
@@ -0,0 +1,83 @@
+
diff --git a/images/plane-b-dark.svg b/images/plane-b-dark.svg
new file mode 100644
index 00000000..8b9eb009
--- /dev/null
+++ b/images/plane-b-dark.svg
@@ -0,0 +1,83 @@
+
diff --git a/images/plane-b-light.svg b/images/plane-b-light.svg
new file mode 100644
index 00000000..97cfe281
--- /dev/null
+++ b/images/plane-b-light.svg
@@ -0,0 +1,83 @@
+
diff --git a/images/plane-c-dark.svg b/images/plane-c-dark.svg
new file mode 100644
index 00000000..f3b4018a
--- /dev/null
+++ b/images/plane-c-dark.svg
@@ -0,0 +1,83 @@
+
diff --git a/images/plane-c-light.svg b/images/plane-c-light.svg
new file mode 100644
index 00000000..75eabcc2
--- /dev/null
+++ b/images/plane-c-light.svg
@@ -0,0 +1,83 @@
+
diff --git a/images/solution-company-wallets.png b/images/solution-company-wallets.png
new file mode 100644
index 00000000..ddececb6
Binary files /dev/null and b/images/solution-company-wallets.png differ
diff --git a/images/solution-embedded-wallets.png b/images/solution-embedded-wallets.png
new file mode 100644
index 00000000..a7c17765
Binary files /dev/null and b/images/solution-embedded-wallets.png differ
diff --git a/images/solution-key-management.png b/images/solution-key-management.png
new file mode 100644
index 00000000..403d9e6c
Binary files /dev/null and b/images/solution-key-management.png differ
diff --git a/images/solution-verifiable-cloud.png b/images/solution-verifiable-cloud.png
new file mode 100644
index 00000000..df86a452
Binary files /dev/null and b/images/solution-verifiable-cloud.png differ
diff --git a/images/solutions/dark/agentic-wallets.svg b/images/solutions/dark/agentic-wallets.svg
new file mode 100644
index 00000000..f77de399
--- /dev/null
+++ b/images/solutions/dark/agentic-wallets.svg
@@ -0,0 +1,9 @@
+
diff --git a/images/solutions/dark/embedded-business-wallets.svg b/images/solutions/dark/embedded-business-wallets.svg
new file mode 100644
index 00000000..0a88e01b
--- /dev/null
+++ b/images/solutions/dark/embedded-business-wallets.svg
@@ -0,0 +1,8 @@
+
diff --git a/images/solutions/dark/embedded-consumer-wallets.svg b/images/solutions/dark/embedded-consumer-wallets.svg
new file mode 100644
index 00000000..417c3cf2
--- /dev/null
+++ b/images/solutions/dark/embedded-consumer-wallets.svg
@@ -0,0 +1,9 @@
+
diff --git a/images/solutions/dark/embedded-wallet-as-a-service.svg b/images/solutions/dark/embedded-wallet-as-a-service.svg
new file mode 100644
index 00000000..63ad1d94
--- /dev/null
+++ b/images/solutions/dark/embedded-wallet-as-a-service.svg
@@ -0,0 +1,7 @@
+
diff --git a/images/solutions/dark/encryption-key-storage.svg b/images/solutions/dark/encryption-key-storage.svg
new file mode 100644
index 00000000..d5708a35
--- /dev/null
+++ b/images/solutions/dark/encryption-key-storage.svg
@@ -0,0 +1,12 @@
+
diff --git a/images/solutions/dark/enterprise-disaster-recovery.svg b/images/solutions/dark/enterprise-disaster-recovery.svg
new file mode 100644
index 00000000..43cfd4f6
--- /dev/null
+++ b/images/solutions/dark/enterprise-disaster-recovery.svg
@@ -0,0 +1,7 @@
+
diff --git a/images/solutions/dark/payment-orchestration.svg b/images/solutions/dark/payment-orchestration.svg
new file mode 100644
index 00000000..c443810d
--- /dev/null
+++ b/images/solutions/dark/payment-orchestration.svg
@@ -0,0 +1,10 @@
+
diff --git a/images/solutions/dark/smart-contract-management.svg b/images/solutions/dark/smart-contract-management.svg
new file mode 100644
index 00000000..ce85e2e2
--- /dev/null
+++ b/images/solutions/dark/smart-contract-management.svg
@@ -0,0 +1,17 @@
+
diff --git a/images/solutions/dark/tvc.svg b/images/solutions/dark/tvc.svg
new file mode 100644
index 00000000..08d2b020
--- /dev/null
+++ b/images/solutions/dark/tvc.svg
@@ -0,0 +1,12 @@
+
diff --git a/images/solutions/light/agentic-wallets.svg b/images/solutions/light/agentic-wallets.svg
new file mode 100644
index 00000000..465060f6
--- /dev/null
+++ b/images/solutions/light/agentic-wallets.svg
@@ -0,0 +1,9 @@
+
diff --git a/images/solutions/light/embedded-business-wallets.svg b/images/solutions/light/embedded-business-wallets.svg
new file mode 100644
index 00000000..647ef54e
--- /dev/null
+++ b/images/solutions/light/embedded-business-wallets.svg
@@ -0,0 +1,8 @@
+
diff --git a/images/solutions/light/embedded-consumer-wallets.svg b/images/solutions/light/embedded-consumer-wallets.svg
new file mode 100644
index 00000000..1a85be8d
--- /dev/null
+++ b/images/solutions/light/embedded-consumer-wallets.svg
@@ -0,0 +1,16 @@
+
diff --git a/images/solutions/light/embedded-wallet-as-a-service.svg b/images/solutions/light/embedded-wallet-as-a-service.svg
new file mode 100644
index 00000000..016a035f
--- /dev/null
+++ b/images/solutions/light/embedded-wallet-as-a-service.svg
@@ -0,0 +1,7 @@
+
diff --git a/images/solutions/light/encryption-key-storage.svg b/images/solutions/light/encryption-key-storage.svg
new file mode 100644
index 00000000..61773682
--- /dev/null
+++ b/images/solutions/light/encryption-key-storage.svg
@@ -0,0 +1,12 @@
+
diff --git a/images/solutions/light/enterprise-disaster-recovery.svg b/images/solutions/light/enterprise-disaster-recovery.svg
new file mode 100644
index 00000000..45d1e082
--- /dev/null
+++ b/images/solutions/light/enterprise-disaster-recovery.svg
@@ -0,0 +1,7 @@
+
diff --git a/images/solutions/light/payment-orchestration.svg b/images/solutions/light/payment-orchestration.svg
new file mode 100644
index 00000000..2815fdf2
--- /dev/null
+++ b/images/solutions/light/payment-orchestration.svg
@@ -0,0 +1,10 @@
+
diff --git a/images/solutions/light/smart-contract-management.svg b/images/solutions/light/smart-contract-management.svg
new file mode 100644
index 00000000..415817f5
--- /dev/null
+++ b/images/solutions/light/smart-contract-management.svg
@@ -0,0 +1,17 @@
+
diff --git a/images/solutions/light/tvc.svg b/images/solutions/light/tvc.svg
new file mode 100644
index 00000000..d8716e1f
--- /dev/null
+++ b/images/solutions/light/tvc.svg
@@ -0,0 +1,12 @@
+
diff --git a/images/uc-agentic-wallets-dark.svg b/images/uc-agentic-wallets-dark.svg
new file mode 100644
index 00000000..f77de399
--- /dev/null
+++ b/images/uc-agentic-wallets-dark.svg
@@ -0,0 +1,9 @@
+
diff --git a/images/uc-agentic-wallets-light.svg b/images/uc-agentic-wallets-light.svg
new file mode 100644
index 00000000..465060f6
--- /dev/null
+++ b/images/uc-agentic-wallets-light.svg
@@ -0,0 +1,9 @@
+
diff --git a/images/uc-embedded-business-wallets-dark.svg b/images/uc-embedded-business-wallets-dark.svg
new file mode 100644
index 00000000..0a88e01b
--- /dev/null
+++ b/images/uc-embedded-business-wallets-dark.svg
@@ -0,0 +1,8 @@
+
diff --git a/images/uc-embedded-business-wallets-light.svg b/images/uc-embedded-business-wallets-light.svg
new file mode 100644
index 00000000..647ef54e
--- /dev/null
+++ b/images/uc-embedded-business-wallets-light.svg
@@ -0,0 +1,8 @@
+
diff --git a/images/uc-embedded-consumer-wallets-dark.svg b/images/uc-embedded-consumer-wallets-dark.svg
new file mode 100644
index 00000000..417c3cf2
--- /dev/null
+++ b/images/uc-embedded-consumer-wallets-dark.svg
@@ -0,0 +1,9 @@
+
diff --git a/images/uc-embedded-consumer-wallets-light.svg b/images/uc-embedded-consumer-wallets-light.svg
new file mode 100644
index 00000000..1a85be8d
--- /dev/null
+++ b/images/uc-embedded-consumer-wallets-light.svg
@@ -0,0 +1,16 @@
+
diff --git a/images/uc-embedded-waas-dark.svg b/images/uc-embedded-waas-dark.svg
new file mode 100644
index 00000000..63ad1d94
--- /dev/null
+++ b/images/uc-embedded-waas-dark.svg
@@ -0,0 +1,7 @@
+
diff --git a/images/uc-embedded-waas-light.svg b/images/uc-embedded-waas-light.svg
new file mode 100644
index 00000000..016a035f
--- /dev/null
+++ b/images/uc-embedded-waas-light.svg
@@ -0,0 +1,7 @@
+
diff --git a/images/uc-encryption-key-storage-dark.svg b/images/uc-encryption-key-storage-dark.svg
new file mode 100644
index 00000000..d5708a35
--- /dev/null
+++ b/images/uc-encryption-key-storage-dark.svg
@@ -0,0 +1,12 @@
+
diff --git a/images/uc-encryption-key-storage-light.svg b/images/uc-encryption-key-storage-light.svg
new file mode 100644
index 00000000..61773682
--- /dev/null
+++ b/images/uc-encryption-key-storage-light.svg
@@ -0,0 +1,12 @@
+
diff --git a/images/uc-enterprise-disaster-recovery-dark.svg b/images/uc-enterprise-disaster-recovery-dark.svg
new file mode 100644
index 00000000..43cfd4f6
--- /dev/null
+++ b/images/uc-enterprise-disaster-recovery-dark.svg
@@ -0,0 +1,7 @@
+
diff --git a/images/uc-enterprise-disaster-recovery-light.svg b/images/uc-enterprise-disaster-recovery-light.svg
new file mode 100644
index 00000000..45d1e082
--- /dev/null
+++ b/images/uc-enterprise-disaster-recovery-light.svg
@@ -0,0 +1,7 @@
+
diff --git a/images/uc-payment-orchestration-dark.svg b/images/uc-payment-orchestration-dark.svg
new file mode 100644
index 00000000..c443810d
--- /dev/null
+++ b/images/uc-payment-orchestration-dark.svg
@@ -0,0 +1,10 @@
+
diff --git a/images/uc-payment-orchestration-light.svg b/images/uc-payment-orchestration-light.svg
new file mode 100644
index 00000000..2815fdf2
--- /dev/null
+++ b/images/uc-payment-orchestration-light.svg
@@ -0,0 +1,10 @@
+
diff --git a/images/uc-smart-contract-management-dark.svg b/images/uc-smart-contract-management-dark.svg
new file mode 100644
index 00000000..ce85e2e2
--- /dev/null
+++ b/images/uc-smart-contract-management-dark.svg
@@ -0,0 +1,17 @@
+
diff --git a/images/uc-smart-contract-management-light.svg b/images/uc-smart-contract-management-light.svg
new file mode 100644
index 00000000..415817f5
--- /dev/null
+++ b/images/uc-smart-contract-management-light.svg
@@ -0,0 +1,17 @@
+
diff --git a/images/uc-tvc-dark.svg b/images/uc-tvc-dark.svg
new file mode 100644
index 00000000..08d2b020
--- /dev/null
+++ b/images/uc-tvc-dark.svg
@@ -0,0 +1,12 @@
+
diff --git a/images/uc-tvc-light.svg b/images/uc-tvc-light.svg
new file mode 100644
index 00000000..d8716e1f
--- /dev/null
+++ b/images/uc-tvc-light.svg
@@ -0,0 +1,12 @@
+
diff --git a/images/whitepaper.png b/images/whitepaper.png
new file mode 100644
index 00000000..e0ae74b8
Binary files /dev/null and b/images/whitepaper.png differ
diff --git a/production-checklist/company-wallet.mdx b/production-checklist/company-wallet.mdx
deleted file mode 100644
index 3cc91c47..00000000
--- a/production-checklist/company-wallet.mdx
+++ /dev/null
@@ -1,141 +0,0 @@
----
-title: "Company wallets implementation guide"
-description: "Implementing Company Wallets with Turnkey"
----
-
-Turnkey's infrastructure provides a secure, flexible way to manage crypto operations at scale, letting you automate everything from
-routine payments and treasury transfers to smart contract deployments and NFT minting.
-
-In this guide, we'll walk through the key decisions you'll face integrating Turnkey, and how to design a high-throughput workflow
-without compromising on security or user experience.
-
-## Wallet structure: how to organize and scale your wallets
-
-Every transaction starts with a wallet. The way you structure them will shape how scalable and maintainable your automation setup is.
-
-**Option 1:** Single wallet with many accounts (HD path fan-out)
-By default, Turnkey wallets use a hierarchical deterministic (HD) structure. That means you can generate unlimited accounts
-from a single wallet seed, each with its own address. This is ideal for:
-
-- Managing multiple user deposit addresses
-- Creating large numbers of accounts for batching or privacy
-- Assigning different onchain roles (e.g. one account for contract deployment, another for transfers)
-
-This approach scales well and stays simple: one wallet, one policy, multiple accounts.
-
-**Option 2:** Multiple wallets in a single org
-Use this when you need separation by use case. For example:
-
-- One wallet for treasury ops
-- One for NFT mints
-- One for sequencing contracts
-
-Policies can be set at the wallet level to enforce clear boundaries (e.g. only certain users or services can touch the NFT minting wallet).
-Note Turnkey's [resource limits](https://docs.turnkey.com/concepts/resource-limits#resource-limits) and ensure your intended
-scaled implementation fits within those limits.
-
-**Option 3:** Separate sub-orgs per wallet
-This option is best when you need strict isolation — e.g. multi-tenant environments, or wallets with different authentication requirements.
-Each sub-org has its own root users and policy namespace. Downside: more setup, more moving parts.
-
-Most teams use a combination: they generate many accounts under a few wallets and reserve sub-orgs for user-facing or high-risk cases.
-
-## Trigger model: what kicks off transactions
-
-Transaction automation can be reactive, proactive, or user-driven. The right model depends on your use case.
-
-**Event-driven (most common):**
-A transaction is triggered by an external event — a webhook, an internal job, or an offchain signal. Examples:
-
-- Market resolution triggers a payout
-- Onchain price changes trigger a rebalancing tx
-- A user hits a “claim” button in your app
-
-Use a background worker or event system to translate that trigger into a signing request.
-
-**Scheduled:**
-Useful for treasury management, yield compounding, or periodic distribution flows. Run a job hourly/daily and trigger signing from there.
-
-**Manual with automation fallback:**
-Sometimes a human should have the final say, but you want the transaction to be ready to go. You can submit a tx to Turnkey
-that requires approval, then notify a signer via Slack, email, or dashboard.
-
-Tip: Think in terms of "intent capture" (when does your system decide something needs to happen) vs. "signing execution"
-(when and how does it actually get signed).
-
-## Policy model: what rules do you want enforced?
-
-Policies are your automation safety net. Every action goes through the policy engine before it's allowed, and is explicitly denied by default.
-
-You'll want to decide:
-**How many approvers?**
-
-- Use single-party approvals for low-risk flows (e.g. daily payouts)
-- Add quorum-based approvals (2-of-N) for anything that could move real money
-- You can enforce consensus based on value thresholds, contract targets, asset type, and more
-
-**Which users can do what?**
-
-- Assign narrow permissions to service accounts (e.g. only sign txs from wallet A to address X)
-- Add additional controls per user role or tag (e.g. “engineer” vs. “ops”)
-
-**What transactions are allowed?**
-
-- Restrict by destination address (eth.tx.to)
-- Restrict by method ID (eth.tx.data\[:4\])
-- Restrict by value (eth.tx.value)
-- Combine all of the above with consensus rules
-
-**How do you enforce UX constraints?**
-
-- Require user co-signing for certain transactions
-- Allow delegated signing within strict bounds
-- Use different policies for different environments (e.g. testnet policy vs. mainnet)
-
-Most automation systems have 3-5 core policies and evolve them as their product grows. Start tight, then expand.
-
-## Integration model: which interface drives automation?
-
-All interfaces (CLI, SDK, API) go through the same policy and enclave flow. The only difference is where your logic lives.
-
-**CLI:**
-Best for prototyping or scripting internal workflows (e.g. rotate a key, create a wallet). You can also use it in CI pipelines.
-
-**SDK:**
-Ideal for integrating into apps or backend services. Available in multiple programming languages. Handles signing, retries,
-and activity submission.
-
-**Direct API:**
-Use this if you want full control or are building from a non-standard language. Slightly more effort to get right, but fully supported.
-
-**Dashboard:**
-Not for automation — but useful for manual approval flows, audit trails, and monitoring.
-
-**Common pattern:**
-
-- Use SDK in your backend to submit signing requests
-- Use webhook or polling to detect consensus-needed flows
-- Use CLI for one-off or recovery flows
-- Use dashboard to inspect what happened
-
-Graveyard - add back when IndexedDb launches
-
-By default, session keys are stored in IndexedDB when running in the browser. These keys are non-extractable and can't be accessed by your app,
-by Turnkey, or by anything else running on the page. On mobile, session keys will typically be stored in the device's secure storage layer
-(e.g. Keychain or Keystore) depending on the SDK and environment.
-
-The biggest decision is how long sessions should last. Longer-lived sessions reduce friction, enabling users to stay signed in across reloads,
-tabs, or app restarts. For most embedded wallet use cases, long-lived sessions in IndexedDB strike a good balance between usability and safety.
-
-Scoping
-You'll also want to decide whether your sessions should be scoped.
-
-Scoped sessions allow you to define exactly what a given session key is allowed to do — and enforce it via Turnkey's policy engine. For example,
-you can issue sessions that:
-
-- are read-only
-- can only sign transactions below a certain value
-- can only interact with specific contracts or functions (e.g. a swap function on Uniswap)
-
-This gives you a flexible way to enforce step-up authentication flows (e.g. OTP for read-only, passkey + OTP for full signing),
-build approval-based transaction flows, or safely grant session access in more complex environments.
diff --git a/production-checklist/embedded-wallet.mdx b/production-checklist/embedded-wallet.mdx
deleted file mode 100644
index 92a98068..00000000
--- a/production-checklist/embedded-wallet.mdx
+++ /dev/null
@@ -1,129 +0,0 @@
----
-title: "Embedded wallets implementation guide"
-description: "Designing your Embedded Wallet implementation"
----
-
-Turnkey is built to give you flexibility in exactly how you integrate.
-This guide outlines the most important architectural and implementation choices that you'll make as you integrate wallets into your app.
-It's designed to help you move quickly, avoid common pitfalls, and launch with confidence.
-
-## Control model: decide who holds the access
-
-This is one of the most important architectural decisions you'll make: who is in control of the wallets you create in your app.
-
-WIth Turnkey embedded wallets, each wallet is created in a segregated sub-organization. You can configure who has access to resources
-in that sub-org at the time of creation. Turnkey offers a wide spectrum of options here, from fully user-controlled to fully app-controlled
-and everything in between.
-
-- **Fully user-controlled:** Only the user can authorize actions. Your backend has zero access. This option is best for personal wallets or
- any use case or audience where self-custody is important.
-
-- **Fully app-controlled:** Your backend holds the authenticators used to authorize actions on behalf of the user. Simple UX and no
- restrictions on when or how actions are triggered, useful for things like limit orders or automated flows.
-
-- **Delegated access:** The user controls the wallet, but your backend is granted narrow signing permissions via Turnkey's policy engine.
- Ideal for transaction automation without taking on full control.
-
-- **Shared custody:** Both the user and your backend (or, the “co-signer) hold authenticators, and actions require approval from both.
- Accomplished via root quorum settings, like a 2-of-2 signing requirement, this setup can offer improved security depending on the level
- of independent validation done at the co-signer level.
-
-Most teams choose user-controlled or delegated access models, but Turnkey supports the full spectrum and allows you to make the choice
-that's right for your business.
-
-## Authentication: decide how users access their wallets
-
-Another key design choice is how users will authenticate to authorize actions. Every API request to Turnkey must include a signature, or stamp,
-over the POST body – that means every request to Turnkey needs to be authorized by a valid authenticator.
-
-Turnkey supports a range of authentication methods that can be enabled **individually or in combination.** You can configure which methods are
-allowed when getting started, and can always enable more options later as your product evolves.
-
-- **Passkeys:** WebAuthn-based authentication using device biometrics or security keys. Provides the strongest combination of security and UX
- when supported by the user's browser and device.
-
-- **Email (magic link or OTP):** Passwordless login using a one-time link or code sent to the user's email. Ubiquitous, familiar,
- and often the easiest option for onboarding. If you use a custom sender name, note that some email clients (e.g. Gmail) screen
- sender names more aggressively than others (e.g. Apple Mail). To ensure a consistent experience, keep your sender name
- "safe looking" — avoid underscores, special symbols, or unusual formatting that may cause it to be filtered or hidden.
-
-- **Social login (OAuth):** Sign in with providers like Google or Apple. Smooth UX and fast setup for users already logged into those ecosystems.
- Requires OIDC configuration.
-
-- **SMS (OTP):** Login via a code sent by text message. Convenient in some markets but generally less secure due to SIM-swap risk.
-
-- **Multiple methods:** You can enable multiple authenticators per user — for example, allowing passkey + email fallback,
- or social login + SMS recovery. This can improve account recovery or accessibility across devices.
-
-Most teams guide users toward one or two authentication methods based on their product goals, but if your use case demands maximum flexibility,
-you can enable any or all of the above and let users choose.
-
-Just like with the control model, there's no single right answer - the best approach depends on who your users are and how much control or
-recovery flexibility you want to offer.
-
-## Session handling: decide how to manage session credentials
-
-In Turnkey, sessions are just asymmetric key pairs held client-side that can be used to authorize actions. Once a user signs in,
-they can take multiple actions like viewing balances or signing transactions without re-authenticating each time.
-When designing your session approach, there are two key decisions to make: where sessions are stored, and how long they last.
-
-Storage
-Turnkey supports multiple storage approaches for session credentials, each with tradeoffs depending on platform and use case.
-
-IndexedDB session (web only): For web apps that want stronger session persistence without relying on iframes or exposing credentials to your app’s JavaScript runtime, Turnkey supports using the [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto) API to generate unextractable asymmetric key pairs and store them securely in the browser’s IndexedDB.
-
-This approach enables long-lived, client-held sessions that survive page reloads, tab closures, and even browser restarts - **without ever exposing the private key** to your JavaScript code.
-
-Turnkey’s SDK provides helpers to:
-- Create a new session by generating a P-256 key pair via `crypto.subtle.generateKey()`
-- Sign requests
-- Store and retrieve the key using IndexedDB under a given session ID
-- Abstractions built on top of the `IndexedDBStamper` that simplify authentication flows
-
-This is currently the **most persistent** session model for modern browsers that support WebCrypto. It is especially valuable in Progressive Web App (PWA) contexts or when iframe and localStorage approaches are insufficient.
-
-To see a full working example, check out our [IndexedDB sdk example](https://github.com/tkhq/sdk/tree/main/examples/with-indexed-db). Or our [Web demo application](https://github.com/tkhq/demo-ewk) that leverages abstractions such as the `IndexedDbClient` for full e2e authentication flows.
-
-Iframe-based session: Turnkey hosts a secure iframe at https://auth.turnkey.com which can be used to store the session credential
-used to authorize actions, without exposing those credentials to your app. This method is secure and browser-isolated, but:
-
-- Sessions last only as long as the iframe persists
-- iOS aggressively clears iframe storage, making it less reliable on mobile
-- React Native does not support iframes
-
-Local storage: The session credential can also be stored directly in Local Storage. This allows the credential to persist across tabs,
-reloads, or components in web apps. However, your app's domain can access Local Storage, so credentials must be handled with care.
-
-SecureStorage (mobile only): On mobile devices, session credentials can be stored in the device's native secure storage layer,
-such as Keychain (iOS) or Keystore (Android). This offers the strongest guarantees for durability and isolation in native mobile apps.
-
-Duration
-Session credentials are time-bound and expire after the duration you specify. This is set via the expirationSeconds parameter
-when the session is created. The default is 900 seconds (15 minutes), but you can configure this to suit your needs.
-
-To read more about sessions and how to manage them, head to the [Sessions Overview page](https://docs.turnkey.com/authentication/sessions#sessions).
-
-## Wallet type: decide between smart contract and key-based wallets
-
-Turnkey supports two types of wallets: smart contract wallets and key-based wallets. Both are fully compatible with Turnkey's signing
-infrastructure — the difference lies in how the wallet behaves on-chain, and what additional infrastructure it requires.
-
-HD wallets generate addresses and private keys from a single seed, and work across multiple chains using standard derivation paths.
-They're contractless, chain-agnostic, and compatible with any network that supports standard signing curves — no bundlers or on-chain
-deployment required.
-
-Smart contract wallets give you more flexibility. These wallets use a smart contract to manage access control, enabling features like gas
-sponsorship, modular recovery, or batching. Turnkey can act as the signer behind these contracts, whether you're using your own implementation
-or integrating with frameworks like ZeroDev or Alchemy's Account Kit.
-
-Use smart contract wallets when you need advanced features. Otherwise, key-based wallets are simpler, faster, and work everywhere.
-
-## Wallet portability: should users be able to import/export?
-
-Turnkey supports both import and export of private keys via secure iframe flows.
-
-Export lets users back up their wallet (e.g. display their mnemonic phrase). Import lets users bring an existing wallet into Turnkey.
-
-You do not need to offer either of these, but we do recommend enabling export to ensure users can bring their funds with them if they need.
-
-Import/export flows never expose the raw private key to your backend; they happen entirely in an isolated iframe and are encrypted client-side.
diff --git a/products/company-wallets/features/dashboard.mdx b/products/company-wallets/features/dashboard.mdx
deleted file mode 100644
index cc959670..00000000
--- a/products/company-wallets/features/dashboard.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: "Dashboard"
-description: "Coming soon!"
----
\ No newline at end of file
diff --git a/products/company-wallets/features/multi-chain-support.mdx b/products/company-wallets/features/multi-chain-support.mdx
deleted file mode 100644
index be961da0..00000000
--- a/products/company-wallets/features/multi-chain-support.mdx
+++ /dev/null
@@ -1,12 +0,0 @@
----
-title: "Multichain support"
-description: "Overview of our multichain network support."
----
-
-import NetworkLinks from "/snippets/shared/networks-links.mdx";
-
-Turnkey delivers robust multichain support that enables seamless integration across a variety of cryptocurrency ecosystems. Leveraging secure cryptographic fundamentals and advanced transaction solutions, our platform simplifies managing digital assets across multiple networks.
-
-Explore more about each network:
-
-
diff --git a/products/company-wallets/features/off-chain-contracts.mdx b/products/company-wallets/features/off-chain-contracts.mdx
deleted file mode 100644
index c4b55003..00000000
--- a/products/company-wallets/features/off-chain-contracts.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: "Off-chain contracts"
-description: "Coming soon!"
----
diff --git a/products/company-wallets/features/scoped-api-key.mdx b/products/company-wallets/features/scoped-api-key.mdx
deleted file mode 100644
index ebcb4e31..00000000
--- a/products/company-wallets/features/scoped-api-key.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: "Scoped API key"
-description: "Coming soon!"
----
diff --git a/products/company-wallets/features/security/compliance.mdx b/products/company-wallets/features/security/compliance.mdx
deleted file mode 100644
index 8dba1ca0..00000000
--- a/products/company-wallets/features/security/compliance.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Compliance"
-description: "Coming soon!"
-sidebarTitle: "Compliance"
----
diff --git a/products/company-wallets/features/security/quorum-os.mdx b/products/company-wallets/features/security/quorum-os.mdx
deleted file mode 100644
index b8928f55..00000000
--- a/products/company-wallets/features/security/quorum-os.mdx
+++ /dev/null
@@ -1,12 +0,0 @@
----
-title: "QuorumOS"
----
-
-# Overview
-
-QuorumOS is Turnkey’s minimal, immutable Linux unikernel designed for high-security enclaves. It provides:
-
-- A deterministic build system ensuring reproducible, auditable artifacts.
-- A small trusted computing base, reducing attack surface.
-- An initialization and attestation framework that verifies only authorized code runs within the enclave.
-- Integration with hardware root-of-trust modules (e.g., AWS Nitro Security Module) to establish secure execution environments.
diff --git a/products/company-wallets/features/security/secure-hardware.mdx b/products/company-wallets/features/security/secure-hardware.mdx
deleted file mode 100644
index f8d8644e..00000000
--- a/products/company-wallets/features/security/secure-hardware.mdx
+++ /dev/null
@@ -1,11 +0,0 @@
----
-title: "Secure hardware"
----
-
-Secure hardware provides strong isolation and attestation for sensitive operations:
-
-- Hardware-enforced isolation: secure enclaves have no external networking or persistent storage.
-- Root quorum: use ≥3 members with threshold ≥2; each critical user should set up multiple authenticators (e.g., Touch ID, YubiKey).
-- Store API keys securely in hardware security modules (HSMs) or encrypted vaults; never hard-code keys in code or client-side.
-- Use HPKE-based secure channels for enclave ↔ end-user communication.
-- Leverages hardware root-of-trust modules (e.g., AWS Nitro Security Module) for cryptographic attestation.
diff --git a/products/company-wallets/policy-engine.mdx b/products/company-wallets/policy-engine.mdx
deleted file mode 100644
index 6077f231..00000000
--- a/products/company-wallets/policy-engine.mdx
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: "Policy engine"
-description: "Our policy engine is the foundation for flexible controls and permissions within your organization. This page provides an overview of how to author policies."
-sidebarTitle: "Overview"
----
-
-import PolicyEngine from '/snippets/shared/policy-engine.mdx';
-
-
\ No newline at end of file
diff --git a/products/embedded-business-wallets/overview.mdx b/products/embedded-business-wallets/overview.mdx
deleted file mode 100644
index d52f3285..00000000
--- a/products/embedded-business-wallets/overview.mdx
+++ /dev/null
@@ -1,195 +0,0 @@
----
-title: "Embedded Business Wallets"
-description: "Turnkey provides non-custodial business wallets that allow multiple employees or operators to access a shared wallet with customizable permissions and signing controls."
----
-
-With Embedded Business Wallets, businesses can grant different levels of access to team members, enabling business operations like seamless onchain payroll automation, vendor payments, merchant settlements, and more.
-
-## Why Turnkey for Embedded Business wallets?
-
-Turnkey's [Embedded Wallet Kit](/embedded-wallets/overview) powers some of the largest consumer applications in crypto, creating user accounts and accompanying wallets using familiar authentication like passkeys, email, and social login. Embedded Business Wallets bring that same infrastructure to business operations.
-
-Assign roles to users within your customers' organizations such as `finance-team`, `operator`, or `accounts-payable`. Then, write policies that reference those roles to control who can sign, what they can sign, and under what conditions. For example, require two finance approvers for large transfers or restrict a backend service to paying only pre-approved vendors.
-
-## Core principles
-
-**Instant wallet provisioning**
-Create secure wallets for businesses with familiar authentication methods, plug & play UI components, and options for white-labeling using [Embedded Wallet Kit](/embedded-wallets/overview).
-
-**Scoped org hierarchy**
-Parent organizations can create fully isolated [sub-organizations](/concepts/sub-organizations) for each business customer — each with their own wallets, users, and policies, all managed from a single integration.
-
-**Role-based access controls (RBAC)**
-Restrict actions based on a user's assigned role rather than their individual identity. Roles are represented by tags assigned to users and services. [Policies](/concepts/policies/overview) reference these tags to determine wallet access, transaction signing permissions, and approval conditions for each role.
-
-**Transaction Management and Gas Sponsorship**
-Sponsor gas fees and manage the transaction lifecycle end-to-end from construction to broadcast. See [Transaction Management](/concepts/transaction-management).
-
-## Architecture
-
-
-
-
-
-## How to get started on Embedded Business wallets with Turnkey
-
-1. **Set up Turnkey and end-user authentication:** Create a Turnkey org and configure how users will authenticate (e.g., email OTP, passkeys, OAuth).
-2. **Integrate Turnkey into the application and initialize the client:** Add Turnkey to the app so authentication, sessions, and wallet operations are available at runtime.
-3. **Provision a sub-organization per business or account:** Create a sub-org that represents the business entity and will contain its wallets, users, and policies.
-4. **Expose roles and permissions in the application UI:** Build UI that allows business users to manage roles (admin, operator, viewer) which map to Turnkey users and policies within the sub-org.
-5. **Enable business-grade wallet actions:** Surface wallet functionality (send/receive, signing, recovery) with policy-backed controls that reflect the business's internal approval structure.
-
-## Example policies your customers can configure
-
-| Need | RBAC Configuration |
-| :--- | :--- |
-| Treasury Manager initiates high-value transactions, requiring sign-off from both the CFO and Controller before processing. | **Multi-approval workflow:** Require 2+ approvers for high-value transactions |
-| The Controller or Head of Finance needs to maintain approved vendors and spending limits without manual review. | **Contractor and vendor payments:** Payments to allowlisted addresses with set spending limits. Manage the allowlist to add or remove recipients. |
-| Finance or Treasury needs to automatically execute recurring payments with set schedules, recipients, and amounts. | **Scheduled payments:** Restrict backend services to send recurring disbursements to approved recipients. |
-| Any changes to policies or admin permissions should require more than one executive approval. | **Organization admin / Root Quorum:** Require 2+ executives to approve changes to policies, permissions, or user access. |
-
-
-
- Create a [Turnkey organization](https://app.turnkey.com/dashboard/auth/initial) and choose which authentication methods to offer your business users. Turnkey supports [passkeys](/authentication/passkeys/introduction), [email OTP](/authentication/email), [phone OTP](/authentication/sms), and [social logins](/authentication/social-logins) out of the box. Enable your preferred methods in the [dashboard](https://app.turnkey.com) or via API. This determines how business users will log in, create sessions, and authorize wallet operations within their sub-organizations.
-
-
-
- Add Turnkey to your application to enable authentication, sessions, and wallet operations for your business users. Our [React Wallet Kit](/sdks/react) provides a drop-in provider component that handles client initialization, session management, and wallet UI.
-
- ```tsx
- import { TurnkeyProvider } from "@turnkey/react-wallet-kit";
-
- const turnkeyConfig = {
- organizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!,
- authProxyConfigId: process.env.NEXT_PUBLIC_AUTH_PROXY_CONFIG_ID!,
- };
-
- export function Providers({ children }: { children: React.ReactNode }) {
- return (
-
- {children}
-
- );
- }
- ```
-
- For server-side operations like provisioning sub-organizations or creating policies, use the [@turnkey/sdk-server](https://www.npmjs.com/package/@turnkey/sdk-server) package.
-
-
-
- Create a sub-organization for each of your business customers. Each sub-organization is an isolated environment containing its own wallets, users, and policies. One business cannot access the resources of another. When creating a sub-organization, you can provision an initial [root user](/concepts/users/root-quorum) and wallet in a single API call. Root users can execute any action or bypass policies if a defined [quorum](/concepts/users/root-quorum) is met. Non-root users can be added after and are recommended for day-to-day operations. They are governed by the policies defined in the sub-organization.
-
- ```ts
- import { Turnkey } from "@turnkey/sdk-server";
-
- const turnkey = new Turnkey({
- defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
- apiBaseUrl: "https://api.turnkey.com",
- apiPrivateKey: process.env.TURNKEY_API_PRIVATE_KEY,
- apiPublicKey: process.env.TURNKEY_API_PUBLIC_KEY,
- });
-
- const apiClient = turnkey.apiClient();
-
- const { subOrganizationId } = await apiClient.createSubOrganization({
- subOrganizationName: "Northstar Logistics",
- rootUsers: [
- {
- userName: "James Rivera",
- userEmail: "james.rivera@northstarlogistics.com",
- authenticators: [],
- apiKeys: [],
- oauthProviders: [],
- },
- ],
- rootQuorumThreshold: 1,
- wallet: {
- walletName: "Northstar Treasury",
- accounts: [
- {
- curve: "CURVE_SECP256K1",
- pathFormat: "PATH_FORMAT_BIP32",
- path: "m/44'/60'/0'/0/0",
- addressFormat: "ADDRESS_FORMAT_ETHEREUM",
- },
- ],
- },
- });
- ```
-
- Your application logic manages resources in each sub-org such as users, tags, and policies on behalf of your business customers. See [Sub-Organizations](/concepts/sub-organizations) for more detail.
-
-
-
- Build UI that allows the root user(s) to add team members and assign roles (admin, operator, viewer) represented by Turnkey users and policies in the sub-organization. When a root user adds a team member or updates a policy, your backend executes the corresponding action in their sub-organization.
-
-
-
-
-
- ```ts
- // Create role tags
- const { userTagId: financeTagId } = await apiClient.createUserTag({
- userTagName: "finance-team",
- userIds: [],
- });
-
- const { userTagId: operatorTagId } = await apiClient.createUserTag({
- userTagName: "operator",
- userIds: [],
- });
-
- // Add the Head of Finance with the finance role
- await apiClient.createUsers({
- users: [
- {
- userName: "Sarah Chen",
- userEmail: "sarah.chen@northstarlogistics.com",
- userTags: [financeTagId],
- apiKeys: [],
- authenticators: [],
- oauthProviders: [],
- },
- ],
- });
- ```
-
- Business users assign roles through your UI, and your application creates the corresponding tags and policies in their sub-org. Once roles are in place, create policies that reference them. See [Policy Quickstart](/concepts/policies/quickstart) for guidance.
-
-
-
- Surface wallet functions like sending payments, signing transactions, and recovery. Combine these with policy-backed controls that reflect the business's internal approval structure. If a transaction doesn't match an allowed policy, it's rejected.
-
- **Top-level policy:** Enforce a maximum transaction size of $100,000 USDC across all business wallets.
-
- ```json
- {
- "policyName": "Global per-transaction USDC limit",
- "effect": "EFFECT_DENY",
- "consensus": "approvers.any(user, true)",
- "condition": "eth.tx.to == '' && eth.tx.function_name == 'transfer' && eth.tx.contract_call_args['value'] > 100000000000"
- }
- ```
-
- **User-configured policy:** When your customers add approved vendors, they dynamically create a policy in their sub-organization.
-
- ```ts
- await apiClient.createPolicy({
- policyName: "Auto-approve payments to allowlisted vendors",
- effect: "EFFECT_ALLOW",
- consensus: "approvers.any(user, user.tags.contains('accounts-payable'))",
- condition: `wallet.id == '${walletId}' && eth.tx.to == '${usdcContractAddress}' && eth.tx.function_name == 'transfer' && eth.tx.contract_call_args['to'] in [${vendorAddresses.map(a => `'${a}'`).join(', ')}]`,
- });
- ```
-
- Our policy engine covers a wide range of uses. See [Policy Language](/concepts/policies/language) to start creating policies for your business users.
-
-
-
-## The result: secure, automated onchain payments
-
-Embedded Business Wallets with Turnkey enables you to launch business wallets built for how your customers operate. Power onchain payroll, vendor payments, and settlements using white-labeled, non-custodial wallets with role-based permissions for secure, automated business transactions.
-
-## Case study
-
-[Mural Pay](https://www.turnkey.com/customers/mural-pay-cross-border-payments), a payments platform, uses Embedded Business Wallets with Turnkey to deliver a simplified experience. They can spin up non-custodial embedded wallets in minutes with familiar login methods like passkey or email authentication. Without seed phrases, business users can rely on email-based flows to recover access to lost wallets. Using Turnkey, Mural Pay simplifies cross-border payments for global businesses, fintechs, and banks.
diff --git a/products/embedded-wallets/features/export-wallets.mdx b/products/embedded-wallets/features/export-wallets.mdx
deleted file mode 100644
index 8b54d031..00000000
--- a/products/embedded-wallets/features/export-wallets.mdx
+++ /dev/null
@@ -1,3 +0,0 @@
-import ExportWallets from "/snippets/shared/export-wallets.mdx";
-
-
\ No newline at end of file
diff --git a/products/embedded-wallets/features/fiat-on-ramp.mdx b/products/embedded-wallets/features/fiat-on-ramp.mdx
deleted file mode 100644
index 5e83b460..00000000
--- a/products/embedded-wallets/features/fiat-on-ramp.mdx
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: "Fiat Onramp"
-description: "Turnkey’s Fiat Onramp lets your end users convert traditional currency (USD, EUR, etc.) into crypto assets (ETH, USDC, BTC, etc.) directly within your application."
----
-
-import FiatOnRamp from "/snippets/shared/fiat-on-ramp.mdx";
-
-
diff --git a/products/embedded-wallets/features/gas-sponsorship.mdx b/products/embedded-wallets/features/gas-sponsorship.mdx
deleted file mode 100644
index 182eeef3..00000000
--- a/products/embedded-wallets/features/gas-sponsorship.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: "Gas sponsorship"
-description: ""
----
diff --git a/products/embedded-wallets/features/import-wallets.mdx b/products/embedded-wallets/features/import-wallets.mdx
deleted file mode 100644
index d32abb96..00000000
--- a/products/embedded-wallets/features/import-wallets.mdx
+++ /dev/null
@@ -1,3 +0,0 @@
-import ImportWallets from "/snippets/shared/import-wallets.mdx";
-
-
\ No newline at end of file
diff --git a/products/embedded-wallets/features/multi-chain-support.mdx b/products/embedded-wallets/features/multi-chain-support.mdx
deleted file mode 100644
index 1b2c79de..00000000
--- a/products/embedded-wallets/features/multi-chain-support.mdx
+++ /dev/null
@@ -1,12 +0,0 @@
----
-title: "Multichain support"
-description: "Overview of our multichain network support."
----
-
-import NetworkLinks from "/snippets/shared/networks-links.mdx";
-
-Turnkey delivers robust multichain support that enables seamless integration across a variety of cryptocurrency ecosystems. Leveraging secure cryptographic fundamentals and advanced transaction solutions, our platform simplifies managing digital assets across multiple networks.
-
-Explore more about each network:
-ss
-
diff --git a/products/embedded-wallets/features/policy-engine.mdx b/products/embedded-wallets/features/policy-engine.mdx
deleted file mode 100644
index 7105f0c9..00000000
--- a/products/embedded-wallets/features/policy-engine.mdx
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: "Policy engine"
-description: "Our policy engine is the foundation for flexible controls and permissions within your organization. This page provides an overview of how to author policies."
----
-
-import PolicyEngine from "/snippets/shared/policy-engine.mdx";
-
-
diff --git a/products/key-management/examples/encryption-key-storage.mdx b/products/key-management/examples/encryption-key-storage.mdx
deleted file mode 100644
index 1e2de7a0..00000000
--- a/products/key-management/examples/encryption-key-storage.mdx
+++ /dev/null
@@ -1,166 +0,0 @@
----
-title: "Encryption Key Storage"
-description: "Use Turnkey as a secure key storage and retrieval service to build user-controlled recovery with risk separation between your infrastructure and Turnkey."
----
-
-This guide demonstrates how to use Turnkey to store and retrieve encryption keys with granular access controls. Storing the encryption key in Turnkey's secure enclave, separate from the data in your platform, allows you to build applications with enhanced security, performance, and flexibility.
-
-## Why Turnkey for Encryption Key Storage?
-
-Turnkey provides secure storage and policy-controlled access for encryption keys. Use it to encrypt sensitive data, build user-controlled recovery flows, or separate risk between your infrastructure and Turnkey's secure enclave.
-
-## Core Principles
-
-- **Risk separation:** Neither party alone can access plaintext data. Your infrastructure holds encrypted data while Turnkey's [secure enclave](/security/secure-enclaves) holds the encryption key.
-- **Secure enclaves:** Keys are generated and stored inside hardware-backed enclaves. Key material never exists in plaintext outside the enclave boundary.
-- **Policy-gated key export:** Use Turnkey's [policy engine](/concepts/policies/overview) to add controls over key export, such as requiring [quorum approval](/concepts/users/root-quorum) for sensitive operations.
-- **Flexible authentication:** Turnkey supports multiple authentication methods for key export: API keys, [passkeys](/authentication/passkeys/introduction), [social logins](/authentication/social-logins), [email](/authentication/email) and [SMS OTP](/authentication/sms), allowing you to match your security requirements.
-
-## Architecture
-
-
-
-
-
-## How to Get Started on Encryption Key Storage with Turnkey
-
-1. **Create encryption keypair:** Generate a P-256 keypair in Turnkey. The private key is stored in the secure enclave and never exposed.
-2. **Retrieve public key:** Fetch the public key to use for encryption on your side.
-3. **Encrypt data locally:** Use the public key to encrypt sensitive data and store it in your infrastructure.
-4. **Authenticate and export decryption key:** Authenticate the user and request the private key from Turnkey.
-5. **Decrypt and use locally:** Decrypt your stored bundles and use them locally, then clear sensitive data from memory.
-
-## Use Cases
-
-| Need | Configuration |
-| :--- | :--- |
-| Users need to recover wallets without managing backup keys themselves. | **User-controlled backup & recovery:** Encrypt recovery bundles on-device using Turnkey's public key, store encrypted bundles client-side, and gate decryption through user authentication ([social logins](/authentication/social-logins), [passkeys](/authentication/passkeys/introduction), [email OTP](/authentication/email)). |
-| Compliance or architecture requires sensitive material is not held by any single party. | **Distributed trust:** Store encrypted credentials, API keys, or secrets in your infrastructure. Gate decryption through Turnkey's policy engine and require quorum approval for key export in high-security scenarios. |
-
-
-
- Generate a P-256 keypair in Turnkey using [createPrivateKeys](/api-reference/private-keys/create-private-keys). The private key is stored in Turnkey's [secure enclave](/security/secure-enclaves) and never exposed.
-
- ```typescript
- const { privateKeys } = await turnkey.apiClient().createPrivateKeys({
- privateKeys: [{
- privateKeyName: "escrow-encryption-key",
- curve: "CURVE_P256",
- addressFormats: [],
- }],
- });
- ```
-
-
-
- Fetch the public key to use for encryption:
-
- ```typescript
- const { privateKey } = await turnkey.apiClient().getPrivateKey({
- privateKeyId: encryptionKeyId,
- });
- const publicKey = privateKey.publicKey;
- ```
-
-
-
- Use the public key to encrypt sensitive data on your side. Turnkey never sees the plaintext or the encrypted result:
-
- ```typescript
- // Using P-256 ECIES encryption
- const encryptedBundle = await encryptWithPublicKey(publicKey, sensitiveData);
-
- // Store in YOUR infrastructure
- await saveToYourStorage(encryptedBundle);
- ```
-
- Encrypted bundles can be stored anywhere you control:
-
- | Storage Type | Use Case |
- | :--- | :--- |
- | **localStorage / IndexedDB** | Client-side web apps (cleared on browser data wipe) |
- | **Secure Enclave (mobile)** | iOS/Android apps with hardware-backed protection |
- | **Your database** | Server-managed data with your standard backup/DR |
- | **Object storage (S3, GCS)** | Scalable, distributed access with appropriate IAM policies |
-
-
-
- Authenticate the user through your normal auth flow, then request the encryption private key from Turnkey using [exportPrivateKey](/api-reference/private-keys/export-private-key):
-
- ```typescript
- const targetKeyPair = generateP256KeyPair();
-
- const { exportBundle } = await turnkey.apiClient().exportPrivateKey({
- privateKeyId: encryptionKeyId,
- targetPublicKey: targetKeyPair.publicKeyUncompressed,
- });
-
- const decryptionKey = await decryptExportBundle({
- exportBundle,
- embeddedKey: targetKeyPair.privateKey,
- organizationId,
- });
- ```
-
- Use Turnkey's [policy engine](/concepts/policies/overview) to add controls on key export:
-
- ```json
- {
- "policyName": "Escrow-Key-Export-Policy",
- "effect": "EFFECT_ALLOW",
- "condition": "activity.type == 'ACTIVITY_TYPE_EXPORT_PRIVATE_KEY' && private_key.id == ''",
- "consensus": "approvers.count() >= 2"
- }
- ```
-
- This example requires two approvers for any export of the encryption key, adding human oversight to sensitive operations.
-
-
-
- Decrypt your stored bundles and use them locally, with no further Turnkey calls:
-
- ```typescript
- const plaintext = await decryptWithPrivateKey(decryptionKey, encryptedBundle);
- // Use the decrypted data (sign transactions, access credentials, etc.)
- ```
-
- When done, clear the decryption key and any decrypted data from memory:
-
- ```typescript
- secureWipe(decryptionKey);
- secureWipe(decryptedData);
- ```
-
-
-
-## The Result: Security Without Compromise
-
-Encryption Key Storage with Turnkey enables you to:
-
-- **Maintain full control** over your data and operations
-- **Implement flexible recovery** flows that keep users in control
-- **Distribute trust** between your infrastructure and Turnkey
-
-Turnkey provides secure key storage, authentication, and policy enforcement. You decide how to use the keys and where to store the encrypted data.
-
-## World App Case Study
-
-[World App](https://www.turnkey.com/blog/turnkey-announces-integration-tools-for-humanitys-world-app) (by Tools for Humanity) uses Encryption Key Storage with Turnkey for user wallet recovery.
-
-Learn more: [World App Backup Service (GitHub)](https://github.com/worldcoin/backup-service)
-
-World App encrypts each user's recovery bundle locally on-device. Turnkey's infrastructure manages the bundle's encryption key within secure enclaves, which can only be used in response to user-authenticated actions such as OAuth.
-
-- Users retain control of their encrypted recovery data
-- The encryption key lives in secure enclaves, not centralized servers
-- Key access requires explicit user authentication
-- No single point of failure: both components must be compromised
-
-## Resources
-
-Explore the complete implementation in our [GitHub encryption-key-escrow example](https://github.com/tkhq/sdk/tree/main/examples/encryption-key-escrow).
-
-- [Secure Enclaves](/security/secure-enclaves): How Turnkey protects key material
-- [Export Private Keys](/wallets/export-wallets): API documentation for key export
-- [Policy Engine](/concepts/policies/overview): Configuring access controls
-- [Root Quorum](/concepts/users/root-quorum): Multi-party approval for sensitive operations
diff --git a/products/key-management/examples/enterprise-disaster-recovery.mdx b/products/key-management/examples/enterprise-disaster-recovery.mdx
deleted file mode 100644
index 68016076..00000000
--- a/products/key-management/examples/enterprise-disaster-recovery.mdx
+++ /dev/null
@@ -1,134 +0,0 @@
----
-title: "Enterprise Disaster Recovery"
-description: "Import and recover wallets with strict access controls. "
----
-
-This guide covers how to backup your wallets on Turnkey for incident response, provider migration,
-and wallet backups.
-
-## Why Turnkey for Enterprise Disaster Recovery?
-
-Turnkey provides a secure foundation for disaster recovery. Our approach combines
-[secure enclaves](/security/secure-enclaves), end-to-end encryption, and
-[programmable policies](/concepts/policies/overview) to ensure recovery material is protected at
-rest, in transit, and during use.
-
-## Core principles
-
-- **End-to-end encryption:** All key import material is encrypted directly to Turnkey's secure
- enclave using [HPKE (Hybrid Public Key Encryption)](/security/enclave-secure-channels). The
- plaintext never exists outside the enclave boundary.
-- **Cryptographic audit trail:** Every recovery operation during transmission and import is
- cryptographically stamped, ensuring that recoveries can not be tampered with along the way.
-- **Policy-based guardrails:** Turnkey’s [policy engine](/concepts/policies/overview) restricts how
- wallets are accessed, like limiting fund movement to allowed addresses or requiring multiple
- approvals from your organization.
-
-## Direct Import Flow
-
-
-
-
-
-## How to Get Started on Enterprise Disaster Recovery with Turnkey
-
-1. **Secure organization & policy setup**: Create your Turnkey org, configure the root quorum, and
- define recovery policies.
-2. **Set up the Turnkey SDK**: Integrate
- [React Wallet Kit](/sdks/react/using-embedded-wallets#importing-and-exporting-wallets) or
- [@turnkey/sdk-server](/embedded-wallets/code-examples/import#nodejs) into your application.
-3. **Import wallets**: Use handleImportWallet() to import wallet keys into Turnkey's secure enclave.
-
-## **Use Cases**
-
-| Need | Configuration |
-| :------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| A key holder becomes unavailable or a hardware wallet fails, requiring immediate recovery of treasury assets. | **Treasury recovery**: Import wallet keys into Turnkey's secure enclave with quorum-controlled access and policy-restricted fund sweeping. |
-| Migrating from another key management provider with no plaintext exposure during transit. | **Provider migration**: Encrypt keys to Turnkey's secure enclave on a hardened machine, import directly with full policy controls inherited immediately. |
-| Operations need to continue even if a primary signer or infrastructure goes down. | **Redundancy and failover**: Import backup copies of critical wallet keys into Turnkey so a secondary signing path is always available. |
-
-### 1. Secure Organization Setup and Recovery Policies
-
-Create a [Turnkey organization](https://app.turnkey.com/dashboard/auth/initial) and establish the
-security foundation for recovery operations:
-
-- Create dedicated recovery users with specific, limited permissions
-- Configure the [Root Quorum](/concepts/users/root-quorum) to require multiple approvers for
- sensitive operations
- - Require [quorum approval](/concepts/users/root-quorum) for high-value operations to prevent any
- single person from unilaterally moving recovered funds. This ensures no single credential
- compromise can trigger unauthorized recovery. See [Policy overview](/concepts/policies/overview)
- for setup guidance.
-
-- Distribute authenticators ([passkeys](/authentication/passkeys/introduction), YubiKeys) across
- geographic locations if possible
-- Define [policies](/concepts/policies/examples/signing-control) that restrict what can be done with
- recovered wallets.
-
-### 2. Set up the Turnkey SDK
-
-Integrate Turnkey into your application to enable wallet import and recovery operations. The
-[NodeJS server SDK](https://github.com/tkhq/sdk/tree/main/examples/import-in-node) is well oriented
-to handle the entire import flow, including encryption and secure transport.
-
-```ts
-import { Turnkey } from "@turnkey/sdk-server";
-import { encryptPrivateKeyToBundle, encryptWalletToBundle } from "@turnkey/crypto";
-
-const initResult = await turnkeyClient.apiClient().initImportWallet({
- userId,
-});
-
-const walletBundle = await encryptWalletToBundle({
- mnemonic,
- importBundle: initResult.importBundle,
- userId,
- organizationId,
-});
-```
-
-### 3. Import Wallets
-
-Use [importWallet()](/generated-docs/core/turnkey-client-import-wallet) to import wallet keys into
-Turnkey's secure enclave. In the last step the SDK encrypts the mnemonic or private key to Turnkey's
-enclave public key using [HPKE (Hybrid Public Key Encryption)](/security/enclave-secure-channels),
-and now transmits the encrypted bundle. The enclave decrypts and stores the key material.
-
-```ts
-const walletImportResult = await turnkeyClient.apiClient().importWallet({
- userId: userId,
- walletName: "Your imported wallet!",
- encryptedBundle: walletBundle,
- accounts: [],
-});
-```
-
-All fund movements are logged with cryptographic signatures, providing a complete audit trail of the
-recovery operation.
-
-## The Result: Enterprise-grade Key Recovery
-
-Turnkey transforms enterprise disaster recovery from a high-risk, manual operation into a secure,
-verifiable process. Import wallet keys directly into Turnkey's secure enclave and gain immediate
-operational capability with full policy controls:
-
-- **Cryptographic guarantees**: Key material is protected by secure enclaves and end-to-end
- encryption
-- **Organizational controls**: Quorum policies prevent unilateral action on sensitive operations
-- **Operational flexibility**: Support for all major chains and key types through a unified
- interface
-- **Audit compliance**: Every operation is logged with cryptographic signatures
-
-## Resources
-
-Explore the complete implementation in our
-[GitHub 'Disaster Recovery' example](https://github.com/tkhq/sdk/tree/main/examples/disaster-recovery).
-
-- [Import Wallets Guide](/wallets/import-wallets)
-- [Export Wallets Guide](/wallets/export-wallets)
-- [Root Quorum Configuration](/concepts/users/root-quorum)
-- [Secure Enclaves Overview](/security/secure-enclaves)
-- [Enclave Secure Channels](/security/enclave-secure-channels)
diff --git a/products/key-management/examples/overview.mdx b/products/key-management/examples/overview.mdx
deleted file mode 100644
index 63edf2db..00000000
--- a/products/key-management/examples/overview.mdx
+++ /dev/null
@@ -1,26 +0,0 @@
----
-title: "Code examples"
-sidebarTitle: "Overview"
-mode: wide
----
-
-
-
- Use Turnkey as a secure key storage and retrieval service
-
-
- Import and recover wallets in Turnkey’s secure enclaves with controlled access
-
-
diff --git a/products/key-management/overview.mdx b/products/key-management/overview.mdx
deleted file mode 100644
index 0e742324..00000000
--- a/products/key-management/overview.mdx
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "Overview"
----
-
-Turnkey is not just for crypto wallets. Our infrastructure also allows for more generic private key
-management: store, recover, and manage cryptographic keys with programmable access controls, and
-quorum approvals.
-
-With Key Management, you can:
-
-- Securely store cryptographic keys in hardware-backed
- [secure enclave infrastructure](/security/secure-enclaves)
-- Implement disaster recovery with cryptographic guarantees
-- Protect sensitive material like API secrets, credentials, and recovery bundles
-
-## Solutions
-
-| Example | Description |
-| :--------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------ |
-| [Enterprise Disaster Recovery](/products/key-management/examples/enterprise-disaster-recovery) | Back up wallets and private keys for disaster scenarios |
-| [Encryption Key Storage](/products/key-management/examples/encryption-key-storage) | Use Turnkey private keys to encrypt sensitive data (e.g., recovery bundles, API secrets, credentials) with simple authentication & policies |
-
-## Next Steps
-
-Explore the [code examples](/products/key-management/examples/overview) for detailed implementation
-guides, or learn more about [secure enclaves](/security/secure-enclaves) and
-[quorum policies](/concepts/users/root-quorum).
diff --git a/products/verifiable-cloud/lifecycle.mdx b/products/verifiable-cloud/lifecycle.mdx
deleted file mode 100644
index 5c78503f..00000000
--- a/products/verifiable-cloud/lifecycle.mdx
+++ /dev/null
@@ -1,69 +0,0 @@
----
-title: "Deployment Lifecycle"
----
-
-This page walks through the full lifecycle of a TVC deployment, from submitting your container image to verifying a signed response. It is intended for developers who want to understand the security guarantees at each step.
-
-## Deployment Setup
-
-Deployments can be done through the [Turnkey dashboard](https://app.turnkey.com/dashboard/tvc) or the [`tvc` CLI](https://crates.io/crates/tvc). To deploy, you provide Turnkey with:
-- Your container registry URL (any OCI-compliant registry: GHCR, Docker Hub, ECR, ACR, etc.)
-- The expected executable digest, the SHA256 hash of your binary (the **pivot hash**)
-- The binary path within the container image
-- Arguments and port configuration
-
-You can verify the binary hash yourself at any time by pulling the container image, extracting the binary, and computing its SHA256 hash.
-
-Turnkey uses these inputs to generate a [QOS manifest](/products/verifiable-cloud/overview#manifests) containing the pivot hash, arguments, ports, and expected PCR values. The manifest must be cryptographically signed by your configured [Manifest Set](https://github.com/tkhq/qos#manifest-set) operators before deployment proceeds. No deployment can happen without Manifest Set approval.
-
-## Enclave Boot
-
-When the deployment runs, Turnkey's infrastructure boots an AWS Nitro enclave from an EIF (Enclave Image File). The Nitro hypervisor measures the enclave image into [Platform Configuration Registers (PCRs)](https://docs.aws.amazon.com/enclaves/latest/user/set-up-attestation.html#where) as part of this process. These measurements are hardware-rooted and cannot be forged. See [Claims and verification](/security/turnkey-verified#claims-and-verification) for how PCR values are used to verify a specific enclave.
-
-Immediately after boot, QOS generates an [ephemeral key](https://github.com/tkhq/qos#ephemeral-key) pair. This key is created fresh on every enclave boot and never leaves the enclave.
-
-## Binary Verification
-
-In parallel with boot, your container image is pulled from the registry and the binary is extracted. QOS receives this binary and hashes it, then compares the hash against the pivot hash inside the manifest. If they match, the binary is accepted and execution continues. If they don't match, boot fails. Your binary cannot run unless it exactly matches what [Manifest Set](https://github.com/tkhq/qos#manifest-set) operators approved in the manifest.
-
-## Attestation
-
-QOS requests an attestation document from the Nitro Security Module (NSM), embedding the ephemeral public key and the manifest hash into the document. The NSM produces a document containing:
-- The PCR values (hardware measurements of the enclave image)
-- The ephemeral public key
-- The manifest hash
-
-The NSM signs this document with its own hardware key. This signature cryptographically binds the manifest and the ephemeral key to the measured enclave, so an external verifier can confirm that a specific binary is running inside a specific enclave. See [Boot Proofs](/security/turnkey-verified#boot-proofs) for the full set of claims this enables and how to verify them.
-
-## Quorum Key Provisioning
-
-After attestation, the enclave receives its [Quorum Key](https://github.com/tkhq/qos#quorum-key), the long-lived key shared across all replicas of a deployment. See [Quorum Deployments](/security/quorum-deployments) for a deeper look at the provisioning flow.
-
-For the first enclave boot, key provisioning requires N-of-M [Share Set](https://github.com/tkhq/qos#share-set) members to participate based on a configured threshold. For subsequent replicas (or when a replica is replaced), an already-running healthy enclave exports the quorum key encrypted to the new enclave's ephemeral public key. Only the target enclave can decrypt it. This [key forwarding mechanism](https://github.com/tkhq/qos/blob/main/docs/key_forward.md) means Share Set members don't need to intervene for routine scaling or replica replacement.
-
-> Turnkey handles quorum key provisioning automatically for TVC deployments. Support for custom quorum keys is actively being developed.
-
-Once provisioning is complete, the pivot process starts. A [**boot proof**](https://docs.turnkey.com/security/turnkey-verified#boot-proofs) containing the NSM attestation document, the manifest envelope, and the ephemeral public key is posted to the boot proof database and is available for verification.
-
-## Runtime & App Proofs
-
-Incoming requests are forwarded to your pivot application, which executes its logic and returns a result. Applications can choose how to sign their responses:
-
-| Signing approach | When to use |
-|:---|:---|
-| Ephemeral key | Full verifiability. Proves the result came from a specific enclave instance running a specific binary. |
-| Quorum key | Authentication, encryption, or data that must persist across enclave instances and upgrades |
-| No signature | Read-only or non-sensitive responses |
-
-The recommended approach for full verifiability is to sign with the ephemeral key. An [**app proof**](https://docs.turnkey.com/security/turnkey-verified#app-proofs) contains the signature scheme, the ephemeral public key, the payload, and a signature over the SHA256 of that payload. See [App Proof structure](/security/turnkey-verified#app-proof-structure) for the full schema and a worked example.
-
-## Verifying the Full Chain
-
-To independently verify that a result came from a specific, unmodified binary running inside a genuine Nitro enclave, a verifier needs four things:
-
-1. **Source code** that compiles to a binary whose SHA256 matches pivot hash within the manifest
-2. **Manifest envelope** confirming the pivot hash, expected PCR values, and Manifest Set signatures
-3. **Boot proof** containing the NSM-signed attestation document, whose PCRs match the manifest and which embeds the ephemeral public key and manifest hash
-4. **App proof** whose signing key matches the ephemeral key in the boot proof, confirming the result was produced inside that specific enclave instance
-
-For step-by-step verification instructions, see [Claims and verification](/security/turnkey-verified#claims-and-verification). Turnkey has also published verification tooling in [Rust](https://crates.io/crates/turnkey_proofs), [JavaScript](https://github.com/tkhq/sdk/blob/main/packages/crypto/src/proof.ts), and [Go](https://github.com/tkhq/go-sdk/tree/main/pkg/proofs).
diff --git a/reference/embedded-wallet-kit.mdx b/reference/embedded-wallet-kit.mdx
deleted file mode 100644
index 5a928e6c..00000000
--- a/reference/embedded-wallet-kit.mdx
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: "Embedded Wallet Kit (EWK)"
-description: "Turnkey's Embedded Wallets enable you to integrate secure, custom wallet experiences directly into your product. With features like advanced security, seamless authentication, and flexible UX options, you can focus on building great products while we handle the complexities of private key management."
----
-
-The Embedded Wallet Kit is a powerful SDK that allows you to integrate Turnkey's embedded wallets into your React applications, no backend required. It provides a set of UI components and easy-to-use functions, all exported from a hook, enabling you to quickly build secure embedded wallet experiences.
-
-Head over to the [Getting Started](/sdks/react/getting-started) guide to set up your React app with Turnkey's Embedded Wallet Kit.
diff --git a/faq.mdx b/reference/faq.mdx
similarity index 97%
rename from faq.mdx
rename to reference/faq.mdx
index 98d77655..9790dbfa 100644
--- a/faq.mdx
+++ b/reference/faq.mdx
@@ -31,7 +31,7 @@ title: "FAQ"
A Turnkey API key is simply a way to authenticate requests to Turnkey. Crypto assets are not tied to it in any way.
- Think about Turnkey API keys as an access-gating mechanism to Turnkey functionality. They're flexible in what they can do (you get to decide this with [Policies](/concepts/policies/overview)!), and revocable if they are lost or compromised.
+ Think about Turnkey API keys as an access-gating mechanism to Turnkey functionality. They're flexible in what they can do (you get to decide this with [Policies](/features/policies/overview)!), and revocable if they are lost or compromised.
Losing your Turnkey API key doesn't mean you'll lose your crypto:
@@ -63,7 +63,7 @@ title: "FAQ"
- See [resource limits](/concepts/resource-limits).
+ See [resource limits](/reference/resource-limits).
Yes - Turnkey's public API enforces rate limits that vary by plan:
@@ -114,15 +114,15 @@ title: "FAQ"
If there are specific ecosystems or chains you'd like to see us offer deeper support for, please let us know by contacting us at [hello@turnkey.com](mailto:hello@turnkey.com), on [X](https://x.com/turnkeyhq/), or [on Slack](https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ).
- Turnkey's [Transaction Management](/concepts/transaction-management) supports gas sponsorship, transaction construction, broadcast, nonce management and monitoring capabilities, down to just a few API calls.
+ Turnkey's [Transaction Management](/features/transaction-management) supports gas sponsorship, transaction construction, broadcast, nonce management and monitoring capabilities, down to just a few API calls.
We handle gassing and our battle-tested broadcast logic ensures inclusion even under adverse network conditions. You and your users never touch gas tokens or deal with stuck transactions.
While we've abstracted gas sponsorship, you're always able to bring in your own gas service, and we can handle the rest.
- This functionality is currently supported for EVM chains (Base, Polygon, Ethereum, Arbitrum) and Solana. We're actively expanding coverage — reach out if you need a specific chain. For more detail visit the [Transaction Management](/concepts/transaction-management) overview page.
+ This functionality is currently supported for EVM chains (Base, Polygon, Ethereum, Arbitrum) and Solana. We're actively expanding coverage — reach out if you need a specific chain. For more detail visit the [Transaction Management](/features/transaction-management) overview page.
- Gas sponsorship is available on Pro (up to \$50/day) and Enterprise (unlimited and configurable). Pay-as-you-go customers can access transaction construction, signing, and broadcast. See [Transaction Management](/concepts/transaction-management) for details.
+ Gas sponsorship is available on Pro (up to \$50/day) and Enterprise (unlimited and configurable). Pay-as-you-go customers can access transaction construction, signing, and broadcast. See [Transaction Management](/features/transaction-management) for details.
In the ECDSA context, messages are hashed before signing. Turnkey can perform this hashing for you, as we support two hash functions: `HASH_FUNCTION_KECCAK256` and `HASH_FUNCTION_SHA256` (for Ethereum and Bitcoin ecosystems respectively). If your message had already been hashed, you should use the `HASH_FUNCTION_NO_OP` option to sign the raw hash, in which case Turnkey will sign the payload as is. `HASH_FUNCTION_NO_OP` also has privacy implications: if a raw hashed message is passed in, Turnkey has no knowledge of the underlying pre-image.
diff --git a/getting-started/migration-guide.mdx b/reference/migration-guide.mdx
similarity index 79%
rename from getting-started/migration-guide.mdx
rename to reference/migration-guide.mdx
index e39af511..0d6fc661 100644
--- a/getting-started/migration-guide.mdx
+++ b/reference/migration-guide.mdx
@@ -6,14 +6,14 @@ sidebarTitle: "Migrating to Turnkey"
**The pattern for migrating a wallet to Turnkey is straightforward**: we want to export the wallet from the existing provider, and securely import it to Turnkey.
-No matter which approach, it is recommended to create a [sub-organization](/concepts/sub-organizations) for each user. Each suborg can have its own set of wallets, authenticators, and policies that govern access. These ["delegated access"](/concepts/policies/delegated-access) flows are key to enabling powerful and secure use, whose configuration is an important part of the migration to Turnkey.
+No matter which approach, it is recommended to create a [sub-organization](/features/sub-organizations) for each user. Each suborg can have its own set of wallets, authenticators, and policies that govern access. These ["delegated access"](/features/policies/delegated-access/overview) flows are key to enabling powerful and secure use, whose configuration is an important part of the migration to Turnkey.
For further guidance continue in our docs, and don't hesitate to reach out to [hello@turnkey.com](mailto:hello@turnkey.com).
-Additionally, familiarize yourself with Turnkey's [resource](/concepts/resource-limits) and [rate limits](/faq#limits). Ensure that finite suborg resources (like authenticators & private keys) and RPS limits are compatible with your migration approach.
+Additionally, familiarize yourself with Turnkey's [resource](/reference/resource-limits) and [rate limits](/reference/faq#limits). Ensure that finite suborg resources (like authenticators & private keys) and RPS limits are compatible with your migration approach.
### Asset availability
-In most circumstances user assets remain exactly as they were on-chain, belonging to the same key/address. However, if a provider does not meaningfully support export, you may have to instead create a new wallet in Turnkey and transfer assets to it.
+In most circumstances user assets remain exactly as they were onchain, belonging to the same key/address. However, if a provider does not meaningfully support export, you may have to instead create a new wallet in Turnkey and transfer assets to it.
**Security note:** be mindful that there are no guarantees a previous provider destroys their copy of exported keys, or that it wasn't logged somewhere. It can be worth considering creating a new wallet and transferring assets to it anyway.
@@ -37,7 +37,7 @@ This export typically takes the form of an export modal which displays the priva
Setting up the import modal is easy. We maintain an embedded iframe element on `import.turnkey.com`, which ensures the mnemonics and keys travel securely directly to and from Turnkey's infrastructure (instead of through yours). This frame should appear after the user has copied (exported) their key/seed in the first step, and will guide them through importing it to Turnkey.
We've created a package designed to help you insert this iframe and interact with it: `@turnkey/iframe-stamper`\
-This is covered completely in the [Import - Embedded iframe](/embedded-wallets/code-examples/import#embedded-iframe) docs section.
+This is covered completely in the [Import - Embedded iframe](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets#embedded-iframe) docs section.
Additional information on key transport is covered in our [Enclave to end-user secure channels](/security/enclave-secure-channels#import-flow) page.
## Custodial wallets
@@ -59,7 +59,7 @@ It is preferable for this migration script to not directly write/save these expo
### Import to Turnkey
There are two options for importing wallets to Turnkey programmatically:
-* [Node](/embedded-wallets/code-examples/import#nodejs) (`@turnkey/sdk-server`)
-* [Turnkey CLI ](/embedded-wallets/code-examples/import#cli)(`tkcli`)
+* [Node](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets#nodejs) (`@turnkey/sdk-server`)
+* [Turnkey CLI ](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets#cli)(`tkcli`)
Please visit these linked resources for implementation-specific guides and code samples.
diff --git a/concepts/resource-limits.mdx b/reference/resource-limits.mdx
similarity index 100%
rename from concepts/resource-limits.mdx
rename to reference/resource-limits.mdx
diff --git a/reference/solana-gasless-transactions.mdx b/reference/solana-gasless-transactions.mdx
deleted file mode 100644
index 76927812..00000000
--- a/reference/solana-gasless-transactions.mdx
+++ /dev/null
@@ -1,53 +0,0 @@
----
-title: "How to integrate gasless transactions on Solana with Turnkey"
-sidebarTitle: "Gasless Solana Transactions"
-hidden: true
----
-
-Turnkey offers flexible infrastructure to create and manage private keys. By combining the secure private key infrastructure and with gas abstracted transactions, developers can easily integrate account abstraction features for any Turnkey-powered wallets.
-
-## **Setting up gasless transactions on Solana (SVM)**
-
-Turnkey offers deep and robust support for the [Solana (SVM) ecosystem](https://docs.turnkey.com/networks/solana). We utilize the Ed25519 cryptographic curve as the primitive for signing transactions, provide address derivation support, and make it easy to integrate for SVM through various SDKs. Beyond this, Solana developers can also leverage SVM transaction parsing and policies, managed by the Turnkey Policy Engine.
-
-Here’s how to take advantage of Turnkey’s composable primitives for gas abstraction:
-
-### **Option 1: using Solana address fee payer**
-
-For this approach, we will leverage [examples/with-solana](https://github.com/tkhq/sdk/tree/main/examples/with-solana), a full example of Solana transaction construction, and broadcasting using [@turnkey/with-solana](https://www.npmjs.com/package/@turnkey/solana). For a more comprehensive, full-stack example that leverages passkeys, check out [examples/with-solana-passkeys](https://github.com/tkhq/sdk/tree/main/examples/with-solana-passkeys).
-
-\
-First, you’ll need to use one of the two optional environmental variables: `SOLANA_ADDRESS_FEE_PAYER`. While optional, the variable is necessary to create a separate fee payer address. The setup is as simple as passing in the fee payer address into the [withFeePayer.ts](https://github.com/tkhq/sdk/blob/main/examples/with-solana/src/withFeePayer.ts)
-
-```javascript
-// Assumes `turnkeyClient` is initialized and `createNewSolanaWallet` is available.
-
-let feePayerAddress = process.env.SOLANA_ADDRESS_FEE_PAYER;
-if (!feePayerAddress) {
- feePayerAddress = await createNewSolanaWallet(turnkeyClient.apiClient());
- console.log(`\nYour new Solana address: "${feePayerAddress}"`);
-} else {
- console.log(
- `\nUsing existing Solana address from ENV: "${feePayerAddress}"`,
- );
-}
-```
-
-### **Option 2: build a paymaster on Solana using Turnkey**
-
-This method showcases the flexibility of Turnkey infrastructure and was written and open sourced by another developer building on top of Turnkey. Please note that the repo referenced below is not maintained by Turnkey itself.
-
-[Build a Paymaster on Solana using Turnkey](https://github.com/tkhq/turnkey-solana-paymaster) is easy to follow and will guide you from start to finish:
-
-1. Admin: Setting up Turnkey account, API keys, and Solana public/private key pairs
-2. Installing Dependencies
-3. Frontend Implementation
-4. Backend Implementation
-5. Receiving and Broadcasting the Completed Transactions
-
-## **Thinking about gasless transactions for other chains?**
-
-If you have questions, feedback, or find yourself in need of a gas abstraction or integration that doesn’t exist yet, please get in touch with us!
-
-- Join our slack community [here](https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ)
-- Contact us at [hello@turnkey.com](mailto:hello@turnkey.com)
diff --git a/reference/tron-gasless-transactions.mdx b/reference/tron-gasless-transactions.mdx
deleted file mode 100644
index 42b08354..00000000
--- a/reference/tron-gasless-transactions.mdx
+++ /dev/null
@@ -1,54 +0,0 @@
----
-title: "How to integrate gasless transactions on Tron with Turnkey"
-sidebarTitle: "Gasless Tron Transactions"
----
-
-Turnkey offers flexible infrastructure to create and manage private keys. By combining the secure private key infrastructure and with gas abstracted transactions, developers can easily integrate account abstraction features for any Turnkey-powered wallets.
-
-## **Setting up gasless transactions on Tron (TVM)**
-
-Turnkey offers deep and robust support for the [Tron (TVM) ecosystem](https://docs.turnkey.com/networks/tron). We utilize the SECP256K1 elliptic curve as the primitive for signing transactions, and provide address derivation support. Beyond this, Tron developers can also leverage TVM transaction parsing and policies for additional security and transaction granularity, all managed by the Turnkey Policy Engine.
-
-Below, we demonstrate how to take advantage of Tron’s existing smart contract functions, combining it with Turnkey’s infrastructure to give end-users a gasless wallet experience, while maintaining the high standard for security, flexibility, and scalability.
-
-### **Gasless architecture: setup guide**
-
-1. **Stake TRX for Bandwidth (resource)**
- - Ensure that your organization’s Turnkey wallet is funded with a sufficient TRX balance
-
- > **TIP:** This can be a wallet contained within your parent organization
- - Initialize the staking activity by calling the [freezeBalanceV2](https://developers.tron.network/reference/freezebalancev2-1) function
-
- > Refer to Tron Network’s [official documentation](https://developers.tron.network/docs/) for further information
-2. **Delegate the resource to end-user wallets**
- - After you’ve initialized the staking operation using freezeBalanceV2 (Step 1) you’re now able to delegate the resources to end-user wallets
- - From the staking wallet, make a call to the Tron network using [DelegateResource](https://developers.tron.network/reference/delegateresource-1) function
- - `owner_address`: Wallet that is staking TRX (Step 1A)
- - `receiver_address`: Wallet controlled by the end-user
- - `resource`: The resource you’re delegating, bandwidth
-3. **Transaction flow (end-user)**
- - After the staking has been initialized and resources delegated, the user experience is trivial: end-user wallets (receiver_address) can transact via the Tron network without needing to provide gas for their own transactions.
-
-### **Leveraging delegateResource smart contract function**
-
-As shown above, we are leveraging the existing [DelegateResource](https://developers.tron.network/reference/delegateresource-1) call to delegate bandwidth or energy resources to other accounts. Note that this operation requires you to have Tron’s native network token TRX staked in order to fund end-user’s transactions.
-
-```shellscript
-{
- "owner_address": "TZ4UXDV5ZhNW7fb2AMSbgfAEZ7hWsnYS2g",
- "receiver_address": "TPswDDCAWhJAZGdHPidFg5nEf8TkNToDX1",
- "balance": 1000000,
- "resource": "BANDWIDTH",
- "lock": false,
- "visible": true
-}
-```
-
-> **Remember**: In the context of Tron, `owner_address` will be the Turnkey wallet that holds and stakes TRX. The `receiver_address` will be the end-user wallets.
-
-### **Thinking about gasless transactions for other chains?**
-
-If you have questions, feedback, or find yourself in need of a gas abstraction or integration that doesn’t exist yet, please get in touch with us! You can
-
-- Join our slack community [here](https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ)
-- Contact us at [hello@turnkey.com](mailto:hello@turnkey.com)
diff --git a/developer-reference/webhooks.mdx b/reference/webhooks.mdx
similarity index 93%
rename from developer-reference/webhooks.mdx
rename to reference/webhooks.mdx
index ac219319..5d0d4fc5 100644
--- a/developer-reference/webhooks.mdx
+++ b/reference/webhooks.mdx
@@ -1,6 +1,6 @@
---
title: "Activity webhooks"
-description: "Webhooks provide a powerful mechanism to receive notifications about activity requests in your Turnkey organization. Additionally, you'll be able to receive all activity requests for both the parent organization and all its child organizations. This functionality can be enabled via the organization feature capabilities of our platform, as detailed in the section on [organization features](/concepts/organizations#features)."
+description: "Webhooks provide a powerful mechanism to receive notifications about activity requests in your Turnkey organization. Additionally, you'll be able to receive all activity requests for both the parent organization and all its child organizations. This functionality can be enabled via the organization feature capabilities of our platform, as detailed in the section on [organization features](/features/organizations#features)."
sidebarTitle: "Webhooks"
---
@@ -8,7 +8,7 @@ This guide is designed to walk you through the process of setting up webhooks, f
## Prerequisites
-Before diving into webhook configuration, ensure you have completed the necessary preliminary steps outlined in our [Quickstart Guide](/getting-started/quickstart#create-your-turnkey-organization). This guide will assist you in setting up a new organization and installing the Turnkey CLI. Note: We'll create a new API Key for testing webhooks below.
+Before diving into webhook configuration, ensure you have completed the necessary preliminary steps outlined in our [Quickstart Guide](/get-started/quickstart#create-your-turnkey-organization). This guide will assist you in setting up a new organization and installing the Turnkey CLI. Note: We'll create a new API Key for testing webhooks below.
## Environment setup
diff --git a/scripts/openapi-gen/openapi-gen.ts b/scripts/openapi-gen/openapi-gen.ts
index 7b0bc1df..3b1cc6b1 100644
--- a/scripts/openapi-gen/openapi-gen.ts
+++ b/scripts/openapi-gen/openapi-gen.ts
@@ -188,18 +188,6 @@ export const tags = ${tagsStr};`;
const docsJsonContent = fs.readFileSync(docsJsonPath, "utf-8");
const docsConfig = JSON.parse(docsJsonContent);
- // console.log("docsConfig", docsConfig.navigation);
- // Define overview paths
- const activityOverviewPath = path.join(
- relativeMdxBaseDir,
- "activities",
- "overview"
- );
- const queryOverviewPath = path.join(
- relativeMdxBaseDir,
- "queries",
- "overview"
- );
// Remove duplicates before sorting
const uniqueActivityPaths = [...new Set(activityPaths)];
@@ -220,57 +208,61 @@ export const tags = ${tagsStr};`;
throw new Error("'docs.json' structure is not as expected.");
}
- // Find the API Reference tab
+ // Find the API & SDK reference tab
const apiRefTab = docsConfig.navigation.tabs.find(
- (item: any) => item.tab === "API reference"
+ (item: any) => item.tab === "API & SDK reference"
+ );
+
+ // Activities and Queries live inside the "REST API" group within the tab
+ const restApiGroup = apiRefTab?.pages?.find(
+ (item: any) => typeof item === "object" && item.group === "REST API"
);
- if (apiRefTab && Array.isArray(apiRefTab.pages)) {
+ if (restApiGroup && Array.isArray(restApiGroup.pages)) {
if (options.authProxy && options.navGroup) {
// Auth-proxy mode: find or create the named nav group and set its pages
- let navGroup = apiRefTab.pages.find(
+ let navGroup = restApiGroup.pages.find(
(item: any) => typeof item === "object" && item.group === options.navGroup
);
if (!navGroup) {
navGroup = { group: options.navGroup, pages: [] };
- apiRefTab.pages.push(navGroup);
+ restApiGroup.pages.push(navGroup);
console.log(`Created new nav group '${options.navGroup}' in docs.json`);
}
navGroup.pages = uniqueAuthProxyPaths;
console.log(`Updated '${options.navGroup}' paths in docs.json`);
} else {
// Standard mode: update Activities and Queries groups
- const activitiesGroup = apiRefTab.pages.find(
+ const activitiesGroup = restApiGroup.pages.find(
(item: any) =>
typeof item === "object" && item.group === "Activities"
);
if (activitiesGroup) {
activitiesGroup.pages = [
- activityOverviewPath,
...uniqueActivityPaths,
];
console.log(`Updated Activities paths in docs.json`);
} else {
console.warn(
- `Could not find 'Activities' group in docs.json under 'API Reference'`
+ `Could not find 'Activities' group in docs.json under 'REST API'`
);
}
- const queriesGroup = apiRefTab.pages.find(
+ const queriesGroup = restApiGroup.pages.find(
(item: any) => typeof item === "object" && item.group === "Queries"
);
if (queriesGroup) {
- queriesGroup.pages = [queryOverviewPath, ...uniqueQueryPaths];
+ queriesGroup.pages = [...uniqueQueryPaths];
console.log(`Updated Queries paths in docs.json`);
} else {
console.warn(
- `Could not find 'Queries' group in docs.json under 'API Reference'`
+ `Could not find 'Queries' group in docs.json under 'REST API'`
);
}
}
} else {
console.warn(
- `Could not find 'API reference' tab in docs.json navigation`
+ `Could not find 'REST API' group in 'API & SDK reference' tab in docs.json navigation`
);
}
diff --git a/sdks/advanced/api-key-stamper.mdx b/sdks/advanced/api-key-stamper.mdx
index 7131a56a..ab892d55 100644
--- a/sdks/advanced/api-key-stamper.mdx
+++ b/sdks/advanced/api-key-stamper.mdx
@@ -4,7 +4,7 @@ title: "ApiKeyStamper"
## Introduction
-The [`@turnkey/api-key-stamper`](https://www.npmjs.com/package/@turnkey/api-key-stamper) package simplifies the process of using your public/private API keys and passkeys to stamp and approve activity requests for Turnkey's API. This stamping mechanism is central to the API's security, ensuring that each request is authenticated and authorized. For an in-depth understanding of API keys see [this section](/faq#why-do-you-require-a-public--private-key-pair-to-access-turnkey-api).
+The [`@turnkey/api-key-stamper`](https://www.npmjs.com/package/@turnkey/api-key-stamper) package simplifies the process of using your public/private API keys and passkeys to stamp and approve activity requests for Turnkey's API. This stamping mechanism is central to the API's security, ensuring that each request is authenticated and authorized. For an in-depth understanding of API keys see [this section](/reference/faq#why-do-you-require-a-public--private-key-pair-to-access-turnkey-api).
## Installing
diff --git a/embedded-wallets/code-examples/client-side-signing.mdx b/sdks/advanced/client-side-signing.mdx
similarity index 100%
rename from embedded-wallets/code-examples/client-side-signing.mdx
rename to sdks/advanced/client-side-signing.mdx
diff --git a/sdks/advanced/iframe-stamper.mdx b/sdks/advanced/iframe-stamper.mdx
index 65c5ef26..9421ca48 100644
--- a/sdks/advanced/iframe-stamper.mdx
+++ b/sdks/advanced/iframe-stamper.mdx
@@ -6,7 +6,7 @@ title: "IframeStamper"
The [`@turnkey/iframe-stamper`](https://www.npmjs.com/package/@turnkey/iframe-stamper) package, while sharing a similar purpose with the `@turnkey/api-key-stamper`, caters specifically to the unique context of iframes. This package is designed for stamping requests within an iframe, using credentials for Turnkey's API, but operates distinctly from the API key stamper. Unlike the API key stamper, which has direct access to the API private key to compute signatures or stamps directly, the iframe stamper interacts with credentials in a more indirect manner.
-It leverages the `postMessage` communication mechanism to send and receive messages within the iframe, ensuring the credential does not leave its secure environment. This approach is particularly crucial in sensitive flows such as [Email Auth](/authentication/email), and [Key or Wallet Export](/wallets/export-wallets), where heightened security is required. The `@turnkey/iframe-stamper` works in tandem with `@turnkey/http`, facilitating secure and efficient communication in these specific use cases.
+It leverages the `postMessage` communication mechanism to send and receive messages within the iframe, ensuring the credential does not leave its secure environment. This approach is particularly crucial in sensitive flows such as [Email Auth](/features/authentication/email), and [Key or Wallet Export](/features/wallets/export-wallets), where heightened security is required. The `@turnkey/iframe-stamper` works in tandem with `@turnkey/http`, facilitating secure and efficient communication in these specific use cases.
By bridging the gap between the iframe's isolated environment and Turnkey's API, the iframe stamper plays a pivotal role in maintaining the integrity and security of the credential while ensuring seamless operation within the iframe context.
@@ -84,7 +84,7 @@ type TIframeStamperConfig = {
#### Example
-For full example check out the [email-auth](https://github.com/tkhq/sdk/tree/main/examples/email-auth) example in our SDK repo. You should also read up [Email Auth](/authentication/email) for more information on the technical details of how it works.
+For full example check out the [email-auth](https://github.com/tkhq/sdk/tree/main/examples/email-auth) example in our SDK repo. You should also read up [Email Auth](/features/authentication/email) for more information on the technical details of how it works.
## Methods
diff --git a/sdks/advanced/overview.mdx b/sdks/advanced/overview.mdx
new file mode 100644
index 00000000..1cd958d1
--- /dev/null
+++ b/sdks/advanced/overview.mdx
@@ -0,0 +1,17 @@
+---
+title: "Advanced"
+description: "Use Turnkey's low-level http libraries directly"
+sidebarTitle: "Overview"
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
+
+
+
+
+
+
+
+
+
diff --git a/sdks/advanced/turnkey-client.mdx b/sdks/advanced/turnkey-client.mdx
index d33a136e..0f2eeb78 100644
--- a/sdks/advanced/turnkey-client.mdx
+++ b/sdks/advanced/turnkey-client.mdx
@@ -63,7 +63,7 @@ Currently Turnkey provides 3 stampers:
* applications signing requests with API keys should use [`@turnkey/api-key-stamper`](/sdks/advanced/api-key-stamper)
* applications that need to sign requests within an iframe, particularly when handling sensitive operations like Auth, or Key or Wallet Export, should use the [`@turnkey/iframe-stamper`](/sdks/advanced/iframe-stamper).
-You can also implement the TStamper interface yourself. For more information on implementing a custom stamper checkout the [API Design](/developer-reference/api-overview/intro) docs.
+You can also implement the TStamper interface yourself. For more information on implementing a custom stamper checkout the [API Design](/api-reference/overview/intro) docs.
### Types
@@ -97,6 +97,6 @@ const apiPrivateKey = process.env.TURNKEY_API_PRIVATE_KEY;
// Initialize the API key stamper
const stamper = new ApiKeyStamper({ apiPublicKey, apiPrivateKey });
-// Initialize the Turnkey client and then you're ready to use the Turnkey client! 🎉
+// Initialize the Turnkey client and then you're ready to use the Turnkey client.
const client = new TurnkeyClient({ baseUrl }, stamper);
```
diff --git a/sdks/advanced/wallet-stamper.mdx b/sdks/advanced/wallet-stamper.mdx
index 13133d93..649e1d6a 100644
--- a/sdks/advanced/wallet-stamper.mdx
+++ b/sdks/advanced/wallet-stamper.mdx
@@ -168,7 +168,7 @@ const walletStamper = new WalletStamper(new SolanaWallet());
// Instantiate the TurnkeyClient with the WalletStamper
const client = new TurnkeyClient({ baseUrl: BASE_URL }, walletStamper);
-// You're now ready to make requests to Turnkey's API 🎉
+// You're now ready to make requests to Turnkey's API.
```
## Conclusion
diff --git a/sdks/advanced/webauthn-stamper.mdx b/sdks/advanced/webauthn-stamper.mdx
index b4d7921b..de84d53a 100644
--- a/sdks/advanced/webauthn-stamper.mdx
+++ b/sdks/advanced/webauthn-stamper.mdx
@@ -6,7 +6,7 @@ title: "WebauthnStamper"
The [`@turnkey/webauthn-stamper`](https://www.npmjs.com/package/@turnkey/webauthn-stamper) package is used for stamping requests made to Turnkey's API with WebAuthn credentials, but specifically for use with passkeys.
-For more information on passkeys and WebAuthn refer to [this section](/authentication/passkeys/introduction).
+For more information on passkeys and WebAuthn refer to [this section](/features/authentication/passkeys/introduction).
## Installing
@@ -92,7 +92,7 @@ type TWebauthnStamperConfig = {
type UserVerificationRequirement = "discouraged" | "preferred" | "required";
```
-Refer to our guide on [using passkeys](/authentication/passkeys/options#userverification) for more information on this type and its usage.
+Refer to our guide on [using passkeys](/features/authentication/passkeys/options#userverification) for more information on this type and its usage.
##### `PublicKeyCredentialDescriptor`
@@ -104,7 +104,7 @@ interface PublicKeyCredentialDescriptor {
}
```
-Refer to our guide on [using passkeys](/authentication/passkeys/options#allowcredentials) for more information on this type and its usage.
+Refer to our guide on [using passkeys](/features/authentication/passkeys/options#allowcredentials) for more information on this type and its usage.
#### Example
diff --git a/sdks/cli.mdx b/sdks/cli.mdx
deleted file mode 100644
index 0ef0b8da..00000000
--- a/sdks/cli.mdx
+++ /dev/null
@@ -1,113 +0,0 @@
----
-title: "Using the CLI"
-description: "This quickstart will guide you through Turnkey’s onboarding, adding an API key, creating a wallet, and signing your first Ethereum transaction."
-sidebarTitle: "CLI"
----
-
-## Create your Turnkey organization
-
-- Visit [app.turnkey.com/dashboard/auth/initial](https://app.turnkey.com/dashboard/auth/initial) and enter your email address
-- Confirm your email by clicking on the link inside of the confirmation email
-- Follow the prompts to add your first authenticator and create your organization
-
-## Find your organization ID
-
-All API requests require an organization ID. Yours can be located in the user dropdown menu at the top right corner of the dashboard.
-
-
-
-
-
-For convenience, it's worth setting this as a permanent shell variable:
-
-```bash
-export ORGANIZATION_ID=""
-```
-
-## Add an API key
-
-Turnkey API Keys are generic public / private key pairs that allow you to make requests to our API. To generate a new key pair, we'll use the Turnkey CLI.
-
-#### Installing `turnkey`
-
-```bash
-brew install tkhq/tap/turnkey
-```
-
-We are employing [Homebrew](https://brew.sh/) in this guide as a quick and easy install path. For an installation path that **requires no trust in external parties**, refer to our [CLI repo](https://github.com/tkhq/tkcli).
-
-#### Generate an API key
-
-```bash
-turnkey generate api-key --organization $ORGANIZATION_ID --key-name quickstart
-```
-
-When you run this command, Turnkey’s CLI generates an API key pair and **stores the API private key locally**. Copy the `publicKey` field in the output. In the next step, we'll add this to our User.
-
-#### Add your public API key
-
-Navigate to your user page by clicking on "User Details" in the user dropdown menu.
-
-
-
-
-
-Click on "Create API keys" and follow the prompts to add the generated public API key. You'll be required to authenticate with the same authenticator used during onboarding. After this succeeds, you should be all set to interact with our API.
-
-NOTES:
-
-- if you would like to manually copy your locally stored public/private API key files (e.g. `key.public`, `key.private`), you will have to save the files without newlines (which occupy extra bytes). For example, for VIM, use `:set binary noeol` or `:set binary noendofline` before writing.
-- only P-256 keys (API_KEY_CURVE_P256) are currently supported
-
-## Create a wallet
-
-Wallets are collections of cryptographic key pairs typically used for sending and receiving digital assets. To create one, we need to provide a name:
-
-```bash
-turnkey wallets create --name default --key-name quickstart
-```
-
-## Create an Ethereum account
-
-To create a cryptographic key pair on our new Wallet, we need to pass our desired address format:
-
-```bash
-turnkey wallets accounts create --wallet default --address-format ADDRESS_FORMAT_ETHEREUM --key-name quickstart
-```
-
-This command will produce an Ethereum address (e.g. `0x08cb1216C95149DF66978b574E484869512CE2bF`) that we'll need to sign a transaction. You can see your new Wallet account with:
-
-```bash
-turnkey wallets accounts list --wallet default --key-name quickstart
-```
-
-## Sign a transaction
-
-Now you can sign an Ethereum transaction with this new address with our [`sign_transaction` endpoint](/api-reference/signing/sign-transaction). Make sure to replace the `unsignedTransaction` below with your own. You can use our [simple transaction generator](https://build.tx.xyz) if you need a quick transaction for testing:
-
-```json
-turnkey request --path /public/v1/submit/sign_transaction --body '{
- "timestampMs": "'"$(date +%s)"'000",
- "type": "ACTIVITY_TYPE_SIGN_TRANSACTION_V2",
- "organizationId": "'"$ORGANIZATION_ID"'",
- "parameters": {
- "type": "TRANSACTION_TYPE_ETHEREUM",
- "signWith": "",
- "unsignedTransaction": ""
- }
-}' --key-name quickstart
-```
-
-If you'd like to broadcast your transaction, you can easily do so via [Etherscan](https://etherscan.io/pushTx).
-
-## Next steps
-
-- Check out our [examples](/getting-started/examples) to see what can be built
-- Learn more about [Organizations](/concepts/organizations) and [Wallets](/concepts/wallets)
-- See our [API design](/developer-reference/api-overview/intro) or dive into our [API reference](/api-reference/overview)
diff --git a/sdks/flutter/index.mdx b/sdks/flutter/index.mdx
deleted file mode 100644
index 8816f50b..00000000
--- a/sdks/flutter/index.mdx
+++ /dev/null
@@ -1,62 +0,0 @@
----
-title: "Overview"
-description: "Turnkey's Flutter SDK [`(turnkey_sdk_flutter)`](https://pub.dev/packages/turnkey_sdk_flutter) is the easiest way to integrate Turnkey’s Embedded Wallets into your Flutter applications. It supports both backendless setups via Turnkey’s managed [Auth Proxy](https://docs.turnkey.com/reference/auth-proxy) and traditional backend-based architectures. It provides a set of functions and utilities to interact with Turnkey's APIs, a powerful session management system, built-in stampers, and a raw HTTP client for advanced use cases."
-sidebarTitle: "Overview"
----
-
-Find `turnkey_sdk_flutter` on [pub.dev](https://pub.dev/packages/turnkey_sdk_flutter) or view the source code on [GitHub](https://github.com/tkhq/dart-sdk)!
-
-
-
-
- The initial setup guide for integrating Turnkey's Flutter SDK into your app.
-
-
- Learn how to set up authentication that leverages Turnkey's Auth Proxy, enabling fast and secure user authentication in your Flutter app.
-
-
- Discover how to create and manage embedded wallets in your Flutter
- application, including wallet creation, account derivation, and more.
-
-
-
- Learn how to sign transactions and messages in your Flutter app using
- Turnkey's Embedded Wallets.
-
-
-
- Learn how to customize the sub-organization settings in your Flutter app,
- including wallet creation options and default usernames for different
- authentication methods.
-
-
\ No newline at end of file
diff --git a/sdks/flutter/landing.mdx b/sdks/flutter/landing.mdx
deleted file mode 100644
index 1b316755..00000000
--- a/sdks/flutter/landing.mdx
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: "Flutter"
-description: "Turnkey's Flutter SDK [`(turnkey_sdk_flutter)`](https://pub.dev/packages/turnkey_sdk_flutter) is the easiest way to integrate Turnkey's Embedded Wallets into your Flutter applications, no backend required. It provides a set of functions and utilities to interact with Turnkey's APIs, a powerful session management system, built-in stampers, and a raw HTTP client for advanced use cases."
-sidebarTitle: "Flutter"
----
-
-Head over to the [Getting Started](/sdks/flutter/getting-started) guide to set up your Flutter app with Turnkey's Embedded Wallets.
diff --git a/sdks/introduction.mdx b/sdks/introduction.mdx
index 2674a2eb..38b02e55 100644
--- a/sdks/introduction.mdx
+++ b/sdks/introduction.mdx
@@ -8,35 +8,35 @@ The following SDK reference tables separate our SDKs by Client and Server. The c
A checkmark in the table indicates that the SDK provides either a complete implementation for a feature or helper methods exist and can be composed in a few lines of code to implement a workflow. If no checkmark is present it means the SDK does not offer support for that feature.
-Turnkey also has several [wrappers for popular web3 libraries](/category/web3-libraries) to streamline integration into existing dApps.
+Turnkey also has several [wrappers for popular web3 libraries](/sdks/web3/overview) to streamline integration into existing dApps.
## Client side SDKs
-| | TypeScript | React | React Native | Flutter | iOS | Android |
+| | [TypeScript](/solutions/embedded-wallets/integration-guide/typescript/index) | [React](/solutions/embedded-wallets/integration-guide/react/index) | [React Native](/solutions/embedded-wallets/integration-guide/react-native/overview) | [Flutter](/solutions/embedded-wallets/integration-guide/flutter/index) | [Swift](/solutions/embedded-wallets/integration-guide/swift/overview) | [Kotlin](/solutions/embedded-wallets/integration-guide/kotlin/overview) |
|-------------------------------|-----------------------------------------------|-----------------------------------------------|-----------------------------------------------|-----------------------------------------------|-----------------------------------------------| ----------------------------------------------|
| **Authentication** | | | | | |
-| Email | | | | | | |
-| SMS | | | | | | |
-| Passkey | | | | | | |
-| Google | | | | | | |
-| Facebook | | | | | | |
-| Apple | | | | | | |
-| Discord | | | | | | |
-| X (Twitter) | | | | | | |
-| Web3 Wallets | | | | | |
+| Email | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| SMS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Passkey | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Google | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Facebook | ✓ | ✓ | ✓ | | | |
+| Apple | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Discord | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| X (Twitter) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Web3 Wallets | ✓ | ✓ | | | |
| **Embedded Wallets** | | | | | |
-| Wallet Creation | | | | | | |
-| Signing | | | | | | |
-| Import | | | | | | |
-| Export | | | | | | |
+| Wallet Creation | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Signing | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Import | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Export | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| **Arbitrary Request Signing** | | | | | |
-| Stamping | | | | | | |
+| Stamping | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
## Server side SDKs
-| | TypeScript | Go | Ruby | Rust | Python |
-|---------------------|------------|-----|------|------|--------|
-| **Authentication** | | | | | |
-| **Wallet Management** | | | | | |
-| **Policy Management** | | | | | |
+| | [TypeScript](/solutions/company-wallets/integration-guide/javascript-server) | [Go](/solutions/company-wallets/integration-guide/golang) | [Ruby](/solutions/company-wallets/integration-guide/ruby) | [Rust](/solutions/company-wallets/integration-guide/rust) | [Python](/solutions/company-wallets/integration-guide/python) |
+|---------------------|---------------------------------------|--------------------|--------------------|--------------------|-----------------------|
+| **Authentication** | ✓ | ✓ | ✓ | ✓ | ✓ |
+| **Wallet Management** | ✓ | ✓ | ✓ | | |
+| **Policy Management** | ✓ | ✓ | ✓ | | |
diff --git a/sdks/kotlin.mdx b/sdks/kotlin.mdx
deleted file mode 100644
index fba8d85a..00000000
--- a/sdks/kotlin.mdx
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "Turnkey Kotlin SDK"
-sidebarTitle: "Android"
-description: "This documentation contains guides for using Turnkey's [Kotlin packages](https://github.com/tkhq/kotlin-sdk/tree/main/packages)."
----
-
-Using these packages combined will help you create a fully-featured Android app, powered by Turnkey.
-
-## Packages
-
-| Package Name | Description | Link |
-| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ |
-| com.turnkey.sdk-kotlin | A high-level Kotlin SDK that simplifies the integration of the Turnkey API into Android applications. It provides secure session management, authentication, and embedded wallet management operations | [com.turnkey.sdk-kotlin](https://github.com/tkhq/kotlin-sdk/tree/main/packages/sdk-kotlin) |
-| com.turnkey.http | A lower-level, fully typed HTTP client for interacting with the Turnkey API. | [com.turnkey.http](https://github.com/tkhq/kotlin-sdk/tree/main/packages/http) |
-| com.turnkey.types | This package contains common types used across Turnkey's Kotlin packages. | [com.turnkey.types](https://github.com/tkhq/kotlin-sdk/tree/main/packages/types) |
-| com.turnkey.stamper | A Kotlin package for API & passkey stamping functionalities. It is meant to be used alongside Turnkey's Kotlin HTTP package. | [com.turnkey.stamper](https://github.com/tkhq/kotlin-sdk/tree/main/packages/stamper) |
-| com.turnkey.passkey | A Kotlin package for stamping payloads with passkeys. It is meant to be used with Turnkey's Kotlin HTTP package. | [com.turnkey.passkey](https://github.com/tkhq/kotlin-sdk/tree/main/packages/passkey) |
-| com.turnkey.crypto | This package consolidates common cryptographic utilities used across our applications, particularly primitives related to keys, encryption, and decryption in a pure Kotlin implementation. | [com.turnkey.crypto](https://github.com/tkhq/kotlin-sdk/tree/main/packages/crypto) |
-| com.turnkey.encoding | This package contains decoding and encoding functions used by other Turnkey packages. | [com.turnkey.encoding](https://github.com/tkhq/kotlin-sdk/tree/main/packages/encoding) |
-
-## Getting started
-
-The easiest way to build an Android app with Turnkey is to use our [Kotlin demo wallet](https://github.com/tkhq/kotlin-sdk/tree/main/examples/kotlin-demo-wallet) as a starter. This app is a fully-featured example that demonstrates how to use the Turnkey's Kotlin SDK to authenticate users, create wallets, export wallets, sign messages, and more.
-
-#### For a complete guide on how to use all the ins and outs of the Kotlin SDK, check out the [Getting Started](/sdks/kotlin/getting-started) section.
\ No newline at end of file
diff --git a/sdks/kotlin/authentication/overview.mdx b/sdks/kotlin/authentication/overview.mdx
deleted file mode 100644
index f3de1f63..00000000
--- a/sdks/kotlin/authentication/overview.mdx
+++ /dev/null
@@ -1,64 +0,0 @@
----
-title: "Overview"
-description: "Learn how to set up, log in, or sign up easily in your Android app using the Turnkey Kotlin SDK."
-sidebarTitle: "Overview"
----
-
-The Kotlin SDK makes authentication simple.
-You can call specific login and signup functions to create your own UI components and authentication flow.
-
-## Authentication state
-
-To check if a user is authenticated, you can use the `authState` variable from the `TurnkeyContext`.
-
-```kotlin
-val authState: AuthState = TurnkeyContext.authState.value
-```
-
-## Customize sub-organization creation
-
-Need to configure default user names, passkey names, wallet creations or anything sub-org related?
-You can learn more about customizing the sub-orgs you create in the [Sub-Organization Customization](/sdks/kotlin/sub-organization-customization) section.
-
-Follow the guides below to learn how to set up email and SMS authentication, passkey authentication, and social logins in your Android app.
-
-
-
- Learn how to set up email and SMS authentication in your Android app.
-
-
- Learn how to set up passkey authentication in your Android app.
-
-
- Discover how to create and manage social logins in your Kotlin
- application, including wallet creation, account derivation, and more.
-
-
- Learn how to set up the relying party ID (rpId) for passkey authentication in your Android app.
-
-
-
\ No newline at end of file
diff --git a/sdks/kotlin/landing.mdx b/sdks/kotlin/landing.mdx
deleted file mode 100644
index 995d14c5..00000000
--- a/sdks/kotlin/landing.mdx
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: "Kotlin"
-description: "Turnkey's Kotlin SDK is the easiest way to integrate Turnkey's Embedded Wallets into your Android applications, no backend required. It provides a set of functions and utilities to interact with Turnkey's APIs, a powerful session management system, built-in stampers, and a raw HTTP client for advanced use cases."
-sidebarTitle: "Kotlin"
----
-
-Head over to the [Getting Started](/sdks/kotlin/getting-started) guide to set up your Android app with Turnkey's Embedded Wallets.
\ No newline at end of file
diff --git a/sdks/kotlin/overview.mdx b/sdks/kotlin/overview.mdx
deleted file mode 100644
index 6ed1354e..00000000
--- a/sdks/kotlin/overview.mdx
+++ /dev/null
@@ -1,62 +0,0 @@
----
-title: "Overview"
-description: "Turnkey's Kotlin SDK is the easiest way to integrate Turnkey's Embedded Wallets into your Android applications. It supports both backendless setups via Turnkey’s managed [Auth Proxy](https://docs.turnkey.com/reference/auth-proxy) and traditional backend-based architectures. It provides easy-to-use functions accessible through a context provider, allowing you to quickly build secure embedded wallet experiences."
-sidebarTitle: "Overview"
----
-
-Find Turnkey's `kotlin-sdk` on [Maven Central](https://central.sonatype.com/artifact/com.turnkey/sdk-kotlin) or view the source code on [GitHub](https://github.com/tkhq/kotlin-sdk).
-
-
-
- The initial setup guide for integrating Turnkey into your Android app.
-
-
- Learn how to set up authentication that leverages Turnkey's Auth Proxy, enabling fast and secure user authentication in your Android app.
-
-
- Discover how to create and manage embedded wallets in your Kotlin
- application, including wallet creation, account derivation, and more.
-
-
-
- Learn how to sign transactions and messages in your Android app using
- Turnkey's Embedded Wallets.
-
-
-
- Learn how to customize the sub-organization settings in your Android app,
- including wallet creation options and default usernames for different
- authentication methods.
-
-
-
\ No newline at end of file
diff --git a/sdks/react-native.mdx b/sdks/react-native.mdx
deleted file mode 100644
index 0dfcaecc..00000000
--- a/sdks/react-native.mdx
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "React Native"
-description: "Turnkey's React Native SDK offerings provide a powerful way to integrate Turnkey's Embedded Wallets into your React Native applications. With features like secure authentication, wallet management, and transaction signing, you can build seamless wallet experiences directly in your mobile apps."
-sidebarTitle: "React Native"
----
-
-## @turnkey/react-native-wallet-kit
-
-The `@turnkey/react-native-wallet-kit` is a powerful SDK that allows you to integrate Turnkey's Embedded Wallets into your React Native applications. It provides a set of UI components and easy-to-use functions, all exported from a hook, enabling you to quickly build secure embedded wallet experiences. It is built on top of the `@turnkey/core` SDK.
-
-Head over to the [Getting Started](/sdks/react-native/overview) guide to set up your React Native app with Turnkey's Embedded Wallets, or explore the [example app](https://github.com/tkhq/sdk/tree/main/examples/with-react-native-wallet-kit) for a working reference implementation.
-
-## @turnkey/sdk-react-native (LEGACY)
-
-`@turnkey/sdk-react-native` is our legacy React Native SDK, which is still available for use but is not recommended for new projects.
-
-If you're starting a new project, we recommend using `@turnkey/react-native-wallet-kit` instead.
diff --git a/sdks/react-native/overview.mdx b/sdks/react-native/overview.mdx
deleted file mode 100644
index e28d6e92..00000000
--- a/sdks/react-native/overview.mdx
+++ /dev/null
@@ -1,62 +0,0 @@
----
-title: "Overview"
-description: "Turnkey's Embedded Wallet Kit [`(@turnkey/react-native-wallet-kit)`](https://www.npmjs.com/package/@turnkey/react-native-wallet-kit) is the easiest way to integrate Turnkey’s Embedded Wallets into your React Native applications. It supports both backendless setups via Turnkey’s managed [Auth Proxy](https://docs.turnkey.com/reference/auth-proxy) and traditional backend-based architectures. Built on [`@turnkey/core`](https://www.npmjs.com/package/@turnkey/core), it provides easy-to-use functions exported from a hook, allowing you to quickly build secure embedded wallet experiences."
-sidebarTitle: "Overview"
----
-
-Find `@turnkey/react-native-wallet-kit` on [npm](https://www.npmjs.com/package/@turnkey/react-native-wallet-kit) or view the source code on [GitHub](https://github.com/tkhq/sdk/tree/main/packages/react-native-wallet-kit)!
-
-
-
- The initial setup guide for integrating the Embedded Wallet Kit into your React Native app.
-
-
- Learn how to set up authentication that leverages Turnkey's Auth Proxy, enabling fast and secure user authentication in your React Native app.
-
-
- Discover how to create and manage embedded wallets in your React Native
- application, including wallet creation, account derivation, and more.
-
-
-
- Learn how to sign transactions and messages in your React Native app using
- Turnkey's Embedded Wallets.
-
-
-
- Learn how to customize the sub-organization settings in your React Native app,
- including wallet creation options and default usernames for different
- authentication methods.
-
-
-
diff --git a/sdks/react/index.mdx b/sdks/react/index.mdx
deleted file mode 100644
index ac5329c1..00000000
--- a/sdks/react/index.mdx
+++ /dev/null
@@ -1,118 +0,0 @@
----
-title: "Overview"
-description: "Turnkey's Embedded Wallet Kit [`(@turnkey/react-wallet-kit)`](https://www.npmjs.com/package/@turnkey/react-wallet-kit) is the easiest way to integrate Turnkey’s Embedded Wallets into React applications. It supports both backendless setups via Turnkey’s managed [Auth Proxy](https://docs.turnkey.com/reference/auth-proxy) and traditional backend-based architectures. Built on [`@turnkey/core`](https://www.npmjs.com/package/@turnkey/core), it provides a set of UI components and easy-to-use functions, all exported from a hook, allowing you to quickly build secure embedded wallet experiences."
-sidebarTitle: "Overview"
----
-
-
-Find `@turnkey/react-wallet-kit` on [npm](https://www.npmjs.com/package/@turnkey/react-wallet-kit) or view the source code on [GitHub](https://github.com/tkhq/sdk/tree/main/packages/react-wallet-kit)!
-
-
-
-
- The initial setup guide for integrating the Embedded Wallet Kit into your React app.
-
-
- Learn how to set up authentication that leverages Turnkey's Auth Proxy, enabling fast and secure user authentication in your React app.
-
-
- Discover how to create and manage embedded wallets in your React
- application, including wallet creation, account derivation, and more.
-
-
-
- Learn how to use external wallets alongside your embedded wallets in your
- React app using Turnkey's abstractions.
-
-
-
- Learn how to sign transactions and messages in your React app using Turnkey's
- Embedded Wallets or an external "browser" wallet.
-
-
-
- Customize the look and feel of the modals in your React app using the provided
- UI components.
-
-
-
- Learn how to customize the sub-organization settings in your React app,
- including wallet creation options and default usernames for different
- authentication methods.
-
-
-
- Explore how to make advanced API requests to Turnkey's infrastructure. This
- will help you build more complex features and functionalities in your app that
- go beyond what is included as helper functions in the SDK.
-
-
- Learn how to set up authentication using your backend and the Embedded Wallet
- Kit.
-
-
- Find solutions to common issues and errors you might encounter while using the
- Embedded Wallet Kit in your React application.
-
-
-
diff --git a/sdks/react/landing.mdx b/sdks/react/landing.mdx
deleted file mode 100644
index 6bd19770..00000000
--- a/sdks/react/landing.mdx
+++ /dev/null
@@ -1,19 +0,0 @@
----
-title: "React"
-description: "Turnkey's React SDK offerings provide a powerful way to integrate Turnkey's Embedded Wallets into your React applications. With features like secure authentication, wallet management, and transaction signing, you can build seamless wallet experiences directly in your React apps."
-sidebarTitle: "React"
----
-
-## @turnkey/react-wallet-kit
-
-The `@turnkey/react-wallet-kit` is a powerful SDK that allows you to integrate Turnkey's Embedded Wallets into your React applications. It provides a set of UI components and easy-to-use functions, all exported from a hook, enabling you to quickly build secure embedded wallet experiences. This is our latest React SDK, currently in beta, and it is built on top of the `@turnkey/core` SDK.
-
-Head over to the [Getting Started](/sdks/react/getting-started) guide to set up your React app with Turnkey's Embedded Wallets, explore the [example app](https://github.com/tkhq/sdk/tree/main/examples/react-wallet-kit) for a working reference implementation, or try the [live demo](https://wallets.turnkey.com).
-
-## @turnkey/sdk-react (LEGACY)
-
-`@turnkey/sdk-react` is our legacy React SDK, which is still available for use but is not recommended for new projects. It is built off `@turnkey/sdk-browser` and provides direct integration with Turnkey's API into React applications.
-
-This package will soon be discontinued, if you're starting a new project, we recommend using the `@turnkey/react-wallet-kit` instead.
-
-For more information on `@turnkey/sdk-react`, see the [Legacy Guide](/sdks/react/legacy).
diff --git a/sdks/swift.mdx b/sdks/swift.mdx
deleted file mode 100644
index 9916f7b1..00000000
--- a/sdks/swift.mdx
+++ /dev/null
@@ -1,14 +0,0 @@
----
-title: Turnkey Swift SDK
-sidebarTitle: "iOS"
-description: "This documentation contains guides for using the [Turnkey Swift SDK](https://github.com/tkhq/swift-sdk)."
----
-
-
-
- Using the Proxy Middleware from the Turnkey Swift SDK
-
-
- Register Passkey
-
-
diff --git a/sdks/swift/landing.mdx b/sdks/swift/landing.mdx
deleted file mode 100644
index 02ad077c..00000000
--- a/sdks/swift/landing.mdx
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: "Swift"
-description: "Turnkey's Swift SDK is the easiest way to integrate Turnkey's Embedded Wallets into your Swift applications, no backend required. It provides a set of functions and utilities to interact with Turnkey's APIs, a powerful session management system, built-in stampers, and a raw HTTP client for advanced use cases."
-sidebarTitle: "Swift"
----
-
-Head over to the [Getting Started](/sdks/swift/getting-started) guide to set up your Swift app with Turnkey's Embedded Wallets.
\ No newline at end of file
diff --git a/sdks/swift/overview.mdx b/sdks/swift/overview.mdx
deleted file mode 100644
index 2fb65f58..00000000
--- a/sdks/swift/overview.mdx
+++ /dev/null
@@ -1,61 +0,0 @@
----
-title: "Overview"
-description: "Turnkey Swift SDK makes it simple to integrate Turnkey-powered embedded wallets into your native Swift app. It supports both backendless setups via Turnkey’s managed [Auth Proxy](https://docs.turnkey.com/reference/auth-proxy) and traditional backend-based architectures."
-sidebarTitle: "Overview"
----
-
-Find the Turnkey Swift SDK on [GitHub](https://github.com/tkhq/swift-sdk).
-
-
-
- Set up your Swift project with Swift Package Manager, configure the SDK, and
- prepare your app for development.
-
-
- Learn how to set up authentication that leverages Turnkey's Auth Proxy,
- enabling fast and secure user authentication in your Swift app.
-
-
- Discover how to create and manage embedded wallets in your Swift
- application, including wallet creation, account derivation, and more.
-
-
- Learn how to sign transactions and messages in your Swift app using Turnkey
- sessions.
-
-
- Learn how to customize the sub-organization settings in your Swift app,
- including wallet creation options and default usernames for different
- authentication methods.
-
-
diff --git a/sdks/swift/proxy-middleware.mdx b/sdks/swift/proxy-middleware.mdx
index 2d60f0de..b08c9005 100644
--- a/sdks/swift/proxy-middleware.mdx
+++ b/sdks/swift/proxy-middleware.mdx
@@ -22,9 +22,9 @@ This initializer configures the `TurnkeyClient` to route all requests through th
This setup is especially useful for operations like:
-* Email [authentication](/authentication/email)
-* Wallet [import](/wallets/import-wallets) & [export](/wallets/export-wallets)
-* [Sub-organization creation](/concepts/sub-organizations#creating-sub-organizations)
+* Email [authentication](/features/authentication/email)
+* Wallet [import](/features/wallets/import-wallets) & [export](/features/wallets/export-wallets)
+* [Sub-organization creation](/features/sub-organizations#creating-sub-organizations)
## Request header
diff --git a/sdks/swift/register-passkey.mdx b/sdks/swift/register-passkey.mdx
index 916a4202..1949c721 100644
--- a/sdks/swift/register-passkey.mdx
+++ b/sdks/swift/register-passkey.mdx
@@ -61,7 +61,7 @@ import TurnkeySDK // Import TurnkeySDK to use TurnkeyClient
-Create an instance of `PasskeyManager`, providing the [Relying Party Identifier](/authentication/passkeys/options#rp) and the [presentation anchor]().
+Create an instance of `PasskeyManager`, providing the [Relying Party Identifier](/features/authentication/passkeys/options#rp) and the [presentation anchor]().
```swift ViewController.swift
class ViewController: UIViewController {
@@ -282,7 +282,7 @@ let disableOtpEmailAuth = false
- You can find more information about the optional parameters in the [Organization Features](/concepts/organizations#features) section of the documentation.
+ You can find more information about the optional parameters in the [Organization Features](/features/organizations#features) section of the documentation.
diff --git a/sdks/typescript-frontend/index.mdx b/sdks/typescript-frontend/index.mdx
deleted file mode 100644
index 27373995..00000000
--- a/sdks/typescript-frontend/index.mdx
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: "Overview"
-description: "`@turnkey/core` is the core TypeScript client-side SDK for Turnkey's Embedded Wallets. It provides a set of functions and utilities to interact with Turnkey's APIs, a powerful session management system, built-in stampers, and a raw HTTP client for advanced use cases. This SDK is designed to be used as a foundation for building Turnkey's Embedded Wallets in various frontend frameworks, including React, React-native (alpha), Angular, Vue, and Svelte. If you're using React, please consider using the [`@turnkey/react-wallet-kit`](/sdks/react/) for a more tailored experience."
-sidebarTitle: "Overview"
----
-
-
-
- Learn how to set up `@turnkey/core` in your frontend JavaScript application. This page will guide you through creating a Turnkey organization, configuring authentication, installing the SDK, and initializing the client.
-
-
-
- Learn how to set up log in or sign up using @turnkey/core in your frontend
- JavaScript application.
-
-
-
- Learn how to setup authentication using your backend and `@turnkey/core`
-
-
-
- Learn how to make advanced API requests to Turnkey's infrastructure.
-
-
-
diff --git a/sdks/typescript-frontend/landing.mdx b/sdks/typescript-frontend/landing.mdx
deleted file mode 100644
index c63748fd..00000000
--- a/sdks/typescript-frontend/landing.mdx
+++ /dev/null
@@ -1,19 +0,0 @@
----
-title: "TypeScript | Frontend"
-description: "Turnkey provides a TypeScript SDK for building secure embedded wallet experiences in frontend applications. This SDK is designed to be used as a foundation for building Turnkey's Embedded Wallets in various frontend frameworks, including React, Angular, Vue, and Svelte."
-sidebarTitle: "TypeScript | Frontend"
----
-
-## @turnkey/core
-
-`@turnkey/core` is the core TypeScript client-side SDK for Turnkey's Embedded Wallets. It provides a set of functions and utilities to interact with Turnkey's APIs, a powerful session management system, built-in stampers, and a raw HTTP client for advanced use cases. This SDK is designed to be used as a foundation for building Turnkey's Embedded Wallets in various frontend frameworks, including React, React-native (alpha), Angular, Vue, and Svelte. If you're using React, please consider using the [`@turnkey/react-wallet-kit`](/sdks/react/) for a more tailored experience.
-
-Head over to the [Getting Started](/sdks/typescript-frontend/getting-started) guide to set up your app with Turnkey's Embedded Wallets.
-
-## @turnkey/sdk-browser (LEGACY)
-
-`@turnkey/sdk-browser` is our legacy browser SDK, which is still available for use but is not recommended for new projects.
-
-This package will soon be discontinued, if you're starting a new project, we recommend using the `@turnkey/react-wallet-kit` or `@turnkey/core` instead.
-
-For more information on `@turnkey/sdk-browser`, see the [Legacy Guide](/sdks/typescript-frontend/legacy).
diff --git a/sdks/web3/gas-station.mdx b/sdks/web3/gas-station.mdx
index 6e7ff106..c53abccd 100644
--- a/sdks/web3/gas-station.mdx
+++ b/sdks/web3/gas-station.mdx
@@ -1,11 +1,11 @@
---
-title: "Gas Station SDK"
+title: "Gas station SDK"
description: "An SDK for implementing gasless transactions using EIP-7702, Turnkey wallet management, and your own paymaster."
mode: wide
---
- Looking for a turnkey solution? If you don't want to build your own paymaster, Turnkey's native Transaction Management handles gas sponsorship for both EVM and Solana out of the box. See the [Transaction Management](/concepts/transaction-management) overview to get started.
+ Looking for a turnkey solution? If you don't want to build your own paymaster, Turnkey's native Transaction Management handles gas sponsorship for both EVM and Solana out of the box. See the [Transaction Management](/features/transaction-management) overview to get started.
The Gas Station SDK enables you to implement gasless transactions using EIP-7702 delegation and EIP-712 signed intents. This SDK is designed to work with Turnkey-managed paymaster wallets within your organization, allowing you to sponsor transactions for your users so they can execute transactions without needing ETH for gas fees.
diff --git a/sdks/web3/overview.mdx b/sdks/web3/overview.mdx
new file mode 100644
index 00000000..1c1b1790
--- /dev/null
+++ b/sdks/web3/overview.mdx
@@ -0,0 +1,18 @@
+---
+title: "Web3 libraries"
+description: "Turnkey Web3 libraries"
+mode: wide
+sidebarTitle: "Overview"
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
+
+
+
+
+
+
+
+
+
diff --git a/wallets/wagmi.mdx b/sdks/web3/wagmi.mdx
similarity index 99%
rename from wallets/wagmi.mdx
rename to sdks/web3/wagmi.mdx
index 20501a68..f9e394e4 100644
--- a/wallets/wagmi.mdx
+++ b/sdks/web3/wagmi.mdx
@@ -3,8 +3,6 @@ title: Integrating an embedded wallet with Wagmi
---
-# Introduction
-
Turnkey wallets are embedded, web-based wallets that differ from injected wallets (like MetaMask).
While injected wallets store private keys locally and decrypt them using a password to sign transactions,
embedded wallets rely on UI-based authentication to access private keys that are securely stored and
@@ -358,7 +356,7 @@ At this point you can:
2. Integrate the minimal provider + connector in a dApp.
3. Click **Connect Wallet** in the dApp → the pop-up opens → authenticate → dApp receives the account.
-🎉 You now have a working end-to-end connection flow! Next we'll extend both the wallet UI and the provider to support signing transactions and messages.
+You now have a working end-to-end connection flow. Next we'll extend both the wallet UI and the provider to support signing transactions and messages.
## Add transaction and message signing
diff --git a/security/enclave-secure-channels.mdx b/security/enclave-secure-channels.mdx
index 041bfa3a..f6394e8b 100644
--- a/security/enclave-secure-channels.mdx
+++ b/security/enclave-secure-channels.mdx
@@ -1,6 +1,6 @@
---
title: "Enclave to end-user secure channels"
-sidebarTitle: "Enclave Secure Channels"
+sidebarTitle: "Enclave secure channels"
---
Turnkey does not trust anything running outside of secure enclaves. See [our approach](/security/our-approach) for more details. When enclaves and end-users need to exchange private information, we rely on a protocol based on [HPKE](https://datatracker.ietf.org/doc/html/rfc9180) to establish a **secure channel**.
diff --git a/security/non-custodial-key-mgmt.mdx b/security/non-custodial-key-mgmt.mdx
index 0a6d5e02..b77155fe 100644
--- a/security/non-custodial-key-mgmt.mdx
+++ b/security/non-custodial-key-mgmt.mdx
@@ -16,4 +16,4 @@ Turnkey does not store unencrypted private keys, but rather persists encrypted p
## Non-custodial wallets for end users
-In a wallet-as-a-service implementation model, it is possible for you, as a Turnkey customer, to configure your organization in a way that limits access to your end users’ funds and private keys. When a new end user signs up to your app, you will need to create a separate Turnkey sub-organization, user, and private key for that end user, accessible only by the end user’s secret (e.g., API key or Passkey credentials). With this implementation, only your end user will be able to authorize Turnkey to process a signature request by providing their secret. Use of the private key is limited to the end user via their secret. When a signature request is initiated by the end user’s secret, Turnkey’s functionality is limited to processing the request based on any policy rules that have been set, and returning the signed transaction to you for broadcast on chain.
+In a wallet-as-a-service implementation model, it is possible for you, as a Turnkey customer, to configure your organization in a way that limits access to your end users’ funds and private keys. When a new end user signs up to your app, you will need to create a separate Turnkey sub-organization, user, and private key for that end user, accessible only by the end user’s secret (e.g., API key or Passkey credentials). With this implementation, only your end user will be able to authorize Turnkey to process a signature request by providing their secret. Use of the private key is limited to the end user via their secret. When a signature request is initiated by the end user’s secret, Turnkey’s functionality is limited to processing the request based on any policy rules that have been set, and returning the signed transaction to you for broadcast onchain.
diff --git a/security/overview.mdx b/security/overview.mdx
new file mode 100644
index 00000000..849399e8
--- /dev/null
+++ b/security/overview.mdx
@@ -0,0 +1,30 @@
+---
+title: Security & architecture
+sidebarTitle: Overview
+description: "Learn how Turnkey achieves innovative, cloud scale, no single point of failure security."
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
+Turnkey is the first verifiable key management system of its kind, securing millions of wallets and private keys for a wide variety of use cases.
+Turnkey's security architecture ensures that raw private keys are never exposed to Turnkey, your software, or your team.
+We provide end-to-end private key generation and access control within secure enclaves, with strong isolation guarantees and
+cryptographic attestation proving that only authorized code is running. Our custom-built operating system, QuorumOS,
+minimizes attack surface and enables reproducible, auditable deployments. From hardware-backed trust to multi-factor access controls,
+every layer of Turnkey's architecture is designed to be secure, verifiable, and developer-friendly by default. Our whitepaper covers our
+holistic security model in-depth, and speaks to our vision for building verifiable key management infrastructure. Learn more about our approach to security here.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/products/company-wallets/features/security/remote-attestation.mdx b/security/remote-attestation.mdx
similarity index 100%
rename from products/company-wallets/features/security/remote-attestation.mdx
rename to security/remote-attestation.mdx
diff --git a/security/shared-responsibility-model.mdx b/security/shared-responsibility-model.mdx
index d9044641..4022336e 100644
--- a/security/shared-responsibility-model.mdx
+++ b/security/shared-responsibility-model.mdx
@@ -2,7 +2,6 @@
title: "Turnkey shared responsibility model"
---
-# Introduction
When integrating your product with Turnkey, it is critical to understand which security tasks are Turnkey’s responsibility, and which tasks are your responsibility.
Turnkey provides secure, scalable, and programmable crypto infrastructure. Flexibility is at the core of our product, which means you have the freedom to integrate Turnkey in ways that may or may not fully meet your product’s security requirements. As detailed below, you are responsible for securing both your Turnkey organization, and your integration with Turnkey.
diff --git a/security/turnkey-verified.mdx b/security/turnkey-verified.mdx
index 57064277..2b84abe1 100644
--- a/security/turnkey-verified.mdx
+++ b/security/turnkey-verified.mdx
@@ -2,7 +2,7 @@
title: "Turnkey Verified"
---
-Turnkey Verified is a new feature launched in Turnkey's [dashboard](https://app.turnkey.com) and [Embedded Wallet Kit](/reference/embedded-wallet-kit).
+Turnkey Verified is a new feature launched in Turnkey's [dashboard](https://app.turnkey.com) and [Embedded Wallet Kit](/solutions/embedded-wallets/integration-guide/react/getting-started).
As outlined in our [Whitepaper](https://whitepaper.turnkey.com/foundations#boot-proofs-and-app-proofs), Turnkey deploys software in secure enclaves and can remotely attest to the software running inside of them. We've done this since day one, internally: remote attestations are at the core of our deployment process and are a crucial tool to ensure Turnkey operators are provisioning enclaves with the correct configuration.
@@ -44,13 +44,13 @@ Verifying an App Proof thus involves 3 simple steps:
* Verify the App Proof signature validity (standard P-256 signature verification)
* Parse the content of the App Proof payload (JSON) and use the data within it to verify claimed facts (see below for an example).
-# Use cases
+## Use cases
You can enable App Proofs for any [activity](/api-reference/activities/overview). Turnkey Verified currently supports two App Proof types, each verifying a different operation performed inside a secure enclave.
### Address derivation proofs
-Address derivation proofs verify that a crypto address was correctly derived by Turnkey's **signer application**. These proofs are generated when new wallets are created. Turnkey verified will automatically fetch and verify proofs for you when new wallets are created through Turnkey's [Embedded Wallet Kit](/reference/embedded-wallet-kit) or via Turnkey's [dashboard](https://app.turnkey.com).
+Address derivation proofs verify that a crypto address was correctly derived by Turnkey's **signer application**. These proofs are generated when new wallets are created. Turnkey verified will automatically fetch and verify proofs for you when new wallets are created through Turnkey's [Embedded Wallet Kit](/solutions/embedded-wallets/integration-guide/react/getting-started) or via Turnkey's [dashboard](https://app.turnkey.com).
The payload:
```json
diff --git a/security/verifiable-data.mdx b/security/verifiable-data.mdx
index fa0dfc64..b957e694 100644
--- a/security/verifiable-data.mdx
+++ b/security/verifiable-data.mdx
@@ -1,5 +1,5 @@
---
-title: "Verifiable Data"
+title: "Verifiable data"
---
Enclave applications in Turnkey's infrastructure are stateless, meaning there is no persistent data held behind the enclave boundary. Instead, data is stored in a PostgreSQL instance in our primary AWS account. Before any enclave application operates on account data, it first verifies that the data has been recently notarized by Turnkey's notarizer. A recent stamp could be the result of an update or be initiated by the heartbeat service.
diff --git a/snippets/feature-card.mdx b/snippets/feature-card.mdx
new file mode 100644
index 00000000..c05867ee
--- /dev/null
+++ b/snippets/feature-card.mdx
@@ -0,0 +1,38 @@
+export const FeatureCard = ({ title, description, icon, logo, href }) => {
+ return (
+
+
+
+ );
+};
diff --git a/snippets/shared/export-wallets.mdx b/snippets/shared/export-wallets.mdx
index 6e139a3f..a51a0f44 100644
--- a/snippets/shared/export-wallets.mdx
+++ b/snippets/shared/export-wallets.mdx
@@ -1,6 +1,6 @@
---
title: "Export Wallets and Keys"
-description: "Turnkey's export functionality allows your end users to backup or transfer a [Wallet](/concepts/wallets) by securely viewing the wallet's [mnemonic phrase](https://learnmeabitcoin.com/technical/mnemonic). We engineered this feature to ensure that the user can export their mnemonic without exposing the mnemonic itself to Turnkey or your application."
+description: "Turnkey's export functionality allows your end users to backup or transfer a [Wallet](/features/wallets) by securely viewing the wallet's [mnemonic phrase](https://learnmeabitcoin.com/technical/mnemonic). We engineered this feature to ensure that the user can export their mnemonic without exposing the mnemonic itself to Turnkey or your application."
mode: wide
---
@@ -21,4 +21,4 @@ See the [Enclave to end-user secure channel](/security/enclave-secure-channels)
## Implementation Guides
-See [Code Examples](/embedded-wallets/code-examples/export) for more details.
+See [Code Examples](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets) for more details.
diff --git a/snippets/shared/fiat-on-ramp.mdx b/snippets/shared/fiat-on-ramp.mdx
index 78ca3a89..cdcd7203 100644
--- a/snippets/shared/fiat-on-ramp.mdx
+++ b/snippets/shared/fiat-on-ramp.mdx
@@ -110,4 +110,4 @@ The Coinbase demo is running in a sandbox environment which means:
## Implementation Guide
-See the [Fiat Onramp Code Example](/embedded-wallets/code-examples/fiat-on-ramp) for more details on how to implement.
+See the [Fiat Onramp Code Example](/features/transaction-management/fiat-on-ramp) for more details on how to implement.
diff --git a/snippets/shared/import-wallets.mdx b/snippets/shared/import-wallets.mdx
index 164907bc..ecc82e23 100644
--- a/snippets/shared/import-wallets.mdx
+++ b/snippets/shared/import-wallets.mdx
@@ -1,6 +1,6 @@
---
title: "Import Wallets and Keys"
-description: "Turnkey's import functionality allows your end users to securely transfer a [Wallet](/concepts/wallets) or a [Private Key](/concepts/wallets#private-keys) onto the Turnkey platform via CLI or an embedded iframe. We engineered this feature to ensure that the user can import their mnemonic or private key into a Turnkey secure enclave without exposing it to Turnkey or your application."
+description: "Turnkey's import functionality allows your end users to securely transfer a [Wallet](/features/wallets) or a [Private Key](/features/wallets#private-keys) onto the Turnkey platform via CLI or an embedded iframe. We engineered this feature to ensure that the user can import their mnemonic or private key into a Turnkey secure enclave without exposing it to Turnkey or your application."
mode: wide
---
@@ -21,4 +21,4 @@ See the [Enclave to end-user secure channel](/security/enclave-secure-channels)
## Implementation Guides
-See [Code Examples](/embedded-wallets/code-examples/import) for more details.
+See [Code Examples](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets) for more details.
diff --git a/snippets/shared/networks-links.mdx b/snippets/shared/networks-links.mdx
index bb095883..a9e5c6f5 100644
--- a/snippets/shared/networks-links.mdx
+++ b/snippets/shared/networks-links.mdx
@@ -1,137 +1,55 @@
-
-
- Overview
-
-
- Ethereum (EVM)
-
-
- Solana (SVM)
-
-
- Bitcoin
-
-
- Spark
-
-
- Movement
-
-
- Cosmos
-
-
- Tron
-
-
- Sui
-
-
- Sei
-
-
- Aptos
-
-
- Tempo
-
-
- Movement
-
-
- IOTA
-
-
- Others
-
-
+export const NetworkLinks = () => {
+ const NetworkCard = ({ title, icon, logo, href }) => (
+
+
+ );
+};
diff --git a/snippets/shared/policy-engine.mdx b/snippets/shared/policy-engine.mdx
index 2c3e4cf4..c113b2b3 100644
--- a/snippets/shared/policy-engine.mdx
+++ b/snippets/shared/policy-engine.mdx
@@ -8,7 +8,7 @@ sidebarTitle: "Policy Engine"
Our policies are defined using **JSON**. The `effect` determines if an activity should be allowed or denied based on the evaluation of the `consensus` and `condition` fields.
-`consensus` and `condition` are composed of ergonomic expressions written in our [policy language](/concepts/policies/language) that must evaluate to a `bool`. `consensus` determines which user(s) may take an action (e.g. a given user ID). `condition` determines the conditions under which the policy applies (e.g. signing with a specific wallet). These fields can be used alone or together.
+`consensus` and `condition` are composed of ergonomic expressions written in our [policy language](/features/policies/language) that must evaluate to a `bool`. `consensus` determines which user(s) may take an action (e.g. a given user ID). `condition` determines the conditions under which the policy applies (e.g. signing with a specific wallet). These fields can be used alone or together.
#### See below for an example policy that allows a single user to send transactions to a single address
diff --git a/snippets/shared/send-solana-tx-sdk-overview.mdx b/snippets/shared/send-solana-tx-sdk-overview.mdx
index 33bd1a88..204df866 100644
--- a/snippets/shared/send-solana-tx-sdk-overview.mdx
+++ b/snippets/shared/send-solana-tx-sdk-overview.mdx
@@ -21,11 +21,11 @@ You can sign and broadcast Solana transactions in two primary ways:
This is the right choice for Node.js backends. It exposes the same methods via the server SDK client.
-This page walks you through the React flow with full code examples. For using `@turnkey/core` directly, see [Sending Sponsored Transactions](/company-wallets/code-examples/sending-sponsored-transactions).
+This page walks you through the React flow with full code examples. For using `@turnkey/core` directly, see [Sending Sponsored Transactions](/features/transaction-management/broadcasting).
Before sponsoring Solana transactions, review
- [Solana Rent Sponsorship](/networks/solana-rent-refunds). Rent sponsorship is
+ [Solana Rent Sponsorship](/features/networks/solana-rent-refunds). Rent sponsorship is
opt-in, disabled by default, and must be enabled in the dashboard first. This
is especially important if you sponsor transactions from swap providers or
other third-party builders that may create and close accounts.
diff --git a/snippets/solution-card.mdx b/snippets/solution-card.mdx
new file mode 100644
index 00000000..48c6920d
--- /dev/null
+++ b/snippets/solution-card.mdx
@@ -0,0 +1,29 @@
+export const SolutionCard = ({ title, description, icon, href }) => {
+ return (
+
+
+
+ );
+};
diff --git a/solutions/company-wallets/agentic-wallets.mdx b/solutions/company-wallets/agentic-wallets.mdx
new file mode 100644
index 00000000..f20f1a1f
--- /dev/null
+++ b/solutions/company-wallets/agentic-wallets.mdx
@@ -0,0 +1,236 @@
+---
+title: "Agentic Wallets"
+description: "Give AI agents scoped signing authority over company wallets with policy-enforced access control, spending caps, and multi-party consensus for high-value actions."
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+import { SolutionCard } from '/snippets/solution-card.mdx'
+
+This guide covers the key implementation decisions for giving AI agents secure access to company wallets, then walks through provisioning an agent end-to-end: creating a scoped wallet, assigning a non-root agent user, and defining policies that constrain exactly what the agent can sign. For basic signing, start with the [Quickstart](/solutions/company-wallets/quickstart).
+
+## Turnkey agent skills
+
+[Agent Skills](/get-started/ai-skills) let you operate on Turnkey directly through an AI assistant, no application code required. The agent provisioning workflow skill lets you quickly create a wallet scoped for agent usage through your AI assistant. You can then equip your agent with skills so it can autonomously operate within the boundaries you've configured.
+
+## Agent personas
+
+Turnkey supports different agent roles through policy composition:
+
+| Persona | What it can do | Policy approach |
+| :--- | :--- | :--- |
+| **Worker** | Signs transactions on a designated wallet | ALLOW with wallet scope + destination/function/value constraints |
+| **Observer** | Read-only access (balance checks, activity monitoring) | No policies needed; default-deny prevents signing. Add explicit DENY if org has shared ALLOWs. |
+| **Approver** | Reviews and approves other agents' transactions | Narrow ALLOW for `APPROVE_ACTIVITY` and `REJECT_ACTIVITY` only. Must NOT have signing permissions. |
+
+These personas can be composed for multi-agent systems. For example, a worker agent proposes trades, an approver agent validates them against risk models, and a human admin retains override authority for high-value actions.
+
+## Key implementation decisions
+
+| Decision | What to consider |
+| :--- | :--- |
+| Wallet scope | Dedicate a wallet (or specific accounts) to the agent. Never share wallets between agents with different trust levels. |
+| Destination allowlist | Restrict which addresses the agent can send to (e.g., only a treasury address, only a specific DEX router) |
+| Spending caps | Bound transaction values per-signing to limit blast radius if the agent misbehaves |
+| Function restrictions | For smart contract interactions, restrict to specific function selectors or [upload the ABI](/features/policies/smart-contract-interfaces) for argument-level control |
+| Consensus requirements | For high-value actions, require both the agent and a human (or another agent) to approve before the enclave signs |
+| Key management | Store agent API keys in a secrets manager. Plan for rotation without downtime. Use short-lived keys where viable. |
+| Transaction management | Enterprise customers can use Turnkey's [transaction management](/features/transaction-management) to offload gas sponsorship, nonce management, and broadcasting — so agents only need to handle signing logic. |
+
+## Example: autonomous trading agent
+
+An AI agent that analyzes market data and executes trades on a DEX needs scoped signing authority: it should only be able to call specific router functions on approved contracts, with spending limits and human oversight for large trades.
+
+| Need | How Turnkey solves it |
+| :--- | :--- |
+| Agent must never access the private key | Keys stay in the [secure enclave](/security/secure-enclaves); the agent authenticates via API key and receives signatures only |
+| Signing must be restricted to approved contracts | Policies target specific contract addresses and function selectors |
+| Large trades need human approval | Consensus expressions require both the agent and a human approver for transactions above a threshold |
+| Must support multiple chains | One agent user with chain-specific policies (EVM, SVM, etc.) covering each network |
+| Must be revocable instantly | Delete the agent user to permanently and immediately revoke all access |
+
+### Implementation steps
+
+
+ The [agent provisioning skill](/get-started/ai-skills) can run this entire workflow for you through an AI assistant. Use the steps below if you prefer to implement it manually.
+
+
+
+ This guide assumes you've completed the [Quickstart](/solutions/company-wallets/quickstart) and have a Turnkey client initialized with your root credentials. The agent will get its own separate credentials.
+
+
+
+
+
+Create a dedicated wallet scoped to the agent's needs. Always check for existing wallets first to avoid creating duplicates.
+
+```ts
+const { wallets } = await turnkeyClient.apiClient().getWallets();
+console.log("Existing wallets:", wallets.map((w) => `${w.walletName} (${w.walletId})`));
+
+const { walletId, addresses } = await turnkeyClient.apiClient().createWallet({
+ walletName: "Trading Agent Wallet",
+ accounts: [
+ {
+ curve: "CURVE_SECP256K1",
+ pathFormat: "PATH_FORMAT_BIP32",
+ path: "m/44'/60'/0'/0/0",
+ addressFormat: "ADDRESS_FORMAT_ETHEREUM",
+ },
+ ],
+});
+
+const agentAddress = addresses[0];
+```
+
+
+
+
+
+The agent gets its own user with a P-256 API key pair. This user is **non-root** by default, meaning it has zero permissions until you explicitly create policies.
+
+Generate a key pair for the agent (the private key never touches Turnkey):
+
+```ts
+import crypto from "crypto";
+
+const keyPair = crypto.generateKeyPairSync("ec", { namedCurve: "P-256" });
+const pubJwk = keyPair.publicKey.export({ format: "jwk" });
+const privJwk = keyPair.privateKey.export({ format: "jwk" });
+
+// SEC1-compressed P-256 public key (33 bytes, 66 hex chars)
+const xHex = Buffer.from(pubJwk.x!, "base64url").toString("hex").padStart(64, "0");
+const yBuf = Buffer.from(
+ Buffer.from(pubJwk.y!, "base64url").toString("hex").padStart(64, "0"),
+ "hex"
+);
+const prefix = (yBuf[yBuf.length - 1] & 1) === 0 ? "02" : "03";
+const agentPublicKey = prefix + xHex;
+const agentPrivateKey = Buffer.from(privJwk.d!, "base64url").toString("hex").padStart(64, "0");
+```
+
+Then create a user tag and the agent user. `userTags` takes tag IDs (UUIDs), not string labels, so create the tag first:
+
+```ts
+const { userTagId: agentTagId } = await turnkeyClient.apiClient().createUserTag({
+ userTagName: "agent",
+ userIds: [],
+});
+
+const { userIds } = await turnkeyClient.apiClient().createUsers({
+ users: [
+ {
+ userName: "trading-agent",
+ userTags: [agentTagId],
+ apiKeys: [
+ {
+ apiKeyName: "trading-agent-key",
+ publicKey: agentPublicKey,
+ curveType: "API_KEY_CURVE_P256",
+ },
+ ],
+ authenticators: [],
+ oauthProviders: [],
+ },
+ ],
+});
+
+const agentUserId = userIds[0];
+```
+
+
+ Never create agents as root users. Root users bypass the policy engine entirely. Always use non-root users with explicit ALLOW policies.
+
+
+
+
+
+
+With the agent user and wallet created, define policies that scope exactly what the agent can do. Turnkey is default-deny: without an ALLOW policy, the agent cannot sign anything.
+
+**Base signing policy** (scoped to the agent's wallet):
+
+```json
+{
+ "policyName": "Allow trading agent to sign on its wallet",
+ "effect": "EFFECT_ALLOW",
+ "consensus": "approvers.any(user, user.id == '')",
+ "condition": "activity.type in ['ACTIVITY_TYPE_SIGN_TRANSACTION_V2', 'ACTIVITY_TYPE_ETH_SEND_TRANSACTION'] && wallet.id == ''"
+}
+```
+
+**Destination allowlist** (restrict to a specific DEX router):
+
+```json
+{
+ "policyName": "Restrict agent to Uniswap router",
+ "effect": "EFFECT_ALLOW",
+ "consensus": "approvers.any(user, user.id == '')",
+ "condition": "activity.action == 'SIGN' && wallet.id == '' && eth.tx.to == '' && eth.tx.chain_id == '1'"
+}
+```
+
+**Spending cap** (limit per-transaction value):
+
+```json
+{
+ "policyName": "Cap agent transactions at 0.5 ETH",
+ "effect": "EFFECT_DENY",
+ "consensus": "approvers.any(user, user.id == '')",
+ "condition": "activity.action == 'SIGN' && eth.tx.value > 500000000000000000"
+}
+```
+
+**Multi-party consensus for large trades:**
+
+```json
+{
+ "policyName": "Require human approval above 0.1 ETH",
+ "effect": "EFFECT_ALLOW",
+ "consensus": "approvers.any(user, user.id == '') && approvers.any(user, user.id == '')",
+ "condition": "activity.action == 'SIGN' && wallet.id == '' && eth.tx.value > 100000000000000000"
+}
+```
+
+
+
+
+
+Test the agent's credentials by initializing a client with the agent's key pair and verifying access:
+
+```ts
+const agentClient = new Turnkey({
+ apiBaseUrl: "https://api.turnkey.com",
+ apiPublicKey: agentPublicKey,
+ apiPrivateKey: agentPrivateKey,
+ defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID!,
+});
+
+const whoami = await agentClient.apiClient().getWhoami();
+console.log("Agent user ID:", whoami.userId);
+console.log("Agent org ID:", whoami.organizationId);
+```
+
+Store the agent's credentials in your secrets manager:
+
+```bash
+TURNKEY_API_PUBLIC_KEY=
+TURNKEY_API_PRIVATE_KEY=
+TURNKEY_ORGANIZATION_ID=
+SIGN_WITH=
+```
+
+
+ Never output or log root credentials alongside agent credentials. The agent should only ever have its own key pair.
+
+
+
+
+
+## Next steps
+
+
+
+
+
+
+
diff --git a/sdks/golang.mdx b/solutions/company-wallets/integration-guide/golang.mdx
similarity index 100%
rename from sdks/golang.mdx
rename to solutions/company-wallets/integration-guide/golang.mdx
diff --git a/sdks/javascript-server.mdx b/solutions/company-wallets/integration-guide/javascript-server.mdx
similarity index 81%
rename from sdks/javascript-server.mdx
rename to solutions/company-wallets/integration-guide/javascript-server.mdx
index 8dcb65d4..d988ffee 100644
--- a/sdks/javascript-server.mdx
+++ b/solutions/company-wallets/integration-guide/javascript-server.mdx
@@ -1,14 +1,21 @@
---
title: "TypeScript server"
-description: "The [`@turnkey/sdk-server`](https://www.npmjs.com/package/@turnkey/sdk-server) package exposes functionality that lets developers build server-side functionality for applications that interact with the Turnkey API."
-sidebarTitle: "TypeScript | Server"
+description:
+ "The [`@turnkey/sdk-server`](https://www.npmjs.com/package/@turnkey/sdk-server) package exposes
+ functionality that lets developers build server-side functionality for applications that interact
+ with the Turnkey API."
+sidebarTitle: "TypeScript server"
---
## Overview
-It exposes a ready-made API client class which manages the process of constructing requests to the Turnkey API and authenticating them with a valid API key. Furthermore, it exposes API proxies that forward requests from your application's client that need to be signed by parent organizations API key.
+It exposes a ready-made API client class which manages the process of constructing requests to the
+Turnkey API and authenticating them with a valid API key. Furthermore, it exposes API proxies that
+forward requests from your application's client that need to be signed by parent organizations API
+key.
-Use the [`@turnkey/sdk-server`](https://www.npmjs.com/package/@turnkey/sdk-server) package to handle server-side interactions for applications that interact with the Turnkey API.
+Use the [`@turnkey/sdk-server`](https://www.npmjs.com/package/@turnkey/sdk-server) package to handle
+server-side interactions for applications that interact with the Turnkey API.
## Installation
@@ -63,7 +70,8 @@ The root organization that requests will be made from unless otherwise specified
required
>
-The base URL that API requests will be sent to (use [https://api.turnkey.com](https://api.turnkey.com) when making requests to Turnkey's API)
+The base URL that API requests will be sent to (use
+[https://api.turnkey.com](https://api.turnkey.com) when making requests to Turnkey's API)
-The API Private Key to sign requests with (this will normally be the API Private Key to your root organization)
+The API Private Key to sign requests with (this will normally be the API Private Key to your root
+organization)
## Creating clients
-Calls to Turnkey's API must be signed with a valid credential (often referred to in the docs as [stamping](/developer-reference/api-overview/stamps)) from the user initiating the API call. When using the Server SDK, the user initiating the API call is normally your root organization, and the API call is authenticated with the API keypair you create on the Turnkey dashboard.
+Calls to Turnkey's API must be signed with a valid credential (often referred to in the docs as
+[stamping](/api-reference/overview/stamps)) from the user initiating the API call. When
+using the Server SDK, the user initiating the API call is normally your root organization, and the
+API call is authenticated with the API keypair you create on the Turnkey dashboard.
#### `apiClient()`
-The `apiClient` method returns an instance of the `TurnkeyApiClient` which will sign requests with the injected `apiPrivateKey`, and `apiPublicKey` credentials.
+The `apiClient` method returns an instance of the `TurnkeyApiClient` which will sign requests with
+the injected `apiPrivateKey`, and `apiPublicKey` credentials.
```js
const apiClient = turnkey.apiClient();
@@ -99,13 +112,20 @@ const walletsResponse = await apiClient.getWallets();
## Creating API proxies
-There are certain actions that are initiated by users, but require the activity to be signed by the root organization itself. Examples of this include the initial creation of the user `subOrganization` or sending an email to a user with a login credential as part of an `emailAuth` flow.
+There are certain actions that are initiated by users, but require the activity to be signed by the
+root organization itself. Examples of this include the initial creation of the user
+`subOrganization` or sending an email to a user with a login credential as part of an `emailAuth`
+flow.
-These can be implemented in your backend by creating an `apiClient` and handling requests from your browser application at different routes, but we have also provided a convenience method for doing this by having allowing a single `apiProxy` to handle requests at a single route and automatically sign specific user actions with the root organization's credentials.
+These can be implemented in your backend by creating an `apiClient` and handling requests from your
+browser application at different routes, but we have also provided a convenience method for doing
+this by having allowing a single `apiProxy` to handle requests at a single route and automatically
+sign specific user actions with the root organization's credentials.
#### expressProxyHandler()
-The `expressProxyHandler()` method creates a proxy handler designed as a middleware for Express applications. It provides an API endpoint that forwards requests to the Turnkey API server.
+The `expressProxyHandler()` method creates a proxy handler designed as a middleware for Express
+applications. It provides an API endpoint that forwards requests to the Turnkey API server.
```js
const turnkeyProxyHandler = turnkey.expressProxyHandler({
@@ -119,7 +139,8 @@ app.post("/apiProxy", turnkeyProxyHandler);
#### 2. nextProxyHandler()
-The `nextProxyHandler()` method creates a proxy handler designed as a middleware for Next.js applications. It provides an API endpoint that forwards requests to the Turnkey API server.
+The `nextProxyHandler()` method creates a proxy handler designed as a middleware for Next.js
+applications. It provides an API endpoint that forwards requests to the Turnkey API server.
```js
// Configure the Next.js handler with allowed methods
@@ -134,7 +155,8 @@ export default turnkeyProxyHandler;
## TurnkeyServerClient
-The `@turnkey/sdk-server` exposes NextJS Server Actions. These server actions can be used to facilitate implementing common authentication flows.
+The `@turnkey/sdk-server` exposes NextJS Server Actions. These server actions can be used to
+facilitate implementing common authentication flows.
### `sendOtp()`
@@ -173,8 +195,7 @@ if (initAuthResponse?.otpId) {
#### Parameters
- An object containing the parameters to initiate an `EMAIL` or `SMS` OTP
- authentication flow.
+ An object containing the parameters to initiate an `EMAIL` or `SMS` OTP authentication flow.
@@ -268,13 +289,13 @@ if (verifyResponse?.verificationToken) {
- Optional. The session lifetime in seconds. Defaults to 900 seconds (15
- minutes).
+ Optional. The session lifetime in seconds. Defaults to 900 seconds (15 minutes).
### `createOauthSession()`
-Complete an OAuth authentication flow after obtaining an OIDC token from the OAuth provider. This creates a Turnkey session bound to the provided public key.
+Complete an OAuth authentication flow after obtaining an OIDC token from the OAuth provider. This
+creates a Turnkey session bound to the provided public key.
```typescript
import { server } from "@turnkey/sdk-server";
@@ -367,13 +388,11 @@ const sendCredentialResponse = await server.sendCredential({
- IP Address, iframePublicKey, or other unique identifier used for rate
- limiting.
+ IP Address, iframePublicKey, or other unique identifier used for rate limiting.
- Specify the length of the session in seconds. Defaults to 900 seconds or 15
- minutes.
+ Specify the length of the session in seconds. Defaults to 900 seconds or 15 minutes.
diff --git a/solutions/company-wallets/integration-guide/overview.mdx b/solutions/company-wallets/integration-guide/overview.mdx
new file mode 100644
index 00000000..dab40e6d
--- /dev/null
+++ b/solutions/company-wallets/integration-guide/overview.mdx
@@ -0,0 +1,69 @@
+---
+title: "Server SDKs"
+description:
+ "Language and framework options for integrating Company Wallets from a backend service."
+sidebarTitle: "Overview"
+---
+
+Company wallet integrations are backend-driven. Your server creates wallets, constructs
+transactions, and signs them via the Turnkey API using an API key. This page covers that model, and
+choosing the right SDK for your stack.
+
+## Choose your SDK
+
+
+
+ Our most complete SDK. Recommended if your backend can run Node.js.
+
+
+ Native Go SDK.
+
+
+ turnkey_client gem for Ruby and Rails projects.
+
+
+ Native Rust SDK.
+
+
+ Pydantic type definitions, an HTTP-client for easy direct requests, and API-key stamper.
+
+
+ Call the Turnkey REST API directly from any language.
+
+
+
+## How server integrations work
+
+All server integrations follow the same pattern regardless of language:
+
+1. **Create an API keypair** on the Turnkey dashboard create an API user and save its credentials.
+2. **Initialize a client** with your API credentials. The SDK handles request construction and
+ signing.
+3. **Call the API** — create wallets, sign transactions, manage policies — and receive results. For
+ signing operations, only the signature is returned; private keys never leave the enclave.
+4. **Create policies** scoping your API user to only its routinely performed functions.
+
+This credential model is simpler than embedded wallets: there's no end-user authentication, no
+sessions to manage, and no Auth Proxy. Your API private key lives on your server and signs every
+request.
+
+## API users and policies
+
+API users are native to your organization. You can create multiple API users — one per service or
+environment — and scope each with policies that restrict what it can sign.
+
+For example, a payment sweeper service might be allowed to sign outbound transfers up to a certain
+value, while a contract deployer has authority over a specific set of addresses. Turnkey is
+deny-by-default: if no policy explicitly allows an action, it is rejected.
+
+See [Policies](/features/policies/overview) for the policy language and
+[Policy Quickstart](/features/policies/quickstart) to set up your first rules.
+
+## Organization structure
+
+Most custodial integrations run within a single parent organization. Your org holds the wallets;
+your API users (backend services and human operators) act on them subject to policy.
+
+If you need tenant isolation — for example, you're building a product that provisions wallets on
+behalf of your customers — you can create sub-organizations, one per tenant, each with its own
+wallets and policies. See [Sub-Organizations](/features/sub-organizations).
diff --git a/sdks/python.mdx b/solutions/company-wallets/integration-guide/python.mdx
similarity index 98%
rename from sdks/python.mdx
rename to solutions/company-wallets/integration-guide/python.mdx
index 60162c77..9d3e8e21 100644
--- a/sdks/python.mdx
+++ b/solutions/company-wallets/integration-guide/python.mdx
@@ -4,8 +4,6 @@ description: "Turnkey offers support for interacting with the API using Python.
mode: wide
---
-# Turnkey Python SDK
-
This repository contains support for interacting with the Turnkey API using Python.
Unlike other languages ([Typescript](https://github.com/tkhq/sdk), [Ruby](https://github.com/tkhq/ruby-sdk)), we do not yet offer a full SDK for Rust.
diff --git a/sdks/ruby.mdx b/solutions/company-wallets/integration-guide/ruby.mdx
similarity index 100%
rename from sdks/ruby.mdx
rename to solutions/company-wallets/integration-guide/ruby.mdx
diff --git a/sdks/rust.mdx b/solutions/company-wallets/integration-guide/rust.mdx
similarity index 100%
rename from sdks/rust.mdx
rename to solutions/company-wallets/integration-guide/rust.mdx
diff --git a/solutions/company-wallets/overview.mdx b/solutions/company-wallets/overview.mdx
new file mode 100644
index 00000000..860fd21f
--- /dev/null
+++ b/solutions/company-wallets/overview.mdx
@@ -0,0 +1,90 @@
+---
+title: "Overview"
+---
+
+import { SolutionCard } from '/snippets/solution-card.mdx';
+
+## What are company wallets?
+
+Company wallets are custodial wallets owned and operated by your organization. Your team controls the keys and defines who can sign, what they can sign, and under what conditions. **The wallets belong to your business; Turnkey provides the infrastructure to operate them securely at scale.**
+
+Where [embedded wallets](/solutions/embedded-wallets/overview) give each end user their own wallet, company wallets centralize control within your organization. Your backend services, operators, and automated systems sign transactions through Turnkey's API, governed by role-based access controls and the policy engine.
+
+## Why Turnkey for company wallets?
+
+Managing company-controlled keys means solving for security, access control, multi-chain support, and automation, all without exposing private keys to your team or your infrastructure. Turnkey handles this so you can focus on your operations.
+
+With Turnkey, you can:
+
+- Sign millions of transactions with sub-100ms latency via [secure enclaves](/security/secure-enclaves)
+- Define role-based access controls so each operator, service, or team member can only sign what they're authorized to
+- Require multi-party approval for high-value or sensitive operations
+- Support any blockchain with chain-agnostic, arbitrary signing
+- Automate workflows like sweeps, payouts, and contract interactions via API
+- Import existing keys or export them when needed
+
+## How it works
+
+Your backend authenticates to Turnkey via API key. Inside the secure enclave, the [policy engine](/features/policies/overview) evaluates the request against the signing policies you've defined. If approved, the enclave signs and returns the signature. If denied, no signature is produced.
+
+Private keys never leave the [secure enclave](/security/secure-enclaves). Your operators and services interact with signatures, not keys.
+
+### Access control model
+
+Company wallets use a single [organization](/features/organizations) (or [sub-organizations](/features/sub-organizations) for tenant isolation). Within that org, you define:
+
+- **Users** representing human operators and automated services, each with their own credentials (API keys, passkeys)
+- **Tags** grouping users by role (e.g. `deployer`, `treasury-ops`, `sweeper`)
+- **Policies** controlling what each role can sign: by recipient address, contract address, function selector, chain ID, transaction value, or any combination
+
+Turnkey is deny-by-default. If no policy explicitly allows an action, it is rejected. See [Policies](/features/policies/overview) and [Policy Language](/features/policies/language).
+
+### Security model
+
+- **Keys never leave the enclave.** Private keys live in [Trusted Execution Environments (TEEs)](/security/secure-enclaves). All signing happens inside verifiable infrastructure; only signatures are returned.
+- **Role-scoped access.** Every signing request is evaluated against policies in the enclave. Operators and services can only perform actions they've been explicitly authorized for.
+- **Multi-party approval.** For sensitive operations, require multiple approvers before the enclave will sign. See [Co-signing transactions](/features/policies/examples/co-signing-transactions).
+- **Trusted vs. untrusted separation.** A breach of your backend does not expose keys or signing capability. The enclave enforces policies independently of your infrastructure.
+
+For a deeper look, see [Security](/security/our-approach) and [Secure Enclaves](/security/secure-enclaves).
+
+## Building with Turnkey
+
+Most company wallet integrations are backend-driven. Use Turnkey's server SDKs to create wallets, sign transactions, and manage policies programmatically from your infrastructure.
+
+Server SDKs are available for [TypeScript](/solutions/company-wallets/integration-guide/javascript-server), [Go](/solutions/company-wallets/integration-guide/golang), [Ruby](/solutions/company-wallets/integration-guide/ruby), [Python](/solutions/company-wallets/integration-guide/python), and [Rust](/solutions/company-wallets/integration-guide/rust). For full control, you can call the [Turnkey API](/api-reference/overview/intro) directly.
+
+The [Turnkey Dashboard](https://app.turnkey.com) serves as an internal GUI for managing wallets, users, and policies. If you need a custom operator-facing interface, you can build one using the [Embedded Wallet Kit](/solutions/embedded-wallets/integration-guide/react/index).
+
+See the [Company Wallets Quickstart](/solutions/company-wallets/quickstart) to get started.
+
+## Use cases
+
+Company wallets serve different needs depending on what you're building. Choose the pattern that matches your operations.
+
+
+
+
+
+
+
+## Ready to build?
+
+- [Company Wallets Quickstart](/solutions/company-wallets/quickstart) -- set up your organization, create wallets, and sign your first transaction
+- [Policy Quickstart](/features/policies/quickstart) -- define access controls and signing rules for your team
+- [SDK Reference](/sdks/introduction) -- server SDKs for TypeScript, Go, Ruby, Python, and Rust
diff --git a/solutions/company-wallets/payment-orchestration.mdx b/solutions/company-wallets/payment-orchestration.mdx
new file mode 100644
index 00000000..89a947b5
--- /dev/null
+++ b/solutions/company-wallets/payment-orchestration.mdx
@@ -0,0 +1,172 @@
+---
+title: "Payment Orchestration"
+description: "Build automated sweep, deposit, and treasury flows with policy-enforced access control and gas sponsorship."
+mode: wide
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+import { SolutionCard } from '/snippets/solution-card.mdx'
+
+Move funds programmatically across deposit, omnibus, and cold wallets with sub-100ms signing and policy-enforced access control at every transaction. For a basic signing walkthrough, start with the [Quickstart](/solutions/company-wallets/quickstart).
+
+This guide covers the key implementation decisions for company wallet payment flows, then walks through a production example end-to-end: creating per-user deposit addresses, sweeping those deposits into an omnibus wallet with gas sponsorship, and gating treasury outflows with multi-party approval.
+
+## Powered by Turnkey
+
+Leading platforms use Turnkey to deliver onchain payment rails at scale:
+
+- [**Squads**](https://www.turnkey.com/customers/how-squads-improves-ux-and-accounting-efficiency-with-turnkey) improved UX and accounting efficiency for multisig treasury management.
+- [**Flutterwave**](https://flutterwave.com/us/blog/flutterwave-partners-with-turnkey-to-power-secure-stablecoin-wallets-for-customers) powers secure stablecoin wallets for customers across Africa.
+
+## Key implementation decisions
+
+| Decision | What to consider |
+| :--- | :--- |
+| Wallet architecture | Single HD wallet with many accounts (cost-efficient, shared seed) vs separate wallets per function (deposits, omnibus, cold) |
+| Deposit addressing | Per-user deposit addresses via `createWalletAccounts` at no extra cost |
+| Sweep strategy | Policy-enforced sweeps restricting deposit addresses to a single omnibus destination |
+| Gas management | [Sponsored transactions](/features/transaction-management/broadcasting) (`sponsor: true`) eliminate the need to fund each deposit address for gas |
+| Chain coverage | EVM and SVM require separate policies due to different transaction models |
+| Hot wallet controls | Automated API key user with policies scoping exactly which transfers are allowed |
+| Treasury controls | Multi-party approval via [consensus expressions](/features/policies/quickstart) (e.g., 2-of-N ops team) |
+| Cold storage transfers | Policy-gated with parsed calldata for token transfers, or [upload the contract ABI](/features/policies/smart-contract-interfaces) for full parsing |
+
+## Example: custodial payment processing
+
+Exchanges and custodial payment processors are common examples requiring highly scalable, highly secure onchain systems.
+
+
+
+| Need | How Turnkey solves it |
+| :--- | :--- |
+| All users have a unique deposit address | Wallet accounts are efficiently created and controlled within a Turnkey organization |
+| Access to all wallets must be strictly permissioned | Policies enforce RBAC and least-privilege for all signing actions |
+| Keys must never be exposed | Keys remain in the [secure enclave](/security/secure-enclaves); only signatures are returned |
+| Must support automation and human review | Policies allow automation for routine tasks and require multi-party consensus for sensitive ones |
+| Must move funds efficiently | [Transaction sponsorship](/features/transaction-management/broadcasting) eliminates the cost of funding thousands of deposit addresses for gas |
+
+### Implementation steps
+
+
+ This guide assumes you've completed the [Quickstart](/solutions/company-wallets/quickstart) and have a Turnkey client initialized. If not, start there first.
+
+
+
+
+
+Turnkey lets you create unlimited wallet accounts at no cost, each with a unique address belonging to the same underlying [wallet](/features/wallets). Create a deposits wallet with both EVM and SVM accounts:
+
+```ts
+const { walletId } = await turnkeyClient.apiClient().createWallet({
+ walletName: "Deposits wallet",
+ accounts: [
+ {
+ curve: "CURVE_SECP256K1",
+ pathFormat: "PATH_FORMAT_BIP32",
+ path: "m/44'/60'/0'/0/0",
+ addressFormat: "ADDRESS_FORMAT_ETHEREUM",
+ },
+ {
+ curve: "CURVE_ED25519",
+ pathFormat: "PATH_FORMAT_BIP32",
+ path: "m/44'/501'/0'/0'",
+ addressFormat: "ADDRESS_FORMAT_SOLANA",
+ },
+ ],
+});
+```
+
+Then generate fresh deposit addresses on demand:
+
+```ts
+async function createDepositAddresses(
+ turnkeyClient: Turnkey,
+ walletId: string
+): Promise {
+ const addresses = await turnkeyClient.apiClient().createWalletAccounts({
+ walletId,
+ accounts: ["ADDRESS_FORMAT_ETHEREUM", "ADDRESS_FORMAT_SOLANA"],
+ });
+
+ return addresses.addresses;
+}
+```
+
+This function can be triggered by end-user signup, a deposit request, or any internal flow.
+
+
+
+
+
+Now that you have deposit addresses generating on demand, the next step is moving those funds into a central omnibus wallet. This is where the complexity typically starts: sweeping funds from thousands of addresses involves both security and cost considerations.
+
+**Policy-enforced sweeps**
+
+Create policies that restrict deposit wallets to only transfer to the omnibus address. EVM and SVM require separate policies due to their different transaction models:
+
+```json
+{
+ "policyName": "(EVM) Deposit wallet sweep to omnibus",
+ "effect": "EFFECT_ALLOW",
+ "consensus": "approvers.any(user, user.id == '')",
+ "condition": "activity.action == 'SIGN' && wallet.id == '' && eth.tx.to == ''"
+},
+{
+ "policyName": "(SVM) Deposit wallet sweep to omnibus",
+ "effect": "EFFECT_ALLOW",
+ "consensus": "approvers.any(user, user.id == '')",
+ "condition": "activity.action == 'SIGN' && wallet.id == '' && solana.tx.transfers.count == 1 && solana.tx.transfers[0].to == ''"
+}
+```
+
+Turnkey's Policy Engine is default-deny: you only specify the exact conditions to allow. Raw or obfuscated payloads are rejected unless explicitly permitted.
+
+**Gas sponsorship**
+
+Normally you'd need to fund every deposit address with gas before sweeping. Sponsored transactions bypass this entirely:
+
+```ts
+const sendTransactionStatusId = await turnkeyClient.apiClient().ethSendTransaction({
+ transaction: {
+ from: depositAddress,
+ to: "OMNIBUS_ADDRESS",
+ caip2: "eip155:8453",
+ sponsor: true,
+ value: "0",
+ data: "0x",
+ nonce: "0",
+ },
+});
+```
+
+See the [gas sponsorship guide](/features/transaction-management/broadcasting) for more details.
+
+
+
+
+
+The omnibus wallet likely requires human-operator approval for outbound transfers and may need more sophisticated automations like asset rebalancing.
+
+Create a user tag (e.g., `ops-team`) and apply it to your teammates, then set a policy requiring their approval for transfers to a cold wallet:
+
+```json
+{
+ "policyName": "Require 2 ops-team for cold wallet deposits",
+ "effect": "EFFECT_ALLOW",
+ "consensus": "approvers.filter(user, user.tags.contains('')).count() > 1",
+ "condition": "activity.action == 'SIGN' && wallet.id == '' && (eth.tx.to == '' || (eth.tx.data[0..10] == '0xa9059cbb' && eth.tx.data[34..74] == ''))"
+}
+```
+
+For token transfers, the policy above parses the ERC-20 `transfer` function signature. For production use, the recommended approach is to [upload the contract ABI](/features/policies/smart-contract-interfaces) for supported assets and act on fully parsed transactions.
+
+
+
+
+## Next steps
+
+
+
+
+
+
diff --git a/solutions/company-wallets/quickstart.mdx b/solutions/company-wallets/quickstart.mdx
new file mode 100644
index 00000000..bd807e3f
--- /dev/null
+++ b/solutions/company-wallets/quickstart.mdx
@@ -0,0 +1,158 @@
+---
+title: "Company Wallets quickstart"
+description: "Get from zero to a signed transaction with Turnkey's Company Wallets. Initialize the server SDK, create a wallet, and sign your first Ethereum transaction using Viem or Ethers."
+sidebarTitle: "Quickstart"
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+import { SolutionCard } from '/snippets/solution-card.mdx'
+
+## Prerequisites
+
+This guide assumes you've completed the steps to create an account, organization, and API keypair as described in the [account setup](/get-started/quickstart) section. This guide uses the TypeScript server SDK (`@turnkey/sdk-server`). For other languages, see [Server SDKs](/sdks/introduction).
+
+## Installation
+
+Install the server SDK and your preferred Ethereum library:
+
+
+
+```bash Viem
+npm install @turnkey/sdk-server @turnkey/viem viem
+```
+
+```bash Ethers
+npm install @turnkey/sdk-server @turnkey/ethers ethers
+```
+
+
+
+
+ This quickstart uses Ethereum, but Turnkey supports all EVM and SVM chains, along with Bitcoin, Tron, and [more](/features/networks/overview). To sign Solana transactions, derive a Solana address using `ADDRESS_FORMAT_SOLANA` with `CURVE_ED25519` and use [`@turnkey/solana`](https://www.npmjs.com/package/@turnkey/solana) or the server SDK's [`solSendTransaction`](/features/networks/solana) method.
+
+
+## Sign your first transaction
+
+
+
+
+Add your API credentials to a `.env` file:
+
+```bash
+TURNKEY_ORGANIZATION_ID=
+TURNKEY_API_PRIVATE_KEY=
+TURNKEY_API_PUBLIC_KEY=
+```
+
+Then initialize the client in your application:
+
+```ts
+import { Turnkey } from "@turnkey/sdk-server";
+
+const turnkeyClient = new Turnkey({
+ apiBaseUrl: "https://api.turnkey.com",
+ defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID!,
+ apiPrivateKey: process.env.TURNKEY_API_PRIVATE_KEY!,
+ apiPublicKey: process.env.TURNKEY_API_PUBLIC_KEY!,
+});
+```
+
+
+
+
+Create a wallet and derive an Ethereum address in a single call:
+
+```ts
+const { walletId, addresses } = await turnkeyClient.apiClient().createWallet({
+ walletName: "default",
+ accounts: [
+ {
+ curve: "CURVE_SECP256K1",
+ pathFormat: "PATH_FORMAT_BIP32",
+ path: "m/44'/60'/0'/0/0",
+ addressFormat: "ADDRESS_FORMAT_ETHEREUM",
+ },
+ ],
+});
+
+const ethereumAddress = addresses[0];
+console.log("Ethereum address:", ethereumAddress);
+```
+
+
+
+
+
+
+```ts
+import { createAccount } from "@turnkey/viem";
+import { createWalletClient, http } from "viem";
+import { mainnet } from "viem/chains";
+
+const turnkeyAccount = await createAccount({
+ client: turnkeyClient.apiClient(),
+ organizationId: process.env.TURNKEY_ORGANIZATION_ID!,
+ signWith: ethereumAddress,
+});
+
+const walletClient = createWalletClient({
+ account: turnkeyAccount,
+ chain: mainnet,
+ transport: http(),
+});
+```
+
+
+```ts
+import { ethers } from "ethers";
+import { TurnkeySigner } from "@turnkey/ethers";
+
+const provider = new ethers.JsonRpcProvider("YOUR_RPC_URL");
+const turnkeySigner = new TurnkeySigner({
+ client: turnkeyClient.apiClient(),
+ organizationId: process.env.TURNKEY_ORGANIZATION_ID!,
+ signWith: ethereumAddress,
+});
+const connectedSigner = turnkeySigner.connect(provider);
+```
+
+
+
+
+
+
+
+
+```ts
+import { parseEther } from "viem";
+
+const txHash = await walletClient.sendTransaction({
+ to: "",
+ value: parseEther(""),
+});
+console.log("Transaction hash:", txHash);
+```
+
+
+```ts
+const txHash = await connectedSigner.sendTransaction({
+ to: "",
+ value: ethers.parseEther(""),
+ type: 2,
+});
+console.log("Transaction hash:", txHash.hash);
+```
+
+
+
+
+
+
+## Next steps
+
+
+
+
+
+
+
diff --git a/solutions/company-wallets/smart-contract-management.mdx b/solutions/company-wallets/smart-contract-management.mdx
new file mode 100644
index 00000000..d4c9b0dd
--- /dev/null
+++ b/solutions/company-wallets/smart-contract-management.mdx
@@ -0,0 +1,124 @@
+---
+title: "Smart Contract Management"
+description: "Secure the full smart contract lifecycle with policy-enforced deployment, function-level access control, and safe upgrade workflows."
+mode: wide
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+import { SolutionCard } from '/snippets/solution-card.mdx'
+
+This guide covers the key implementation decisions for securing smart contract operations, then walks through the contract lifecycle end-to-end: permissioned deployment, function-level interaction policies, and minimizing risk during upgrades. For basic signing, start with the [Quickstart](/solutions/company-wallets/quickstart).
+
+## Powered by Turnkey
+
+Teams managing high-value contracts use Turnkey for policy-enforced signing at every stage:
+
+- [**Polymarket**](/solutions/cookbooks/polymarket-builders) transitioned to Turnkey for secure contract interactions at scale, including Safe deployment and gasless trading infrastructure.
+- [**Brale**](/solutions/cookbooks/brale) uses Turnkey's policy engine to constrain stablecoin minting and transfer operations to an allowlist of approved contracts.
+
+Turnkey also fits **existing** contract deployments. You don't need to redeploy to start managing signing through Turnkey.
+
+## Key implementation decisions
+
+| Decision | What to consider |
+| :--- | :--- |
+| Role isolation | Separate wallets for deployer, operator, and upgrade owner so each role has its own keys and scoped policies |
+| Deployment permissions | Policy scoping the deployer to a specific wallet and network |
+| Function-level controls | Policies targeting specific contract addresses and function signatures, or [upload the ABI](/features/policies/smart-contract-interfaces) for full parsing |
+| Value thresholds | Automated approval for routine operations (small mints), multi-party consensus for large ones |
+| Upgrade controls | Grant upgrade permissions only when needed via temporary policies, then revoke immediately after |
+
+## Example: stablecoins and RWAs
+
+Stablecoins and tokenized Real-World Assets often secure billions of dollars in value. These contracts typically involve minting, burning, pausing, and upgrades, each requiring different levels of authorization.
+
+| Need | How Turnkey solves it |
+| :--- | :--- |
+| Minting must be constrained to approved limits | Policies can bound mint amounts and require multi-party approval above a threshold via [smart contract interfaces](/features/policies/smart-contract-interfaces) |
+| Only authorized addresses can receive new supply | Policies target specific contract addresses and function arguments, restricting who the `mint` recipient can be |
+| Must support emergency pause | A dedicated pause operator wallet with a scoped policy for the `pause` function, separate from day-to-day minting |
+| Upgrades must not introduce unreviewed logic | Temporary upgrade policies with multi-party consensus, revoked immediately after execution |
+| Full audit trail of every operation | Every signing action is an activity in Turnkey with a complete audit log of who approved what and when |
+
+
+
+### Implementation steps
+
+
+ This guide assumes you've completed the [Quickstart](/solutions/company-wallets/quickstart) and have a Turnkey client initialized. If not, start there first.
+
+
+
+
+
+Deployment is strictly permissioned. A designated deployer user must have a policy that explicitly grants them permission to sign the deployment transaction for a specific wallet and network.
+
+```json
+{
+ "policyName": "Allow deployer to deploy on Base",
+ "effect": "EFFECT_ALLOW",
+ "consensus": "approvers.any(user, user.id == '')",
+ "condition": "activity.action == 'SIGN' && wallet.id == '' && eth.tx.to == '' && eth.tx.chain_id == '8453'"
+}
+```
+
+The `eth.tx.to == ''` condition matches contract creation transactions (where the `to` field is empty). Combined with a chain ID constraint, this ensures the deployer can only deploy on the intended network.
+
+
+
+
+
+Once deployed, interactions like minting new token supply are governed by precise policies. For example, a minting policy can be configured to:
+
+- Allow a specific operator user to sign
+- Require the transaction to originate from a designated wallet
+- Target the deployed contract's exact address
+- Call only the `mint` function
+
+```json
+{
+ "policyName": "Allow minter to mint tokens",
+ "effect": "EFFECT_ALLOW",
+ "consensus": "approvers.any(user, user.id == '')",
+ "condition": "activity.action == 'SIGN' && wallet.id == '' && eth.tx.to == '' && eth.tx.data[0..10] == '0x40c10f19'"
+}
+```
+
+The `0x40c10f19` value is the function selector for `mint(address,uint256)`. For production use, the recommended approach is to [upload the contract ABI](/features/policies/smart-contract-interfaces) so policies can reference function names and constrain arguments directly (e.g., bounding mint amounts or requiring multi-party approval above a threshold).
+
+
+
+
+
+Upgrading a contract redirects the underlying implementation logic, making it one of the most sensitive operations. Turnkey minimizes the risk window:
+
+1. Designate a specific upgrade owner wallet (separate from the operator wallet).
+2. Create a temporary, highly restrictive policy **only when an upgrade is needed**, granting the upgrade owner permission to sign the upgrade transaction.
+3. Once the upgrade is complete, remove the policy. The wallet remains dormant and secured until the next upgrade.
+
+```json
+{
+ "policyName": "Temporary: allow upgrade owner to upgrade proxy",
+ "effect": "EFFECT_ALLOW",
+ "consensus": "approvers.any(user, user.id == '')",
+ "condition": "activity.action == 'SIGN' && wallet.id == '' && eth.tx.to == '' && eth.tx.data[0..10] == '0x3659cfe6'"
+}
+```
+
+The `0x3659cfe6` selector matches `upgradeTo(address)`. After the upgrade completes, delete this policy to close the window.
+
+
+
+
+
+ This lifecycle is further explored in the [Smart Contract Management demo](https://github.com/tkhq/solutions/tree/main/smart-contract-mgmt) on GitHub.
+
+
+## Next steps
+
+
+
+
+
+
+
diff --git a/cookbook/0x.mdx b/solutions/cookbooks/0x.mdx
similarity index 98%
rename from cookbook/0x.mdx
rename to solutions/cookbooks/0x.mdx
index 74d7d81b..3f312034 100644
--- a/cookbook/0x.mdx
+++ b/solutions/cookbooks/0x.mdx
@@ -13,7 +13,7 @@ We'll demonstrate this using the [`with-0x`](https://github.com/tkhq/sdk/tree/ma
## Getting started
-Before you begin, make sure you’ve followed the [Turnkey Quickstart guide](/getting-started/quickstart).
+Before you begin, make sure you’ve followed the [Turnkey Quickstart guide](/get-started/quickstart).
You should have:
- A Turnkey **organization** and **Auth Proxy Config ID**
@@ -218,7 +218,7 @@ if (currentAllowance < parseUnits(fromAmount, 6)) {
## Summary
-✅ You’ve now learned how to:
+You’ve now learned how to:
- Authenticate with Turnkey via @turnkey/react-wallet-kit
diff --git a/cookbook/aave.mdx b/solutions/cookbooks/aave.mdx
similarity index 99%
rename from cookbook/aave.mdx
rename to solutions/cookbooks/aave.mdx
index f6b5ea5f..fd51d9ae 100644
--- a/cookbook/aave.mdx
+++ b/solutions/cookbooks/aave.mdx
@@ -13,7 +13,7 @@ A working example can be found [here](https://github.com/tkhq/sdk/tree/main/exam
## Getting started
-The first step is to set up your Turnkey organization and account. By following the [Quickstart guide](/getting-started/quickstart), you should have:
+The first step is to set up your Turnkey organization and account. By following the [Quickstart guide](/get-started/quickstart), you should have:
- A root user with a public/private API key pair within the Turnkey parent organization
- An organization ID
diff --git a/cookbook/base-builder-codes.mdx b/solutions/cookbooks/base-builder-codes.mdx
similarity index 96%
rename from cookbook/base-builder-codes.mdx
rename to solutions/cookbooks/base-builder-codes.mdx
index ced71d33..7fde64b9 100644
--- a/cookbook/base-builder-codes.mdx
+++ b/solutions/cookbooks/base-builder-codes.mdx
@@ -1,6 +1,6 @@
---
title: "Builder codes with Turnkey on Base"
-sidebarTitle: "Base Builders"
+sidebarTitle: "Base builders"
---
## Overview
@@ -11,7 +11,7 @@ By appending an encoded Builder Code to transaction data, you can track usage an
## Getting started
-The first step is to set up your Turnkey organization and account. By following the [Quickstart guide](/getting-started/quickstart), you should have:
+The first step is to set up your Turnkey organization and account. By following the [Quickstart guide](/get-started/quickstart), you should have:
- A root user with a public/private API key pair within the Turnkey parent organization
- An organization ID
@@ -145,4 +145,4 @@ To confirm your Builder Code is being appended correctly:
- [Base Builder Codes documentation](https://docs.base.org/base-chain/builder-codes/builder-codes)
- [ERC-8021 specification](https://www.erc8021.com/)
- [Turnkey viem integration](/sdks/web3/viem)
-- [Turnkey policy engine](/concepts/policies/overview)
+- [Turnkey policy engine](/features/policies/overview)
diff --git a/cookbook/brale.mdx b/solutions/cookbooks/brale.mdx
similarity index 100%
rename from cookbook/brale.mdx
rename to solutions/cookbooks/brale.mdx
diff --git a/cookbook/breeze.mdx b/solutions/cookbooks/breeze.mdx
similarity index 98%
rename from cookbook/breeze.mdx
rename to solutions/cookbooks/breeze.mdx
index 3cb533a5..e50e18c2 100644
--- a/cookbook/breeze.mdx
+++ b/solutions/cookbooks/breeze.mdx
@@ -13,7 +13,7 @@ We'll demonstrate this using the [`with-breeze`](https://github.com/tkhq/sdk/tre
## Getting started
-Before you begin, make sure you’ve followed the [Turnkey Quickstart guide](/getting-started/quickstart).
+Before you begin, make sure you’ve followed the [Turnkey Quickstart guide](/get-started/quickstart).
You should have
- A Turnkey **organization** and **Auth Proxy Config ID**
@@ -224,7 +224,7 @@ async function handleCheckData(userId: string) {
## Summary
-✅ You’ve now learned how to:
+You’ve now learned how to:
- Authenticate with Turnkey via @turnkey/react-wallet-kit
diff --git a/cookbook/jupiter.mdx b/solutions/cookbooks/jupiter.mdx
similarity index 98%
rename from cookbook/jupiter.mdx
rename to solutions/cookbooks/jupiter.mdx
index b21b538e..04b219e1 100644
--- a/cookbook/jupiter.mdx
+++ b/solutions/cookbooks/jupiter.mdx
@@ -14,7 +14,7 @@ You’ll learn how to authenticate with Turnkey, load a wallet, and use it to cr
## Getting started
-Before you begin, make sure you’ve followed the [Turnkey Quickstart guide](/getting-started/quickstart).
+Before you begin, make sure you’ve followed the [Turnkey Quickstart guide](/get-started/quickstart).
You should have:
- A Turnkey **organization** and **Auth Proxy Config ID**
@@ -266,7 +266,7 @@ console.log("User balances:", JSON.stringify(balancesResponse, null, 2));
## Summary
-✅ You’ve now learned how to:
+You’ve now learned how to:
- Authenticate a user with Turnkey
diff --git a/solutions/cookbooks/landing.mdx b/solutions/cookbooks/landing.mdx
new file mode 100644
index 00000000..eea0eebf
--- /dev/null
+++ b/solutions/cookbooks/landing.mdx
@@ -0,0 +1,83 @@
+---
+title: "Cookbooks"
+description: "Step-by-step guides for integrating Turnkey with protocols, platforms, and services."
+sidebarTitle: "Overview"
+slug: "cookbook/landing"
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx';
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cookbook/lifi.mdx b/solutions/cookbooks/lifi.mdx
similarity index 99%
rename from cookbook/lifi.mdx
rename to solutions/cookbooks/lifi.mdx
index 725ea08b..417ef26e 100644
--- a/cookbook/lifi.mdx
+++ b/solutions/cookbooks/lifi.mdx
@@ -13,7 +13,7 @@ We'll demonstrate this using the [`with-lifi`](https://github.com/tkhq/sdk/tree/
## Getting started
-Before you begin, make sure you’ve followed the [Turnkey Quickstart guide](/getting-started/quickstart).
+Before you begin, make sure you’ve followed the [Turnkey Quickstart guide](/get-started/quickstart).
You should have:
- A Turnkey **organization** and **Auth Proxy Config ID**
@@ -248,7 +248,7 @@ async function getStatus() {
## Summary
-✅ You’ve now learned how to:
+You’ve now learned how to:
- Authenticate with Turnkey via @turnkey/react-wallet-kit
diff --git a/cookbook/morpho.mdx b/solutions/cookbooks/morpho.mdx
similarity index 99%
rename from cookbook/morpho.mdx
rename to solutions/cookbooks/morpho.mdx
index be0ae82b..46f79449 100644
--- a/cookbook/morpho.mdx
+++ b/solutions/cookbooks/morpho.mdx
@@ -13,7 +13,7 @@ The working example can be found [here](https://github.com/tkhq/sdk/tree/main/ex
## Getting started
-The first step is to set up your Turnkey organization and account. By following the [Quickstart guide](/getting-started/quickstart), you should have:
+The first step is to set up your Turnkey organization and account. By following the [Quickstart guide](/get-started/quickstart), you should have:
- A root user with a public/private API key pair within the Turnkey parent organization
- An organization ID
diff --git a/cookbook/polymarket-builders.mdx b/solutions/cookbooks/polymarket-builders.mdx
similarity index 99%
rename from cookbook/polymarket-builders.mdx
rename to solutions/cookbooks/polymarket-builders.mdx
index cf4015d8..c2698ce6 100644
--- a/cookbook/polymarket-builders.mdx
+++ b/solutions/cookbooks/polymarket-builders.mdx
@@ -1,6 +1,6 @@
---
title: 'Polymarket builders with Turnkey'
-sidebarTitle: "Polymarket Builders"
+sidebarTitle: "Polymarket builders"
---
## Overview
diff --git a/cookbook/relay.mdx b/solutions/cookbooks/relay.mdx
similarity index 97%
rename from cookbook/relay.mdx
rename to solutions/cookbooks/relay.mdx
index 41f6cd06..a1154ec9 100644
--- a/cookbook/relay.mdx
+++ b/solutions/cookbooks/relay.mdx
@@ -161,7 +161,7 @@ For a real-time stream instead of polling, you can use [Relay’s WebSocket API]
## Handling EIP-191 and EIP-712 signatures
-Some Relay steps (particularly for swaps) require off-chain signatures before the deposit transaction. Handle both signature kinds with the Turnkey-backed viem wallet client:
+Some Relay steps (particularly for swaps) require offchain signatures before the deposit transaction. Handle both signature kinds with the Turnkey-backed viem wallet client:
```tsx
"use client";
@@ -193,7 +193,7 @@ async function signItem(walletClient: WalletClient, item: StepItem): Promise **TIP:** This can be a wallet contained within your parent organization
+
+ - Initialize the staking activity by calling the
+ [freezeBalanceV2](https://developers.tron.network/reference/freezebalancev2-1) function
+
+ > Refer to Tron Network’s [official documentation](https://developers.tron.network/docs/) for
+ > further information
+
+2. **Delegate the resource to end-user wallets**
+ - After you’ve initialized the staking operation using freezeBalanceV2 (Step 1) you’re now able
+ to delegate the resources to end-user wallets
+ - From the staking wallet, make a call to the Tron network using
+ [DelegateResource](https://developers.tron.network/reference/delegateresource-1) function
+ - `owner_address`: Wallet that is staking TRX (Step 1A)
+ - `receiver_address`: Wallet controlled by the end-user
+ - `resource`: The resource you’re delegating, bandwidth
+3. **Transaction flow (end-user)**
+ - After the staking has been initialized and resources delegated, the user experience is trivial:
+ end-user wallets (receiver_address) can transact via the Tron network without needing to
+ provide gas for their own transactions.
+
+### **Leveraging delegateResource smart contract function**
+
+As shown above, we are leveraging the existing
+[DelegateResource](https://developers.tron.network/reference/delegateresource-1) call to delegate
+bandwidth or energy resources to other accounts. Note that this operation requires you to have
+Tron’s native network token TRX staked in order to fund end-user’s transactions.
+
+```shellscript
+{
+ "owner_address": "TZ4UXDV5ZhNW7fb2AMSbgfAEZ7hWsnYS2g",
+ "receiver_address": "TPswDDCAWhJAZGdHPidFg5nEf8TkNToDX1",
+ "balance": 1000000,
+ "resource": "BANDWIDTH",
+ "lock": false,
+ "visible": true
+}
+```
+
+> **Remember**: In the context of Tron, `owner_address` will be the Turnkey wallet that holds and
+> stakes TRX. The `receiver_address` will be the end-user wallets.
+
+### **Thinking about gasless transactions for other chains?**
+
+If you have questions, feedback, or find yourself in need of a gas abstraction or integration that
+doesn’t exist yet, please get in touch with us! You can
+
+- Join our slack community
+ [here](https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ)
+- Contact us at [hello@turnkey.com](mailto:hello@turnkey.com)
diff --git a/cookbook/yieldxyz.mdx b/solutions/cookbooks/yieldxyz.mdx
similarity index 100%
rename from cookbook/yieldxyz.mdx
rename to solutions/cookbooks/yieldxyz.mdx
diff --git a/solutions/embedded-wallets/embedded-business-wallets.mdx b/solutions/embedded-wallets/embedded-business-wallets.mdx
new file mode 100644
index 00000000..6b8d2fac
--- /dev/null
+++ b/solutions/embedded-wallets/embedded-business-wallets.mdx
@@ -0,0 +1,61 @@
+---
+title: "Embedded Business Wallets"
+description: "Shared wallets with role-based signing controls for teams, operators, and finance workflows."
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
+With Turnkey, your application can provision wallets designed for team usage. Multiple end users operate within a single sub-organization with role-based access control governed by the policy engine. No seed phrases, no browser extensions.
+
+## Architecture at a glance
+
+Your parent organization sits at the top with read-only visibility. Each business customer gets its own sub-organization — fully isolated, with independent wallets, team members, and policy configurations.
+
+
+ 
+
+
+## Powered by Turnkey
+
+- [**Mural Pay**](https://www.turnkey.com/customers/mural-pay-cross-border-payments) -- cross-border stablecoin payments platform processing 5,000+ monthly transactions for global businesses, fintechs, and banks
+- [**AllScale**](https://www.turnkey.com/customers/allscale-cross-border-stablecoin-transactions) -- stablecoin neobank where small businesses manage payments with team-based wallet access
+
+## Key implementation decisions
+
+Turnkey enables developers to build shared business wallets with role-based controls across dimensions such as organization hierarchy, access control, and custody. See the key implementation decisions below to curate the exact experience your business customers need.
+
+| Decision | Explanation | Learn more |
+| :------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| **Organization hierarchy** | Create a sub-organization for each business customer. Each sub-org is a fully isolated environment with its own wallets, users, and policies. | [Sub-Organizations](/features/sub-organizations) |
+| **Role-based access control** | Assign roles to users via tags (e.g. `finance-team`, `operator`, `admin`). Write policies that reference these roles to control who can sign, what they can sign, and under what conditions. | [Policies](/features/policies/overview), [Policy Language](/features/policies/language) |
+| **Policies and guardrails** | With roles in place, enforce spending limits, require multi-party approval for high-value transactions, restrict payments to allowlisted addresses, or require quorum for policy changes. Optionally let business customers configure their own guardrails. | [Policies](/features/policies/overview), [Delegated Access](/features/policies/delegated-access/overview) |
+| **Custody model** | Choose who can authorize the enclave to sign: the user only (non-custodial), your application (custodial), or both with scoped permissions (hybrid). Business wallets commonly use hybrid custody with policy-backed controls. | [Custody models](/solutions/embedded-wallets/overview#custody-models) |
+| **Authentication methods** | Choose user auth methods: Passkeys, OAuth/email, or SMS. You can use the [Auth Proxy](/features/authentication/auth-proxy) for backend-signed OTP/OAuth/signup without your own backend, or wire auth to your app. | [Authentication Overview](/features/authentication/overview), [Auth Proxy](/features/authentication/auth-proxy) |
+| **Session management** | Allow a user to take multiple, contiguous actions in a defined period of time. Actions include: Read-write or read-only. | [Sessions](/features/authentication/sessions) |
+| **Gas sponsorship** | Integrate a gasless UX via sponsored transactions to cover who pays gas and how transactions are broadcast. | [Transaction Management](/features/transaction-management), [Sending sponsored transactions](/features/transaction-management/sending-sponsored-transactions) |
+| **Key portability** | Determine whether users can import or export keys. | [Import wallets](/features/wallets/import-wallets), [Export wallets](/features/wallets/export-wallets) |
+| **Recovery flows** | Define how users regain access if they lose their authenticator. Options include email recovery and backup passkeys. | [Email recovery](/features/authentication/email) |
+| **Agent-delegated signing** | Let end users grant scoped signing authority to AI agents or automated systems from their own wallet. The user retains root control and can revoke access at any time. | [End-User Delegated Agent Signing](/features/policies/delegated-access/agentic-wallets) |
+
+## Example: Payments platform with role-based controls
+
+Typical requirements and how Turnkey addresses them:
+
+| Requirement | Turnkey capability |
+| :-------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Multi-user team access | One [sub-organization](/features/sub-organizations) per business customer with isolated wallets, users, and [role-based policies](/features/policies/overview) |
+| Non-custodial with oversight | Hybrid custody with [policy engine](/features/policies/overview) controls. See [Custody models](/solutions/embedded-wallets/overview#custody-models) |
+| Multi-party approval | [Policies](/features/policies/language) requiring 2+ approvers for high-value transactions or policy changes |
+| Vendor and recipient controls | Allowlisted addresses and spending limits via [policy language](/features/policies/language) |
+| Familiar auth for non-crypto users | Passkey and email authentication with [email recovery](/features/authentication/email). No seed phrases |
+| Cross-border payments | Chain-agnostic derivation and signing. See [Networks](/features/networks/overview) and [Wallets Concept](/features/wallets) |
+| Gasless UX | [Sponsored transactions](/features/transaction-management) and [sending sponsored transactions](/features/transaction-management/sending-sponsored-transactions) |
+| Fast integration | Use the [Embedded Wallet Kit](/solutions/embedded-wallets/integration-guide/react/index) for built-in auth and wallet UI components. See [Quickstart](/solutions/embedded-wallets/quickstart) |
+
+## Next steps
+
+
+
+
+
diff --git a/solutions/embedded-wallets/embedded-consumer-wallet.mdx b/solutions/embedded-wallets/embedded-consumer-wallet.mdx
new file mode 100644
index 00000000..e9c1554b
--- /dev/null
+++ b/solutions/embedded-wallets/embedded-consumer-wallet.mdx
@@ -0,0 +1,64 @@
+---
+title: "Embedded Consumer Wallet"
+description: "Give every user of your application their own wallet, provisioned automatically at signup."
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx';
+
+With Turnkey, you can provision a dedicated wallet for every user as part of your application's signup flow, at any scale. Users authenticate with familiar methods like passkeys, email, or social login. They never manage keys or install extensions.
+
+## Powered by Turnkey
+
+- [**Moonshot**](https://www.turnkey.com/customers/how-moonshot-powers-millions-of-self-custodial-wallets-using-turnkey) -- millions of self-custodial wallets powering one of crypto's fastest-growing consumer apps
+- [**Infinex**](https://www.turnkey.com/customers/making-onchain-ux-seamless-with-infinex-and-turnkey) -- seamless onchain UX for a unified DeFi experience
+- [**Axiom**](https://www.turnkey.com/customers/axiom-global-defi-trading-platform) -- global DeFi trading platform with embedded wallet infrastructure
+
+## Key implementation decisions
+
+Turnkey enables developers to tailor non-custodial, embedded user wallets across dimensions such as
+custody model, authentication, and more. See the key implementation decisions below to curate the
+exact user experience you need.
+
+| Decision | Explanation | Learn more |
+| :------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| **Custody model** | Choose who can authorize the enclave to sign: the user only (non-custodial), your application (custodial), or both with scoped permissions (hybrid). | [Custody models](/solutions/embedded-wallets/overview#custody-models) |
+| **Authentication methods** | Choose user auth methods: Passkeys, OAuth/email, or SMS. You can use the [Auth Proxy](/features/authentication/auth-proxy) for backend-signed OTP/OAuth/signup without your own backend, or wire auth to your app. | [Authentication Overview](/features/authentication/overview), [Auth Proxy](/features/authentication/auth-proxy) |
+| **Policies and guardrails** | Set guardrails for what your end users can do, such as spending limits, allowed destinations, or multi-party approval. Optionally let users configure their own guardrails within your app. | [Policies](/features/policies/overview), [Delegated Access](/features/policies/delegated-access/overview) |
+| **Session management** | Allow a user to take multiple, contiguous actions in a defined period of time. Actions include: Read-write or read-only. | [Sessions](/features/authentication/sessions) |
+| **Wallet architecture** | Choose between key-based (HD) or smart contract wallets for your users. Turnkey supports both. | [Wallets Concept](/features/wallets), [Transaction Management](/features/transaction-management) |
+| **Gas sponsorship** | Integrate a gasless UX via sponsored transactions to cover who pays gas and how transactions are broadcast. | [Transaction Management](/features/transaction-management), [Sending sponsored transactions](/features/transaction-management/sending-sponsored-transactions) |
+| **Key portability** | Determine whether users can import or export keys. | [Import wallets](/features/wallets/import-wallets), [Export wallets](/features/wallets/export-wallets) |
+| **Recovery flows** | Define how users regain access if they lose their authenticator. Options include email recovery and backup passkeys. | [Email recovery](/features/authentication/email) |
+| **Agent-delegated signing** | Let end users grant scoped signing authority to AI agents or automated systems from their own wallet. The user retains root control and can revoke access at any time. | [End-User Delegated Agent Signing](/features/policies/delegated-access/agentic-wallets) |
+
+## Example: Neobank-style embedded consumer wallet
+
+Typical requirements and how Turnkey addresses them:
+
+| Requirement | Turnkey capability |
+| :-------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Seamless onboarding | Passkey registration and automated wallet provisioning. See [Quickstart](/solutions/embedded-wallets/quickstart) or [Integration Guide](/solutions/embedded-wallets/integration-guide/overview) |
+| User custody without key exposure | Keys remain in [secure enclaves](/security/secure-enclaves); only signatures are returned. See [Security](/security/our-approach) |
+| Gasless UX | [Sponsored transactions](/features/transaction-management) and [sending sponsored transactions](/features/transaction-management/sending-sponsored-transactions) |
+| Email-based auth and recovery | [Sub-organization recovery](/features/authentication/email) |
+| Send without wallet setup | [Claim links](/features/wallets/claim-links#claim-links): send via URL; recipient claims with email |
+| Backend automation | [Delegated access](/features/policies/delegated-access/overview) and scoped signing policies |
+| Multichain support | Chain-agnostic derivation and signing. See [Networks](/features/networks/overview) and [Wallets Concept](/features/wallets) |
+| Fast integration | Use the [Embedded Wallet Kit](/solutions/embedded-wallets/integration-guide/react/index) for built-in auth and wallet UI components. See [Quickstart](/solutions/embedded-wallets/quickstart) |
+
+## Next steps
+
+
+
+
+
diff --git a/solutions/embedded-wallets/embedded-waas.mdx b/solutions/embedded-wallets/embedded-waas.mdx
new file mode 100644
index 00000000..0d650751
--- /dev/null
+++ b/solutions/embedded-wallets/embedded-waas.mdx
@@ -0,0 +1,176 @@
+---
+title: "Embedded Wallet-as-a-Service"
+sidebarTitle: "Wallet-as-a-Service"
+description: "Distribute embedded wallets through your developer platform with co-signing authority, billing gates, and compliance controls."
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
+With Turnkey, you can build a platform that distributes embedded wallets to your own customers. Your platform abstracts Turnkey behind your own SDK, APIs, or UI components. A 2-of-2 root quorum model gives your platform co-signing authority over every transaction, enabling billing gates, compliance checks, and risk controls at the infrastructure layer, while end users remain non-custodial.
+
+## Powered by Turnkey
+
+- [**DIMO**](https://www.turnkey.com/customers/how-dimo-is-bringing-transportation-solutions-onchain-with-turnkey) -- decentralized transportation network with 165,000+ connected vehicles. 90% reduction in onboarding time, 30% increase in completion rates. Built their own [transactions SDK](https://github.com/DIMO-Network/transactions) on Turnkey's infrastructure
+
+## What makes Wallet-as-a-Service different
+
+With [consumer wallets](/solutions/embedded-wallets/embedded-consumer-wallet) and [business wallets](/solutions/embedded-wallets/embedded-business-wallets), your application integrates Turnkey directly and manages wallets for end users. With Wallet-as-a-Service, your platform is an intermediary layer: you build wallet infrastructure on top of Turnkey, and your customers integrate with your SDK rather than Turnkey directly.
+
+The defining pattern is the **2-of-2 root quorum**. Both the end user and your platform must approve every fund-moving transaction. The end user authenticates via passkey (or equivalent), then your platform evaluates its own rules (billing status, compliance, risk) before co-signing. If either party withholds approval, the transaction does not execute.
+
+No transaction executes without the end user's authentication. End users remain non-custodial because they can always [export their keys](/features/wallets/export-wallets) independently, without platform approval.
+
+### When to use Wallet-as-a-Service
+
+| Scenario | Why Wallet-as-a-Service fits |
+| :-------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------- |
+| Your customers embed wallets through your SDK, not Turnkey's | You own the developer experience end-to-end. Downstream integrators never interact with Turnkey directly. |
+| You need platform-level co-signing on every transaction | 2-of-2 root quorum lets your platform enforce billing gates, compliance checks, or risk controls before any fund-moving transaction. |
+| You want to white-label wallet infrastructure | Fork or wrap the Embedded Wallet Kit with your branding and expose your own APIs. Turnkey is invisible to your customers. |
+
+## Architecture
+
+Each end user maps to a [Turnkey sub-organization](/features/sub-organizations). The sub-org contains the user's wallets, credentials, policies, and activity logs, fully isolated from other users and from your platform's management layer.
+
+
+
+
+
+### Transaction authorization flow
+
+1. End user initiates a transaction from your embedded wallet UI
+2. End user approves via their authenticator (e.g. passkey). Turnkey records the activity as partially approved
+3. Your platform evaluates on its backend: billing status, risk/compliance rules, and any other checks
+4. Your platform approves via API key and the transaction executes
+5. If the platform withholds approval, the transaction does not execute
+
+
+
+
+
+See [Activities and approvals](/get-started/about-turnkey#activities) and [Root quorum](/features/users/root-quorum).
+
+## Implementation
+
+### Step 1: Define the tenant model
+
+Map each end user to a [sub-organization](/features/sub-organizations). One sub-org per end user.
+
+- **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.
+
+See [Sub-organizations](/features/sub-organizations) and [Root quorum](/features/users/root-quorum).
+
+### Step 2: Design the sub-organization control model
+
+Define what lives inside each sub-org and how control is shared between your platform and the end user.
+
+- **End user (root):** Authenticated via passkey or equivalent user-controlled authenticator.
+- **Platform provider (root):** Authenticated via API key. Used to approve or block transactions based on your service rules.
+- **Delegated access (optional):** For automation or backend-initiated workflows, add a scoped non-root API key via [Delegated Access](/features/policies/delegated-access/overview). This must be tightly policy-scoped and should never have broad signing authority or bypass user consent.
+
+See [Delegated Access](/features/policies/delegated-access/overview) and [Policies](/features/policies/overview).
+
+### Step 3: Create sub-org with wallet and export policy
+
+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 your platform can configure policies (including export) with only your platform's approval. Once the 2-of-2 quorum is established, the end user can trigger exports via the export policy without needing your platform's co-signature. This keeps the co-managed model non-custodial: 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: "Platform", 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],
+ },
+});
+```
+
+See [Export wallets](/features/wallets/export-wallets) and [Policy examples](/features/policies/examples/access-control).
+
+### Step 4: Build your integration surface
+
+Create the SDK, APIs, or UI components that downstream developers will integrate with. Abstract Turnkey and expose only your platform's intended wallet, auth, and signing flows.
+
+- **Embedded Wallet Kit (EWK):** Fork or wrap [EWK](/solutions/embedded-wallets/integration-guide/react/index) components (authentication, wallet UI, approval prompts) with your branding. Surface "pending platform approval" states in the transaction flow.
+- **Backend service:** Handle platform 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.
+
+See [Embedded Wallet Kit](/solutions/embedded-wallets/integration-guide/react/index) and [SDK Reference](/sdks/introduction).
+
+### Step 5: Wire the wallet into your platform flow
+
+Integrate 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 user registration. The end user should experience passkey registration 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](/features/authentication/sessions) for batched signing workflows to reduce authentication friction.
+- **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.
+
+## Next steps
+
+
+
+
+
diff --git a/sdks/flutter/advanced-api-requests.mdx b/solutions/embedded-wallets/integration-guide/flutter/advanced-api-requests.mdx
similarity index 92%
rename from sdks/flutter/advanced-api-requests.mdx
rename to solutions/embedded-wallets/integration-guide/flutter/advanced-api-requests.mdx
index cef999b2..1edd40cd 100644
--- a/sdks/flutter/advanced-api-requests.mdx
+++ b/solutions/embedded-wallets/integration-guide/flutter/advanced-api-requests.mdx
@@ -15,7 +15,7 @@ However, you can also make advanced API requests directly to Turnkey's endpoints
To make advanced API requests, use the `client` retrieved from the `TurnkeyProvider`.
This client is tied to the active session, so stamping, authentication, and organization context are automatically handled for you.
-You can see the [API Reference](/api-reference/overview) for a complete list of available API endpoints and their parameters. All of these can be accessed through the `client`.
+You can see the [API Reference](/api-reference/overview/intro) for a complete list of available API endpoints and their parameters. All of these can be accessed through the `client`.
Here's how you can use the `client` to make a `signRawPayload` request to Turnkey:
@@ -108,5 +108,5 @@ final passkeyClient = await tk.createPasskeyClient(
);
```
-To learn more about using passkeys in your Flutter app, check out the [Passkey Authentication](/sdks/flutter/authentication/passkey) guide.
+To learn more about using passkeys in your Flutter app, check out the [Passkey Authentication](/solutions/embedded-wallets/integration-guide/flutter/authentication/passkey) guide.
diff --git a/sdks/flutter/authentication/email-sms.mdx b/solutions/embedded-wallets/integration-guide/flutter/authentication/email-sms.mdx
similarity index 100%
rename from sdks/flutter/authentication/email-sms.mdx
rename to solutions/embedded-wallets/integration-guide/flutter/authentication/email-sms.mdx
diff --git a/sdks/flutter/authentication/overview.mdx b/solutions/embedded-wallets/integration-guide/flutter/authentication/overview.mdx
similarity index 84%
rename from sdks/flutter/authentication/overview.mdx
rename to solutions/embedded-wallets/integration-guide/flutter/authentication/overview.mdx
index 15989f21..3c37298c 100644
--- a/sdks/flutter/authentication/overview.mdx
+++ b/solutions/embedded-wallets/integration-guide/flutter/authentication/overview.mdx
@@ -4,6 +4,8 @@ description: "Learn how to set up, log in, or sign up easily in your Flutter app
sidebarTitle: "Overview"
---
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
Turnkey's Flutter SDK makes authentication simple. You can call specific login and signup functions (email/SMS OTP, passkeys, or social logins) to build your own UI and auth flow.
## Authentication state
@@ -132,36 +134,12 @@ class DashboardScreenState extends State {
## Customize sub-organization creation
-Need to configure default user names, passkey names, wallet creations or anything sub-org related? You can learn more about customizing the sub-orgs you create in the [Sub-Organization Customization](/sdks/flutter/sub-organization-customization).
+Need to configure default user names, passkey names, wallet creations or anything sub-org related? You can learn more about customizing the sub-orgs you create in the [Sub-Organization Customization](/solutions/embedded-wallets/integration-guide/flutter/sub-organization-customization).
Follow the guides below to learn how to set up email and SMS authentication, passkey authentication, and social logins in your Flutter app.
-
-
- Learn how to set up email and SMS authentication in your Flutter app.
-
-
- Learn how to set up passkey authentication in your Flutter app.
-
-
- Discover how to add social logins (Google, Apple, X, Discord) and handle wallet creation and account derivation.
-
-
\ No newline at end of file
+
+
+
+
+
\ No newline at end of file
diff --git a/sdks/flutter/authentication/passkey.mdx b/solutions/embedded-wallets/integration-guide/flutter/authentication/passkey.mdx
similarity index 100%
rename from sdks/flutter/authentication/passkey.mdx
rename to solutions/embedded-wallets/integration-guide/flutter/authentication/passkey.mdx
diff --git a/sdks/flutter/authentication/social-logins.mdx b/solutions/embedded-wallets/integration-guide/flutter/authentication/social-logins.mdx
similarity index 98%
rename from sdks/flutter/authentication/social-logins.mdx
rename to solutions/embedded-wallets/integration-guide/flutter/authentication/social-logins.mdx
index 77fa6ebd..fe3fc6f1 100644
--- a/sdks/flutter/authentication/social-logins.mdx
+++ b/solutions/embedded-wallets/integration-guide/flutter/authentication/social-logins.mdx
@@ -11,7 +11,7 @@ Using OAuth requires configuration in the Turnkey Dashboard and in your app.
### Enabling OAuth
-Navigate to the **Wallet Kit** section in the [Turnkey Dashboard](https://app.turnkey.com/dashboard/walletKit) and enable **OAuth**. If you have not enabled the Auth Proxy, enable it first. See [Getting Started](/sdks/flutter/getting-started) for details.
+Navigate to the **Wallet Kit** section in the [Turnkey Dashboard](https://app.turnkey.com/dashboard/walletKit) and enable **OAuth**. If you have not enabled the Auth Proxy, enable it first. See [Getting Started](/solutions/embedded-wallets/integration-guide/flutter/getting-started) for details.
diff --git a/sdks/flutter/getting-started.mdx b/solutions/embedded-wallets/integration-guide/flutter/getting-started.mdx
similarity index 98%
rename from sdks/flutter/getting-started.mdx
rename to solutions/embedded-wallets/integration-guide/flutter/getting-started.mdx
index 6013c18c..b036b12b 100644
--- a/sdks/flutter/getting-started.mdx
+++ b/solutions/embedded-wallets/integration-guide/flutter/getting-started.mdx
@@ -6,7 +6,7 @@ sidebarTitle: "Getting started"
## Turnkey organization setup
-To start, you must create a Turnkey organization via the [Turnkey dashboard](https://app.turnkey.com). The steps to do so are described in the [Account Setup](/getting-started/quickstart) section.
+To start, you must create a Turnkey organization via the [Turnkey dashboard](https://app.turnkey.com). The steps to do so are described in the [Account Setup](/get-started/quickstart) section.
For this setup, we will be using Turnkey's Auth Proxy to handle authentication. We can enable and configure this through the Turnkey dashboard.
diff --git a/solutions/embedded-wallets/integration-guide/flutter/index.mdx b/solutions/embedded-wallets/integration-guide/flutter/index.mdx
new file mode 100644
index 00000000..f11b53c8
--- /dev/null
+++ b/solutions/embedded-wallets/integration-guide/flutter/index.mdx
@@ -0,0 +1,17 @@
+---
+title: "Overview"
+description: "Turnkey's Flutter SDK [`(turnkey_sdk_flutter)`](https://pub.dev/packages/turnkey_sdk_flutter) is the easiest way to integrate Turnkey’s Embedded Wallets into your Flutter applications. It supports both backendless setups via Turnkey’s managed [Auth Proxy](https://docs.turnkey.com/reference/auth-proxy) and traditional backend-based architectures. It provides a set of functions and utilities to interact with Turnkey's APIs, a powerful session management system, built-in stampers, and a raw HTTP client for advanced use cases."
+sidebarTitle: "Overview"
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
+Find `turnkey_sdk_flutter` on [pub.dev](https://pub.dev/packages/turnkey_sdk_flutter) or view the source code on [GitHub](https://github.com/tkhq/dart-sdk)! For a working reference implementation covering auth, wallet creation, export, and signing, see the [flutter-demo-app](https://github.com/tkhq/dart-sdk/tree/main/examples/flutter-demo-app) example app.
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sdks/flutter/signing.mdx b/solutions/embedded-wallets/integration-guide/flutter/signing.mdx
similarity index 100%
rename from sdks/flutter/signing.mdx
rename to solutions/embedded-wallets/integration-guide/flutter/signing.mdx
diff --git a/sdks/flutter/sub-organization-customization.mdx b/solutions/embedded-wallets/integration-guide/flutter/sub-organization-customization.mdx
similarity index 94%
rename from sdks/flutter/sub-organization-customization.mdx
rename to solutions/embedded-wallets/integration-guide/flutter/sub-organization-customization.mdx
index 83ee7401..b5da0e38 100644
--- a/sdks/flutter/sub-organization-customization.mdx
+++ b/solutions/embedded-wallets/integration-guide/flutter/sub-organization-customization.mdx
@@ -96,4 +96,4 @@ For a full list of parameters available, inspect the `CreateSubOrgParams` class
## Next steps
-Now that you can customize sub-org creation in Flutter, check out the [Using Embedded Wallets](/sdks/flutter/using-embedded-wallets) guide next to learn how to create and manage wallets within your app!
+Now that you can customize sub-org creation in Flutter, check out the [Using Embedded Wallets](/solutions/embedded-wallets/integration-guide/flutter/using-embedded-wallets) guide next to learn how to create and manage wallets within your app!
diff --git a/sdks/flutter/using-embedded-wallets.mdx b/solutions/embedded-wallets/integration-guide/flutter/using-embedded-wallets.mdx
similarity index 96%
rename from sdks/flutter/using-embedded-wallets.mdx
rename to solutions/embedded-wallets/integration-guide/flutter/using-embedded-wallets.mdx
index b9c31b76..703f227e 100644
--- a/sdks/flutter/using-embedded-wallets.mdx
+++ b/solutions/embedded-wallets/integration-guide/flutter/using-embedded-wallets.mdx
@@ -8,7 +8,7 @@ sidebarTitle: "Using embedded wallets"
Turnkey's Flutter SDK provides a straightforward way to create and manage embedded wallets in your Flutter application. You can create wallets, derive accounts, import wallets, and keep local UI state in sync with provider data.
-Before starting, review the concepts of **[Wallets](/concepts/wallets)** and **[Wallet Accounts](/concepts/wallets#accounts)**.
+Before starting, review the concepts of **[Wallets](/features/wallets)** and **[Wallet Accounts](/features/wallets#accounts)**.
## Creating an embedded wallet
@@ -250,7 +250,7 @@ class ExportWalletButton extends StatelessWidget {
## Next steps
-Continue to **[Signing](/sdks/flutter/signing)** to learn how to sign messages and transactions with your embedded wallets.
+Continue to **[Signing](/solutions/embedded-wallets/integration-guide/flutter/signing)** to learn how to sign messages and transactions with your embedded wallets.
diff --git a/sdks/kotlin/advanced-api-requests.mdx b/solutions/embedded-wallets/integration-guide/kotlin/advanced-api-requests.mdx
similarity index 96%
rename from sdks/kotlin/advanced-api-requests.mdx
rename to solutions/embedded-wallets/integration-guide/kotlin/advanced-api-requests.mdx
index 941654ee..21bf545d 100644
--- a/sdks/kotlin/advanced-api-requests.mdx
+++ b/solutions/embedded-wallets/integration-guide/kotlin/advanced-api-requests.mdx
@@ -13,7 +13,7 @@ However, you can also make advanced API requests directly to Turnkey's endpoints
To make advanced API requests, use the `client` from the `TurnkeyContext`.
-You can see the [API Reference](/api-reference/overview) for a complete list of available API endpoints and their parameters. All of these can be accessed through the `client`.
+You can see the [API Reference](/api-reference/overview/intro) for a complete list of available API endpoints and their parameters. All of these can be accessed through the `client`.
Here's how you can use the `client` to make a `signRawPayload` request to Turnkey:
diff --git a/sdks/kotlin/authentication/email-sms.mdx b/solutions/embedded-wallets/integration-guide/kotlin/authentication/email-sms.mdx
similarity index 100%
rename from sdks/kotlin/authentication/email-sms.mdx
rename to solutions/embedded-wallets/integration-guide/kotlin/authentication/email-sms.mdx
diff --git a/solutions/embedded-wallets/integration-guide/kotlin/authentication/overview.mdx b/solutions/embedded-wallets/integration-guide/kotlin/authentication/overview.mdx
new file mode 100644
index 00000000..64ca0f8d
--- /dev/null
+++ b/solutions/embedded-wallets/integration-guide/kotlin/authentication/overview.mdx
@@ -0,0 +1,32 @@
+---
+title: "Overview"
+description: "Learn how to set up, log in, or sign up easily in your Android app using the Turnkey Kotlin SDK."
+sidebarTitle: "Overview"
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
+The Kotlin SDK makes authentication simple.
+You can call specific login and signup functions to create your own UI components and authentication flow.
+
+## Authentication state
+
+To check if a user is authenticated, you can use the `authState` variable from the `TurnkeyContext`.
+
+```kotlin
+val authState: AuthState = TurnkeyContext.authState.value
+```
+
+## Customize sub-organization creation
+
+Need to configure default user names, passkey names, wallet creations or anything sub-org related?
+You can learn more about customizing the sub-orgs you create in the [Sub-Organization Customization](/solutions/embedded-wallets/integration-guide/kotlin/sub-organization-customization) section.
+
+Follow the guides below to learn how to set up email and SMS authentication, passkey authentication, and social logins in your Android app.
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sdks/kotlin/authentication/passkey.mdx b/solutions/embedded-wallets/integration-guide/kotlin/authentication/passkey.mdx
similarity index 95%
rename from sdks/kotlin/authentication/passkey.mdx
rename to solutions/embedded-wallets/integration-guide/kotlin/authentication/passkey.mdx
index 668af116..8e7cb7ca 100644
--- a/sdks/kotlin/authentication/passkey.mdx
+++ b/solutions/embedded-wallets/integration-guide/kotlin/authentication/passkey.mdx
@@ -12,7 +12,7 @@ You'll add the necessary platform configuration, set up the provider with a prop
## Passkey setup
To enable passkeys, you must configure your app's relying party ID (`rpId`) correctly.
-For Android, you must configure a Digital Asset Links by setting up an `assetlinks.json` file. Refer to [our relying party setup guide](/sdks/kotlin/authentication/rp-id-setup) and [Google's Documentation](https://developer.android.com/training/app-links/verify-android-applinks).
+For Android, you must configure a Digital Asset Links by setting up an `assetlinks.json` file. Refer to [our relying party setup guide](/solutions/embedded-wallets/integration-guide/kotlin/authentication/rp-id-setup) and [Google's Documentation](https://developer.android.com/training/app-links/verify-android-applinks).
### 1. Ensure `rpId` is set correctly in your Turnkey SDK initialization
diff --git a/sdks/kotlin/authentication/rp-id-setup.mdx b/solutions/embedded-wallets/integration-guide/kotlin/authentication/rp-id-setup.mdx
similarity index 100%
rename from sdks/kotlin/authentication/rp-id-setup.mdx
rename to solutions/embedded-wallets/integration-guide/kotlin/authentication/rp-id-setup.mdx
diff --git a/sdks/kotlin/authentication/social-logins.mdx b/solutions/embedded-wallets/integration-guide/kotlin/authentication/social-logins.mdx
similarity index 96%
rename from sdks/kotlin/authentication/social-logins.mdx
rename to solutions/embedded-wallets/integration-guide/kotlin/authentication/social-logins.mdx
index d0b6dcb6..b451a408 100644
--- a/sdks/kotlin/authentication/social-logins.mdx
+++ b/solutions/embedded-wallets/integration-guide/kotlin/authentication/social-logins.mdx
@@ -11,7 +11,7 @@ Using OAuth requires a bit of configuration in the Turnkey Dashboard and your ap
### Enabling OAuth
Navigate to the **Wallet Kit** section in the [Turnkey Dashboard](https://app.turnkey.com/dashboard/walletKit) and enable the
-**OAuth**. Note if you have not enabled the Auth Proxy, you will need to do so first. Check out the [Getting Started](/sdks/kotlin/getting-started) guide for more details.
+**OAuth**. Note if you have not enabled the Auth Proxy, you will need to do so first. Check out the [Getting Started](/solutions/embedded-wallets/integration-guide/kotlin/getting-started) guide for more details.
For OAuth2.0 providers, you will need to upload the client ID and secret in
the dashboard. Check out the [OAuth2.0
- providers](/sdks/kotlin/authentication/social-logins#oauth2-0-providers)
+ providers](/solutions/embedded-wallets/integration-guide/kotlin/authentication/social-logins#oauth2-0-providers)
section for more details.
diff --git a/sdks/kotlin/getting-started.mdx b/solutions/embedded-wallets/integration-guide/kotlin/getting-started.mdx
similarity index 93%
rename from sdks/kotlin/getting-started.mdx
rename to solutions/embedded-wallets/integration-guide/kotlin/getting-started.mdx
index f37ad756..dcb0a127 100644
--- a/sdks/kotlin/getting-started.mdx
+++ b/solutions/embedded-wallets/integration-guide/kotlin/getting-started.mdx
@@ -6,7 +6,7 @@ sidebarTitle: "Getting started"
## Turnkey organization setup
-To start, you must create a Turnkey organization via the [Turnkey dashboard](https://app.turnkey.com). The steps to do so are described in the [Account Setup](/getting-started/quickstart) section.
+To start, you must create a Turnkey organization via the [Turnkey dashboard](https://app.turnkey.com). The steps to do so are described in the [Account Setup](/get-started/quickstart) section.
For this setup, we will be using Turnkey's Auth Proxy to handle authentication. We can enable and configure this through the Turnkey dashboard.
@@ -144,6 +144,6 @@ lifecycleScope.launch {
## Next steps
Now that you have set up the Turnkey Kotlin SDK in your application, you can explore the following guides to implement authentication and wallet functionalities:
-- [Authentication Guide](/sdks/kotlin/authentication)
-- [Wallet Management Guide](/sdks/kotlin/wallet-management)
-- [Signing Guides](/sdks/kotlin/signing)
\ No newline at end of file
+- [Authentication Guide](/solutions/embedded-wallets/integration-guide/kotlin/authentication/overview)
+- [Wallet Management Guide](/solutions/embedded-wallets/integration-guide/kotlin/using-embedded-wallets)
+- [Signing Guides](/solutions/embedded-wallets/integration-guide/kotlin/signing)
\ No newline at end of file
diff --git a/solutions/embedded-wallets/integration-guide/kotlin/overview.mdx b/solutions/embedded-wallets/integration-guide/kotlin/overview.mdx
new file mode 100644
index 00000000..f00c3ab3
--- /dev/null
+++ b/solutions/embedded-wallets/integration-guide/kotlin/overview.mdx
@@ -0,0 +1,17 @@
+---
+title: "Overview"
+description: "Turnkey's Kotlin SDK is the easiest way to integrate Turnkey's Embedded Wallets into your Android applications. It supports both backendless setups via Turnkey’s managed [Auth Proxy](https://docs.turnkey.com/reference/auth-proxy) and traditional backend-based architectures. It provides easy-to-use functions accessible through a context provider, allowing you to quickly build secure embedded wallet experiences."
+sidebarTitle: "Overview"
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
+Find Turnkey's `kotlin-sdk` on [Maven Central](https://central.sonatype.com/artifact/com.turnkey/sdk-kotlin) or view the source code on [GitHub](https://github.com/tkhq/kotlin-sdk).
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sdks/kotlin/signing.mdx b/solutions/embedded-wallets/integration-guide/kotlin/signing.mdx
similarity index 100%
rename from sdks/kotlin/signing.mdx
rename to solutions/embedded-wallets/integration-guide/kotlin/signing.mdx
diff --git a/sdks/kotlin/sub-organization-customization.mdx b/solutions/embedded-wallets/integration-guide/kotlin/sub-organization-customization.mdx
similarity index 97%
rename from sdks/kotlin/sub-organization-customization.mdx
rename to solutions/embedded-wallets/integration-guide/kotlin/sub-organization-customization.mdx
index e95166f3..0d0bbbe1 100644
--- a/sdks/kotlin/sub-organization-customization.mdx
+++ b/solutions/embedded-wallets/integration-guide/kotlin/sub-organization-customization.mdx
@@ -160,5 +160,5 @@ Create a wallet (container) plus one or more accounts at signup.
## Next steps
-Now that you know how to customize the sub-orgs created in your Android application, check out the [Advanced API Requests](/sdks/kotlin/advanced-api-requests) guide to learn how to make advanced API requests to Turnkey's infrastructure.
+Now that you know how to customize the sub-orgs created in your Android application, check out the [Advanced API Requests](/solutions/embedded-wallets/integration-guide/kotlin/advanced-api-requests) guide to learn how to make advanced API requests to Turnkey's infrastructure.
This will help you build more complex features and functionalities in your app that go beyond what is included as helper functions in the SDK.
\ No newline at end of file
diff --git a/sdks/kotlin/using-embedded-wallets.mdx b/solutions/embedded-wallets/integration-guide/kotlin/using-embedded-wallets.mdx
similarity index 98%
rename from sdks/kotlin/using-embedded-wallets.mdx
rename to solutions/embedded-wallets/integration-guide/kotlin/using-embedded-wallets.mdx
index 45194950..1c7d6dde 100644
--- a/sdks/kotlin/using-embedded-wallets.mdx
+++ b/solutions/embedded-wallets/integration-guide/kotlin/using-embedded-wallets.mdx
@@ -8,7 +8,7 @@ sidebarTitle: "Using embedded wallets"
The Kotlin SDK allows you to create and manage embedded wallets in your Android application. This includes creating wallets, deriving wallet accounts, and accessing wallet information.
-Before we start, ensure you're familiar with the concepts of [Wallets](/concepts/wallets) and [Wallet Accounts](/concepts/wallets#accounts).
+Before we start, ensure you're familiar with the concepts of [Wallets](/features/wallets) and [Wallet Accounts](/features/wallets#accounts).
## Creating a wallet
@@ -394,4 +394,4 @@ class MainActivity : AppCompatActivity() {
## Next steps
-Check out the [Signing](/sdks/kotlin/signing) guide to learn how to sign transactions and messages with the embedded wallets you've created.
+Check out the [Signing](/solutions/embedded-wallets/integration-guide/kotlin/signing) guide to learn how to sign transactions and messages with the embedded wallets you've created.
diff --git a/solutions/embedded-wallets/integration-guide/overview.mdx b/solutions/embedded-wallets/integration-guide/overview.mdx
new file mode 100644
index 00000000..cee28c72
--- /dev/null
+++ b/solutions/embedded-wallets/integration-guide/overview.mdx
@@ -0,0 +1,145 @@
+---
+title: "Integration guide"
+description:
+ "An SDK-agnostic introduction to integrating Turnkey embedded wallets: how to choose your SDK, how
+ integrations are structured, and when to use the Auth Proxy."
+sidebarTitle: "Overview"
+---
+
+You've seen what Turnkey's embedded wallets can do. This page covers the concepts and architectural
+decisions that apply across all platforms before you dive into the platform-specific guides.
+
+## Choose your SDK
+
+Turnkey provides SDKs at different levels of abstraction. The right choice depends on your platform
+and how much you want pre-built for you.
+
+
+
+ Pre-built UI components, hook-based API, and no backend required. Recommended for React and
+ Next.js apps.
+
+
+ The mobile counterpart to the React wallet kit, optimized for mobile-native flows.
+
+
+ The underlying TypeScript SDK. Best for Angular, Vue, Svelte, or any web framework where the
+ React Wallet Kit doesn't apply.
+
+
+ Dart SDK — Cross-platform iOS and Android support.
+
+
+ Swift SDK — Native iOS integration.
+
+
+ Kotlin SDK — Native Android integration.
+
+
+ Call the Turnkey REST API directly from any language.
+
+
+
+## How integrations are structured
+
+Every Turnkey embedded wallet integration is built around the same model: **one sub-organization per
+user.**
+
+Your account is the **parent organization**. Each end user gets their own **sub-organization** — a
+fully isolated environment with its own wallets, credentials, and policies. Isolation is strict:
+credentials in one sub-org cannot authorize actions in another.
+
+
+
+
+
+See [Embedded Wallets Overview](/solutions/embedded-wallets/overview#custody-models) for a breakdown of
+custodial models based on this architecture.
+
+## The Auth Proxy
+
+Creating a sub-organization and initiating email/SMS OTP flows require a request stamped by your
+root organization's API key. Traditionally this means hosting a backend.
+
+The **Auth Proxy** is Turnkey's managed backend for these operations. Enable it in the dashboard,
+configure your allowed origins and auth methods, and your frontend can call
+`https://authproxy.turnkey.com` directly — no server needed on your end.
+
+
+
+
+
You want to ship without standing up a backend
+
You're using the React or React Native Wallet Kit (they're designed around it)
+
Your auth flows are OTP, OAuth, and new-user signup
+
+
+
+
+
You already run a backend and want to keep signing logic there
+
You need flows the Auth Proxy doesn't cover
+
You need full control over request construction and error handling
+
+
+
+
+
+ The React Wallet Kit's `TurnkeyProvider` accepts an `authProxyConfigId` and handles all
+ proxy-bound requests automatically. You only need your Organization ID and Proxy Config ID from
+ the dashboard.
+
+
+See [Auth Proxy reference](/features/authentication/auth-proxy) for endpoint documentation and configuration
+options.
+
+## How request signing works
+
+Every write to Turnkey — creating a wallet, signing a transaction, updating a policy — is an
+**activity**. Activities must be **stamped** (cryptographically signed) by an authorized credential
+before the enclave will execute them.
+
+The typical flow for a user-initiated action:
+
+
+
+ The user completes an auth flow (passkey prompt, OTP code, OAuth). The SDK stores a session
+ credential — a short-lived signing key — in the device's secure storage.
+
+
+ When your app calls an SDK method (e.g., `createWallet`, `signTransaction`), the SDK constructs
+ the activity payload and signs it with the session credential.
+
+
+ The enclave verifies the stamp, checks it against the sub-org's policies, and executes the
+ operation. For signing operations, only the signature is returned — private keys never leave the
+ enclave.
+
+
+
+For operations that require your root org's authorization (like creating a new sub-org), the stamp
+comes from the Auth Proxy or your own backend, not the user's session credential.
+
+## Sessions
+
+Sessions control how long a user stays authenticated without re-prompting. The SDK stores the
+session credential in device-native secure storage (IndexedDB in browsers, SecureStorage on mobile)
+and renews it automatically when possible.
+
+Default session length is 15 minutes, configurable per flow. If a session expires, the SDK surfaces
+an unauthenticated state and your app prompts re-auth.
+
+See [Sessions](/features/authentication/sessions) for configuration options.
+
+## What the platform guides cover
+
+Each platform guide walks through the full integration lifecycle:
+
+- Installing and configuring the SDK
+- Auth flows: passkeys, email/SMS OTP, and OAuth (Google, Apple, etc.)
+- Creating wallets and deriving addresses
+- Signing transactions
+- Advanced topics: custom sub-org configuration, backend-authenticated flows, import/export
+
+Select your platform from the sidebar to begin.
diff --git a/sdks/react-native/advanced-api-requests.mdx b/solutions/embedded-wallets/integration-guide/react-native/advanced-api-requests.mdx
similarity index 94%
rename from sdks/react-native/advanced-api-requests.mdx
rename to solutions/embedded-wallets/integration-guide/react-native/advanced-api-requests.mdx
index b4ea0f9a..afd13a9c 100644
--- a/sdks/react-native/advanced-api-requests.mdx
+++ b/solutions/embedded-wallets/integration-guide/react-native/advanced-api-requests.mdx
@@ -13,7 +13,7 @@ However, you can also make advanced API requests directly to Turnkey's endpoints
To make advanced API requests, use the `httpClient` from the `useTurnkey` hook in `@turnkey/react-native-wallet-kit`. This client is tied to the active session, so stamping and organization context are automatically handled for you.
-You can see the [API Reference](/api-reference/overview) for a complete list of available API endpoints and their parameters. All of these can be accessed through the `httpClient`.
+You can see the [API Reference](/api-reference/overview/intro) for a complete list of available API endpoints and their parameters. All of these can be accessed through the `httpClient`.
Here's how you can use the `httpClient` to make a `signRawPayload` request to Turnkey:
diff --git a/sdks/react-native/authentication/email-sms.mdx b/solutions/embedded-wallets/integration-guide/react-native/authentication/email-sms.mdx
similarity index 100%
rename from sdks/react-native/authentication/email-sms.mdx
rename to solutions/embedded-wallets/integration-guide/react-native/authentication/email-sms.mdx
diff --git a/sdks/react-native/authentication/overview.mdx b/solutions/embedded-wallets/integration-guide/react-native/authentication/overview.mdx
similarity index 62%
rename from sdks/react-native/authentication/overview.mdx
rename to solutions/embedded-wallets/integration-guide/react-native/authentication/overview.mdx
index 74e5d8f1..389c8c51 100644
--- a/sdks/react-native/authentication/overview.mdx
+++ b/solutions/embedded-wallets/integration-guide/react-native/authentication/overview.mdx
@@ -4,6 +4,8 @@ description: "Learn how to set up, log in, or sign up easily in your React app u
sidebarTitle: "Overview"
---
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
The Embedded Wallet Kit makes authentication simple.
You can call specific login and signup functions to create your own UI components and authentication flow.
@@ -48,38 +50,12 @@ You can also set up an `onAuthenticationSuccess` callback passed in through the
## Customize sub-organization creation
Need to configure default user names, passkey names, wallet creations or anything sub-org related?
-You can learn more about customizing the sub-orgs you create in the [Sub-Organization Customization](/sdks/react-native/sub-organization-customization) section.
+You can learn more about customizing the sub-orgs you create in the [Sub-Organization Customization](/solutions/embedded-wallets/integration-guide/react-native/sub-organization-customization) section.
Follow the guides below to learn how to set up email and SMS authentication, passkey authentication, and social logins in your React Native app.
-
-
- Learn how to set up email and SMS authentication in your React Native app.
-
-
- Learn how to set up passkey authentication in your React Native app.
-
-
- Discover how to create and manage social logins in your React Native
- application, including wallet creation, account derivation, and more.
-
-
-
+
+
+
+
+
diff --git a/sdks/react-native/authentication/passkey.mdx b/solutions/embedded-wallets/integration-guide/react-native/authentication/passkey.mdx
similarity index 100%
rename from sdks/react-native/authentication/passkey.mdx
rename to solutions/embedded-wallets/integration-guide/react-native/authentication/passkey.mdx
diff --git a/sdks/react-native/authentication/social-logins.mdx b/solutions/embedded-wallets/integration-guide/react-native/authentication/social-logins.mdx
similarity index 96%
rename from sdks/react-native/authentication/social-logins.mdx
rename to solutions/embedded-wallets/integration-guide/react-native/authentication/social-logins.mdx
index 5e1b1d6f..d542280d 100644
--- a/sdks/react-native/authentication/social-logins.mdx
+++ b/solutions/embedded-wallets/integration-guide/react-native/authentication/social-logins.mdx
@@ -11,7 +11,7 @@ Using OAuth requires a bit of configuration in the Turnkey Dashboard and your ap
### Enabling OAuth
Navigate to the **Wallet Kit** section in the [Turnkey Dashboard](https://app.turnkey.com/dashboard/walletKit) and enable the
-**OAuth**. Note if you have not enabled the Auth Proxy, you will need to do so first. Check out the [Getting Started](/sdks/react-native/getting-started) guide for more details.
+**OAuth**. Note if you have not enabled the Auth Proxy, you will need to do so first. Check out the [Getting Started](/solutions/embedded-wallets/integration-guide/react-native/getting-started) guide for more details.
For OAuth2.0 providers, you will need to upload the client ID and secret in
the dashboard. Check out the [OAuth2.0
- providers](/sdks/react-native/authentication/social-logins#oauth2-0-providers)
+ providers](/solutions/embedded-wallets/integration-guide/react-native/authentication/social-logins#oauth2-0-providers)
section for more details.
diff --git a/sdks/react-native/getting-started.mdx b/solutions/embedded-wallets/integration-guide/react-native/getting-started.mdx
similarity index 97%
rename from sdks/react-native/getting-started.mdx
rename to solutions/embedded-wallets/integration-guide/react-native/getting-started.mdx
index fd0efcf2..d04b6310 100644
--- a/sdks/react-native/getting-started.mdx
+++ b/solutions/embedded-wallets/integration-guide/react-native/getting-started.mdx
@@ -6,7 +6,7 @@ sidebarTitle: "Getting started"
## Turnkey organization setup
-To start, you must create a Turnkey organization via the [Turnkey dashboard](https://app.turnkey.com). The steps to do so are described in the [Account Setup](/getting-started/quickstart) section.
+To start, you must create a Turnkey organization via the [Turnkey dashboard](https://app.turnkey.com). The steps to do so are described in the [Account Setup](/get-started/quickstart) section.
For this setup, we will be using Turnkey's Auth Proxy to handle authentication. We can enable and configure this through the Turnkey dashboard.
@@ -220,4 +220,4 @@ export default function RootLayout() {
## Next steps
-Ready to start building your app? Check out the [Authentication](/sdks/react-native/authentication/overview) guide to learn how to set up login or signup in React Native!
+Ready to start building your app? Check out the [Authentication](/solutions/embedded-wallets/integration-guide/react-native/authentication/overview) guide to learn how to set up login or signup in React Native!
diff --git a/solutions/embedded-wallets/integration-guide/react-native/overview.mdx b/solutions/embedded-wallets/integration-guide/react-native/overview.mdx
new file mode 100644
index 00000000..a55ebf52
--- /dev/null
+++ b/solutions/embedded-wallets/integration-guide/react-native/overview.mdx
@@ -0,0 +1,17 @@
+---
+title: "Overview"
+description: "Turnkey's Embedded Wallet Kit [`(@turnkey/react-native-wallet-kit)`](https://www.npmjs.com/package/@turnkey/react-native-wallet-kit) is the easiest way to integrate Turnkey’s Embedded Wallets into your React Native applications. It supports both backendless setups via Turnkey’s managed [Auth Proxy](https://docs.turnkey.com/reference/auth-proxy) and traditional backend-based architectures. Built on [`@turnkey/core`](https://www.npmjs.com/package/@turnkey/core), it provides easy-to-use functions exported from a hook, allowing you to quickly build secure embedded wallet experiences."
+sidebarTitle: "Overview"
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
+Find `@turnkey/react-native-wallet-kit` on [npm](https://www.npmjs.com/package/@turnkey/react-native-wallet-kit) or view the source code on [GitHub](https://github.com/tkhq/sdk/tree/main/packages/react-native-wallet-kit)! For a working reference implementation covering auth, wallet creation, export, and signing, see the [with-react-native-wallet-kit](https://github.com/tkhq/sdk/tree/main/examples/with-react-native-wallet-kit) example app.
+
+
+
+
+
+
+
+
diff --git a/sdks/react-native/signing.mdx b/solutions/embedded-wallets/integration-guide/react-native/signing.mdx
similarity index 100%
rename from sdks/react-native/signing.mdx
rename to solutions/embedded-wallets/integration-guide/react-native/signing.mdx
diff --git a/sdks/react-native/sub-organization-customization.mdx b/solutions/embedded-wallets/integration-guide/react-native/sub-organization-customization.mdx
similarity index 96%
rename from sdks/react-native/sub-organization-customization.mdx
rename to solutions/embedded-wallets/integration-guide/react-native/sub-organization-customization.mdx
index 0fda2b4b..6bb43939 100644
--- a/sdks/react-native/sub-organization-customization.mdx
+++ b/solutions/embedded-wallets/integration-guide/react-native/sub-organization-customization.mdx
@@ -109,5 +109,5 @@ For a complete list of available parameters, inspect the `CreateSubOrgParams` in
## Next steps
-Now that you know how to customize the sub-orgs created in your React Native application, check out the [Advanced API Requests](/sdks/react/advanced-api-requests) guide to learn how to make advanced API requests to Turnkey's infrastructure.
+Now that you know how to customize the sub-orgs created in your React Native application, check out the [Advanced API Requests](/solutions/embedded-wallets/integration-guide/react/advanced-api-requests) guide to learn how to make advanced API requests to Turnkey's infrastructure.
This will help you build more complex features and functionalities in your app that go beyond what is included as helper functions in the SDK.
diff --git a/sdks/react-native/using-embedded-wallets.mdx b/solutions/embedded-wallets/integration-guide/react-native/using-embedded-wallets.mdx
similarity index 97%
rename from sdks/react-native/using-embedded-wallets.mdx
rename to solutions/embedded-wallets/integration-guide/react-native/using-embedded-wallets.mdx
index d468c408..fd686701 100644
--- a/sdks/react-native/using-embedded-wallets.mdx
+++ b/solutions/embedded-wallets/integration-guide/react-native/using-embedded-wallets.mdx
@@ -8,7 +8,7 @@ sidebarTitle: "Using embedded wallets"
The Embedded Wallet Kit provides a straightforward way to create and manage embedded wallets in your React Native application. EWK offers function abstractions to easily create embedded wallets, derive accounts, import and export wallets and more.
-Before we start, ensure you're familiar with the concepts of [Wallets](/concepts/wallets) and [Wallet Accounts](/concepts/wallets#accounts).
+Before we start, ensure you're familiar with the concepts of [Wallets](/features/wallets) and [Wallet Accounts](/features/wallets#accounts).
## Creating an embedded wallet
@@ -314,4 +314,4 @@ const privateKeyId = await importPrivateKey({
## Next steps
-Check out the [Signing](/sdks/react-native/signing) guide to learn how to sign transactions and messages with the embedded wallets you've created.
+Check out the [Signing](/solutions/embedded-wallets/integration-guide/react-native/signing) guide to learn how to sign transactions and messages with the embedded wallets you've created.
diff --git a/sdks/react/advanced-api-requests.mdx b/solutions/embedded-wallets/integration-guide/react/advanced-api-requests.mdx
similarity index 94%
rename from sdks/react/advanced-api-requests.mdx
rename to solutions/embedded-wallets/integration-guide/react/advanced-api-requests.mdx
index 555168a3..1f8b6ac0 100644
--- a/sdks/react/advanced-api-requests.mdx
+++ b/solutions/embedded-wallets/integration-guide/react/advanced-api-requests.mdx
@@ -12,7 +12,7 @@ The Embedded Wallet Kit provides a wide variety of helper functions to abstract
To make advanced API requests, you can use the `httpClient` provided by the `useTurnkey` hook. This client is tied to the active session meaning stamping and organization context are automatically handled for you.
-You can see the [API Reference](/api-reference/overview) for a complete list of available API endpoints and their parameters. All of these can be accessed through the `httpClient`.
+You can see the [API Reference](/api-reference/overview/intro) for a complete list of available API endpoints and their parameters. All of these can be accessed through the `httpClient`.
Here's how you can use the `httpClient` to make a `signRawPayload` request to Turnkey:
diff --git a/sdks/react/advanced-backend-authentication.mdx b/solutions/embedded-wallets/integration-guide/react/advanced-backend-authentication.mdx
similarity index 95%
rename from sdks/react/advanced-backend-authentication.mdx
rename to solutions/embedded-wallets/integration-guide/react/advanced-backend-authentication.mdx
index 62b82980..16380f0d 100644
--- a/sdks/react/advanced-backend-authentication.mdx
+++ b/solutions/embedded-wallets/integration-guide/react/advanced-backend-authentication.mdx
@@ -163,11 +163,11 @@ const otpLogin = async (verificationToken: string) => {
};
```
-The private key generated from `createApiKeyPair` will be automatically stored in [`indexedDB`](/authentication/sessions#indexeddb-web-only-%3A) and used for stamping requests to Turnkey after authentication. You can learn more about stamps [here](/developer-reference/api-overview/stamps).
+The private key generated from `createApiKeyPair` will be automatically stored in [`indexedDB`](/features/authentication/sessions#indexeddb-web-only-%3A) and used for stamping requests to Turnkey after authentication. You can learn more about stamps [here](/api-reference/overview/stamps).
### Storing the session
-Login endpoints like `otpLogin` and `oauthLogin` will [return a session token in JWT format](/authentication/sessions#creating-a-read-write-session) that you need to store in your application. You can use the `storeSession` function from the `useTurnkey` hook to store the session token.
+Login endpoints like `otpLogin` and `oauthLogin` will [return a session token in JWT format](/features/authentication/sessions#creating-a-read-write-session) that you need to store in your application. You can use the `storeSession` function from the `useTurnkey` hook to store the session token.
```tsx
import { useTurnkey } from "@turnkey/react-wallet-kit";
diff --git a/sdks/react/auth.mdx b/solutions/embedded-wallets/integration-guide/react/auth.mdx
similarity index 92%
rename from sdks/react/auth.mdx
rename to solutions/embedded-wallets/integration-guide/react/auth.mdx
index 91526982..6909e11e 100644
--- a/sdks/react/auth.mdx
+++ b/solutions/embedded-wallets/integration-guide/react/auth.mdx
@@ -45,7 +45,7 @@ yarn run dev
-When a user clicks this button, they'll see a modal with the authentication options you configured during the [organization setup](/sdks/react/getting-started#turnkey-organization-setup).
+When a user clicks this button, they'll see a modal with the authentication options you configured during the [organization setup](/solutions/embedded-wallets/integration-guide/react/getting-started#turnkey-organization-setup).
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sdks/react/legacy.mdx b/solutions/embedded-wallets/integration-guide/react/legacy.mdx
similarity index 95%
rename from sdks/react/legacy.mdx
rename to solutions/embedded-wallets/integration-guide/react/legacy.mdx
index f724b7f5..8ce4955a 100644
--- a/sdks/react/legacy.mdx
+++ b/solutions/embedded-wallets/integration-guide/react/legacy.mdx
@@ -5,7 +5,7 @@ sidebarTitle: "Legacy (@turnkey/sdk-react)"
`@turnkey/sdk-react` is our legacy React SDK, which is still available for use but is not recommended for new projects. It is built off `@turnkey/sdk-browser` and provides direct integration with Turnkey's API into React applications.
-This package will soon be discontinued, if you're starting a new project, we recommend using the [`@turnkey/react-wallet-kit`](/sdks/react/getting-started) instead.
+This package will soon be discontinued, if you're starting a new project, we recommend using the [`@turnkey/react-wallet-kit`](/solutions/embedded-wallets/integration-guide/react/getting-started) instead.
## Overview
@@ -47,7 +47,7 @@ const turnkeyConfig = {
serverSignUrl: "http://localhost:3000/api"
}
-For further context on RPID's for passkeys, used in the above example, [look here](/authentication/passkeys/options#rp).
+For further context on RPID's for passkeys, used in the above example, [look here](/features/authentication/passkeys/options#rp).
@@ -122,4 +122,4 @@ const loginWithOauth = async (oidcToken: string, suborgID: string) => {
};
```
-For more complete and in depth examples using the [`@turnkey/sdk-react`](https://www.npmjs.com/package/@turnkey/sdk-react) package, check out our [Code Examples](/category/code-examples) section.
+For more complete and in depth examples using the [`@turnkey/sdk-react`](https://www.npmjs.com/package/@turnkey/sdk-react) package, check out our [Code Examples](/solutions/embedded-wallets/overview) section.
diff --git a/sdks/react/migrating-sdk-react.mdx b/solutions/embedded-wallets/integration-guide/react/migrating-sdk-react.mdx
similarity index 98%
rename from sdks/react/migrating-sdk-react.mdx
rename to solutions/embedded-wallets/integration-guide/react/migrating-sdk-react.mdx
index c7f1de1a..c5483772 100644
--- a/sdks/react/migrating-sdk-react.mdx
+++ b/solutions/embedded-wallets/integration-guide/react/migrating-sdk-react.mdx
@@ -137,7 +137,7 @@ Key differences:
- Single helper per provider; popup or full-page redirect
- Redirect completion handled automatically by the provider
-The same applies for other OAuth providers such as Apple, Facebook. See [Configuring OAuth](/sdks/react/auth#configuring-oauth) for more details.
+The same applies for other OAuth providers such as Apple, Facebook. See [Configuring OAuth](/solutions/embedded-wallets/integration-guide/react/auth#configuring-oauth) for more details.
#### Passkeys
@@ -873,10 +873,10 @@ await signer.sendTransaction(tx);
Use `useTurnkey()`'s signing helpers:
- `signTransaction`: signs and returns a signature (you broadcast separately).
-- `signAndSendTransaction`: signs and broadcasts, returning the on-chain transaction hash.
+- `signAndSendTransaction`: signs and broadcasts, returning the onchain transaction hash.
The provider handles session state and request stamping; you pass a wallet account and an unsigned transaction.
-For more details, see: [Signing transactions](/sdks/react/signing#signing-transactions).
+For more details, see: [Signing transactions](/solutions/embedded-wallets/integration-guide/react/signing#signing-transactions).
```tsx
import { useTurnkey } from "@turnkey/react-wallet-kit";
@@ -981,4 +981,4 @@ function SignMessageButton() {
}
```
-See Signing messages for more details: [Signing messages](/sdks/react/signing#signing-messages).
+See Signing messages for more details: [Signing messages](/solutions/embedded-wallets/integration-guide/react/signing#signing-messages).
diff --git a/sdks/react/signing.mdx b/solutions/embedded-wallets/integration-guide/react/signing.mdx
similarity index 95%
rename from sdks/react/signing.mdx
rename to solutions/embedded-wallets/integration-guide/react/signing.mdx
index a53bdd0e..d3120e33 100644
--- a/sdks/react/signing.mdx
+++ b/solutions/embedded-wallets/integration-guide/react/signing.mdx
@@ -154,4 +154,4 @@ The user will be prompted by their external wallet to sign the message.
## Next steps
-Now that you know how to sign messages and transactions in your React application, checkout the [UI Customization](/sdks/react/ui-customization) guide to learn how to customize the look and feel of the signing modals and other UI components.
+Now that you know how to sign messages and transactions in your React application, checkout the [UI Customization](/solutions/embedded-wallets/integration-guide/react/ui-customization) guide to learn how to customize the look and feel of the signing modals and other UI components.
diff --git a/sdks/react/sub-organization-customization.mdx b/solutions/embedded-wallets/integration-guide/react/sub-organization-customization.mdx
similarity index 89%
rename from sdks/react/sub-organization-customization.mdx
rename to solutions/embedded-wallets/integration-guide/react/sub-organization-customization.mdx
index 93bf88e9..d06d2c48 100644
--- a/sdks/react/sub-organization-customization.mdx
+++ b/solutions/embedded-wallets/integration-guide/react/sub-organization-customization.mdx
@@ -108,8 +108,8 @@ function App() {
}
```
-For a complete list of available parameters, check out the [SDK Reference](/sdks/react/sdk-reference), or inspect the `CreateSubOrgParams` interface.
+For a complete list of available parameters, check out the [SDK Reference](/sdks/introduction), or inspect the `CreateSubOrgParams` interface.
## Next steps
-Now that you know how to customize the sub-orgs created in your React application, check out the [Advanced API Requests](/sdks/react/advanced-api-requests) guide to learn how to make advanced API requests to Turnkey's infrastructure. This will help you build more complex features and functionalities in your app that go beyond what is included as helper functions in the SDK.
+Now that you know how to customize the sub-orgs created in your React application, check out the [Advanced API Requests](/solutions/embedded-wallets/integration-guide/react/advanced-api-requests) guide to learn how to make advanced API requests to Turnkey's infrastructure. This will help you build more complex features and functionalities in your app that go beyond what is included as helper functions in the SDK.
diff --git a/sdks/react/troubleshooting.mdx b/solutions/embedded-wallets/integration-guide/react/troubleshooting.mdx
similarity index 98%
rename from sdks/react/troubleshooting.mdx
rename to solutions/embedded-wallets/integration-guide/react/troubleshooting.mdx
index 66c78cf4..f86a11a6 100644
--- a/sdks/react/troubleshooting.mdx
+++ b/solutions/embedded-wallets/integration-guide/react/troubleshooting.mdx
@@ -91,7 +91,7 @@ console.log(
console.log("Organization ID:", process.env.NEXT_PUBLIC_ORGANIZATION_ID);
```
-If you are using Turnkey's Auth Proxy, ensure it is enabled in the Turnkey Dashboard under the **Wallet Kit** section. You can also check the [Getting Started](/sdks/react/getting-started) guide for more details on setting up the Auth Poxy.
+If you are using Turnkey's Auth Proxy, ensure it is enabled in the Turnkey Dashboard under the **Wallet Kit** section. You can also check the [Getting Started](/solutions/embedded-wallets/integration-guide/react/getting-started) guide for more details on setting up the Auth Poxy.
If you decide to use your own authentication setup with a backend, you can simply omit the `authProxyConfigId` from the `TurnkeyProvider` config. This will disable the Turnkey auth proxy and allow you to use your own authentication flow. Note that the **Log in or sign up** modal will not be available in this case, and you will need to implement your own authentication flow.
@@ -465,7 +465,7 @@ This error occurs when you try to use Turnkey client functions before the SDK ha
#### Solution
-To resolve this issue, ensure that you only call Turnkey client functions after the SDK has fully initialized. You can do this by checking the `clientState` state variable from the `useTurnkey` hook. The `clientState` variable indicates the current state of the Turnkey client. You can read up more about how to use the `clientState` variable and why its important in the [Getting Started](/sdks/react/getting-started#client-readiness) guide.
+To resolve this issue, ensure that you only call Turnkey client functions after the SDK has fully initialized. You can do this by checking the `clientState` state variable from the `useTurnkey` hook. The `clientState` variable indicates the current state of the Turnkey client. You can read up more about how to use the `clientState` variable and why its important in the [Getting Started](/solutions/embedded-wallets/integration-guide/react/getting-started#client-readiness) guide.
Example solutions to potential issues:
diff --git a/sdks/react/ui-customization.mdx b/solutions/embedded-wallets/integration-guide/react/ui-customization.mdx
similarity index 95%
rename from sdks/react/ui-customization.mdx
rename to solutions/embedded-wallets/integration-guide/react/ui-customization.mdx
index 35891ed0..68a100fd 100644
--- a/sdks/react/ui-customization.mdx
+++ b/solutions/embedded-wallets/integration-guide/react/ui-customization.mdx
@@ -155,4 +155,4 @@ Here's how it will look:
## Next steps
-Now that you know how to customize the UI components in your React application, check out the [Sub-Organization Customization](/sdks/react/sub-organization-customization) guide to learn how to customize the sub-orgs that are created for your users. This includes automatically creating wallets, having multiple authentication methods, default usernames, and more.
+Now that you know how to customize the UI components in your React application, check out the [Sub-Organization Customization](/solutions/embedded-wallets/integration-guide/react/sub-organization-customization) guide to learn how to customize the sub-orgs that are created for your users. This includes automatically creating wallets, having multiple authentication methods, default usernames, and more.
diff --git a/sdks/react/using-embedded-wallets.mdx b/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets.mdx
similarity index 87%
rename from sdks/react/using-embedded-wallets.mdx
rename to solutions/embedded-wallets/integration-guide/react/using-embedded-wallets.mdx
index bc99124a..39f7bacb 100644
--- a/sdks/react/using-embedded-wallets.mdx
+++ b/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets.mdx
@@ -8,7 +8,7 @@ sidebarTitle: "Using embedded wallets"
The Embedded Wallet Kit provides a straightforward way to create and manage embedded wallets in your React application. EWK offers function abstractions to easily create embedded wallets, derive accounts, import and export wallets and more.
-Before we start, ensure you're familiar with the concepts of [Wallets](/concepts/wallets) and [Wallet Accounts](/concepts/wallets#accounts).
+Before we start, ensure you're familiar with the concepts of [Wallets](/features/wallets) and [Wallet Accounts](/features/wallets#accounts).
## Creating an embedded wallet
@@ -154,7 +154,7 @@ function AddAccountButton({ walletId }) {
You can also import and export wallets using the `handleImportWallet` and `handleExportWallet` functions. These functions open up UI modals that allows users to export or import wallets through a secure iframe.
-You can learn more about [importing using an iframe](/embedded-wallets/code-examples/import#embedded-iframe) and [exporting using an iframe](/embedded-wallets/code-examples/export#embedded-iframe) before continuing.
+You can learn more about [importing using an iframe](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets#embedded-iframe) and [exporting using an iframe](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets#embedded-iframe) before continuing.
```tsx
import { useTurnkey } from "@turnkey/react-wallet-kit";
@@ -203,8 +203,8 @@ Check out this [example](https://github.com/tkhq/sdk/tree/main/examples/import-e
## Next steps
-Now that you know how to create and manage embedded wallets in your React application, check out the [Connecting External Wallets](/sdks/react/using-external-wallets/connecting) guide to learn how to connect and use external wallets.
+Now that you know how to create and manage embedded wallets in your React application, check out the [Connecting External Wallets](/solutions/embedded-wallets/integration-guide/react/using-external-wallets/connecting) guide to learn how to connect and use external wallets.
-Looking to add funds via on ramp? Check out the [OnRamp](/products/embedded-wallets/features/fiat-on-ramp) guide to learn how to add funds to your Turnkey Wallet.
+Looking to add funds via on ramp? Check out the [OnRamp](/features/transaction-management/fiat-on-ramp) guide to learn how to add funds to your Turnkey Wallet.
-Don't want to use external wallets? Check out the [Signing](/sdks/react/signing) guide to learn how to sign transactions and messages with the embedded wallets you've created.
+Don't want to use external wallets? Check out the [Signing](/solutions/embedded-wallets/integration-guide/react/signing) guide to learn how to sign transactions and messages with the embedded wallets you've created.
diff --git a/sdks/react/using-external-wallets/authentication.mdx b/solutions/embedded-wallets/integration-guide/react/using-external-wallets/authentication.mdx
similarity index 95%
rename from sdks/react/using-external-wallets/authentication.mdx
rename to solutions/embedded-wallets/integration-guide/react/using-external-wallets/authentication.mdx
index d190ee0f..7485fa1b 100644
--- a/sdks/react/using-external-wallets/authentication.mdx
+++ b/solutions/embedded-wallets/integration-guide/react/using-external-wallets/authentication.mdx
@@ -5,7 +5,7 @@ sidebarTitle: "Authentication"
---
> **Prerequisite:**
-> If you haven’t already, check out the [External Wallets Overview](/sdks/react/using-external-wallets/overview) first, this guide builds on the concepts introduced there.
+> If you haven’t already, check out the [External Wallets Overview](/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview) first, this guide builds on the concepts introduced there.
## Setting up wallet authentication
@@ -118,7 +118,7 @@ Below are screenshots of what the default UI looks like out of the box when usin
-> **Note**: this UI is customizable. Checkout the [UI Customization](/sdks/react/ui-customization) guide to learn how to customize the look and feel of the Auth modal and other UI components.
+> **Note**: this UI is customizable. Checkout the [UI Customization](/solutions/embedded-wallets/integration-guide/react/ui-customization) guide to learn how to customize the look and feel of the Auth modal and other UI components.
### Option 2: build a custom auth flow
diff --git a/sdks/react/using-external-wallets/connecting.mdx b/solutions/embedded-wallets/integration-guide/react/using-external-wallets/connecting.mdx
similarity index 96%
rename from sdks/react/using-external-wallets/connecting.mdx
rename to solutions/embedded-wallets/integration-guide/react/using-external-wallets/connecting.mdx
index eed413d6..742601e4 100644
--- a/sdks/react/using-external-wallets/connecting.mdx
+++ b/solutions/embedded-wallets/integration-guide/react/using-external-wallets/connecting.mdx
@@ -5,7 +5,7 @@ sidebarTitle: "Connecting"
---
> **Prerequisite:**
-> If you haven’t already, check out the [External Wallets Overview](/sdks/react/using-external-wallets/overview) first, this guide builds on the concepts introduced there.
+> If you haven’t already, check out the [External Wallets Overview](/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview) first, this guide builds on the concepts introduced there.
## Setting up connecting wallet support
The toggle to enable connecting external wallets is available in the `TurnkeyProvider` configuration. You can further customize settings, such as which chains are enabled, which providers are supported, and whether WalletConnect is allowed.
@@ -210,7 +210,7 @@ Below are screenshots of what the default UI looks like out of the box when usin
-> **Note**: this UI is customizable. Checkout the [UI Customization](/sdks/react/ui-customization) guide to learn how to customize the look and feel of the Connect External Wallet modal and other UI components.
+> **Note**: this UI is customizable. Checkout the [UI Customization](/solutions/embedded-wallets/integration-guide/react/ui-customization) guide to learn how to customize the look and feel of the Connect External Wallet modal and other UI components.
#### Option 2: build a custom connection flow
If you prefer full control over the connection experience, you can use our low-level functions to handle the flow manually.
@@ -275,4 +275,4 @@ We included this feature because many developers want to allow users to connect
## Next steps
-Now that you have an external wallet connected, check out the [Signing](/sdks/react/signing) guide to learn how to sign transactions and messages.
+Now that you have an external wallet connected, check out the [Signing](/solutions/embedded-wallets/integration-guide/react/signing) guide to learn how to sign transactions and messages.
diff --git a/sdks/react/using-external-wallets/overview.mdx b/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview.mdx
similarity index 100%
rename from sdks/react/using-external-wallets/overview.mdx
rename to solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview.mdx
diff --git a/sdks/swift/advanced-api-requests.mdx b/solutions/embedded-wallets/integration-guide/swift/advanced-api-requests.mdx
similarity index 94%
rename from sdks/swift/advanced-api-requests.mdx
rename to solutions/embedded-wallets/integration-guide/swift/advanced-api-requests.mdx
index 522cdacb..7ed311da 100644
--- a/sdks/swift/advanced-api-requests.mdx
+++ b/solutions/embedded-wallets/integration-guide/swift/advanced-api-requests.mdx
@@ -17,7 +17,7 @@ This guide shows how to:
To make advanced API requests, use the `TurnkeyClient` exposed by `TurnkeyContext`.
This client is tied to the active session, so stamping and organization context are automatically handled for you.
-You can see the [API Reference](/api-reference/overview) for a complete list of available API endpoints and their parameters. All of these can be accessed through the `TurnkeyClient`.
+You can see the [API Reference](/api-reference/overview/intro) for a complete list of available API endpoints and their parameters. All of these can be accessed through the `TurnkeyClient`.
## Sign a raw payload
diff --git a/sdks/swift/advanced-backend-authentication.mdx b/solutions/embedded-wallets/integration-guide/swift/advanced-backend-authentication.mdx
similarity index 98%
rename from sdks/swift/advanced-backend-authentication.mdx
rename to solutions/embedded-wallets/integration-guide/swift/advanced-backend-authentication.mdx
index 5f906cfe..2f0ae63c 100644
--- a/sdks/swift/advanced-backend-authentication.mdx
+++ b/solutions/embedded-wallets/integration-guide/swift/advanced-backend-authentication.mdx
@@ -12,7 +12,7 @@ Use this guide if you want to run authentication through your own server instead
- Create or resume sessions
- Persist and expose session/user/wallet state via `TurnkeyContext`
-If you prefer a no-backend setup, use the [Auth Proxy](/reference/auth-proxy) instead.
+If you prefer a no-backend setup, use the [Auth Proxy](/features/authentication/auth-proxy) instead.
## What you can't use
diff --git a/sdks/swift/authentication/email-sms.mdx b/solutions/embedded-wallets/integration-guide/swift/authentication/email-sms.mdx
similarity index 91%
rename from sdks/swift/authentication/email-sms.mdx
rename to solutions/embedded-wallets/integration-guide/swift/authentication/email-sms.mdx
index f5d43ad3..aba08669 100644
--- a/sdks/swift/authentication/email-sms.mdx
+++ b/solutions/embedded-wallets/integration-guide/swift/authentication/email-sms.mdx
@@ -4,6 +4,8 @@ description: "Set up and implement email and SMS OTP authentication using the Tu
sidebarTitle: "Email & SMS"
---
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
## Overview
This guide shows how to implement email or SMS OTP authentication using the Turnkey Swift SDK and the Auth Proxy.
@@ -11,7 +13,7 @@ You'll send an OTP to a user's contact, present a verification screen, and compl
Before you begin:
-- Ensure you've completed the setup in [Getting Started](/sdks/swift/getting-started) and enabled the Auth Proxy with Email/SMS OTP in the Turnkey Dashboard.
+- Ensure you've completed the setup in [Getting Started](/solutions/embedded-wallets/integration-guide/swift/getting-started) and enabled the Auth Proxy with Email/SMS OTP in the Turnkey Dashboard.
- Make sure your app is configured with `TurnkeyConfig` and `TurnkeyContext.configure(...)`.
## Send an OTP code
@@ -149,14 +151,4 @@ Tip: You can use a library like [PhoneNumberKit](https://github.com/PhoneNumberK
## Next steps
-
-
- Learn how to add passkey login and signup to your app.
-
-
+
diff --git a/sdks/swift/authentication/overview.mdx b/solutions/embedded-wallets/integration-guide/swift/authentication/overview.mdx
similarity index 78%
rename from sdks/swift/authentication/overview.mdx
rename to solutions/embedded-wallets/integration-guide/swift/authentication/overview.mdx
index 6f7ad034..7376765d 100644
--- a/sdks/swift/authentication/overview.mdx
+++ b/solutions/embedded-wallets/integration-guide/swift/authentication/overview.mdx
@@ -4,6 +4,8 @@ description: "Learn how to set up, log in, or sign up in your Swift app using th
sidebarTitle: "Overview"
---
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
## Choose your authentication path
Decide whether you'll use Turnkey's managed Auth Proxy (no backend required) or route auth through your own server.
@@ -14,13 +16,13 @@ Decide whether you'll use Turnkey's managed Auth Proxy (no backend required) or
- Origin validation, CORS, session lifetimes, and templates are centrally managed in the Dashboard.
- Proxy keys are HPKE-encrypted and decrypted only in-memory per request inside Turnkey's enclave.
- The frontend calls Auth Proxy endpoints directly — no backend endpoints needed for OTP, OAuth, or signup flows.
- - See the full details in the [Auth Proxy reference](/reference/auth-proxy).
+ - See the full details in the [Auth Proxy reference](/features/authentication/auth-proxy).
- **Your backend**
- Implement OTP, OAuth, and signup on your server using Turnkey's public API.
- Keep custom validations, logging, and rate-limiting in your control; store user metadata alongside sub-orgs.
- Enable co-signing patterns (e.g., 2/2) from your backend.
- - Follow the Swift guide: [Advanced backend authentication](/sdks/swift/authentication/advanced-backend-authentication).
+ - Follow the Swift guide: [Advanced backend authentication](/solutions/embedded-wallets/integration-guide/swift/advanced-backend-authentication).
Note: The Swift SDK's high-level auth helpers on `TurnkeyContext` (e.g., `initOtp`, `verifyOtp`, `completeOtp`, `handleGoogleOAuth`, `handleAppleOAuth`, `handleDiscordOAuth`, `handleXOauth`, and `signUpWithPasskey`) call the Auth Proxy and require an `authProxyConfigId`.
If you are using your own backend, omit `authProxyConfigId` in `TurnkeyContext.configure` and use your server endpoints; after your server returns a session JWT, store it via `TurnkeyContext.storeSession(...)`.
@@ -29,7 +31,7 @@ If you are using your own backend, omit `authProxyConfigId` in `TurnkeyContext.c
Before implementing any specific method, make sure you've:
-- Completed the Swift SDK [Getting started](/sdks/swift/getting-started) guide
+- Completed the Swift SDK [Getting started](/solutions/embedded-wallets/integration-guide/swift/getting-started) guide
- Configured `TurnkeyContext` with your `organizationId` and (if using Auth Proxy) `authProxyConfigId`
- Set `rpId` and Associated Domains if you plan to use Passkeys
- Optionally enabled managed auto-refresh for session state (`autoRefreshManagedState`)
@@ -96,7 +98,7 @@ You can tailor default user and wallet creation settings by:
- Passing `CreateSubOrgParams` to signup helpers (e.g., OTP or passkey signup), or
- Providing defaults via `TurnkeyConfig.Auth.createSuborgParams`
-For more information, see [Sub-organization customization](/sdks/swift/sub-organization-customization).
+For more information, see [Sub-organization customization](/solutions/embedded-wallets/integration-guide/swift/sub-organization-customization).
---
@@ -104,33 +106,8 @@ For more information, see [Sub-organization customization](/sdks/swift/sub-organ
Follow the guides below to implement Email/SMS authentication, Passkey authentication, and Social Logins in your Swift app.
-
-
- Learn how to set up email and SMS authentication using the Auth Proxy.
-
-
- Learn how to set up passkey authentication with system UI and secure sessions.
-
-
- Implement OAuth-based logins (Google, Apple, Discord, X) and complete auth via Auth Proxy.
-
-
-
+
+
+
+
+
diff --git a/sdks/swift/authentication/passkey.mdx b/solutions/embedded-wallets/integration-guide/swift/authentication/passkey.mdx
similarity index 93%
rename from sdks/swift/authentication/passkey.mdx
rename to solutions/embedded-wallets/integration-guide/swift/authentication/passkey.mdx
index 5bb7ce4d..4c5f5c9c 100644
--- a/sdks/swift/authentication/passkey.mdx
+++ b/solutions/embedded-wallets/integration-guide/swift/authentication/passkey.mdx
@@ -4,6 +4,8 @@ description: "Set up and implement passkey authentication using the Turnkey Swif
sidebarTitle: "Passkeys"
---
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
## Overview
This guide shows how to implement passkey authentication in a Swift app using the Turnkey Swift SDK.
@@ -123,14 +125,4 @@ try await turnkey.signUpWithPasskey(
## Next steps
-
-
- Set up OAuth-based logins (Google, Apple, Discord, X).
-
-
+
diff --git a/sdks/swift/authentication/social-logins.mdx b/solutions/embedded-wallets/integration-guide/swift/authentication/social-logins.mdx
similarity index 92%
rename from sdks/swift/authentication/social-logins.mdx
rename to solutions/embedded-wallets/integration-guide/swift/authentication/social-logins.mdx
index 6319e97a..bbca86ed 100644
--- a/sdks/swift/authentication/social-logins.mdx
+++ b/solutions/embedded-wallets/integration-guide/swift/authentication/social-logins.mdx
@@ -4,6 +4,8 @@ description: "Implement Google, Apple, Discord, and X OAuth using the Turnkey Sw
sidebarTitle: "Social logins"
---
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
## Overview
This guide shows how to implement social logins with the Turnkey Swift SDK.
@@ -14,7 +16,7 @@ For other providers, run your own OAuth flow to obtain an OIDC token and complet
Before you begin:
-- Ensure you've completed the setup in [Getting Started](/sdks/swift/getting-started).
+- Ensure you've completed the setup in [Getting Started](/solutions/embedded-wallets/integration-guide/swift/getting-started).
- Set provider client IDs and `appScheme` in your `TurnkeyConfig`; configure `redirectUri` in the Turnkey Dashboard (Auth Proxy).
- Add your app scheme to iOS URL Types (Info.plist) so the OAuth redirect returns to your app.
@@ -204,20 +206,10 @@ let result = try await turnkey.completeOAuth(
// result.session is stored automatically when completeOAuth succeeds
```
-For more information, refer to the [Social Logins](/authentication/social-logins) guide.
+For more information, refer to the [Social Logins](/features/authentication/social-logins) guide.
---
## Next steps
-
-
- Learn how to sign transactions and messages using wallets and accounts.
-
-
+
diff --git a/sdks/swift/getting-started.mdx b/solutions/embedded-wallets/integration-guide/swift/getting-started.mdx
similarity index 93%
rename from sdks/swift/getting-started.mdx
rename to solutions/embedded-wallets/integration-guide/swift/getting-started.mdx
index 0f7bbe8f..ebdd331f 100644
--- a/sdks/swift/getting-started.mdx
+++ b/solutions/embedded-wallets/integration-guide/swift/getting-started.mdx
@@ -6,7 +6,7 @@ sidebarTitle: "Getting started"
## Turnkey organization setup
-To start, you must create a Turnkey organization via the [Turnkey dashboard](https://app.turnkey.com). The steps to do so are described in the [Account Setup](/getting-started/quickstart) section.
+To start, you must create a Turnkey organization via the [Turnkey dashboard](https://app.turnkey.com). The steps to do so are described in the [Account Setup](/get-started/quickstart) section.
For this setup, we will be using Turnkey's Auth Proxy to handle authentication. We can enable and configure this through the Turnkey dashboard.
@@ -89,7 +89,7 @@ targets: [
## Configure URL scheme and passkeys
- If you are using OAuth, add your app scheme (e.g., `myapp`) so it can be used for OAuth redirects
-- If you plan to use passkeys, add an Associated Domain capability (Signing & Capabilities → Associated Domains) with `webcredentials:yourdomain.com`. For detailed passkey setup (entitlements, RP ID, UX), see the [Passkeys](/sdks/swift/authentication/passkey) guide.
+- If you plan to use passkeys, add an Associated Domain capability (Signing & Capabilities → Associated Domains) with `webcredentials:yourdomain.com`. For detailed passkey setup (entitlements, RP ID, UX), see the [Passkeys](/solutions/embedded-wallets/integration-guide/swift/authentication/passkey) guide.
## SDK configuration
@@ -186,4 +186,4 @@ class ViewController: UIViewController {
## Next steps
-- Move on to [Authentication](/sdks/swift/authentication/overview) to learn how to authenticate users in your app.
+- Move on to [Authentication](/solutions/embedded-wallets/integration-guide/swift/authentication/overview) to learn how to authenticate users in your app.
diff --git a/solutions/embedded-wallets/integration-guide/swift/overview.mdx b/solutions/embedded-wallets/integration-guide/swift/overview.mdx
new file mode 100644
index 00000000..a5daa075
--- /dev/null
+++ b/solutions/embedded-wallets/integration-guide/swift/overview.mdx
@@ -0,0 +1,47 @@
+---
+title: "Overview"
+description:
+ "Turnkey Swift SDK makes it simple to integrate Turnkey-powered embedded wallets into your native
+ Swift app. It supports both backendless setups via Turnkey’s managed [Auth
+ Proxy](https://docs.turnkey.com/reference/auth-proxy) and traditional backend-based architectures."
+sidebarTitle: "Overview"
+---
+
+import { FeatureCard } from "/snippets/feature-card.mdx";
+
+Find the Turnkey Swift SDK on [GitHub](https://github.com/tkhq/swift-sdk). For a working reference
+implementation covering OTP, OAuth, passkey auth, wallet creation, message signing, and transaction
+sending, see [swift-sdk/Examples](https://github.com/tkhq/swift-sdk/tree/main/Examples).
+
+
+
+
+
+
+
+
diff --git a/sdks/swift/signing.mdx b/solutions/embedded-wallets/integration-guide/swift/signing.mdx
similarity index 100%
rename from sdks/swift/signing.mdx
rename to solutions/embedded-wallets/integration-guide/swift/signing.mdx
diff --git a/sdks/swift/sub-organization-customization.mdx b/solutions/embedded-wallets/integration-guide/swift/sub-organization-customization.mdx
similarity index 98%
rename from sdks/swift/sub-organization-customization.mdx
rename to solutions/embedded-wallets/integration-guide/swift/sub-organization-customization.mdx
index 1c08e5d1..b126b959 100644
--- a/sdks/swift/sub-organization-customization.mdx
+++ b/solutions/embedded-wallets/integration-guide/swift/sub-organization-customization.mdx
@@ -185,4 +185,4 @@ try await turnkey.signUpWithPasskey(
## Next steps
-- [Advanced API requests](/sdks/swift/advanced-api-requests)
+- [Advanced API requests](/solutions/embedded-wallets/integration-guide/swift/advanced-api-requests)
diff --git a/sdks/swift/using-embedded-wallets.mdx b/solutions/embedded-wallets/integration-guide/swift/using-embedded-wallets.mdx
similarity index 96%
rename from sdks/swift/using-embedded-wallets.mdx
rename to solutions/embedded-wallets/integration-guide/swift/using-embedded-wallets.mdx
index 2c4ef32a..a4fd3805 100644
--- a/sdks/swift/using-embedded-wallets.mdx
+++ b/solutions/embedded-wallets/integration-guide/swift/using-embedded-wallets.mdx
@@ -8,13 +8,13 @@ sidebarTitle: "Using wallets"
The Turnkey Swift SDK provides a straightforward way to create and manage wallets in your Swift application. You can create wallets, derive accounts, import/export, and refresh wallet state from `TurnkeyContext`.
-Before you start, make sure you're familiar with [Wallets](/concepts/wallets) and [Wallet Accounts](/concepts/wallets#accounts).
+Before you start, make sure you're familiar with [Wallets](/features/wallets) and [Wallet Accounts](/features/wallets#accounts).
## Creation
There are two ways to create wallets and accounts:
-- During signup (sub-organization creation): Configure default wallet/accounts in your signup parameters so users get a wallet at account creation time. See [Sub-organization customization](/sdks/swift/sub-organization-customization) for how to set `CreateSubOrgParams` globally or per auth method.
+- During signup (sub-organization creation): Configure default wallet/accounts in your signup parameters so users get a wallet at account creation time. See [Sub-organization customization](/solutions/embedded-wallets/integration-guide/swift/sub-organization-customization) for how to set `CreateSubOrgParams` globally or per auth method.
- After authentication (active session): Create wallets programmatically using the `TurnkeyContext` once the user is authenticated.
### Wallet
diff --git a/sdks/typescript-frontend/advanced-api-requests.mdx b/solutions/embedded-wallets/integration-guide/typescript/advanced-api-requests.mdx
similarity index 94%
rename from sdks/typescript-frontend/advanced-api-requests.mdx
rename to solutions/embedded-wallets/integration-guide/typescript/advanced-api-requests.mdx
index bf0d638b..8ca8822c 100644
--- a/sdks/typescript-frontend/advanced-api-requests.mdx
+++ b/solutions/embedded-wallets/integration-guide/typescript/advanced-api-requests.mdx
@@ -12,7 +12,7 @@ The `@turnkey/core` provides a wide variety of helper functions to abstract inte
To make advanced API requests, you can use the `httpClient` provided in the `TurnkeyClient`. This client is tied to the active session meaning stamping and organization context are automatically handled for you.
-You can see the [API Reference](/api-reference/overview) for a complete list of available API endpoints and their parameters. All of these can be accessed through the `httpClient`.
+You can see the [API Reference](/api-reference/overview/intro) for a complete list of available API endpoints and their parameters. All of these can be accessed through the `httpClient`.
Here's how you can use the `httpClient` to make a `signRawPayload` request to Turnkey:
diff --git a/sdks/typescript-frontend/advanced-backend-authentication.mdx b/solutions/embedded-wallets/integration-guide/typescript/advanced-backend-authentication.mdx
similarity index 92%
rename from sdks/typescript-frontend/advanced-backend-authentication.mdx
rename to solutions/embedded-wallets/integration-guide/typescript/advanced-backend-authentication.mdx
index 4323e144..e5f53f0b 100644
--- a/sdks/typescript-frontend/advanced-backend-authentication.mdx
+++ b/solutions/embedded-wallets/integration-guide/typescript/advanced-backend-authentication.mdx
@@ -134,11 +134,11 @@ const otpLogin = async (verificationToken: string) => {
};
```
-The private key generated from `createApiKeyPair` will be automatically stored in [indexedDB](/authentication/sessions#indexeddb-web-only-%3A) on web environments or [secure storage](/authentication/sessions#securestorage-mobile-only) on React Native and used for stamping requests to Turnkey after authentication. You can learn more about stamps [here](/developer-reference/api-overview/stamps).
+The private key generated from `createApiKeyPair` will be automatically stored in [indexedDB](/features/authentication/sessions#indexeddb-web-only-%3A) on web environments or [secure storage](/features/authentication/sessions#securestorage-mobile-only) on React Native and used for stamping requests to Turnkey after authentication. You can learn more about stamps [here](/api-reference/overview/stamps).
### Storing the session
-Login endpoints like `otpLogin` and `oauthLogin` will [return a session token in JWT format](/authentication/sessions#creating-a-read-write-session) that you need to store in your application. You can use the `storeSession` function from the `TurnkeyClient` to store the session token.
+Login endpoints like `otpLogin` and `oauthLogin` will [return a session token in JWT format](/features/authentication/sessions#creating-a-read-write-session) that you need to store in your application. You can use the `storeSession` function from the `TurnkeyClient` to store the session token.
```tsx
const otpLogin = async (verificationToken: string) => {
diff --git a/sdks/typescript-frontend/auth.mdx b/solutions/embedded-wallets/integration-guide/typescript/auth.mdx
similarity index 100%
rename from sdks/typescript-frontend/auth.mdx
rename to solutions/embedded-wallets/integration-guide/typescript/auth.mdx
diff --git a/sdks/typescript-frontend/getting-started.mdx b/solutions/embedded-wallets/integration-guide/typescript/getting-started.mdx
similarity index 98%
rename from sdks/typescript-frontend/getting-started.mdx
rename to solutions/embedded-wallets/integration-guide/typescript/getting-started.mdx
index 35324818..fd074764 100644
--- a/sdks/typescript-frontend/getting-started.mdx
+++ b/solutions/embedded-wallets/integration-guide/typescript/getting-started.mdx
@@ -6,7 +6,7 @@ sidebarTitle: "Getting started"
## Turnkey organization setup
-To start, you must create a Turnkey organization via the [Turnkey dashboard](https://app.turnkey.com). The steps are described in the [Account Setup](/getting-started/quickstart) section.
+To start, you must create a Turnkey organization via the [Turnkey dashboard](https://app.turnkey.com). The steps are described in the [Account Setup](/get-started/quickstart) section.
For this setup, we will use Turnkey's **Auth Proxy** to handle authentication. You can enable and configure this through the Turnkey dashboard.
diff --git a/solutions/embedded-wallets/integration-guide/typescript/index.mdx b/solutions/embedded-wallets/integration-guide/typescript/index.mdx
new file mode 100644
index 00000000..84063afd
--- /dev/null
+++ b/solutions/embedded-wallets/integration-guide/typescript/index.mdx
@@ -0,0 +1,20 @@
+---
+title: "Overview"
+description:
+ "`@turnkey/core` is the core TypeScript client-side SDK for Turnkey's Embedded Wallets. It
+ provides a set of functions and utilities to interact with Turnkey's APIs, a powerful session
+ management system, built-in stampers, and a raw HTTP client for advanced use cases. This SDK is
+ designed to be used as a foundation for building Turnkey's Embedded Wallets in various frontend
+ frameworks, including React, React Native, Angular, Vue, and Svelte. If you're using React, please
+ consider using the [`@turnkey/react-wallet-kit`](/solutions/embedded-wallets/integration-guide/react/index) for a more tailored experience."
+sidebarTitle: "Overview"
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
+
+
+
+
+
+
diff --git a/sdks/typescript-frontend/legacy.mdx b/solutions/embedded-wallets/integration-guide/typescript/legacy.mdx
similarity index 85%
rename from sdks/typescript-frontend/legacy.mdx
rename to solutions/embedded-wallets/integration-guide/typescript/legacy.mdx
index 92fd79c9..d75659cb 100644
--- a/sdks/typescript-frontend/legacy.mdx
+++ b/solutions/embedded-wallets/integration-guide/typescript/legacy.mdx
@@ -3,9 +3,11 @@ title: "@turnkey/sdk-browser (legacy)"
sidebarTitle: "Legacy (@turnkey/sdk-browser)"
---
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
`@turnkey/sdk-browser` is our legacy TypeScript SDK for building embedded wallet experiences in browser applications.
-This package will soon be discontinued, if you're starting a new project, we recommend using [`@turnkey/core`](/sdks/typescript-frontend/index) instead. If you're using React, please consider using the [`@turnkey/react-wallet-kit`](/sdks/react/getting-started) for a more tailored experience.
+This package will soon be discontinued, if you're starting a new project, we recommend using [`@turnkey/core`](/solutions/embedded-wallets/integration-guide/typescript/index) instead. If you're using React, please consider using the [`@turnkey/react-wallet-kit`](/solutions/embedded-wallets/integration-guide/react/getting-started) for a more tailored experience.
## Overview
@@ -303,26 +305,8 @@ const result = await turnkey.serverSign("method", [param1, param2]);
## Examples
-
-
-
-
-
+
+
+
+
+
diff --git a/solutions/embedded-wallets/overview.mdx b/solutions/embedded-wallets/overview.mdx
new file mode 100644
index 00000000..70bc6cd4
--- /dev/null
+++ b/solutions/embedded-wallets/overview.mdx
@@ -0,0 +1,96 @@
+---
+title: "Overview"
+---
+
+import { SolutionCard } from '/snippets/solution-card.mdx';
+
+## What are embedded wallets?
+
+An embedded wallet is a crypto wallet built directly into your application. Instead of asking users to install a browser extension or manage seed phrases, your app handles wallet creation, authentication, and signing behind the scenes. **Users interact with your product; the wallet is infrastructure they never have to think about.**
+
+## Why Turnkey for embedded wallets?
+
+Building embedded wallets from scratch means solving key management, multi-chain signing, authentication, custody models, and policy controls, all without exposing private keys. Turnkey handles this infrastructure so you can focus on your product.
+
+With Turnkey, you can:
+
+- Authenticate users via email, phone number, biometrics, social logins, or passkeys
+- Create and manage wallets across multiple chains
+- Configure custodial, non-custodial, or hybrid custody models
+- Control signing permissions with a programmable policy engine
+- Sponsor gas so users never need native tokens
+- Leverage pre-built UI components or build fully custom experiences
+- Import and export keys to support user sovereignty
+
+## How it works
+
+User authentication flows into a signed request to Turnkey. Inside the secure enclave, the
+[policy engine](/features/policies/overview) evaluates the request; key derivation and signing
+follow, and only the signature is returned. Your app can then broadcast the transaction through
+another provider or with
+[Turnkey Transaction Management](/features/transaction-management).
+
+
+ 
+
+
+### Custody models
+
+We recommend creating a Turnkey [sub-organization](/features/sub-organizations) for each end user. This gives every user a fully isolated environment with their own wallets, credentials, and policies.
+
+Private keys in Turnkey never leave the [secure enclave](/security/secure-enclaves). Custody is determined by who holds the credentials that can authorize the enclave to sign.
+
+- **Non-custodial:** The user is the sole party with signing authority. Only their authenticator (passkey, email, biometric) can authorize the enclave to produce a signature. Users can [export their keys](/features/wallets/export-wallets) to access assets independently of your application.
+- **Custodial:** Your application holds signing authority (via API key) and can authorize transactions without per-action user approval. Common for automated workflows like trading or subscription payments.
+- **Hybrid:** Both the user and your application hold credentials, but [policies](/features/policies/quickstart) define what each party can authorize. For example, the user controls asset transfers while your app handles gas sponsorship or scheduled operations.
+
+Turnkey supports all three models. The custody configuration is up to your application and can be tailored to match your product's requirements.
+
+### Security model
+
+- **Keys never leave the enclave.** Private keys live in [Trusted Execution Environments (TEEs)](/security/secure-enclaves). All derivation and signing happen inside verifiable infrastructure; only signatures are returned.
+- **Authenticator-bound requests.** Every sensitive operation is signed by a user-held authenticator (passkey, email, etc.). The enclave verifies the signature before performing the operation. See [Authentication Overview](/features/authentication/overview).
+- **Scoped, programmable control.** Choose non-custodial, hybrid, or app-controlled custody. [Policies](/features/policies/quickstart) and sub-organization isolation limit who can sign what.
+- **Trusted vs. untrusted separation.** Verification and execution run only inside secure enclaves. A breach of your app or backend does not expose keys or signing capability.
+
+For a deeper look, see [Security](/security/our-approach) and [Secure Enclaves](/security/secure-enclaves).
+
+## Building with Turnkey
+
+For React applications, the **[Embedded Wallet Kit (EWK)](/solutions/embedded-wallets/integration-guide/react/index)** is the recommended starting point. It provides pre-built auth and wallet UI components, a hook-based API, and requires no backend. It is the most opinionated path, designed to get you to a working embedded wallet with minimal configuration.
+
+Turnkey also provides SDKs for [React Native](/solutions/embedded-wallets/integration-guide/react-native/overview), [Swift](/solutions/embedded-wallets/integration-guide/swift/overview), [Kotlin](/solutions/embedded-wallets/integration-guide/kotlin/overview), and [Flutter](/solutions/embedded-wallets/integration-guide/flutter/index). For fully custom implementations, you can call the Turnkey API directly.
+
+See the [Integration Guide](/solutions/embedded-wallets/integration-guide/overview) to start building, or the [SDK Reference](/sdks/introduction) for detailed method documentation.
+
+## Use cases
+
+Embedded wallets serve different needs depending on who holds the wallet and how it's operated. Choose the pattern that matches what you're building.
+
+
+
+
+
+
+
+## Ready to build?
+
+- [Quickstart](/solutions/embedded-wallets/quickstart) -- explore the live demo, clone a starter app, or jump straight into building
+- [Integration Guide](/solutions/embedded-wallets/integration-guide/overview) -- step-by-step guides for React, React Native, Flutter, Swift, and Kotlin
+- [Documentation](/features/authentication/overview) -- dig into the underlying concepts: auth, wallets, policies, and more
diff --git a/solutions/embedded-wallets/quickstart.mdx b/solutions/embedded-wallets/quickstart.mdx
new file mode 100644
index 00000000..27b7f36f
--- /dev/null
+++ b/solutions/embedded-wallets/quickstart.mdx
@@ -0,0 +1,131 @@
+---
+title: "Embedded wallets quickstart"
+description:
+ "Three paths to get started with Turnkey's embedded wallets, whether you want to explore, clone,
+ or build from scratch."
+sidebarTitle: "Quickstart"
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+
+Turnkey's embedded wallets let you add secure, fully-featured wallet experiences to your app. There
+are three ways to get started, depending on how hands-on you want to be.
+
+
+ **Building with AI?** Connect your IDE or LLM to Turnkey's docs via our [MCP server and LLM
+ feeds](/get-started/using-llms) for contextual help while you integrate.
+
+
+
+
+
+
+
+
+---
+
+## Explore the live demo
+
+The fastest way to see Turnkey embedded wallets in action. Our
+[live demo app](https://wallets.turnkey.com/) is a fully functional embedded wallet built with the
+Wallet Kit. Use it to try out authentication flows, wallet creation, transaction signing, and more,
+all from your browser with no setup.
+
+
+
+## Clone and customize
+
+If you want to get running locally, clone one of the demo apps below and start customizing. Each is
+a complete, runnable application you can use as a starting point for your own integration.
+
+### Web
+
+#### Demo embedded wallet ([code](https://github.com/tkhq/sdk/tree/main/examples/react-wallet-kit))
+
+The flagship embedded wallet demo. Built with `@turnkey/react-wallet-kit`. Covers the full embedded
+wallet lifecycle:
+
+- Authentication via passkeys, email OTP, and OAuth
+- Creating wallets and wallet accounts
+- Sending and receiving funds
+- Importing and exporting wallets
+- Adding credentials
+
+
+
+
+
+
+
+
+
+
+### Mobile
+
+#### React Native demo ([code](https://github.com/tkhq/react-native-demo-wallet))
+
+Demonstrates Turnkey's JavaScript packages in a React Native environment. Covers authentication,
+wallet creation, export, and transaction signing.
+
+
+
+
+
+#### Flutter demo ([code](https://github.com/tkhq/dart-sdk/tree/main/examples/flutter-demo-app))
+
+Demonstrates Turnkey's Flutter packages. Covers authentication, wallet creation, export, and
+transaction signing.
+
+
+
+
+
+## Build with the integration guide
+
+Ready to integrate Turnkey into your own app? The
+[Integration Guide](/solutions/embedded-wallets/integration-guide/overview) walks you through everything step
+by step.
+
+For React apps, the **Wallet Kit** is the recommended starting point. It provides pre-built auth and
+wallet UI components, a hook-based API, and requires no backend setup.
+
+For React Native, Flutter, Swift, or Kotlin, choose the guide for your platform:
+
+
+
+ Pre-built components with minimal configuration.
+
+
+ JavaScript packages for React Native.
+
+
+ Dart SDK for Flutter apps.
+
+
+ Native iOS integration.
+
+
+ Native Android integration.
+
+
+
+For fully custom implementations or lower-level control, you can work directly with the
+[Turnkey API](/api-reference/overview/intro).
diff --git a/solutions/key-management/encryption-key-storage.mdx b/solutions/key-management/encryption-key-storage.mdx
new file mode 100644
index 00000000..dd291190
--- /dev/null
+++ b/solutions/key-management/encryption-key-storage.mdx
@@ -0,0 +1,138 @@
+---
+title: "Encryption Key Storage"
+description: "Build recovery flows with risk separation between your infrastructure and Turnkey."
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+import { SolutionCard } from '/snippets/solution-card.mdx'
+
+Store and retrieve encryption keys from Turnkey's secure enclave with policy-controlled access. Your infrastructure holds encrypted data and Turnkey holds the encryption key. Neither party alone can access plaintext. For an overview of Turnkey's key management capabilities, see the [Key Management Overview](/solutions/key-management/overview).
+
+## Powered by Turnkey
+
+- [**World App**](https://www.turnkey.com/blog/turnkey-announces-integration-tools-for-humanitys-world-app) (by Tools for Humanity) -- encrypts each user's recovery bundle on-device and stores the encryption key in Turnkey's secure enclave, gated by user authentication via OAuth. [View on GitHub](https://github.com/worldcoin/backup-service).
+
+## Key implementation decisions
+
+| Decision | What to consider | Learn more |
+| :--- | :--- | :--- |
+| **Export controls** | Gate key export through policies. Require quorum approval, restrict which users can trigger export, or scope export to specific key IDs. | [Policy Engine](/features/policies/overview), [Root Quorum](/features/users/root-quorum) |
+| **Authentication method** | Choose how users authenticate to access keys: API keys, passkeys, social logins, email, or SMS OTP. Match the method to your security and UX requirements. | [Authentication Overview](/features/authentication/overview) |
+| **Encrypted data storage** | Store encrypted bundles wherever you control: client-side (localStorage, IndexedDB), mobile secure enclave, your database, or object storage (S3, GCS). Turnkey only holds the encryption key. | |
+
+## Example: backup and recovery
+
+A common pattern for applications: encrypt recovery bundles, store them in your infrastructure, and authenticate through Turnkey to decrypt when needed. No single party holds both the encrypted data and the decryption key.
+
+
+
+
+
+| Need | How Turnkey solves it |
+| :--- | :--- |
+| Risk separation between platforms | Turnkey never sees the encrypted data; your infrastructure never sees the encryption key. Both must be compromised. |
+| Decrypt recovery bundles without managing keys directly | Encryption key lives in the enclave; authenticate to export it on demand |
+| Caller retains control | Only the caller's authenticator (passkey, email, social login) can trigger key export |
+| Policy-gated access for sensitive operations | Quorum approval, scoped export policies, and audit trails for every key operation |
+
+### Implementation steps
+
+
+ Explore the complete implementation in the [GitHub encryption-key-escrow example](https://github.com/tkhq/sdk/tree/main/examples/encryption-key-escrow).
+
+
+
+
+ Generate a P-256 keypair in Turnkey using [createPrivateKeys](/api-reference/private-keys/create-private-keys). The private key is stored in Turnkey's [secure enclave](/security/secure-enclaves) and never exposed.
+
+ ```typescript
+ const { privateKeys } = await turnkey.apiClient().createPrivateKeys({
+ privateKeys: [{
+ privateKeyName: "escrow-encryption-key",
+ curve: "CURVE_P256",
+ addressFormats: [],
+ }],
+ });
+ ```
+
+
+
+ Fetch the public key to use for encryption:
+
+ ```typescript
+ const { privateKey } = await turnkey.apiClient().getPrivateKey({
+ privateKeyId: encryptionKeyId,
+ });
+ const publicKey = privateKey.publicKey;
+ ```
+
+
+
+ Use the public key to encrypt sensitive data on your side. Turnkey never sees the plaintext or the encrypted result:
+
+ ```typescript
+ // Using P-256 ECIES encryption
+ const encryptedBundle = await encryptWithPublicKey(publicKey, sensitiveData);
+
+ // Store in YOUR infrastructure
+ await saveToYourStorage(encryptedBundle);
+ ```
+
+
+
+ Authenticate the user through your normal auth flow, then request the encryption private key from Turnkey using [exportPrivateKey](/api-reference/private-keys/export-private-key):
+
+ ```typescript
+ const targetKeyPair = generateP256KeyPair();
+
+ const { exportBundle } = await turnkey.apiClient().exportPrivateKey({
+ privateKeyId: encryptionKeyId,
+ targetPublicKey: targetKeyPair.publicKeyUncompressed,
+ });
+
+ const decryptionKey = await decryptExportBundle({
+ exportBundle,
+ embeddedKey: targetKeyPair.privateKey,
+ organizationId,
+ });
+ ```
+
+ Use Turnkey's [policy engine](/features/policies/overview) to add controls on key export:
+
+ ```json
+ {
+ "policyName": "Escrow-Key-Export-Policy",
+ "effect": "EFFECT_ALLOW",
+ "condition": "activity.type == 'ACTIVITY_TYPE_EXPORT_PRIVATE_KEY' && private_key.id == ''",
+ "consensus": "approvers.count() >= 2"
+ }
+ ```
+
+ This example requires two approvers for any export of the encryption key, adding human oversight to sensitive operations.
+
+
+
+ Decrypt your stored bundles and use them locally, with no further Turnkey calls:
+
+ ```typescript
+ const plaintext = await decryptWithPrivateKey(decryptionKey, encryptedBundle);
+ // Use the decrypted data (sign transactions, access credentials, etc.)
+ ```
+
+ When done, clear the decryption key and any decrypted data from memory:
+
+ ```typescript
+ secureWipe(decryptionKey);
+ secureWipe(decryptedData);
+ ```
+
+
+
+## Next steps
+
+
+
+
+
+
+
diff --git a/solutions/key-management/enterprise-disaster-recovery.mdx b/solutions/key-management/enterprise-disaster-recovery.mdx
new file mode 100644
index 00000000..62162f2b
--- /dev/null
+++ b/solutions/key-management/enterprise-disaster-recovery.mdx
@@ -0,0 +1,96 @@
+---
+title: "Enterprise Disaster Recovery"
+description: "Import and recover wallets with end-to-end encryption, quorum-controlled access, and a cryptographic audit trail."
+---
+
+import { FeatureCard } from '/snippets/feature-card.mdx'
+import { SolutionCard } from '/snippets/solution-card.mdx'
+
+Back up wallets on Turnkey and recover them when you need to for incident response, provider migration, and redundancy. All key material is encrypted directly to Turnkey's secure enclave using [HPKE](/security/enclave-secure-channels), and every recovery operation is cryptographically stamped. For an overview of Turnkey's key management capabilities, see the [Key Management Overview](/solutions/key-management/overview).
+
+## Key implementation decisions
+
+| Decision | What to consider | Learn more |
+| :--- | :--- | :--- |
+| **Organization setup** | Create dedicated recovery users with limited permissions. Distribute authenticators (passkeys, YubiKeys) across geographic locations where possible. | [Organizations](/features/organizations) |
+| **Root quorum** | Require multiple approvers for sensitive operations to prevent any single credential compromise from triggering unauthorized recovery. | [Root Quorum](/features/users/root-quorum) |
+| **Recovery policies** | Restrict what can be done with recovered wallets: limit fund movement to allowed addresses, require multi-party approval, scope signing by chain or value. | [Policy Engine](/features/policies/overview), [Signing Control](/features/policies/examples/signing-control) |
+| **Import method** | Use the NodeJS server SDK for the full import flow including encryption and secure transport, or the React Wallet Kit for client-side import. | [Import Wallets](/features/wallets/import-wallets), [SDK Server](https://github.com/tkhq/sdk/tree/main/examples/import-in-node) |
+
+## Example: treasury recovery
+
+Import wallet keys into Turnkey's secure enclave ahead of time. If a key holder becomes unavailable or a hardware wallet fails, recover treasury assets with quorum-controlled access and policy-restricted fund movement.
+
+
+
+
+
+| Need | How Turnkey solves it |
+| :--- | :--- |
+| Import keys with no plaintext exposure in transit | All key material is encrypted directly to the enclave using [HPKE](/security/enclave-secure-channels). Plaintext never exists outside the enclave boundary. |
+| No single person can unilaterally move recovered funds | [Quorum approval](/features/users/root-quorum) requires multiple approvers for sensitive operations |
+| Restrict what can be done with recovered wallets | [Policies](/features/policies/overview) scope fund movement to allowed addresses, chains, and value thresholds |
+| Cryptographic audit trail | Every recovery operation is cryptographically stamped, ensuring recoveries cannot be tampered with |
+| Secondary signing path must always be available | Import backup copies of critical wallet keys so operations continue if a primary signer goes down |
+
+### Implementation steps
+
+
+ Explore the complete implementation in the [GitHub disaster-recovery example](https://github.com/tkhq/sdk/tree/main/examples/disaster-recovery).
+
+
+
+
+ Create a [Turnkey organization](https://app.turnkey.com/dashboard/auth/initial) and establish the security foundation for recovery operations:
+
+ - Create dedicated recovery users with specific, limited permissions
+ - Configure the [Root Quorum](/features/users/root-quorum) to require multiple approvers for sensitive operations
+ - Distribute authenticators ([passkeys](/features/authentication/passkeys/introduction), YubiKeys) across geographic locations
+ - Define [policies](/features/policies/examples/signing-control) that restrict what can be done with recovered wallets
+
+
+
+ Use the [NodeJS server SDK](https://github.com/tkhq/sdk/tree/main/examples/import-in-node) to initialize the import and encrypt the wallet material to Turnkey's enclave:
+
+ ```ts
+ import { Turnkey } from "@turnkey/sdk-server";
+ import { encryptPrivateKeyToBundle, encryptWalletToBundle } from "@turnkey/crypto";
+
+ const initResult = await turnkeyClient.apiClient().initImportWallet({
+ userId,
+ });
+
+ const walletBundle = await encryptWalletToBundle({
+ mnemonic,
+ importBundle: initResult.importBundle,
+ userId,
+ organizationId,
+ });
+ ```
+
+
+
+ Use [importWallet()](/generated-docs/core/turnkey-client-import-wallet) to transmit the encrypted bundle. The enclave decrypts and stores the key material. All fund movements are logged with cryptographic signatures.
+
+ ```ts
+ const walletImportResult = await turnkeyClient.apiClient().importWallet({
+ userId: userId,
+ walletName: "Your imported wallet!",
+ encryptedBundle: walletBundle,
+ accounts: [],
+ });
+ ```
+
+
+
+## Next steps
+
+
+
+
+
+
+
diff --git a/solutions/key-management/overview.mdx b/solutions/key-management/overview.mdx
new file mode 100644
index 00000000..f8ecba93
--- /dev/null
+++ b/solutions/key-management/overview.mdx
@@ -0,0 +1,76 @@
+---
+title: "Overview"
+---
+
+import { SolutionCard } from '/snippets/solution-card.mdx';
+
+## What is key management?
+
+Turnkey provides infrastructure to store, recover, and operate on cryptographic keys beyond just wallet use cases. Instead of managing raw key material in your own infrastructure, your application delegates key storage to Turnkey's secure enclaves and controls access through programmable policies. **You define who can use a key and under what conditions; Turnkey ensures the key material is never exposed.**
+
+## Why Turnkey for key management?
+
+Protecting cryptographic keys means solving for secure storage, access control, disaster recovery, and auditability. Turnkey's infrastructure handles this so your keys remain protected throughout their lifecycle.
+
+With Turnkey, you can:
+
+- Store and [import](/security/enclave-secure-channels) cryptographic keys in hardware-backed [secure enclaves](/security/secure-enclaves) where key material never exists in plaintext outside the enclave boundary
+- Gate key access and export through a programmable [policy engine](/features/policies/overview), including [quorum approval](/features/users/root-quorum) for sensitive operations
+- Authenticate key access through multiple methods including API keys, [passkeys](/features/authentication/passkeys/introduction), [social logins](/features/authentication/social-logins), [email](/features/authentication/email), and [SMS OTP](/features/authentication/sms)
+- Maintain a cryptographic audit trail where every key operation is stamped and verifiable
+- Distribute trust between your infrastructure and Turnkey so no single party can access plaintext material
+
+## How it works
+
+Your backend authenticates to Turnkey via API key. The [policy engine](/features/policies/overview) evaluates every request inside the secure enclave before any key operation executes. Keys are stored and operated on entirely within the enclave. Only derived outputs (public keys, encrypted export bundles, and operation results) are returned.
+
+### Access control model
+
+Key management is configured through an [organization](/features/organizations) with users, tags, and policies to control access:
+
+- **Users** representing human operators and automated services, each with their own credentials (API keys, passkeys)
+- **Tags** grouping users by role (e.g. `recovery-admin`, `backup-operator`)
+- **Policies** controlling who can access keys and under what conditions: by key ID, operation type, approval threshold, or any combination
+
+Turnkey is deny-by-default. If no policy explicitly allows an action, it is rejected. See [Policies](/features/policies/overview) and [Policy Language](/features/policies/language).
+
+### Security model
+
+- **Keys never leave the enclave.** Cryptographic keys live in [Trusted Execution Environments (TEEs)](/security/secure-enclaves). All key operations happen inside verifiable infrastructure; only derived outputs are returned.
+- **End-to-end encryption for import and export.** Key material in transit is encrypted directly to the enclave using [HPKE](/security/enclave-secure-channels). Plaintext never exists outside the enclave boundary.
+- **Policy-gated access.** Every key operation is evaluated against policies in the enclave. Users and services can only perform actions they have been explicitly authorized for.
+- **Trusted vs. untrusted separation.** A breach of your backend does not expose keys. The enclave enforces policies independently of your infrastructure.
+
+For a deeper look, see [Security](/security/our-approach) and [Secure Enclaves](/security/secure-enclaves).
+
+## Building with Turnkey
+
+Key management integrations are backend-driven. Use Turnkey's server SDKs to store keys, manage policies, and handle import and export operations programmatically from your infrastructure.
+
+Server SDKs are available for [TypeScript](/solutions/company-wallets/integration-guide/javascript-server), [Go](/solutions/company-wallets/integration-guide/golang), [Ruby](/solutions/company-wallets/integration-guide/ruby), [Python](/solutions/company-wallets/integration-guide/python), and [Rust](/solutions/company-wallets/integration-guide/rust). For full control, you can call the [Turnkey API](/api-reference/overview/intro) directly.
+
+The [Turnkey Dashboard](https://app.turnkey.com) provides an interface for managing organizations, users, and policies.
+
+## Use cases
+
+Key management serves different needs depending on how your application uses cryptographic keys. Choose the pattern that matches your requirements.
+
+
+
+
+
+
+## Ready to build?
+
+- [Policy Quickstart](/features/policies/quickstart) -- define access controls and approval requirements
+- [SDK Reference](/sdks/introduction) -- server SDKs for TypeScript, Go, Ruby, Python, and Rust
diff --git a/solutions/overview.mdx b/solutions/overview.mdx
new file mode 100644
index 00000000..4724bc32
--- /dev/null
+++ b/solutions/overview.mdx
@@ -0,0 +1,85 @@
+---
+title: "Introducing Turnkey Solutions"
+description: "Structured starting points for building onchain with Turnkey"
+---
+
+import { SolutionCard } from '/snippets/solution-card.mdx';
+
+To help you build quickly, we've packaged common patterns like wallet provisioning, policy enforcement, and transaction flows into easy integration paths called Turnkey Solutions. Each Solution is built on Turnkey's underlying primitives, so you're never locked into a rigid workflow and can always go deeper when you need more flexibility.
+
+Whether you're building consumer apps, business tooling, or AI-powered systems, there's a solution designed for your use case.
+
+---
+
+## Embedded Wallets
+
+Wallet experiences built directly into your product. Users authenticate with email, passkeys, or social login — you control the UX.
+
+
+
+
+
+
+
+---
+
+## Company Wallets
+
+Wallets your organization operates for onchain automation — high-volume signing with programmable controls.
+
+
+
+
+
+
+
+---
+
+## Key Management
+
+Enterprise-grade security for your most sensitive keys — hardware-backed with programmable access controls.
+
+
+ Secure, flexible,
+
+ and scalable wallet infrastructure
+
+
+ Turnkey is infrastructure for generating wallets and keys, signing transactions, and
+ controlling who can use them, when, and how. Private keys are secured in hardware-isolated
+ enclaves and never exposed — not even to Turnkey.
+
+ Build at whichever level best meets your needs. Start with Solutions for common patterns, go
+ deeper with our SDKs for more control, or reach all the way down to the API for complete
+ flexibility. The full stack is always available.
+