diff --git a/.gitignore b/.gitignore index 6bc2b40c..acecd96c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ build .vscode # windsurf rules -.windsurfrules \ No newline at end of file +.windsurfrules +CLAUDE.md \ No newline at end of file diff --git a/README.md b/README.md index 20c400a7..e00d8264 100644 --- a/README.md +++ b/README.md @@ -40,34 +40,7 @@ Changes to the documentation are automatically deployed when merged to the main You can access the Mintlify dashboard for this project at: [dashboard.mintlify.com](https://dashboard.mintlify.com/turnkey-0e7c1f5b/turnkey-0e7c1f5b) - -## The dashboard provides analytics, deployment status, and other management features for our documentation. - -## Legacy Documentation - -The following information pertains to the previous Docusaurus-based documentation setup. - -### Algolia - -We use the Algolia plugin for Docusaurus to manage search on our docs page. The primary dashboard can be accessed via https://dashboard.algolia.com/apps/89KSB43UFT/dashboard. Reach out to Jack, Arnaud, or Andrew for access. - -#### Crawling - -Our crawler settings can be found at https://crawler.algolia.com/admin/crawlers/15584ae7-61de-4f26-af35-4bc55d0de0b5/overview. Algolia crawls our docs site once a week on Monday at 12:31 (UTC). This is simply the default behavior. There are cases where we may want to forcefully trigger Algolia to crawl/index our site, i.e. when we do a big refactor or otherwise reorganize the structure of our docs significantly. - -In order to manually trigger a new crawl, use the `Restart crawling` button: - - - -Our docs site is small, so each crawl is quick (~30-60s). - -### Vercel - -Each push to Github will trigger a Vercel build: - - - -This is a convenient way to view changes, add feedback, and collaborate overall. Any build can also be promoted to production, if need be. +The dashboard provides analytics, deployment status, and other management features for our documentation. ## Build & Code Generation @@ -79,3 +52,20 @@ We provide the following Make targets to generate API reference content: - `make tags`: Generate the endpoint-tags MDX snippet at `snippets/data/endpoint-tags.mdx`. These commands require Node.js and `ts-node`. + +--- + +**Shared Snippets Usage Guidelines** + +The docs in this repository utilize shared MDX snippets to ensure consistency and adherence to DRY principles across duplicate pages. When identical content is required in multiple locations, each duplicate page imports a shared snippet from the `/snippets/shared/` folder. This method minimizes maintenance overhead by centralizing content updates. + +**Important:** Always update the shared MDX file rather than modifying individual duplicate pages. This guarantees that any change propagates throughout all references. + +| Duplicate Page Path | Shared MDX File | +| ------------------------------------------------------------ | -------------------------------------- | +| `concepts/policies/overview.mdx` | `/snippets/shared/policy-engine.mdx` | +| `products/embedded-wallets/features/policy-engine.mdx` | `/snippets/shared/policy-engine.mdx` | +| `products/transaction-automation/features/export-wallets.mdx` | `/snippets/shared/export-wallets.mdx` | +| `products/transaction-automation/features/import-wallets.mdx` | `/snippets/shared/import-wallets.mdx` | + +*Note: Duplicate pages must reside in separate file paths as required by `docs.json`. Mintlify restricts pages with identical content from sharing the same path to ensure correct sidebar behavior.* diff --git a/authentication/email.mdx b/authentication/email.mdx index de790eb1..e4df7ef1 100644 --- a/authentication/email.mdx +++ b/authentication/email.mdx @@ -1,7 +1,6 @@ --- -title: "Overview" +title: "Email Auth & Recovery" description: "Email Authentication enables users to authenticate and recover their Turnkey accounts using email-based verification. There are two methods of email authentication:" -sidebarTitle: "Email" --- **One-Time Password** @@ -26,7 +25,10 @@ Email Authentication is built with expiring API keys as the foundation. The two The authentication process happens in two steps: - A 6-9 digit or alphanumeric OTP code is sent to the user's verified email address + + A 6-9 digit or alphanumeric OTP code is sent to the user's verified email + address + Upon verification of the correct code, an API key credential is generated and encrypted for the client @@ -39,6 +41,18 @@ The API key credential is encrypted and delivered directly through email to the In both cases, once the credential is live on the client side (within the context of an iframe), it is readily available to stamp (authenticate) requests. See the [enclave to end-user secure channel](/security/enclave-secure-channels) for more info on how we achieve secure delivery. +## 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'" +} +``` + ## User Experience ### OTP-based Authentication Flow @@ -109,6 +123,58 @@ The recovery process consists of two phases: auth email +## 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: + } + }, +}); +``` + +### Email Templates + +We also support custom HTML email templates for [Enterprise](https://www.turnkey.com/pricing) clients on the **Scale** tier. 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: + + + ![dynamic email auth + example](/images/embedded-wallets/img/email-auth-example-dynamic.png) + + +If you are interested in implementing bespoke, fully-customized email templates, please reach out to [hello@turnkey.com](mailto:hello@turnkey.com). + ## Authorization Authorization is managed through our [policy engine](/concepts/policies/overview): diff --git a/authentication/overview.mdx b/authentication/overview.mdx index e536b91f..e0708615 100644 --- a/authentication/overview.mdx +++ b/authentication/overview.mdx @@ -3,8 +3,6 @@ title: Overview description: Learn about supported authentication methods for Turnkey, how to add them, and usage details. --- -# Overview - 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**. @@ -68,11 +66,4 @@ For information about managing authenticated sessions, see our [Sessions](/authe Manage authenticated user sessions and access tokens in your application. - - Authenticate and sign requests to the Turnkey API with cryptographic stamps. - diff --git a/concepts/overview.mdx b/concepts/overview.mdx index 728de175..64e628e1 100644 --- a/concepts/overview.mdx +++ b/concepts/overview.mdx @@ -3,16 +3,34 @@ 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." --- -When you sign up to Turnkey, you create an **[organization](/concepts/organizations)**, which is a segregated collection of users (including root users), wallets, and policies that are controlled by your business. This top level organization that is initially created, often referred to as your parent organization, is generally meant to represent an entire Turnkey-powered application. **[Users](/concepts/users/introduction)** can access Turnkey via their **[credentials](/concepts/users/credentials)** (e.g., API key, passkey). There are two primary ways for users to interact with Turnkey -- via the [Turnkey Dashboard](https://app.turnkey.com/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. Users can submit **[activities](/developer-reference/api-overview/submissions)** (e.g. sign transaction, create user) based on the permissions granted by **[policies](/concepts/policies/overview)**. Root users are a special type of user that can bypass our policy engine and take any action if the threshold of **[root quorum](/concepts/users/root-quorum)** is met. Finally, **[wallets](/concepts/wallets)** are HD seed phrases that can derive many wallet accounts (i.e., individual addresses) which are used for signing operations. +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. -Parent organizations can create **[sub-organizations](/concepts/sub-organizations)**, a segregated set of users, policies, and wallets to which the parent has read access, but not write access. These sub-organizations typically map to an end user in an embedded wallet setup, but can be used wherever you may need full segregation of Turnkey resources. +### 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: all concepts screenshot +- **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 and 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: @@ -70,52 +88,13 @@ Resources used to generate crypto addresses and sign transactions or messages. W Learn more about leveraging Wallets across different crypto ecosystems on our [Ecosystem Support](/networks/framework) page. -## Typical implementations - -### Transaction Automation - -Transaction automation entails a business signing transactions on its own behalf. For example, automating payments flows, managing smart contract deployment or programmatically trading in DeFi. - - - transaction automation screenshot - - -In this setup, the business is in full control of its wallets at all times. This use case typically does not require the use of sub-organizations and everything can be managed from the parent organization. We suggest the following setup: - -- **Root Users:** After initial setup of your parent organization, set a reasonable root quorum (e.g., 2 of 3), attach backup credentials to each user for safekeeping, and only use the root users in a “break glass” scenario. -- **Service Users:** Create different users for separate services and/or approval workflows. For example, you might have user A that can automatically sign any transaction with Wallet X, but require both user A and user B to approve transactions with Wallet B. -- **Service Policies:** Set appropriately restrictive policies based on your security needs. -- **Wallets:** Create separate wallets where differentiated policies are needed, otherwise just leverage multiple wallet accounts within a single wallet. - -### Embedded Wallets - -Embedded wallets entail a business creating non-custodial wallets controlled by its end users. For example, allowing an end user to create and use a wallet via Web2 authentication methods like email or OAuth. - - - embedded wallets screenshot - - -This is a non-custodial setup where the end user is in control of its wallet at all times. This use case requires the use of sub-organizations which map to an individual end user, and does not require any wallets in the parent organization. The parent organization will be used by your backend service for onboarding new users and initiating certain authentication methods (e.g., email, SMS), while the sub-organizations will be used by the end users for day-to-day signing. We suggest the following setup: - -- **Root Users:** After initial setup of your parent organization, set a reasonable root quorum (e.g., 2 of 3), attach backup credentials to each user for safekeeping, and only use the root users in a “break glass” scenario. -- **Normal Users:** Create a single service user used for user onboarding and authentication. -- **Policies:** Set a policy granting the user permission to `CREATE_SUB_ORGANIZATION`, `EMAIL_AUTH`, `OAUTH`, `OTP_AUTH`. For examples of how to create such policies [look here](/concepts/policies/examples). -- **Sub-organizations:** Create individual sub-organizations for each user that contain a single root user with any relevant credentials, and a single wallet with any relevant wallet accounts. - -For more details on each individual concepts, refer to the pages below: - Understand Turnkey's core features and fundamentals. {" "} + {" "} + {" "} + {" "} + '" -} -``` - -## Policy evaluation - -All policies defined within an Organization are evaluated on each request. The image below describes how an activity outcome is determined when resolving multiple policies. The rule follows the below steps: - - - - If a quorum of root users takes the action, the final outcome is `OUTCOME_ALLOW` - - - Else if any applicable policy has `EFFECT_DENY`, the final outcome is `OUTCOME_DENY`. This is also referred to as "explicit deny." - - - Else if at least one applicable policy has `EFFECT_ALLOW`, then the final outcome is `OUTCOME_ALLOW` - - - Else the final outcome is `OUTCOME_DENY`. This is also referred to as "implicit deny." In cases of conflicts, `EFFECT_DENY` always wins. - - - -Stated differently: - - - policy overview - - -Almost all actions on Turnkey are implicitly denied by default. There are a few exceptions, however: - -* Root users bypass any policies. -* All users have implicit GET (read) permissions in their own Organization and any associated Sub-Organizations. -* All users have implicit permission to change their own credentials. -* All users have implicit permission to approve an activity if they were included in consensus (i.e., a user specified as part of the consensus required to approve a SIGN\_TRANSACTION activity does not need separate, explicit permission to sign transactions). + diff --git a/concepts/users/introduction.mdx b/concepts/users/introduction.mdx index 1fda70e9..58df30e1 100644 --- a/concepts/users/introduction.mdx +++ b/concepts/users/introduction.mdx @@ -2,7 +2,7 @@ title: "Introduction to 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: "Overview" +sidebarTitle: "Users" --- 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. diff --git a/developer-reference/using-llms.mdx b/developer-reference/using-llms.mdx new file mode 100644 index 00000000..2e1aa129 --- /dev/null +++ b/developer-reference/using-llms.mdx @@ -0,0 +1,69 @@ +--- +title: "Using LLMs" +--- + +### Using AI to integrate Turnkey + +Turnkey documentation is now AI-enhanced. Whether you're using ChatGPT, Claude, or a custom LLM integration, +we've made it easy to feed Turnkey docs directly into your models—and even easier to surface relevant answers programmatically or in your dev tools. + +#### LLM Feed Files + +To help LLMs stay current on how Turnkey works, we expose two continuously updated files for ingestion: + +- [`llms.txt`](https://docs.turnkey.com/llms.txt) - A concise, high-signal list of top-level docs pages, great for smaller models or quick context building. +- [`llms-full.txt`](https://docs.turnkey.com/llms-full.txt) - A more exhaustive listing that includes nearly all pages, ideal for full-context indexing. + +You can regularly ingest these URLs into your custom GPTs or other LLM apps to ensure Turnkey-specific questions are grounded in accurate technical detail. + +#### Search Turnkey Docs with Mintlify MCP + +You can integrate our documentation with any Mintlify MCP-compatible client to perform contextual searches without leaving your development environment. + +To install and register the Turnkey MCP server, run: + +```bash +npx @mintlify/mcp@latest add turnkey-0e7c1f5b +``` + +On execution, you will see output similar to: + +``` +🛠 Installing Tools: + + search + Search across the Turnkey documentation to fetch relevant context for a given query + +✔ Created new MCP server at ~/.mcp/turnkey-0e7c1f5b + +? Select MCP client: › Use arrow keys to select. Return to submit. +❯ Cursor + Windsurf + Claude Desktop + All + +To start the server, run: +``` + +```bash +node ~/.mcp/turnkey-0e7c1f5b/src/index.js +``` + +**Supported MCP Clients:** + +- Cursor +- Windsurf +- Claude Desktop +- All + +#### Chat With Our Docs (Contextual Deep Links) + +We've enabled Mintlify's `contextual` feature across Turnkey's docs: + +- You can copy any Turnkey docs page as Markdown for reuse or embedding. +- Even better: you can launch a chat session with Claude or ChatGPT preloaded with that specific page's context. + +This is perfect for troubleshooting, code generation, or just diving deeper into a topic with AI assistance. + +To enable this, we're using Mintlify's contextual param: +[Learn more here.](https://mintlify.com/docs/settings/global#param-contextual) diff --git a/developer-reference/webhooks.mdx b/developer-reference/webhooks.mdx index f6fe91e5..1e9b1f86 100644 --- a/developer-reference/webhooks.mdx +++ b/developer-reference/webhooks.mdx @@ -1,6 +1,7 @@ --- title: "Activity Webhooks" description: "Webhooks provide a powerful mechanism to receive real-time 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)." +sidebarTitle: "Webhooks" --- This guide is designed to walk you through the process of setting up webhooks, from environment preparation to verification of successful event capturing. @@ -28,13 +29,13 @@ turnkey generate api-key --organization $ORGANIZATION_ID --key-name $KEY_NAME ### Ngrok Installation and Setup Ngrok is a handy tool that allows you to expose your local server to the internet. Follow these steps to set it up: + + Download Ngrok from [their website](https://ngrok.com/download). - Download Ngrok from [their website](https://ngrok.com/download). - - - Follow the provided instructions to install Ngrok and configure your auth token. - + Follow the provided instructions to install Ngrok and configure your auth + token. + ### Local Server Setup diff --git a/docs.json b/docs.json index 2a8f9f49..f1d4792b 100644 --- a/docs.json +++ b/docs.json @@ -17,89 +17,179 @@ "tab": "Documentation", "groups": [ { - "group": "Documentation", + "group": "Get Started", "pages": [ "home", - { - "group": "Getting Started", - "pages": [ - "getting-started", - { - "group": "Quickstart", - "pages": [ - "getting-started/quickstart", - "getting-started/embedded-wallet-quickstart", - "getting-started/signing-automation-quickstart" - ] - }, - "getting-started/examples", - "getting-started/launch-checklist" - ] - }, { "group": "Concepts", "pages": [ "concepts/overview", "concepts/organizations", "concepts/sub-organizations", + "concepts/users/introduction", + "concepts/wallets", + "concepts/resource-limits", + "concepts/policies/overview" + ] + }, + "faq", + "getting-started/quickstart", + { + "group": "Quickstarts", + "pages": [ + "getting-started/embedded-wallet-quickstart", + "getting-started/signing-automation-quickstart" + ] + }, + { + "group": "Production Checklist", + "pages": [ + "production-checklist/embedded-wallet", + "production-checklist/transaction-automation" + ] + } + ] + }, + { + "group": "Products", + "pages": [ + { + "group": "Embedded Wallets", + "pages": [ + "embedded-wallets/overview", { - "group": "Users", + "group": "Features", "pages": [ - "concepts/users/introduction", - "concepts/users/credentials", - "concepts/users/root-quorum", - "concepts/users/best-practices" + "embedded-wallets/features/overview", + "reference/embedded-wallet-kit", + { + "group": "Authentication", + "pages": [ + "authentication/overview", + "authentication/email", + "authentication/social-logins", + "authentication/sms", + { + "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" + ] + }, + "concepts/policies/delegated-access", + "products/embedded-wallets/features/policy-engine", + "products/embedded-wallets/features/multi-chain-support", + "authentication/sessions", + "reference/solana-gasless-transactions", + { + "group": "Wallets", + "pages": [ + "wallets/pregenerated-wallets", + "wallets/claim-links", + "reference/aa-wallets", + "wallets/import-wallets", + "wallets/export-wallets", + "wallets/wagmi" + ] + } ] }, - "concepts/wallets", - "concepts/resource-limits", { - "group": "Policies", + "group": "SDKs", "pages": [ - "concepts/policies/overview", - "concepts/policies/quickstart", - "concepts/policies/examples", - "concepts/policies/delegated-access", - "concepts/policies/language" + "sdks/react", + "sdks/react-native", + "sdks/flutter", + "sdks/swift", + "sdks/javascript-browser" + ] + }, + { + "group": "Examples", + "pages": [ + "category/code-examples", + "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/create-user-email", + "embedded-wallets/code-examples/authenticate-user-email", + "embedded-wallets/code-examples/email-recovery", + "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": "Authentication", + "group": "Transaction Automation", "pages": [ - "authentication/overview", + "signing-automation/overview", { - "group": "Passkeys", + "group": "Policies", "pages": [ - "authentication/passkeys/introduction", - "authentication/passkeys/integration", - "authentication/passkeys/options", - "authentication/passkeys/native", - "authentication/passkeys/discoverable-vs-non-discoverable" + "products/transaction-automation/policy-engine", + "concepts/policies/quickstart", + "concepts/policies/language", + "concepts/policies/examples" ] }, - "authentication/email", - "authentication/social-logins", - "authentication/sms", - "authentication/sessions", - "authentication/backend-setup", - "authentication/proxying-signed-requests" - ] - }, - { - "group": "Wallets", - "pages": [ - "wallets/pregenerated-wallets", - "wallets/claim-links", - "wallets/import-wallets", - "wallets/export-wallets" + { + "group": "Features", + "pages": [ + "products/transaction-automation/features/multi-chain-support", + "sdks/cli", + "signing-automation/co-signing-transactions", + "products/transaction-automation/features/import-wallets", + "products/transaction-automation/features/export-wallets", + "developer-reference/webhooks" + ] + }, + { + "group": "Security", + "pages": [ + "products/transaction-automation/features/security/quorom-os", + "products/transaction-automation/features/security/remote-attestation", + "products/transaction-automation/features/security/secure-hardware" + ] + }, + { + "group": "SDKs", + "pages": [ + "sdks/golang", + "sdks/ruby", + "sdks/rust", + "sdks/python", + "sdks/javascript-server" + ] + }, + { + "group": "Examples", + "pages": [ + "category/code-examples-1", + "signing-automation/code-examples/signing-transactions" + ] + } ] - }, + } + ] + }, + { + "group": "Ecosystem Partners", + "pages": [ + "networks/overview", { "group": "Supported Networks", "pages": [ - "networks/overview", "networks/ethereum", "networks/solana", "networks/bitcoin", @@ -107,23 +197,26 @@ "networks/tron", "networks/sui", "networks/sei", - "networks/aptos" + "networks/aptos", + "networks/movement", + "networks/others" ] - }, + } + ] + }, + { + "group": "Developers", + "pages": [ + "getting-started/examples", + "developer-reference/using-llms", { - "group": "Developer Reference", + "group": "API Overview", "pages": [ - { - "group": "API Overview", - "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" - ] - }, - "developer-reference/webhooks" + "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" ] }, { @@ -140,56 +233,6 @@ "security/whitepaper", "security/reporting-a-vulnerability" ] - }, - "faq" - ] - } - ] - }, - { - "tab": "Solutions", - "groups": [ - { - "group": "Embedded Wallets", - "pages": [ - "embedded-wallets/overview", - "embedded-wallets/sub-organizations-as-wallets", - "embedded-wallets/sub-organization-auth", - "embedded-wallets/sub-organization-recovery", - "reference/aa-wallets", - "reference/embedded-wallet-kit", - "reference/solana-gasless-transactions", - { - "group": "Code Examples", - "pages": [ - "category/code-examples", - "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/create-user-email", - "embedded-wallets/code-examples/authenticate-user-email", - "embedded-wallets/code-examples/email-recovery", - "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", - "embedded-wallets/code-examples/social-linking" - ] - } - ] - }, - { - "group": "Signing Automation", - "pages": [ - "signing-automation/overview", - "signing-automation/co-signing-transactions", - { - "group": "Code Examples", - "pages": [ - "category/code-examples-1", - "signing-automation/code-examples/signing-transactions" - ] } ] } @@ -208,9 +251,10 @@ "sdks/react-native", "sdks/golang", "sdks/rust", - "sdks/Ruby", + "sdks/ruby", "sdks/cli", "sdks/flutter", + "sdks/python", { "group": "Swift", "pages": [ @@ -381,13 +425,13 @@ "global": { "anchors": [ { - "anchor": "Community", + "anchor": "Support", "href": "https://join.slack.com/t/clubturnkey/shared_invite/zt-31v4yhgw6-PwBzyNsWCCBTk2xft3EoHQ", "icon": "slack" }, { "anchor": "Blog", - "href": "https://mirror.xyz/turnkeyhq.eth/", + "href": "https://www.turnkey.com/blog", "icon": "newspaper" }, { @@ -408,9 +452,13 @@ }, "navbar": { "links": [ + { + "label": "Demo", + "href": "https://wallets.turnkey.com/" + }, { "label": "Login", - "href": "https://app.turnkey.com/dashboard" + "href": "https://app.turnkey.com/dashboard/auth/login?step=1" } ], "primary": { @@ -592,11 +640,6 @@ "source": "/ecosystems/:slug*", "destination": "/networks/:slug*", "permanent": true - }, - { - "source": "/networks/others", - "destination": "/networks/overview", - "permanent": true } ] } diff --git a/embedded-wallets/features/overview.mdx b/embedded-wallets/features/overview.mdx new file mode 100644 index 00000000..5240531b --- /dev/null +++ b/embedded-wallets/features/overview.mdx @@ -0,0 +1,111 @@ +--- +title: "Features" +sidebarTitle: "Overview" +--- + + + + + + +{" "} + + +{" "} + + +{" "} + + +{" "} + + +{" "} + + + + + + + + + diff --git a/embedded-wallets/overview.mdx b/embedded-wallets/overview.mdx index 492136bf..54813f71 100644 --- a/embedded-wallets/overview.mdx +++ b/embedded-wallets/overview.mdx @@ -1,48 +1,458 @@ --- -title: "Embedded Wallets" -sidebarTitle: "Introduction" +title: "Overview" +sidebarTitle: "Overview" --- -With embedded wallets on Turnkey, 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. +import { Logo } from "/snippets/logo.mdx"; +import { SquareCard } from "/snippets/square-card.mdx"; -### Why embedded wallets? +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. -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. As one of our customers put it: +### Why Embedded Wallets? -> "The ability for us to build our own stack and control the entire user experience without worrying about security has been one of the best things about Turnkey." +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: +With Embedded Wallets, you can: -* Create custom wallet flows that match your product's look and feel -* Choose between custodial or non-custodial models based on your use case -* Leverage advanced security and UX features like multi-sig and session keys -* Support various authentication methods, from passkeys to email-based flows -* Focus on building great products, not managing private keys +- 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 -### How it works +### Custodial vs non-custodial -Turnkey's Embedded Wallets are built on top of our [Sub-Organizations](/concepts/sub-organizations) primitive. Each wallet is represented by a sub-organization, which can be configured with different security settings and access controls. +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. -##### Custodial vs non-custodial +- 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, + whether it's via their own passkey, API key, or iframe session. -* 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, whether it's via their own passkey, API key, or iframe session. +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. -##### Advanced features +### Embedded Wallets Quickstart -* Multi-sig: Require multiple approvals for sensitive transactions -* Session Keys: Grant temporary, limited access to wallets for improved UX -* Flexible Authentication: Use passkeys, email auth, or other methods to secure user access +If you haven't yet, get started quickly using Turnkey's Account/Embedded Wallets Setup. You'll learn how to: -##### Getting started +- Create an Account +- Get Your Organization ID +- Create an API Key +- Set up Turnkey's React SDK in a Next.js application +- Configure authentication with email sign-in +- Implement message signing functionality using a user's Turnkey wallet +- Handle user sessions and wallet interactions -To start building with embedded wallets, check out our detailed guides and API references: +Get started [here](/getting-started/embedded-wallet-quickstart) and come back when you're ready. + +### Integrating Embedded Wallets + +Now that you've gotten started, this guide walks through 3 ways to use sub-organizations as +Embedded Wallets for your users. We first show that it can be used to create non-custodial wallets, +or end-user controlled wallets. Then we explain how you can create custodial wallets, and lastly shared custody wallets. + +#### Non-Custodial Wallets + +In this example wallet implementation, you will create a segregated sub-organization for each end-user, and leverage [passkeys](/authentication/passkeys/introduction) as cryptographic proof of ownership to ensure only the end-user has the ability to approve signing. Your application will construct transactions on behalf of the end-user, and then surface the relevant Turnkey activity request client-side for end-user approval. + +Note that Turnkey is not a customer authentication platform. This gives you the flexibility to create the user experience you envision. Typically, Turnkey integrators implement their own standard end-user authentication flows for login, then employ passkeys behind that login for transaction signing. + +If you'd like to see a live example, head over to our [✨Demo Embedded Wallet✨](https://wallet.tx.xyz/), and follow along with the code [here](https://github.com/tkhq/demo-embedded-wallet). + +**Before you start** + +Make sure you've set up your primary Turnkey organization with at least one API user for programmatic user onboarding. +Check out our [Quickstart guide](/getting-started/quickstart) if you need help getting started. + + + + + After the end-user is logged in, your application prompts the user for passkey creation on the application domain. Our JavaScript SDK has a helper for this: `getWebAuthnAttestation`. See [this example](https://github.com/tkhq/sdk/tree/main/examples/with-federated-passkeys). + +Your application then uses an API-only user to create a new sub-organization on behalf of the end-user with a `CREATE_SUB_ORGANIZATION` activity. In the example below, the new sub-organization has one root user controlled by the end user's passkey, and an associated Ethereum wallet: + +```js +{ + "type": "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V4", + "timestampMs": "", + "organizationId": "", + "parameters": { + "subOrganizationName": "", + "rootUsers": [ + { + "userName": "", + "userEmail": "(optional)", + "authenticators": [ + { + "authenticatorName": "", + "challenge": "", + "attestation": { + "credentialId": "", + "clientDataJson": "", + "attestationObject": "", + "transports": ["AUTHENTICATOR_TRANSPORT_HYBRID"] + } + } + ], + "apiKeys": [] + } + ], + "rootQuorumThreshold": 1, + "wallet": { + "walletName": "Default Wallet", + "accounts": [ + { + "curve": "CURVE_SECP256K1", + "pathFormat": "PATH_FORMAT_BIP32", + "path": "m/44'/60'/0'/0/0", + "addressFormat": "ADDRESS_FORMAT_ETHEREUM" + } + ] + } + } +} +``` + +The response will contain the new sub-organization ID as well as details about its associated Ethereum wallet: + +```js +{ + "subOrganizationId": "", // the organization_id that the end-user must use when signing requests + "wallet": { + "walletId": "", // the wallet ID used to generate more accounts + "addresses": "" // the addresses you can now sign with + } +} +``` + +Note: root users created with sub-organizations can have both API keys and authenticators (e.g. passkeys). In this example we only expect passkeys. See [Sub-Organizations as shared wallets](#sub-organizations-as-shared-wallets) for a use case which requires both. + +With this setup each end-user now has sole control over their sub-organization and any resources created within it. Your application cannot take any actions on resources within the sub-organization without explicit cryptographic authorization from the end-user in the form of a passkey signature. + +It's important to note that the initial activity to create a sub-organization has to be authorized by an API key of a user in your main Turnkey organization. Otherwise, anyone would be able to create sub-organizations in your organization! Here's an [example](https://github.com/tkhq/sdk/blob/a2bfbf3cbd6040902bbe4c247900ac560be42925/examples/with-federated-passkeys/src/pages/index.tsx#L88-L116) where the initial registration is done, and posted to a NextJS backend. The NextJS backend inserts the attestation and signs the `CREATE_SUB_ORGANIZATION_V4` activity [here](https://github.com/tkhq/sdk/blob/ba360baeb60d80276f7faeca602b99190fe5affe/examples/with-federated-passkeys/src/pages/api/createSubOrg.ts#L27-L106). + + + + + +While the **first wallet creation is already done** (our `CREATE_SUB_ORGANIZATION` activity accepts a `wallet` parameter!), your end-users can derive more accounts or create more wallets after the fact by using their passkeys to sign a `CREATE_WALLET` activity. + +We've abstracted getting WebAuthn signatures and creating signed Turnkey requests behind typed methods (e.g. `createWallet`). + +Our `TurnkeyClient` (from [`@turnkey/http`](https://www.npmjs.com/package/@turnkey/http)) can be initialized with a `WebauthnStamper` (from [`@turnkey/webauthn-stamper`](https://www.npmjs.com/package/@turnkey/webauthn-stamper)): + +```js +import { WebauthnStamper } from "@turnkey/webauthn-stamper"; +import { TurnkeyClient } from "@turnkey/http"; + +const stamper = new WebAuthnStamper({ + rpId: "your-domain.com", +}); + +// New HTTP client able to sign with passkeys! +const httpClient = new TurnkeyClient( + { baseUrl: "https://api.turnkey.com" }, + stamper +); + +// Signs and sends a request to Turnkey +await httpClient.createWallet({ + type: "ACTIVITY_TYPE_CREATE_WALLET", + organizationId: "", + timestampMs: String(Date.now()), + parameters: { + walletName: "New Wallet", + accounts: [ + { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: "m/44'/60'/0'/0/0", + addressFormat: "ADDRESS_FORMAT_ETHEREUM", + }, + ], + }, +}); +``` + +In the snippet above we send the activity directly to Turnkey's backend. Our SDK also comes with abstractions to create a `signedRequest`, which contain all the components needed to forward it to Turnkey: URL, body, and a stamp header (with name and value properties). Use `httpClient.stampCreateWallet` to get a signed request. Your backend server can then proxy it to Turnkey. + +Next, we can derive additional accounts (addresses) given a single HD wallet. The shape of the request is as follows: + +```js + { + "type": "ACTIVITY_TYPE_CREATE_WALLET_ACCOUNTS", + "timestampMs": "", + "organizationId": "", + "parameters": { + "walletId": "", + "accounts": [ + { + "curve": "CURVE_SECP256K1", + "pathFormat": "PATH_FORMAT_BIP32", + "path": "m/44'/60'/0'/0/0", + "addressFormat": "ADDRESS_FORMAT_ETHEREUM" + } + ] + } + } +``` + + + + + +The end-user must provide a signature over each `SIGN_TRANSACTION` activity with their passkey. In your application, a user action (for example tapping a "Withdraw Rewards" button) might trigger the flow. The details of this transaction should be presented to the user for confirmation, followed by a passkey prompt to sign the Turnkey activity. An activity to sign a transaction looks like the following: + +The end-user must provide a signature over each `SIGN_TRANSACTION` activity with their passkey. In your application, a user action (for example tapping a "Withdraw Rewards" button) might trigger the flow. The details of this transaction should be presented to the user for confirmation, followed by a passkey prompt to sign the Turnkey activity. An activity to sign a transaction looks like the following: + +```js +{ + "type": "ACTIVITY_TYPE_SIGN_TRANSACTION_V2", + "timestampMs": "", + "organizationId": "", + "parameters": { + "signWith": "", + "type": "TRANSACTION_TYPE_ETHEREUM", + "unsignedTransaction": "" + } +} +``` + +Turnkey returns a signed transaction in the activity result which your application can broadcast using any provider you'd like. + + + + + +#### Custodial Wallets + +Most of the steps outlined in the previous section remain unchanged: applications creating custodial wallets should still create segregated sub-organizations for their end-users to avoid limits (we currently have a maximum of 100 users per organization, whereas an organization can have unlimited sub-organizations). + +The main difference is in the Root Quorum settings: upon creating a new sub-organization, your business's API key is used to bootstrap each end-user organization. The `CREATE_SUB_ORGANIZATION_V4` activity becomes: + +```json +{ +"type": "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V4", +"timestampMs": "", +"organizationId": "", +"parameters": { + "subOrganizationName": "", + "rootUsers": [{ + "userName": "", + "userEmail": "(optional)", + "authenticators": [], + "apiKeys": [ + "apiKeyName": "", + "publicKey": "" + ], + }], + "rootQuorumThreshold": 1, + "wallet": { + "walletName": "Default ETH Wallet", + "accounts": [ + { + "curve": "CURVE_SECP256K1", + "pathFormat": "PATH_FORMAT_BIP32", + "path": "m/44'/60'/0'/0/0", + "addressFormat": "ADDRESS_FORMAT_ETHEREUM", + }, + ], + }, +} +} +``` + +(Note the empty `"authenticators"` list!) + +Key creation and signatures can also be performed with this root API user, and the end-user doesn't need to be involved in the activity signing process. + +Policies can be use to segregate permissions if needed: you could, for example, bootstrap each sub-org with 2 API users: one to create keys and setup the organization policies; the other to sign transactions. + +#### Shared Wallets + +For the sake of completeness: it is possible to create "shared custody" wallets with the sub-organization primitive. To do this, an application would setup sub-organizations with the following settings: + +- Root quorum threshold: 2 + +- Root users: + + - 1 user representing the end-user (with their Passkey as an authenticator) + - 1 user representing the business (with an API key attached) + +The signing process would then have to involve **both** the user and the business +since the root quorum threshold is 2. To reduce friction for the end-user, +many clients opt to start with a root quorum of 1. This way, you can take +certain actions with your business's API key root user **prior** to updating +the root quorum threshold to 2. + +Looking for more support? Check out our Demos, SDKs and Code Examples below\! + +## Demos + +### 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 - - - - + + demo embedded wallet login view + + + + demo embedded wallet dashboard view + -Or, if you're looking to create smart wallets for your users, using Turnkey as a user-friendly, recoverable EOA, check out our [guide](/reference/aa-wallets) on integrating Account Abstraction (AA) wallets with Turnkey. +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). + + + demo embedded wallet screenshot + + +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. + + + ethers ui screenshot + + +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. + + + viem ui screenshot + + +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). + + +
+ gelato turnkey screenshot +
+ + +#### 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 + +
+ } + label="React" + href="/sdks/react" + /> + } + label="React Native" + href="/sdks/react-native" + /> + } + label="iOS (Swift)" + href="/sdks/swift" + /> + } + label="Flutter" + href="/sdks/flutter" + /> + } + label="Typescript" + href="/sdks/javascript-browser" + /> +
+ +### Next Steps + +Learn more about our powerful features [here](/embedded-wallets/features/overview). diff --git a/getting-started/embedded-wallet-quickstart.mdx b/getting-started/embedded-wallet-quickstart.mdx index 1b759e36..9fcc3445 100644 --- a/getting-started/embedded-wallet-quickstart.mdx +++ b/getting-started/embedded-wallet-quickstart.mdx @@ -6,7 +6,7 @@ sidebarTitle: "Embedded Wallets" ## Prerequisites -This guide assumes you've completed the steps to create an account, organization, and API keypair as described in the [Quickstart](/getting-started/quickstart) section. +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 @@ -25,6 +25,7 @@ pnpm add @turnkey/sdk-react ```bash yarn yarn add @turnkey/sdk-react ``` + @@ -36,12 +37,13 @@ yarn add @turnkey/sdk-react **React 19 Users** - If you're using Next.js 15 with React 19 you may encounter an installation error with `@turnkey/sdk-react`. Consider: +If you're using Next.js 15 with React 19 you may encounter an installation error with `@turnkey/sdk-react`. Consider: + +- Downgrading React to `18.x.x` +- Using `npm install --force` or `--legacy-peer-deps` - * Downgrading React to `18.x.x` - * Using `npm install --force` or `--legacy-peer-deps` +You may learn more about this [here](https://ui.shadcn.com/docs/react-19). - You may learn more about this [here](https://ui.shadcn.com/docs/react-19). ## Setup @@ -67,14 +69,13 @@ yarn add @turnkey/sdk-react Fill in with your Organization ID and API Base URL. - - ```tsx src/app/layout.tsx const config = { apiBaseUrl: "https://api.turnkey.com", defaultOrganizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID, }; ``` + @@ -94,6 +95,7 @@ yarn add @turnkey/sdk-react ); } ``` + **React 19 Users** @@ -114,6 +116,7 @@ yarn add @turnkey/sdk-react ## Authenticate + Auth Component @@ -156,6 +159,7 @@ The auth component contains the UI and logic to handle the authentication flow. }; ``` + @@ -186,6 +190,7 @@ The auth component contains the UI and logic to handle the authentication flow. ); } ``` + @@ -226,15 +231,16 @@ The auth component contains the UI and logic to handle the authentication flow. ); } ``` + Add a dashboard route to the app where the user will be able to view their account and sign messages. - ```tsx src/app/dashboard/page.tsx - export default function Dashboard() { - return
Dashboard
; - } - ``` +```tsx src/app/dashboard/page.tsx +export default function Dashboard() { + return
Dashboard
; +} +``` Since the app is wrapped with the `TurnkeyProvider` component, the `useTurnkey` hook is available to all child components. Calling `turnkey.getCurrentUser()` will return the current user's session information from local storage. @@ -269,7 +275,7 @@ export type Session = { expiry: number; // Unix timestamp representing the expiry of the session set by the server token: string; // publicKey used to verify stamped requests (lives in IndexedDB); can temporarily be a read bearer token }; - +```
@@ -285,35 +291,36 @@ The `signRawPayload` method requires these parameters: * `hashFunction`: The selected hash algorithm - For simplicity, a human readable string, `message`, will be the payload to sign. Add a state variable to store the message and an input field to allow the user to enter the message: +For simplicity, a human readable string, `message`, will be the payload to sign. Add a state variable to store the message and an input field to allow the user to enter the message: ```tsx src/app/dashboard/page.tsx import { useState, useEffect } from "react"; export default function Dashboard() { - //... - - const [message, setMessage] = useState(""); - - //... - - return ( -
- setMessage(e.target.value)} - placeholder="Enter message to sign" - /> -
- ); +//... + +const [message, setMessage] = useState(""); + +//... + +return ( +
+ setMessage(e.target.value)} + placeholder="Enter message to sign" + /> +
+); } -``` +```` +
Signing messages requires a signer e.g. a Turnkey wallet address to sign with and a payload or message to sign. A new wallet is created for each user during the authentication flow. - Create a function called `getSignWith`, to get the user's wallet account address which will be used to sign the message. +Create a function called `getSignWith`, to get the user's wallet account address which will be used to sign the message. Use the `getSession` method from the `useTurnkey` hook to get the user's read-write session: @@ -361,14 +368,15 @@ export default function Dashboard() { return (/*
...
*/*/); } ``` +
Create a function called `signMessage`. This function will: -* Get the user's wallet account for signing the message -* Compute the keccak256 hash of the message -* Call the `signRawPayload` method +- Get the user's wallet account for signing the message +- Compute the keccak256 hash of the message +- Call the `signRawPayload` method Note: To compute the `keccak256` hash of the message, this example uses the `hashMessage` function from `viem`. However, any other hashing library can be used. @@ -387,6 +395,7 @@ const signMessage = async () => { }); }; ``` + @@ -430,6 +439,7 @@ export default function Dashboard() { ); } ``` +
@@ -445,8 +455,8 @@ In this quickstart guide, you've learned how to: - ```tsx src/app/page.tsx - "use client"; +```tsx src/app/page.tsx +"use client"; import { useState } from "react"; import { Auth } from "@turnkey/sdk-react"; @@ -483,13 +493,10 @@ export default function Home() { ); } - ``` +``` + ## Next Steps - - - Check out our examples. - - +Learn more about integrating Embedded Wallets and our powerful features [here](/embedded-wallets/overview). diff --git a/getting-started/quickstart.mdx b/getting-started/quickstart.mdx index 97f05ac1..d10280ad 100644 --- a/getting-started/quickstart.mdx +++ b/getting-started/quickstart.mdx @@ -1,7 +1,7 @@ --- -title: "Quickstart" +title: "Account Setup" description: "Before diving into the code, let's set up your organization and conjure up an API keypair to unlock the full potential of Turnkey!" -sidebarTitle: Overview +sidebarTitle: Account Setup --- ## Create an Account @@ -44,6 +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). + @@ -58,6 +59,7 @@ The API keypair is used to authenticate requests to Turnkey. We'll create one no + @@ -66,15 +68,28 @@ The API keypair is used to authenticate requests to Turnkey. We'll create one no + ## Next Steps 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/getting-started/signing-automation-quickstart.mdx b/getting-started/signing-automation-quickstart.mdx index aacd4bdb..934de841 100644 --- a/getting-started/signing-automation-quickstart.mdx +++ b/getting-started/signing-automation-quickstart.mdx @@ -1,12 +1,12 @@ --- -title: "Signing Automation Quickstart" -description: "Turnkey's Signing Automation enables 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: "Signing Automation" +title: "Transaction Automation Quickstart" +description: "Turnkey's Transaction Automation enables 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: "Transaction Automation" --- ## Prerequisites -This guide assumes you've completed the steps to create an account, organization, and API keypair as described in the [Quickstart](/getting-started/quickstart) section. +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 @@ -48,6 +48,7 @@ You'll see output like this: ``` 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. + @@ -60,21 +61,22 @@ 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: +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" - } - ``` +```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: +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" +} +``` - ```json - { - "error": "failed to associate the API key with an organization; please manually specify the organization ID" - } - ``` @@ -109,13 +111,13 @@ turnkey request --path /public/v1/submit/sign_transaction --body '{ }' --key-name quickstart ``` -If you'd like to broadcast your transaction, you can easily do so via [Etherscan](https://etherscan.io/pushTx). +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) +Learn more about integrating Transaction Automation and our powerful +features [here](/signing-automation/overview). diff --git a/home.mdx b/home.mdx index bc14f182..24747d06 100644 --- a/home.mdx +++ b/home.mdx @@ -1,10 +1,23 @@ --- -title: "Getting started with Turnkey" -description: "Welcome to Turnkey! To make the most out of Turnkey's wallet infrastructure, we've compiled a list of helpful resources for you below." -sidebarTitle: "Welcome" -mode: "wide" +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 transaction automation. + +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. + @@ -40,384 +53,180 @@ mode: "wide" /> -## About +# Turnkey's Products -[Turnkey](https://turnkey.com) is highly flexible key management infrastructure, purpose-built for security and scale. Our API and open-source SDKs make it easy for you to take your product from 0 to 1, and enable developers to create millions of embedded wallets and automate complex onchain transactions. +Turnkey covers two main use cases: Embedded Wallets and Transaction Automation. -Whether you're building a DeFi platform, a payments app, an AI agent, or anything requiring a private key, Turnkey offers the building blocks to bring your ideas to life. +## Embedded Wallets -Our solution covers two main use cases: +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 -Create millions of embedded wallets on behalf of your users for a flawless onboarding and in-app experience. +| 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. | +| Multi-Chain Support | Sign transactions across chains with out-of-the-box support for most chains and assets. | +| 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. | - - - - - - - - -{" "} - +## Transaction Automation -{" "} - +Turnkey's Transaction Automation empowers teams to automate complex workflows at scale with granular policies for transaction limits, user permissions, and more. -{" "} - +### Features -{" "} - - -{" "} - +| Feature | Description | +| :------------------------ | :-------------------------------------------------------------------------------------------------------------------------- | +| Multi-Chain 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. | +| Dashboard | View activities, approve or deny sensitive transactions, manage wallets, and create policies for your Turnkey organization. | +| Compliance (Audit Trail) | Track events and changes across the stack, ensuring accountability. | +| Import / Export | Easily migrate existing private keys without exposure. | +| QuorumOS | Run applications inside Trusted Execution Environments (TEEs). | +| CLI | Use Turnkey's command-line interface to interact with our API. | +| Remote Attestation | Verify that our code is running the way it should be. | +| Offchain Smart Contracts | Deploy smart contracts that are cryptographically verified off-chain. | +| Multi-signature approvals | Set a quorum of users for approving and/or denying transactions. | +| Secure Hardware | Ensure that private keys are never generated, stored, or accessed outside of TEEs. | - - - +# Concepts -{" "} - -To start building with embedded wallets, check out our demos, kits and detailed -guides: +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. - - - - - - - - +#### Here's how that works: -Read our concept overview below for a smooth implementation. - - - - -Automate even the most complex onchain transactions, from staking management to smart contract interactions. - - - - - - - - - - - - - To start using Turnkey for onchain automation, -check out [Quickstart](/getting-started/signing-automation-quickstart), [server signing -guide](/signing-automation/code-examples/signing-transactions), and explore our [API -Reference](/api-reference/overview). - -Read our concept overview below for a smooth implementation. - - - -## Concepts Overview - - - Before getting started, we highly recommend familiarizing yourself with - Turnkey's core concepts below 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: +- **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. -{/* Ensure the text content of this heading below ↓ "Here's how..." matches the href in styles.css to keep it hidden in the table of contents */} - -### Here's how that works: +There is no set relationship between organizations, sub-organizations, activities, wallets, and resources. +This makes Turnkey highly flexible and configurable to any use case. -- **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 and _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. +For a more in-depth overview, learn more [here](/concepts/overview). - - There is no set relationship between organizations, sub-organizations, - activities, wallets, and resources. This makes Turnkey highly flexible and - configurable to any use case. - +# SDKs -For a more in-depth overview, [access our documentation here](/concepts/overview). +Turnkey provides a variety of client libraries for building with Embedded Wallets, Transaction Automation, +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. -## Demos And Examples - - - - - - - - - - - -{/* Ensure the text content of this heading below ↓ "Feature spotlight..." matches the href in styles.css to keep it hidden in the table of contents */} - -### **Feature spotlight: Send crypto via a URL** - -Moonshot users can now send crypto to their friends via a URL. Under the hood, Turnkey pre-generates a wallet for the new user and loads it with the specified amount of crypto — all authenticated via a biometric passkey (e.g. Face ID). - - - - - - - ***To see Turnkey in action, check out some of our favorite customer integrations:*** - -1. [Moonshot](https://moonshot.money/): An app that makes trading crypto as easy as buying stocks. -2. [Infinex](https://infinex.xyz/): A crypto app to access everything onchain in one place. Founded by Kain from Synthetix. -3. [Azura](https://azura.xyz/): A next-generation DeFi platform to make onchain trading easier. -4. [PVP Trade](https://pvp.trade/): A SocialFi experience to trade tokens with friends on Telegram. -5. [Spectral](https://syntax.spectrallabs.xyz/): A platform for creating onchain AI agents. - - - -## SDKs - -Turnkey provides a variety of client libraries for interacting with Turnkey's API and performing common workflows, as well as several wrappers for popular web3 libraries for easy integration into existing dApps. - -| Integration | Package | -| ------------------ | -------------------------------------------------------------------------------------------------------------------------------- | -| JavaScript Browser | [`@turnkey/sdk-browser`](https://www.npmjs.com/package/@turnkey/sdk-browser) | -| JavaScript Server | [`@turnkey/sdk-server`](https://www.npmjs.com/package/@turnkey/sdk-server) | -| React | [`@turnkey/sdk-react`](https://www.npmjs.com/package/@turnkey/sdk-react) | -| React Native | See [React Native passkey stamper](https://github.com/tkhq/sdk/tree/main/packages/react-native-passkey-stamper) for more details | -| Golang | [`go-sdk`](https://github.com/tkhq/go-sdk) | -| Rust | [`rust-sdk`](https://github.com/tkhq/rust-sdk) | -| Ruby | [`ruby-sdk`](https://github.com/tkhq/ruby-sdk) | -| Command Line | [Using the CLI](/sdks/cli) | -| Flutter/Dart | All packages published [here](https://pub.dev/publishers/turnkey.com/packages) | -| Swift | [`swift-sdk`](https://github.com/tkhq/swift-sdk) | -| Ethers | [`@turnkey/ethers`](https://www.npmjs.com/package/@turnkey/ethers) | -| Viem | [`@turnkey/viem`](https://www.npmjs.com/package/@turnkey/viem) | -| CosmJS | [`@turnkey/cosmjs`](https://www.npmjs.com/package/@turnkey/cosmjs) | -| EIP-1193 | [`@turnkey/eip-1193-provider`](https://www.npmjs.com/package/@turnkey/eip-1193-provider) | -| Solana | [`@turnkey/solana`](https://www.npmjs.com/package/@turnkey/solana) | -| Advanced | See [docs](/category/advanced) for more details | - -## Security - -We take security seriously at Turnkey and have built our architecture to ensure that you and your end users' private keys are safe. Our [whitepaper](https://whitepaper.turnkey.com/) covers our holistic security model in-depth and our vision for building verifiable key management infrastructure. - - - - - -Turnkey uses AWS Nitro Enclaves, a type of tamper-proof Trusted Execution Environment (TEE), for all sensitive operations. Private keys are never decrypted outside these enclaves, and only you can authorize key usage with your credentials. Turnkey has also implemented stringent protocols to prevent individual engineers from altering enclave code, ensuring a secure end-to-end deployment process. - -Turnkey does not store unencrypted private keys, but rather persists encrypted private key ciphertext inside of our primary and disaster recovery databases. This ciphertext is only to be decrypted from within the bounds of a secure enclave running verified Turnkey applications. - - - - - -Turnkey's novel security architecture means raw private keys themselves are never exposed to Turnkey, your software, or your team. Specifically, Turnkey stores encrypted private keys that are only decrypted when you authenticate to an auditable, tamper-proof secure enclave with your secret (e.g., API key or Passkey credentials). You (and/or your end users, depending on your implementation) remain the owner of your private keys and the funds controlled by those private keys at all times. See [quorum deployments](/security/quorum-deployments) for more details on how we provision secure enclaves to ensure you're always in control of your private keys. - - - - +
+

+ Embedded Wallets +

+
+ +
+ } + label="React" + href="/sdks/react" + /> + } + label="React Native" + href="/sdks/react-native" + /> + } + label="iOS (Swift)" + href="/sdks/swift" + /> + } + label="Flutter" + href="/sdks/flutter" + /> + } + label="Browser" + href="/sdks/javascript-browser" + /> +
+ +
+

+ Transaction Automation +

+
-Turnkey's infrastructure combines extensive SDK support with open-source packages that allow for straightforward integration across multiple languages and environments. While competitors offers closed or proprietary SDKs that lock you into limited workflows and create dependencies on specific providers, Turnkey's open SDKs enable direct access to both lower-level abstractions and the core API, granting you complete control over your wallet infrastructure. +
-We've also open-sourced [QuorumOS](https://github.com/tkhq/qos): a minimal, immutable, and deterministic Linux unikernel build system for use cases that require high security and accountability. QuorumOS is a critical part of Turnkey's stack for running applications inside TEEs at modern cloud scale. +} + label="Go" + href="/sdks/golang" +/> +} + label="Ruby" + href="/sdks/ruby" +/> +} + label="Python" + href="/sdks/python" +/> +} + label="Rust" + href="/sdks/rust" +/> -Currently, we are working on a verifiable security model for our API, so that third parties can attest to the code that is running inside of Turnkey's secure enclaves. + } + label="Server" + href="/sdks/javascript-server" + /> +
-
+### 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). -Turnkey highly values the security of our software, services, and systems and we actively encourage the ethical reporting of any security vulnerabilities discovered. We invite researchers and users to report potential security vulnerabilities to our Bug Bounty Program via [the form in our docs,](/security/reporting-a-vulnerability) or to us via email at [security@turnkey.com](mailto:security@turnkey.com). When submitting a report via email, please provide a thorough description of the vulnerability, including steps to reproduce it and its potential impact. +# Security -If you believe you have found very serious vulnerability, we ask that you encrypt the message to the `security.turnkey.com` PGP key (FP: `AD6C 3E61 17A5 886E 550E F8BB 3ACD E5EA 8DC7 9275`). This can also be found on Turnkey's website at `https://www.turnkey.com/.well-known/security.asc` +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 +# Support -For support, product feedback, and input, join our community Slack channel [here](https://join.slack.com/t/clubturnkey/shared_invite/zt-31v4yhgw6-PwBzyNsWCCBTk2xft3EoHQ). +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-31v4yhgw6-PwBzyNsWCCBTk2xft3EoHQ). diff --git a/networks/movement.mdx b/networks/movement.mdx new file mode 100644 index 00000000..811c46ab --- /dev/null +++ b/networks/movement.mdx @@ -0,0 +1,208 @@ +--- +title: "Movement" +description: "Movement support on Turnkey" +--- + +## Address derivation + +Turnkey supports Movement address derivation. Movement is built on the Move VM and uses Ed25519 cryptography, which Turnkey fully supports. + +## Transaction construction and signing + +Turnkey supports Movement transaction signing through our core signing capabilities. We provide an example repository that demonstrates how to construct and sign Movement transactions: + +- [`examples/with-movement`](https://github.com/tkhq/sdk/tree/main/examples/with-movement): demonstrates transaction construction and broadcast on Movement. + +## Example + +Here's a comprehensive example showing how to integrate Turnkey with Movement for transaction signing: + +```typescript [expandable] +import { Turnkey } from "@turnkey/sdk-server"; +import { + MovementClient, + AptosAccount, + TxnBuilderTypes, + BCS, + HexString +} from "movement-sdk"; + +// Custom Turnkey signer for Movement +class TurnkeyMovementSigner { + private turnkeyClient: Turnkey; + private movementClient: MovementClient; + private address: string; + private organizationId: string; + + constructor( + apiPrivateKey: string, + apiPublicKey: string, + organizationId: string, + address: string, + nodeUrl: string = "https://seed-node1.movementlabs.xyz" + ) { + this.turnkeyClient = new Turnkey({ + apiBaseUrl: "https://api.turnkey.com", + apiPrivateKey, + apiPublicKey, + defaultOrganizationId: organizationId + }); + + this.movementClient = new MovementClient(nodeUrl); + this.address = address; + this.organizationId = organizationId; + } + + // Get the account address + getAddress(): string { + return this.address; + } + + // Sign a raw payload using Turnkey + async signRawPayload(payload: Uint8Array): Promise { + const hexPayload = Buffer.from(payload).toString('hex'); + + const signResult = await this.turnkeyClient.signRawPayload({ + organizationId: this.organizationId, + signWith: this.address, + payload: hexPayload, + encoding: "hex" + }); + + return Buffer.from(signResult.signature, 'hex'); + } + + // Submit a transaction to Movement + async submitTransaction(payload: any): Promise { + try { + // Get account info for sequence number + const accountInfo = await this.movementClient.getAccount(this.address); + const sequenceNumber = BigInt(accountInfo.sequence_number); + + // Get chain ID for the transaction + const chainId = await this.movementClient.getChainId(); + + // Build raw transaction + const rawTx = new TxnBuilderTypes.RawTransaction( + // Account address + TxnBuilderTypes.AccountAddress.fromHex(this.address), + // Sequence number + sequenceNumber, + // Transaction payload + payload, + // Max gas + BigInt(10000), + // Gas unit price + BigInt(100), + // Expiration timestamp (30 seconds from now) + BigInt(Math.floor(Date.now() / 1000) + 30), + // Chain ID + new TxnBuilderTypes.ChainId(chainId) + ); + + // Serialize the transaction + const serializer = new BCS.Serializer(); + rawTx.serialize(serializer); + const toSign = serializer.getBytes(); + + // Sign the transaction + const signature = await this.signRawPayload(toSign); + + // In a real implementation, you would need the actual public key from the address + // Here we use a placeholder + const dummyPublicKey = new TxnBuilderTypes.Ed25519PublicKey(new Uint8Array(32)); + + // Create authenticator + const authenticator = new TxnBuilderTypes.TransactionAuthenticatorEd25519( + dummyPublicKey, + new TxnBuilderTypes.Ed25519Signature(signature) + ); + + // Create signed transaction + const signedTx = new TxnBuilderTypes.SignedTransaction( + rawTx, + authenticator + ); + + // Submit transaction + const txnResponse = await this.movementClient.submitTransaction( + BCS.bcsToBytes(signedTx) + ); + + return txnResponse.hash; + } catch (error) { + console.error("Error submitting transaction:", error); + throw error; + } + } +} + +// Example usage: Transfer MOV tokens +async function transferMovTokens() { + const signer = new TurnkeyMovementSigner( + process.env.API_PRIVATE_KEY!, + process.env.API_PUBLIC_KEY!, + process.env.ORGANIZATION_ID!, + process.env.MOVEMENT_ADDRESS!, // Your Movement address in Turnkey + "https://testnet.movementlabs.xyz" // Use testnet URL for development + ); + + const recipientAddress = "0x..."; // Recipient address + const amount = 1000000; // Amount (adjust decimal places as needed) + + // Create a transfer transaction payload + const payload = new TxnBuilderTypes.TransactionPayloadEntryFunction( + TxnBuilderTypes.EntryFunction.natural( + "0x1::coin", + "transfer", + [new TxnBuilderTypes.TypeTagStruct( + TxnBuilderTypes.StructTag.fromString("0x1::mov_coin::MOV") + )], + [ + BCS.bcsToBytes(TxnBuilderTypes.AccountAddress.fromHex(recipientAddress)), + BCS.bcsSerializeUint64(amount) + ] + ) + ); + + try { + const txnHash = await signer.submitTransaction(payload); + console.log(`Transaction submitted successfully! Hash: ${txnHash}`); + return txnHash; + } catch (error) { + console.error("Error transferring tokens:", error); + throw error; + } +} + +## Movement Network Support + +Turnkey supports: + +* Movement Mainnet +* Movement Testnet + +## Key Features for Movement + +* **Ed25519 Signing**: Turnkey fully supports the Ed25519 curve used by Movement +* **BCS Format Support**: Sign transactions serialized in the Binary Canonical Serialization format +* **Integration Example**: Our example repository provides a reference implementation for integrating with the Movement ecosystem + +## Benefits of Using Turnkey with Movement + +* **Secure Private Keys**: Keys are securely stored in Turnkey's infrastructure +* **Customizable Policies**: Implement rules to control when and how transactions are signed +* **Developer-Friendly**: Seamless integration with existing Movement development workflows +* **Enterprise-Ready**: Built for production environments with high security requirements + +## Move Smart Contract Development + +Movement leverages the Move VM for smart contracts. When developing Move smart contracts on Movement, Turnkey can securely manage your private keys for: + +* Deploying Move modules +* Publishing packages +* Executing Move functions +* Managing on-chain 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-31v4yhgw6-PwBzyNsWCCBTk2xft3EoHQ). +``` diff --git a/networks/others.mdx b/networks/others.mdx new file mode 100644 index 00000000..31f4dd5f --- /dev/null +++ b/networks/others.mdx @@ -0,0 +1,47 @@ +--- +title: "Others" +mode: "wide" +--- + +**Can't find your preferred network?** +Turnkey is chain-agnostic, and our flexible infrastructure is built to +support underlying cryptographic curves, instead of specific chains and assets. If your chain isn’t mentioned, check if the underlying curve is compatible – we support signing for all chains and assets on the **Ed25519 and Secp256k1** curves. + +This includes chains like: + +- Algorand +- Avalanche +- Cardano +- Dogecoin +- Filecoin +- Hedera +- Litecoin +- Monero +- NEAR +- Polkadot +- Stellar +- Tezos +- TON (The Open Network) +- XRP +- …and more! + +If you're unsure whether your chain is supported, don't hesitate to +[get in touch](https://www.turnkey.com/contact-us). + +**Code example** +Learn how to use Turnkey to interact with over 60 blockchain networks via +this [external demo](https://github.com/AdamikHQ/adamik-tutorial/tree/signer-turnkey). +Adamik's terminal-based application provides a user-friendly interface to explore the +following multichain capabilities, powered by Turnkey: + +- Generating secure cryptographic keys +- Creating addresses for different networks +- Viewing account balances and token holdings +- Preparing, signing, and broadcasting transactions +- Visualizing API interactions in real time + +**Want more support?** +We are continuously evaluating and adding support for emerging assets and protocols. +If there are specific networks you'd like to see us offer deeper support for, or +if you're looking for more code examples, please let us know by contacting us at +hello@turnkey.com, on X, or on Slack. diff --git a/networks/overview.mdx b/networks/overview.mdx index af95a26b..c1569c07 100644 --- a/networks/overview.mdx +++ b/networks/overview.mdx @@ -1,11 +1,18 @@ --- title: "Overview" -description: "Turnkey operates at the **cryptographic curve** level rather that specific assets. As a result Turnkey is asset agnostic and can be used with any type of asset as long as we support the underlying curve." +description: "Turnkey operates at the **cryptographic curve** level rather than specific assets. As a result Turnkey is asset agnostic and can be used with any type of asset as long as we support the underlying curve." +mode: "wide" --- -## Introduction +import NetworkLinks from "/snippets/shared/networks-links.mdx"; -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-31v4yhgw6-PwBzyNsWCCBTk2xft3EoHQ). +## Multichain support at Turnkey + +Turnkey is extremely flexible and supports all EVM and SVM chains, along with a vast majority of chains and assets across crypto. You don’t have to wait for us to add your preferred network. + +This is because while other wallet infrastructure solutions focus on setting up support for each chain individually after they launch, Turnkey’s low-level approach focuses on supporting the underlying cryptographic curves: Secp2456k1 and Ed25519. + +As a result, Turnkey is asset agnostic and can be used with any type of asset, as long as we support its corresponding curve. ## What is Turnkey's approach to supporting crypto assets? @@ -36,37 +43,8 @@ At our highest level of support, Turnkey offers the ability to parse transaction | 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-31v4yhgw6-PwBzyNsWCCBTk2xft3EoHQ). + For more details about each ecosystem, refer to the pages below: - - - Overview - - - Ethereum (EVM) support on Turnkey - - - Solana (SVM) support on Turnkey - - - Bitcoin support on Turnkey - - - Cosmos support on Turnkey - - - Tron support on Turnkey - - - Sui support on Turnkey - - - Sei support on Turnkey - - - Aptos support on Turnkey - - - Specific support for other ecosystems on Turnkey - - \ No newline at end of file + diff --git a/production-checklist/embedded-wallet.mdx b/production-checklist/embedded-wallet.mdx new file mode 100644 index 00000000..adcce80a --- /dev/null +++ b/production-checklist/embedded-wallet.mdx @@ -0,0 +1,35 @@ +--- +title: "Production Checklist - Embedded Wallets" +description: "This checklist contains recommendations and steps specifically for deploying an Embedded Wallet production environment." +sidebarTitle: "Embedded Wallets" +--- + +## 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, 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/production-checklist/transaction-automation.mdx b/production-checklist/transaction-automation.mdx new file mode 100644 index 00000000..d53c9325 --- /dev/null +++ b/production-checklist/transaction-automation.mdx @@ -0,0 +1,35 @@ +--- +title: "Production Checklist - Transaction Automation" +description: "This checklist contains recommendations and steps specifically for deploying a Transaction Automation production environment." +sidebarTitle: "Transaction Automation" +--- + +## 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, 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/products/embedded-wallets/features/export-wallets.mdx b/products/embedded-wallets/features/export-wallets.mdx new file mode 100644 index 00000000..8b54d031 --- /dev/null +++ b/products/embedded-wallets/features/export-wallets.mdx @@ -0,0 +1,3 @@ +import ExportWallets from "/snippets/shared/export-wallets.mdx"; + + \ No newline at end of file diff --git a/products/embedded-wallets/features/gas-sponsorship.mdx b/products/embedded-wallets/features/gas-sponsorship.mdx new file mode 100644 index 00000000..82d07fb2 --- /dev/null +++ b/products/embedded-wallets/features/gas-sponsorship.mdx @@ -0,0 +1,4 @@ +--- +title: "Gas Sponsorship" +description: "" +--- diff --git a/products/embedded-wallets/features/import-wallets.mdx b/products/embedded-wallets/features/import-wallets.mdx new file mode 100644 index 00000000..d32abb96 --- /dev/null +++ b/products/embedded-wallets/features/import-wallets.mdx @@ -0,0 +1,3 @@ +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 new file mode 100644 index 00000000..6085269b --- /dev/null +++ b/products/embedded-wallets/features/multi-chain-support.mdx @@ -0,0 +1,12 @@ +--- +title: "Multi-Chain Support" +description: "Overview of our multi-chain network support." +--- + +import NetworkLinks from "/snippets/shared/networks-links.mdx"; + +Turnkey delivers robust multi-chain 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 new file mode 100644 index 00000000..5244087a --- /dev/null +++ b/products/embedded-wallets/features/policy-engine.mdx @@ -0,0 +1,8 @@ +--- +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/transaction-automation/features/dashboard.mdx b/products/transaction-automation/features/dashboard.mdx new file mode 100644 index 00000000..cc959670 --- /dev/null +++ b/products/transaction-automation/features/dashboard.mdx @@ -0,0 +1,4 @@ +--- +title: "Dashboard" +description: "Coming soon!" +--- \ No newline at end of file diff --git a/products/transaction-automation/features/export-wallets.mdx b/products/transaction-automation/features/export-wallets.mdx new file mode 100644 index 00000000..7c790fed --- /dev/null +++ b/products/transaction-automation/features/export-wallets.mdx @@ -0,0 +1,3 @@ +import ExportWallets from "/snippets/shared/export-wallets.mdx"; + + diff --git a/products/transaction-automation/features/import-wallets.mdx b/products/transaction-automation/features/import-wallets.mdx new file mode 100644 index 00000000..8532ef03 --- /dev/null +++ b/products/transaction-automation/features/import-wallets.mdx @@ -0,0 +1,3 @@ +import ImportWallets from "/snippets/shared/import-wallets.mdx"; + + diff --git a/products/transaction-automation/features/multi-chain-support.mdx b/products/transaction-automation/features/multi-chain-support.mdx new file mode 100644 index 00000000..3351dd9b --- /dev/null +++ b/products/transaction-automation/features/multi-chain-support.mdx @@ -0,0 +1,12 @@ +--- +title: "Multi-Chain Support" +description: "Overview of our multi-chain network support." +--- + +import NetworkLinks from "/snippets/shared/networks-links.mdx"; + +Turnkey delivers robust multi-chain 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/transaction-automation/features/off-chain-contracts.mdx b/products/transaction-automation/features/off-chain-contracts.mdx new file mode 100644 index 00000000..a872d9a9 --- /dev/null +++ b/products/transaction-automation/features/off-chain-contracts.mdx @@ -0,0 +1,4 @@ +--- +title: "Off-chain Contracts" +description: "Coming soon!" +--- diff --git a/products/transaction-automation/features/scoped-api-key.mdx b/products/transaction-automation/features/scoped-api-key.mdx new file mode 100644 index 00000000..0dcec597 --- /dev/null +++ b/products/transaction-automation/features/scoped-api-key.mdx @@ -0,0 +1,4 @@ +--- +title: "Scoped API Key" +description: "Coming soon!" +--- diff --git a/products/transaction-automation/features/security/compliance.mdx b/products/transaction-automation/features/security/compliance.mdx new file mode 100644 index 00000000..8dba1ca0 --- /dev/null +++ b/products/transaction-automation/features/security/compliance.mdx @@ -0,0 +1,5 @@ +--- +title: "Compliance" +description: "Coming soon!" +sidebarTitle: "Compliance" +--- diff --git a/products/transaction-automation/features/security/quorom-os.mdx b/products/transaction-automation/features/security/quorom-os.mdx new file mode 100644 index 00000000..b04bb979 --- /dev/null +++ b/products/transaction-automation/features/security/quorom-os.mdx @@ -0,0 +1,12 @@ +--- +title: "QuoromOS" +--- + +# Overview + +QuoromOS 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/transaction-automation/features/security/remote-attestation.mdx b/products/transaction-automation/features/security/remote-attestation.mdx new file mode 100644 index 00000000..649ce066 --- /dev/null +++ b/products/transaction-automation/features/security/remote-attestation.mdx @@ -0,0 +1,15 @@ +--- +title: "Remote Attestation" +--- + +Remote attestation enables an enclave to cryptographically prove its identity and integrity to a remote verifier. Key points: + +- Enclaves generate a signed quote containing measurements (hashes) of their code and configuration. +- Only quotes signed by a hardware root of trust (e.g., AWS Nitro Security Module) are considered valid. +- The verifier checks the quote against expected measurements to ensure no unauthorized modifications. +- Attestation workflows typically follow: + 1. Host application sends an attestation request to the enclave. + 2. Enclave performs measurement, signs the quote, and returns it. + 3. Host or external verifier validates the signature and measurements. + +This process establishes trust before any sensitive data or operations are performed within the enclave. diff --git a/products/transaction-automation/features/security/secure-hardware.mdx b/products/transaction-automation/features/security/secure-hardware.mdx new file mode 100644 index 00000000..b13401fa --- /dev/null +++ b/products/transaction-automation/features/security/secure-hardware.mdx @@ -0,0 +1,11 @@ +--- +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/transaction-automation/policy-engine.mdx b/products/transaction-automation/policy-engine.mdx new file mode 100644 index 00000000..852ecdc6 --- /dev/null +++ b/products/transaction-automation/policy-engine.mdx @@ -0,0 +1,9 @@ +--- +title: "Policy Engine" +description: "Embedded wallets - Policy Engine feature." +sidebarTitle: "Overview" +--- + +import PolicyEngine from '/snippets/shared/policy-engine.mdx'; + + \ No newline at end of file diff --git a/sdks/Ruby.mdx b/sdks/Ruby.mdx index 42f69e9f..79b41d0e 100644 --- a/sdks/Ruby.mdx +++ b/sdks/Ruby.mdx @@ -4,3 +4,102 @@ description: "Turnkey offers native tooling for interacting with the API using R mode: wide --- +This repository contains a Ruby gem, [`turnkey_client`](https://rubygems.org/gems/turnkey_client) to interact with the Turnkey API. + +## Using Turnkey in your Ruby projects + +To install `turnkey_client`, install it with bundler: + +```rb +bundle add turnkey_client +``` + +Then `require` it in Ruby files to use it: + +```rb +require "turnkey_client" + +client = TurnkeyClient.configure do |c| + c.api_public_key = "your API public key" + c.api_private_key = "your API private key" +end + +response = TurnkeyClient::SessionsApi.new(client).get_whoami({ organization_id: "your organization ID"}) +puts response +``` + +See the [examples](./examples/) folder if you're looking for a complete sample project + +## Examples + +- [Whoami](./examples/whoami/): example showcasing API request signing in its simplest form +- [Signing](./examples/signing/): example showcasing wallet creation and ETH message signing + +## Using Turnkey in your Rails projects + +To use in Rails we recommend creating a new `config/initializers/turnkey.rb` file: + +```rb +require 'turnkey_client' + +TURNKEY_CLIENT = TurnkeyClient.configure do |config| + c.api_public_key = "your API public key" + c.api_private_key = "your API private key" +end +``` + +You can then use this in your controller or models with: + +```rb +require 'turnkey_client' + +TurnkeyClient::SessionsApi.new(TURNKEY_CLIENT).get_whoami({ organization_id: "your organization ID"}) +``` + +## Re-generating `turnkey_client` + +We use a swagger spec and [Swagger Codegen](https://github.com/swagger-api/swagger-codegen) to generate `turnkey_client`. To update this gem: + +- Update the swagger spec in [`turnkey_client_inputs`](./turnkey_client_inputs/) +- Bump `gemVersion` in [`config.json`](./turnkey_client_inputs/config.json) +- Run `make` + +## Updating codegen templates + +We use custom templates to insert custom functionality, namely: + +- added `openssl` as a dependency to load API keys +- added functionality to insert `X-Stamp` headers to requests for authentication +- modified `configure` function to require a valid P256 public/private key pair at initialization time + +If you want to tweak something related to codegen itself, head ([here](./turnkey_client_inputs/templates/)), make the desired change, and re-generate `turnkey_client` + +If you want to update templates with upstream this is a bit harder but possible: these templates were downloaded from [this folder](https://github.com/swagger-api/swagger-codegen-generators/tree/0f7eeb2ca53e5fff886ce1a609bce1b1e75063fe/src/main/resources/handlebars/ruby) (this is a permalink to the right git SHA). You can see all the changes made to these by looking at the history of changes in the templates folder: https://github.com/tkhq/ruby-sdk/commits/main/turnkey_client_inputs/templates. + +## Ruby + +On Mac, Ruby will come installed automatically. However, the default version might not be compatible with certain gems, nor will it allow you to modify the default gems directory. To set up Ruby, there are many options: rbenv, rvm, asdf, chruby, etc. For example, rbenv can be set up by following the instructions [here](https://github.com/rbenv/rbenv?tab=readme-ov-file#installation). + +## Rubocop + +We use Rubocop for linting. To install: + +```sh +$ gem install rubocop +``` + +And run: + +```sh +$ rubocop +``` + +## Releasing on Rubygems.org + +To build and release: + +```sh +$ cd turnkey_client +$ gem build turnkey_client.gemspec +$ gem push turnkey_client-x.y.z.gem +``` diff --git a/sdks/cli.mdx b/sdks/cli.mdx index 2fd7a6a2..3fa9a4a0 100644 --- a/sdks/cli.mdx +++ b/sdks/cli.mdx @@ -1,21 +1,24 @@ --- 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: "Command Line" +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 +- 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. - Find organization ID + Find organization ID For convenience, it's worth setting this as a permanent shell variable: @@ -49,7 +52,10 @@ When you run this command, Turnkey’s CLI generates an API key pair and **store Navigate to your user page by clicking on "User Details" in the user dropdown menu. - Find user details + Find user details 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. @@ -101,6 +107,6 @@ If you'd like to broadcast your transaction, you can easily do so via [Etherscan ## 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) +- 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/javascript-browser.mdx b/sdks/javascript-browser.mdx index 80a6c15c..ebee7a1d 100644 --- a/sdks/javascript-browser.mdx +++ b/sdks/javascript-browser.mdx @@ -1,5 +1,6 @@ --- title: "JavaScript Browser" +sidebarTitle: "Typescript | Browser" --- ## Overview diff --git a/sdks/javascript-server.mdx b/sdks/javascript-server.mdx index 43dec3db..f766fa28 100644 --- a/sdks/javascript-server.mdx +++ b/sdks/javascript-server.mdx @@ -1,6 +1,7 @@ --- title: "JavaScript 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 diff --git a/sdks/python.mdx b/sdks/python.mdx new file mode 100644 index 00000000..60162c77 --- /dev/null +++ b/sdks/python.mdx @@ -0,0 +1,26 @@ +--- +title: "Python" +description: "Turnkey offers support for interacting with the API using Python. See [https://github.com/tkhq/python-sdk](https://github.com/tkhq/python-sdk) for more details." +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. + +If you are working on a project in Python and would benefit from a Python SDK please open an issue or get in touch with us at [hello@turnkey.com](mailto:hello@turnkey.com) to discuss prioritizing this. + +## Stamper + +The Stamper utility stamps requests to the Turnkey API and authenticates your calls. To use it, fill out the fields at the top of the stamper script: + +```python +ENDPOINT = "https://api.turnkey.com/public/v1/whoami" +API_PUBLIC_KEY = "" +API_PRIVATE_KEY = "" +ORG_ID = "" +``` + +You can find the script and examples in the [python-sdk repo](https://github.com/tkhq/python-sdk). diff --git a/sdks/swift.mdx b/sdks/swift.mdx index a195e465..9916f7b1 100644 --- a/sdks/swift.mdx +++ b/sdks/swift.mdx @@ -1,6 +1,6 @@ --- title: Turnkey Swift SDK -sidebarTitle: "Overview" +sidebarTitle: "iOS" description: "This documentation contains guides for using the [Turnkey Swift SDK](https://github.com/tkhq/swift-sdk)." --- diff --git a/signing-automation/co-signing-transactions.mdx b/signing-automation/co-signing-transactions.mdx index 34a9d45a..4e10b989 100644 --- a/signing-automation/co-signing-transactions.mdx +++ b/signing-automation/co-signing-transactions.mdx @@ -1,6 +1,7 @@ --- title: "Co-signing Transactions" description: "Learn how to set up and use co-signing (multi-sig) wallets with Turnkey." +sidebarTitle: "Multi-Sig Approvals" --- ## Introduction to Co-signing diff --git a/signing-automation/overview.mdx b/signing-automation/overview.mdx index d38fc2f0..f3d56999 100644 --- a/signing-automation/overview.mdx +++ b/signing-automation/overview.mdx @@ -1,25 +1,28 @@ --- -title: "Signing Automation" -sidebarTitle: "Introduction" +title: "Overview" --- -## Securely automate any signing workflow +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. Our API and policy engine provide the building blocks for creating custom automation solutions that fit your specific needs, from smart contract interactions to staking management. +Turnkey empowers teams to automate complex signing workflows at scale without compromising on security or flexibility. Transaction Automation provides the building blocks for creating custom solutions that make your product more secure, from role-based access controls to privacy-preserving smart contracts. -### Why automate with Turnkey? +With Transaction Automation, you can: -Turnkey's secure, flexible, and scalable private key infrastructure is built on a custom secure-enclave-based architecture, ensuring the highest level of protection for your automated signing workflows. With Turnkey, 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 -* 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 -### Code examples +At the foundation of Transaction Automation is 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. -Explore the following code examples to see Turnkey's server-side signing automation in action, where requests and transactions are signed in a server context using API keys: +## What kind of policies can you create? | Example | Description | | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | @@ -28,12 +31,46 @@ Explore the following code examples to see Turnkey's server-side signing automat | [`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 | -### Other use cases +Almost all actions on Turnkey are implicitly denied by default. +See our [Policy Overview](/products/transaction-automation/policy-engine) for exceptions. -#### Staking operations +## 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 +- Mnemonic and key generation +- Rewards claiming and distribution +- Network voting and governance actions + +## SDKs + +
+ } label="Go" href="/sdks/golang" /> + } + label="Ruby" + href="/sdks/ruby" + /> + } + label="Python" + href="/sdks/python" + /> + } + label="Rust" + href="/sdks/rust" + /> + + } + label="Typescript" + href="/sdks/javascript-server" + /> +
+ +## Next Steps + +Dig into Transaction Automations features like multi-chain support, scoped API keys, multi-signature approvals, and [more](/products/transaction-automation/features/multi-chain-support). diff --git a/snippets/logo.mdx b/snippets/logo.mdx new file mode 100644 index 00000000..2e00353d --- /dev/null +++ b/snippets/logo.mdx @@ -0,0 +1,344 @@ +export const Logo = ({ id, className = "", fill = "", ...props }) => { + if (id === "react") { + return ( + + React Logo + + + + + + + + ); + } + if (id === "react-native") { + return ( + + React Native Logo + + + ); + } + if (id === "android-kotlin") { + return ( + + Android Kotlin Logo + + + + + + + + + + + + + + + + + + + + ); + } + if (id === "ios-swift") { + return ( + + iOS Swift Logo + + + + ); + } + if (id === "unity") { + return ( + + Unity Logo + + + + + + + ); + +} +if (id === "flutter") { +return ( + + + Flutter Logo + + + + +); } +if (id === "rest-api") { + return ( + + Rest API Logo + + + ); + } + + if (id === 'typescript') { + return ( + + + + + + ); + } + if (id === "go") { + return ( + + Go Logo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); + } + if (id === "rust") { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); + } + if (id === "python") { + return ( + + Python Logo + + + + + + + + + + + + + + ); + } + + if (id === 'ruby') { + return ( + + + + + ) + } + return null; +}; + +export const Card = ({ title, children, className = "", href }) => { + return ( +
+

{title}

+ {children} +
+ ); +}; diff --git a/snippets/shared/export-wallets.mdx b/snippets/shared/export-wallets.mdx new file mode 100644 index 00000000..6e139a3f --- /dev/null +++ b/snippets/shared/export-wallets.mdx @@ -0,0 +1,24 @@ +--- +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." +mode: wide +--- + +The process of exporting wallets or private keys from Turnkey is broken up into two primary steps: + + + + Export the wallet or private key via Turnkey. You must specify the wallet or + private key ID, as well as a target public key, which the wallet or private + key will be encrypted to. Encryption ensures that the key material is only + accessible by the client, and cannot be extracted by any man-in-the-middle + (MITM) + + Decrypt the resulting bundle returned by Turnkey + + +See the [Enclave to end-user secure channel](/security/enclave-secure-channels) for more technical details. + +## Implementation Guides + +See [Code Examples](/embedded-wallets/code-examples/export) for more details. diff --git a/snippets/shared/import-wallets.mdx b/snippets/shared/import-wallets.mdx new file mode 100644 index 00000000..164907bc --- /dev/null +++ b/snippets/shared/import-wallets.mdx @@ -0,0 +1,24 @@ +--- +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." +mode: wide +--- + +The process of importing wallets or private keys into Turnkey is broken up into three primary steps: + + + + Initialize the import process. This produces an import bundle, containing a + public key and signature. These artifacts will be used in the next step to + ensure that key material is only accessible by Turnkey, and cannot be + extracted by any man-in-the-middle (MITM) + + Encrypt the key material to the artifacts from the previous step + Import the encrypted bundle to Turnkey + + +See the [Enclave to end-user secure channel](/security/enclave-secure-channels) for more technical details. + +## Implementation Guides + +See [Code Examples](/embedded-wallets/code-examples/import) for more details. diff --git a/snippets/shared/networks-links.mdx b/snippets/shared/networks-links.mdx new file mode 100644 index 00000000..9c39810d --- /dev/null +++ b/snippets/shared/networks-links.mdx @@ -0,0 +1,101 @@ + + + Overview + + + Ethereum (EVM) + + + Solana (SVM) + + + Bitcoin + + + Cosmos + + + Tron + + + Sui + + + Sei + + + Aptos + + + Movement + + + Others + + diff --git a/snippets/shared/policy-engine.mdx b/snippets/shared/policy-engine.mdx new file mode 100644 index 00000000..e3c4d7e4 --- /dev/null +++ b/snippets/shared/policy-engine.mdx @@ -0,0 +1,59 @@ +--- +title: "Policy overview" +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: "Policy Engine" +--- + +## Policy structure + +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. + +#### See below for an example policy that allows a single user to send transactions to a single address + +```json +{ + "effect": "EFFECT_ALLOW", + "consensus": "approvers.any(user, user.id == '4b894565-fa11-42fc-b813-5bf4ea3d53f9')", + "condition": "eth.tx.to == ''" +} +``` + +## Policy evaluation + +All policies defined within an Organization are evaluated on each request. The image below describes how an activity outcome is determined when resolving multiple policies. The rule follows the below steps: + + + + If a quorum of root users takes the action, the final outcome is + `OUTCOME_ALLOW` + + + Else if any applicable policy has `EFFECT_DENY`, the final outcome is `OUTCOME_DENY`. This is also referred to as "explicit deny." + + + Else if at least one applicable policy has `EFFECT_ALLOW`, then the final + outcome is `OUTCOME_ALLOW` + + + Else the final outcome is `OUTCOME_DENY`. This is also referred to as + "implicit deny." In cases of conflicts, `EFFECT_DENY` always wins. + + + +Stated differently: + + + policy overview + + +Almost all actions on Turnkey are implicitly denied by default. There are a few exceptions, however: + +- Root users bypass any policies. +- All users have implicit GET (read) permissions in their own Organization and any associated Sub-Organizations. +- All users have implicit permission to change their own credentials. +- All users have implicit permission to approve an activity if they were included in consensus (i.e., a user specified as part of the consensus required to approve a SIGN_TRANSACTION activity does not need separate, explicit permission to sign transactions). diff --git a/snippets/square-card.mdx b/snippets/square-card.mdx new file mode 100644 index 00000000..201a7af7 --- /dev/null +++ b/snippets/square-card.mdx @@ -0,0 +1,17 @@ +export const SquareCard = ({ icon, label, className = "", ...props }) => { + return ( + +
+
+ {icon} +
+ + {label} + +
+
+ ); +}; diff --git a/wallets/wagmi.mdx b/wallets/wagmi.mdx new file mode 100644 index 00000000..774fb756 --- /dev/null +++ b/wallets/wagmi.mdx @@ -0,0 +1,560 @@ +--- +title: Integrating an Embedded Wallet with Wagmi +sidebarTitle: "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 +managed by Turnkey. + +With this concept in mind, we're going to build a custom Wagmi connector that communicates +with an embedded wallet rendered in a popup, enabling integration across multiple dApps. + +## System Components Overview + +Our system involves three key parts working together: + +**Embedded Wallet (Pop-up):** A web application (likely React/Next.js) hosted by you. +This UI handles user authentication (passkeys via Turnkey), transaction signing, and communication with the dApp via `postMessage`. +It securely interacts with the Turnkey API. Reference the `popup-wallet-demo`'s [`@/apps/wallet`](https://github.com/tkhq/popup-wallet-demo/blob/6eb0b732d6a57dad229a39120299a1762040e0ad/apps/wallet) provides a concrete example. + +**EIP-1193 Provider:** A JavaScript class implementing the [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) standard. +It acts as the intermediary between the dApp and the popup embedded wallet. Reference the `popup-wallet-demo`'s [`@/apps/dapp/lib/eip1193-provider.ts`](https://github.com/tkhq/popup-wallet-demo/blob/6eb0b732d6a57dad229a39120299a1762040e0ad/apps/dapp/lib/eip1193-provider.ts) provides a concrete example. + +**Wagmi Connector:** A custom connector built using Wagmi's `createConnector` utility. It wraps our EIP-1193 provider, making the wallet compatible with the Wagmi ecosystem. Reference the `popup-wallet-demo`'s [`@/apps/dapp/lib/connector.ts`](https://github.com/tkhq/popup-wallet-demo/blob/6eb0b732d6a57dad229a39120299a1762040e0ad/apps/dapp/lib/connector.ts) and [`@/apps/dapp/lib/wagmi.ts`](https://github.com/tkhq/popup-wallet-demo/blob/6eb0b732d6a57dad229a39120299a1762040e0ad/apps/dapp/lib/wagmi.ts) provide concrete examples. + +## Architecture Flow + +The interaction sequence generally follows these steps: + +**Connection:** + +- A user on a dApp clicks "Connect Wallet" and selects your wallet. +- The dApp calls the `connect` method on your Wagmi connector. +- The connector initializes the EIP-1193 provider. +- The connector calls `provider.request({ method: 'eth_requestAccounts' })`, which opens your Embedded Wallet pop-up. +- The user authenticates in the pop-up and chooses which wallet account to connect. +- The pop-up returns the selected account(s) and `chainId` to the provider via `postMessage`. +- The provider resolves `eth_requestAccounts`, and the connector returns the account(s) and `chainId` to the dApp. + +**RPC Request (e.g., `eth_sendTransaction`):** + +- The dApp uses a Wagmi hook (e.g., `useSendTransaction`) which triggers a request. +- Wagmi sends the `eth_sendTransaction` request to your connector. +- The connector forwards the request to the EIP-1193 provider. +- The provider identifies this as a signing request and opens the Embedded Wallet pop-up (if not already open), sending the transaction details via `postMessage`. +- The user reviews and approves the transaction in the pop-up. +- The pop-up uses Turnkey to sign the transaction and potentially broadcast it (or return the signed transaction). +- The pop-up sends the transaction hash (or signed transaction) back to the provider via `postMessage`. +- The provider resolves the request promise, returning the result to the dApp via the connector. + +**RPC Request (e.g., `eth_blockNumber`):** + +- The dApp triggers a read-only request. +- Wagmi sends the `eth_blockNumber` request to your connector. +- The connector forwards it to the EIP-1193 provider. +- The provider identifies this as a read-only request and forwards it directly to a public RPC node. +- The public RPC node returns the result. +- The provider returns the result to the dApp via the connector. + +## Flow Diagram + +```mermaid +sequenceDiagram + participant DApp + participant WagmiConnector + participant EIP1193Provider + participant EmbeddedWalletPopup + participant PublicRPC + participant TurnkeyAPI + participant User + + %% Connection Flow + DApp->>WagmiConnector: connect() + WagmiConnector->>EIP1193Provider: initialize() + WagmiConnector->>EIP1193Provider: request(eth_requestAccounts) + EIP1193Provider->>EmbeddedWalletPopup: openPopup() + %% User Authentication & Account Selection + EmbeddedWalletPopup->>TurnkeyAPI: exchangeIdToken(idToken) + TurnkeyAPI-->>EmbeddedWalletPopup: accessToken + EmbeddedWalletPopup->>TurnkeyAPI: listAccounts(accessToken) + TurnkeyAPI-->>EmbeddedWalletPopup: accounts + EmbeddedWalletPopup->>User: display account picker + Note over User,EmbeddedWalletPopup: selects account + EmbeddedWalletPopup->>EIP1193Provider: postMessage(accounts, chainId) + EIP1193Provider-->>WagmiConnector: resolve eth_requestAccounts + WagmiConnector-->>DApp: connected(accounts, chainId) + + %% Signing Request Flow (e.g., eth_sendTransaction) + DApp->>WagmiConnector: request({ method: 'eth_sendTransaction', params: [...] }) + WagmiConnector->>EIP1193Provider: request({ method: 'eth_sendTransaction', ... }) + EIP1193Provider->>EmbeddedWalletPopup: postMessage({ type: 'RPC_REQUEST', payload: {...} }) + Note over EmbeddedWalletPopup,TurnkeyAPI: User Approves & Signs Tx + EmbeddedWalletPopup->>EIP1193Provider: postMessage({ type: 'RPC_RESPONSE', payload: { txHash: '0x...' } }) + EIP1193Provider-->>WagmiConnector: success(txHash) + WagmiConnector-->>DApp: success(txHash) + + %% Read Request Flow (e.g., eth_call) + DApp->>WagmiConnector: request({ method: 'eth_call', params: [...] }) + WagmiConnector->>EIP1193Provider: request({ method: 'eth_call', ... }) + EIP1193Provider->>PublicRPC: eth_call(...) + PublicRPC-->>EIP1193Provider: result + EIP1193Provider-->>WagmiConnector: success(result) + WagmiConnector-->>DApp: success(result) +``` + +### Connect flow demo + +